Недавно на созвоне финансовый аналитик показывал мне свою Excel-модель. Двенадцать листов, формулы ссылаются друг на друга чере�� три уровня вложенности, именованные диапазоны вместо переменных, и INDIRECT, который динамически собирает адреса ячеек из строк. Я смотрел на это и думал: чувак, ты же написал компилятор. Ты просто не знаешь об этом.

750 миллионов человек используют Excel. Для сравнения — на Python пишут примерно 15 миллионов, на JavaScript — около 17. Excel обгоняет их всех вместе взятых раз в двадцать. И вот что забавно: подавляющее большинство этих людей искренне считают, что они «просто работают с таблицами». Заполняют ячейки. Делают отчёты.

Нет, они программируют.


Формулы — это функции. Буквально.

Возьмём обычную формулу:

=СУММ(A1:A10) * (1 + B2)

Что здесь происходит? Вызов функции СУММ с аргументом-диапазоном, результат умножается на выражение в скобках. Никаких побочных эффектов, формула не меняет другие ячейки. При одинаковых входных данных всегда возвращает одинаковый результат. Композиция — результат одной функции подставляется в другую.

Это же чистые функции. Это же, простите, функциональное программирование.

И я не натягиваю сову на глобус. Саймон Пейтон-Джонс — один из создателей Haskell, если кто вдруг не в курсе — работал в Microsoft Research и прямо говорил, что Excel самый успешный функциональный язык в истории. Ну, справедливости ради, он ещё добавлял «к сожалению» — но это уже детали )

Подумайте: каждая ячейка — это привязка имени к выражению. B5 — это не «ячейка», это переменная. =A1+A2 — это не «формула», это определение функции без аргументов. Лист — пространство имён. Книга — модуль.


VLOOKUP — это hash table lookup

=ВПР(E2; A:B; 2; ЛОЖЬ)

Переведём на человеческий: «найди значение E2 в первом столбце диапазона A:B, верни соответствующее значение из второго столбца, точное совпадение». Это dict.get(key) в Python. Это map.find(key) в C++. Это lookup в хеш-таблице.

А ИНДЕКС + ПОИСКПОЗ? Это тот же lookup, но с разделённой адресацией — сначала находим позицию, потом по позиции достаём значение. Двухфазный поиск, как в базах данных с отдельным индексом.

Гипотетический бухгалтер Марина из соседнего отдела, которая «просто делает сводную табличку», на самом деле пишет запросы к структурам данных. Марина — программист. Марина об этом не знает, и лучше ей пока не говорить (она и так нервничает перед квартальным отчётом).


IF(AND(...)) — привет, pattern matching

=ЕСЛИ(И(A1>100; B1="Москва"); "VIP"; ЕСЛИ(A1>50; "Стандарт"; "Эконом"))

Вложенные ЕСЛИ — это switch/case. Или, если посмотреть с определённого ракурса, pattern matching. Не самый элегантный, конечно. Семь уровней вложенности ЕСЛИ — это то ещё зрелище, и я видел двенадцать.

Но ведь работает же.

А SWITCH, добавленный в Office 365:

=SWITCH(A1; 1;"Январь"; 2;"Февраль"; 3;"Март"; "Неизвестно")

Это уже просто нормальный switch-case, без вложенности. Даже с дефолтным значением.

IFS, MAXIFS, COUNTIFS — всё это фильтрация с предикатами. =СЧЁТЕСЛИ(A:A; ">100") — это filter(lambda x: x > 100, data).count(). Просто записано через ячейки вместо кода.


LAMBDA: момент, когда Excel перестал притворяться

В 2021 году Microsoft добавила LAMBDA в Excel. И вот тут всё стало совсем серьёзно.

=LAMBDA(x; y; x^2 + y^2)(3; 4)

Анонимная функция. Принимает два аргумента, возвращает сумму квадратов. Вызывается сразу с аргументами 3 и 4. Результат — 25.

Но это цветочки. LAMBDA можно присвоить имя через Диспетчер имён — и получить именованную функцию, которую можно вызывать из любой ячейки:

ГИПОТЕНУЗА = LAMBDA(a; b; КОРЕНЬ(a^2 + b^2))

Теперь =ГИПОТЕНУЗА(3; 4) возвращает 5. Пользовательская функция. Без VBA, без макросов, без единой строчки «настоящего» кода.

