Механизм вычислений Excel
Обзор
HotXLS включает встроенный механизм для разбора и вычисления формул; этот механизм программно вычисляет формулы ячеек в рамках вашего процесса, устраняя необходимость вызывать Excel или внешние OLE-контроллеры для разрешения вычисленных значений книги
Выполнение вычислений
Перед сохранением или экспортом запустите полный перерасчёт книги, используя основной интерфейс книги
procedure Calculate;
Механизм поддерживает стандартные математические, даты, логические, строковые и статистические семейства функций; он последовательно разрешает зависимости ячеек и отслеживает цепочки ссылок, чтобы предотвратить циклические ссылки
Контекстное вычисление формул
TXLSWorksheet и TXLSXWorksheet открывают EvaluateFormulaAt — вычисление текста формулы в выбранной строке и столбце с нумерацией от единицы, без записи временной ячейки и без изменения состояния вычислений книги
Стили ссылок A1 и R1C1, локальные имена, структурированные ссылки, зависимости формул, корни массивов, типизированные значения ошибок Excel, сведения о летучести, явная авторизация внешних ссылок, отмена и стабильные категории сбоев обрабатываются обычным вычислителем книги
CreateFormulaEvaluationTemplate один раз компилирует неизменяемую точку привязки и переиспользует её для разных целевых ячеек; структурированные ссылки A1, зависящие от строки-цели, разрешаются для каждого целевого контекста, а лимиты на вызов ограничивают длину формулы, число шагов по элементам синтаксиса, глубину рекурсии и объём порождаемых массивов
Типы результатов, бюджеты по умолчанию, правила времени жизни и примеры для Delphi и C++Builder описаны на странице Контекстное вычисление формул
Операторы массивов
Арифметические операторы, операторы сравнения, конкатенации, унарного минуса и процента принимают как скалярные значения, так и вычисленные массивы
Скаляр распространяется на каждый элемент, а массив из одной строки или одного столбца — вдоль совместимого измерения; несовместимые формы возвращают #VALUE!
Ошибки сохраняются в своих ячейках результата, поэтому одно деление на ноль или один недопустимый элемент не отбрасывают значения, вычисленные для остальных ячеек
COMBINA и PERMUTATIONA придерживаются одинаковой семантики для скаляров и транслируемых массивов: аргументы усекаются до неотрицательных целых, а переполнение контролируется; MUNIT возвращает компактную двумерную единичную матрицу из значений Double
FormulaArrayMemoryLimit по умолчанию равен 64 МиБ и ограничивает размер порождаемых матриц; MUNIT дополнительно проверяет оставшуюся область листа, доступную для вывода массива (spill), вместо фиксированного потолка размерности
Проверка наличия формулы
ISFORMULA(reference) проверяет, есть ли в ячейке формула, не вычисляя её, поэтому формула остаётся обнаружимой, даже если её кэшированный результат — ошибка или пустая строка
Прямоугольный диапазон возвращает логический массив той же формы; члены общих формул, а также классических и XLSX формул массива возвращают true, ячейкой же с формулой в динамическом массиве (spill) является только его якорь
Непосредственные значения и скалярные определённые имена возвращают #VALUE!, недопустимые ссылки сохраняют #REF!, а порождаемые логические массивы ограничиваются лимитом FormulaArrayMemoryLimit
XLSX записывает _xlfn.ISFORMULA и восстанавливает чистое имя при открытии, ODS использует стандартный синтаксис of:=ISFORMULA, а вывод в Classic XLS отклоняет эту неподдерживаемую future-функцию до записи данных
Современные текстовые функции
UNICHAR усекает числовые входные значения к нулю и преобразует корректные скалярные значения Unicode в UTF-16, включая вывод суррогатных пар для дополнительных плоскостей и все диапазоны частного использования
Ноль и значения вне допустимого диапазона возвращают #VALUE!, а изолированные суррогатные кодовые точки и несимвольные позиции Unicode возвращают #N/A; для диапазонов и порождаемых массивов эти ошибки сохраняются поэлементно
BAHTTEXT преобразует конечные числа в текст в тайских батах и сатангах, округляет промежуточные midpoint-значения от нуля с точностью до двух десятичных знаков, сохраняет знак минус, когда округлённая величина обнуляется, и раскрывает экспоненциальную запись без сужения через целый тип
XLSX сохраняет UNICHAR как _xlfn.UNICHAR и восстанавливает чистое имя при повторном открытии; BAHTTEXT сохраняет своё стандартное имя функции и остаётся без префикса в формулах XLS и XLSX
Регрессия и прогнозирование
LINEST и LOGEST принимают один или несколько столбцов или строк предикторов и возвращают коэффициенты в порядке Excel, за которыми следует необязательный свободный член
Когда аргумент статистики равен true, обе функции возвращают полный результат из пяти строк: ошибки коэффициентов, статистики качества подгонки, F-статистику, степени свободы, регрессионную сумму квадратов и остаточную сумму квадратов
TREND и GROWTH используют ту же многомерную модель и сохраняют форму (строки или столбца) переданных новых значений предикторов
Перерасчёт зависимостей в Classic XLS
TXLSWorkbook.Recalculate при первом вызове строит граф зависимостей формул и вычисляет формулы в порядке «сначала влияющие», а не в физическом порядке ячеек
Последующие вызовы переиспользуют граф и пересчитывают только транзитивно зависимые от изменённых значений ячейки плюс летучие формулы; правки формул, имена, структура листа и перезапись ссылок безопасно инвалидируют граф и перестраивают его
Циклические ссылки используют настройки классической книги EnableIteration, MaxIterations и MaxIterationChange, а UseFullPrecision=False применяет к кэшированным результатам и всем зависящим от них вычислениям точность отображаемого числа
Зависимости определённых имён
Инкрементальное вычисление отслеживает имена с областью видимости книги и листа сквозь вложенные формулы и ссылки на несколько областей
Ациклические формулы имён отдают свои точные зависимости по ячейкам, а рекурсивные циклы имён безопасно уходят в fallback — постоянный перерасчёт, как для летучих формул
Таблицы данных «что если»
Листы как классического XLS, так и современного XLSX умеют создавать, вычислять, читать, записывать, копировать и структурно настраивать таблицы данных «что если» с одной или двумя переменными
function AddDataTable( const AResultRange, ARowInputCell, AColumnInputCell: WideString ): TXLSDataTable;
Диапазон результата содержит только вычисленные выходные ячейки, а формулы и значения подстановки занимают соседние ячейки — в той же раскладке, что и в Excel
- Таблица с подстановкой по столбцу — оставьте
ARowInputCellпустым, поместите исходную формулу над каждым столбцом результата, а значения подстановки — слева от строк результата - Таблица с подстановкой по строке — оставьте
AColumnInputCellпустым, поместите исходную формулу слева от каждой строки результата, а значения подстановки — над столбцами результата - Таблица с двумя переменными — задайте обе входные ячейки, поместите исходную формулу над и слева от диапазона результата, значения подстановки по строке — над результатами, а по столбцу — слева
Sheet.Range['B1', 'B1'].Value := 0;
Sheet.Range['D1', 'D1'].Formula := '=B1*2+1';
Sheet.Range['C2', 'C2'].Value := 1;
Sheet.Range['C3', 'C3'].Value := 2;
Sheet.Range['C4', 'C4'].Value := 3;
Table := Sheet.AddDataTable('D2:D4', '', 'B1');
Workbook.Recalculate;
Этот пример с подстановкой по столбцу вычисляет 3, 5 и 7 в D2:D4; каждое значение подстановки применяется через изолированный контекст вычислений, поэтому формулы, приходящие к B1 косвенно, через другие ячейки с формулами, пересчитываются корректно
AddDataTable возвращает nil при неверном диапазоне, неверной входной ссылке или когда обе входные ссылки пусты; коллекция DataTables листа открывает получившееся определение и его флаги удалённых входных ссылок
Удаление используемой входной ячейки сохраняет определение таблицы и возвращает #REF! для её выходных ячеек — такова семантика сохранённой книги
Пользовательские функции
Расширьте механизм формул собственной бизнес-логикой; зарегистрируйте свои функции, используя события ниже
Опасные внешние имена и имена в стиле макросов отклоняются до выполнения аргументов или обработчиков, если книга или отдельное контекстное вычисление явно не включит AllowUnsafeFormulaCallbacks
- Событие OnUserFunction — Обработка базовых пользовательских функций
- Событие OnUserFunctionEx — Разрешение сложных функций с параметрами диапазона ячеек
- Обратный вызов пользовательской функции — Требования к сигнатуре для внешних обработчиков