А ещё LAMBDA может вызывать сама себя. Рекурсия. В Excel.

ФАКТОРИАЛ = LAMBDA(n; ЕСЛИ(n<=1; 1; n * ФАКТОРИАЛ(n-1)))

Вместе с LAMBDA завезли MAP, REDUCE, SCAN, MAKEARRAY, BYROW, BYCOL. Это полноценные функции высшего порядка. MAP применяет лямбду к каждому элементу массива. REDUCE свёртывает массив в скаляр. Это буквально map и reduce из любого функционального языка, только в ячейках с рамочками.

Haskell-программисты сейчас либо плачут, либо обновляют резюме на «Senior Excel Developer».


Доказательство Тьюринг-полноты: Rule 110 в ячейках

Окей, но «похоже на программирование» и «Тьюринг-полон» — разные вещи. Можно ли на Excel вычислить всё, что вычислимо?

Можно. И это доказано.

Rule 110 — одномерный клеточный автомат, про который Мэтью Кук доказал Тьюринг-полноту в 2004 году. Правило простое: берём ячейку и двух её соседей (три бита → восемь комбинаций), для каждой комбинации определяем, будет ли ячейка живой в следующем поколении. «110» — это двоичное представление таблицы переходов: 01101110.

Реализация в Excel выглядит так (и это не шутка):

Строка 1 — начальное состояние. Одна ячейка = 1, остальн��е = 0.

Каждая последующая строка — новое поколение. Формула в ячейке B2:

=ЕСЛИ(ИЛИ(
  И(A1=1;B1=1;C1=1;0);
  И(A1=1;B1=1;C1=0;1);
  И(A1=1;B1=0;C1=1;1);
  И(A1=0;B1=1;C1=1;1);
  И(A1=0;B1=1;C1=0;1);
  И(A1=0;B1=0;C1=1;1);
  И(A1=0;B1=0;C1=0;0)
); 1; 0)

(Да, можно записать компактнее. Но так нагляднее.)

Копируем вправо и вниз. Включаем условное форматирование: 1 = чёрный, 0 = белый. И получаем характерный фрактальный треугольник Rule 110 — прямо в таблице.

Rule 110 — Тьюринг-полна. Excel реализует Rule 110. Следовательно, Excel — Тьюринг-полон.

Если вам кажется, что это слишком просто, то есть и другие подходы. Построение машины Тьюринга напрямую через ячейки (лента = строка, состояния = столбец, переходы через VLOOKUP). Реализация лямбда-исчисления через LAMBDA. Построение тега-систем. Все дороги ведут к одному: Excel вычисляет всё, что вычислимо.

(правда, он при этом может сожрать 16 гигабайт оперативки и зависнуть на полчаса, но это уже детали реализации)


Ужас из корпоративного мира

Знаете, что интересно? Не то, что Excel Тьюринг-полный язык. А то, что на этом Тьюринг-полном языке работает мировая финансовая система.

По разным оценкам, от 80% до 95% финансовых моделей в мире живут в .xlsx файлах. Инвестиционные банки. Хедж-фонды. Страховые компании. Центральные банки. Бюджеты государств. Всё это формулы в ячейках, без version control, без тестов, без code review.

И это ломается. Регулярно. Иногда эпически.

JPMorgan, 2012. Трейдер по прозвищу «Лондонский кит». Модель оценки рисков — Excel. Ошибка: в одной формуле вместо деления суммы на среднее стояло деление суммы на сумму. Copy-paste, забыли поправить. Результат — $6.2 миллиарда убытков. И��-за одной ячейки.

Расследование показало ещё кое-что: модель частично работала через ряд связанных Excel-файлов, и часть данных между ними передавалась copy-paste вручную. Вы представляете? Риск-модель банка с активами в $2.6 триллиона на copy-paste.

MI5, 2011. Британская контрразведка. Excel-таблица с телефонными номерами подозреваемых. Формат номера автоматически конвертировался — лишние цифры отбрасывались. Результат: прослушивали не тех людей.

Barclays, 2008. При покупке активов Lehman Brothers скрытые строки в Excel не были замечены при конвертации в PDF. Barclays случайно включил в сделку 179 контрактов, которые не собирался покупать.

И мой любимый жанр — «генетика vs. Excel». Десятки научных статей содержали ошибки, потому что Excel услужливо конвертировал названия генов в даты. SEPT2 (Septin 2) → 2-Sep. MARCH1 → 1-Mar. В 2020 году научное сообщество сдалось и переименовало 27 генов. Не Excel поправили, а гены переименовали. Видимо Excel победить невозможно.


Почему мы не относимся к этому серьёзно

Есть такой когнитивный фокус: мы не воспринимаем Excel как язык программирования, потому что у него нет атрибутов «настоящего» программирования. Нет текстового редактора с подсветкой синтаксиса (ну, формулы подсвечиваются, но это не считается, да?). Нет git. Нет Stack Overflow-тредов с пометкой [excel-lang].

А ещё — и это, кажется, главное — пользователи Excel не идентифицируют себя как программистов. Финансист не скажет «я пишу код». Он скажет «я строю модель». HR не скажет «я поддерживаю legacy-систему». Она скажет «я обновляю табличку с отпусками».

Но если мы применим формальные критерии:

  • Переменные? Ячейки.

  • Функции? Формулы. С LAMBDA — пользовательские функции с рекурсией.

  • Условная логика? IF, IFS, SWITCH.

  • Циклы? Ну, формально — через рекурсию в LAMBDA и через протягивание формул вниз (итерация по массиву).

  • Структуры данных? Таблицы, именованные диапазоны, массивы.

  • Ввод-вывод? Ячейки ввода, ячейки вывода, Power Query для чтения данных.

  • Тьюринг-полнота? Доказана.

Это язык программирования. Просто с очень необычным IDE.

(Кстати, хоть и необычным, но удивительно удобным для определённого класса задач. Мгновенная визуализация данных, zero deployment, отладка через тыканье в ячейки — попробуйте получить такой feedback loop в Python.)


Спагетти из ячеек

Каждый, кто наследовал чужой Excel-файл, знает это чувство. Открываешь, а там 47 листов. Формулы ссылаются на другие файлы, которых нет. Именованные диапазоны с именами типа xlnm.PrintArea. Циркулярные ссылки, которые «так и задумано». Условное форматирование на 200 правил. И где-то на листе «Лист3 (2) — копия» — та самая формула, от которой зависит весь квартальный отчёт.

Это же спагетти-код. Это буквально спагетти-код, только в ячейках. И самое грустное — к нему применимы все те же проблемы, от которых страдает обычный legacy: нет документации, автор уволился, никто не понимает почему оно работает, и все боятся что-то менять.

Только в обычном программировании мы хотя бы придумали инструменты: линтеры, тесты, CI/CD, code review. В Excel-мире этого (почти) нет. PwC делали исследование — 88% корпоративных таблиц содержат ошибки.

Мы бы ни за что не допустили такой уровень багов в продакшен-коде. Но в Excel — пожалуйста, вот ваш бюджет на 2026 год, в строке 847 формула ссылается не на тот столбец, удачи.


Что с этим делать

Можно, конечно, сказать «перепишите всё на Python». Ага. Скажите это финансовому директору, который 20 лет строит модели в Excel и чей мозг в буквальном смысле думает ячейками. Он вас вежливо пошлёт. И будет прав — его Excel-модель, при всех её проблемах, работает прямо сейчас, а ваш Python-скрипт надо ещё написать, протестировать, задокументировать, и убедить двадцать человек им пользоваться.

Microsoft, кажется, понимает ситуацию. LAMBDA и функции высшего порядка — это попытка дать Excel-программистам (да, программистам) более мощные инструменты, не заставляя их уходить из привычной среды. Power Query — это ETL прямо в Excel. Power Pivot — OLAP. Типы данных — это, по сути, структуры.

Может, правильный подход — не вытаскивать людей из Excel, а принести в Excel практики нормальной разработки? Тестирование, модульность?

А может, стоит просто признать очевидное. 750 миллионов людей пишут код каждый день. Они используют функциональный, Тьюринг-полный язык с графическим интерфейсом и мгновенным feedback loop. Этот язык запускает мировую финансовую систему, корпоративное планирование и половину научных исследований.

Но интересно, что самый массовый язык программирования в истории — тот, чьи пользователи не знают, что они программисты.