Документация HotXLS

Токены формул и пользовательские функции

HotXLS предоставляет принадлежащие вызывающему коду потоки токенов формул для безошибочного просмотра и защищённой обратной записи в обоих движках книг, а также иерархические реестры пользовательских функций для пользовательских вычислений

Модель токенов

TXLSFormulaTokenClass, TXLSFormulaTokenKindи TXLSFormulaTokenSource классифицируют каждый TXLSFormulaToken и фиксируют, получен ли он из разобранного текста, классических байтов BIFF или другого поддерживаемого источника

TXLSFormulaTokenKind, Opcode, BaseOpcode, TokenClass, RawBytes, TextValue, NumberValue, IntegerValue, ArgumentCount, FunctionIndex, ExternSheetIndex, Row1, Col1, Row2, Col2, Row1Relative, Col1Relative, Row2Relative, Col2Relative, ReferenceUsesOffsets, Supported, ArrayRows, ArrayCols, ArrayValueCountи ArrayValues
TXLSFormulaTokenStreamDecodeBiff, Clone, CloneSyntaxTree, BindContext, CanCompileFor, CanWriteBiffAt, ReplaceReference, Count, Items, Source, FormulaText, FullyDecodedи Rgce, RgbExtra, BiffWritable, and BiffVersion
TXLSCompiledFormulaCreateTokenStream возвращает принадлежащую вызывающему коду копию потока токенов скомпилированной формулы
TXLSFormulaArrayFormulaMode, FormulaLocale, MaxRow, MaxCol, FuncNamebyPtg, FuncArgsCntByPtg, GetCompiled, GetCompiledPreservingUnknownNames, GetCompiledR1C1, GetTokenStream, GetTranslated, GetStoreData, GetStoreDataExt, CanStoreData, BindUserDefinedFunctions, GetTExpData, SetMode, IsKnownFunction, GetFunctionNamesи FunctionArgumentClass

Каждый книжный движок компилирует и транслирует формулы через один общий экземпляр TXLSFormula: GetCompiled разбирает текст в стиле A1 в синтаксическое дерево, GetCompiledR1C1 разрешает ссылки R1C1 относительно координат ячейки, в которой живёт формула, GetTranslated заново строит дерево из классических байтов BIFF, а семейство GetStoreData записывает байты токенов обратно для хранения. MaxRow и MaxCol ограничивают ссылочную сетку, которую принимает компилятор, — движок XLSX поднимает их с умолчаний BIFF8 до сетки XLSX, а ссылки, не помещающиеся в BIFF8, не имеют ptg-формы, поэтому писатели BIFF8 сообщают о них как о некодируемых

ArrayFormulaMode выставляется, когда записывается rgce записи ARRAY (формула массива): ссылки класса значений и константы массивов тогда сериализуются как класс массива (tAreaA / tArrayA), как их и записывает сам Excel. С операндами класса значений Excel вычисляет формулу массива с неявным пересечением, а не как настоящую формулу массива — вот почему движки выставляют флаг для собственного rgce записи ARRAY

Ограниченный осмотр простого сохранённого листа (leaf)

TXLSCompiledFormula.ReadSimpleLeafInfo(ExpectedOwner, MaxBytes, MaxTextCharacters, AllowUnboundBiff) проверяет главное синтаксическое дерево и любой удерживаемый поток токенов на месте, без клонирования, декомпиляции, вычисления или материализации токенов и массивов; по умолчанию AllowUnboundBiff равен False

Поддерживаемые формы — один абсолютный лист REF3D или RANGE3D и один строковый литерал, причём при удерживаемом потоке токен ровно один и связный; выражения, относительные или смещённые ссылки, массивы, внешние данные массивов, неизвестные токены, несовпадающие главное и удерживаемое листья и чужие привязанные владельцы возвращают fslkUnsupported, не меняя кэшированные значения и состояние вычислений

TXLSFormulaSimpleLeafKindfslkUnsupported, fslkRange или fslkLiteral; проверьте Kind, прежде чем пользоваться остальными полями результата
TXLSFormulaLeafOwnerStateflosNoRetainedStream сообщает об отсутствии происхождения у потока токенов, flosUnboundStream сообщает об импортированном непривязанном BIFF, flosSameOwner сообщает о точном совпадении привязанного владельца, а flosForeignOwner отклоняет другого привязанного владельца
TXLSFormulaSimpleLeafInfoЗначимая запись без строк, содержащая Kind, OwnerState, RangeType, ExternId, FirstRow, FirstCol, LastRow, LastCol, TextCharacters, StoredTextCharacters, ReadBytes, SyntaxNodesи TokenCount
Range coordinates and identityКоординаты отсчитываются от нуля; ExternId — это логический идентификатор синтаксического дерева с отсчётом от единицы, а не индекс BIFF на проводе; вызывающий код должен разрешить его через закреплённую книгу и отклонять внешние книги, охваты листов, отсутствующие листы или координаты вне поддерживаемого диапазона захвата
Source costsTextCharacters — длина литерального вывода в кодовых единицах UTF-16 или ноль для диапазона; StoredTextCharacters суммирует удерживаемый исходный текст, текст токена и проверенный текст синтаксиса; ReadBytes суммирует их двухбайтовую стоимость текста и длины удерживаемых исходных байтов, включая отдельно удерживаемые представления; эти счётчики описывают входы ограниченного осмотра, а не общее потребление кучи
Syntax and token countsSyntaxNodes равен единице для простого скомпилированного листа или двум, когда проверяются и главное, и удерживаемое листья; TokenCount равен нулю без потока или единице при поддерживаемом связном удерживаемом потоке
TXLSFormulaTokenStream.ReadSimpleLeafInfoНижний слой принимает те же владельца и квоты, необязательный ComparedLeaf и необязательный ReferenceContext; он проверяет собственные приватные синтаксис, токены и исходные байты потока напрямую; ComparedLeaf добавляет проверки связности главного листа, а ReferenceContext отображает сериализованные внешние индексы текстовых формул без копирования
TXLSCompiledFormula.ReadSimpleLiteralПринимает те же аргументы, повторяет проверки листа и возвращает принадлежащий вызывающему коду WideString только после того, как оставшиеся квоты байтов и символов покрывают и его вывод; неподдерживаемые листья или недостаточная оставшаяся ёмкость возбуждают EInvalidOperation

ExpectedOwner должен быть точным калькулятором, присоединённым к потребляемому источнику, и оставаться живым и стабильным на протяжении всего осмотра и извлечения литерала; отсутствующий владелец возбуждает EArgumentException, отрицательные квоты — EArgumentOutOfRangeException, а слишком большие удерживаемые исходные данные — EInvalidOperation до сравнений содержимого или копирования вывода

Простой лист без удерживаемого потока не устанавливает своего исходного владельца; непривязанный импортированный поток также не несёт идентичности книги, поэтому явный AllowUnboundBiff=True уместен только когда вызывающий код уже закрепил исходный калькулятор и проверит локальную идентичность листа перед чтением ячеек; осмотр импортированных ссылок сейчас принимает ссылки BIFF8 и отклоняет отличающееся представление extern в BIFF5

Устаревшие синтаксические поля с именами FFirstRowRel, FFirstColRel, FLastRowRelи FLastColRel истинны для абсолютных координат; помощник также проверяет независимые флаги относительности токена и представление смещений, поэтому потребителям не нужно выводить абсолютные координаты из этих исторических имён

Syntax tree

CloneSyntaxTree returns a caller-owned parsed tree of TXLSSyntaxItem узлы для структурного осмотра: каждый узел сообщает свой ItemType, literal payload (Value, IntValue, DecValue), leading Spaces, tree links (Parent, Child, ChildCount), the reference leaf as a TXLSRangeItem through Range, and array-constant data (ArrayRows, ArrayCols, ArrayValueCount, and the TXLSArraySerVal entries in ArrayValues). Дерево — отсоединённая копия, поэтому его обход никогда не затрагивает скомпилированные формулы книги, а члены мутации (AddChild, PushChild, CopyObject, OffsetCopyReferences, AdjustForShift, and TXLSRangeItem.CopyObject / AdjustForShift) существуют для инструментов, которые переписывают клонированное дерево перед перекомпиляцией

Точки входа в книгу

Tokens := Worksheet.ParseFormulaTokens('SUM(A1:A4)', 1, 1);
try
  if Tokens.ReplaceReference(OldRef, NewRef) then
    Worksheet.SetFormulaTokens(1, 1, Tokens);
finally
  Tokens.Free;
end;

ParseFormulaTokens, GetFormulaTokens, FormulaTokensToTextи SetFormulaTokens сохраняют явное владение и проверяют контекст, версию BIFF, поддержку токенов, владение массивами и границы ссылок до изменения ячейки

Реестры пользовательских функций

TXLSUserFunctionResolver и TXLSUserFunctionRegistry обеспечивают поиск по имени через RegisterHandler, UnregisterHandler, Clear, Contains, TryGetHandlerи Count

Workbook.RegisterUserFunction('NETMARGIN', CalculateNetMargin);
Workbook.RegisterGlobalUserFunction('FISCALYEAR', CalculateFiscalYear);
try
  Workbook.Calculate;
finally
  Workbook.UnregisterUserFunction('NETMARGIN');
  Workbook.UnregisterGlobalUserFunction('FISCALYEAR');
end;

IXLSWorkbook, TXLSWorkbookи TXLSXWorkbook предоставляют RegisterUserFunction, UnregisterUserFunction, ClearUserFunctions, RegisteredUserFunctionCount, RegisterGlobalUserFunction, UnregisterGlobalUserFunction, ClearGlobalUserFunctionsи RegisteredGlobalUserFunctionCount

Эквивалентные точки входа уровня модуля — XLSRegisterGlobalUserFunction, XLSUnregisterGlobalUserFunction, XLSClearGlobalUserFunctions, XLSRegisteredGlobalUserFunctionCountи XLSGlobalUserFunctionRegistered

TXLSCalculator.OnUserFunctionResolve участвует до устаревшего резервного события, а обработчики реестра вызываются вне блокировки реестра, поэтому обработчик может безопасно отменить свою регистрацию

Опасные внешние и макро-имена функций блокируются до вычисления аргументов и поиска обработчика, если только AllowUnsafeFormulaCallbacks явно не включён для книги или отдельного контекстного вычисления; обычные имена пользовательских функций остаются доступными по умолчанию

Диагностика формул

TXLSXFormulaIssueKind, TXLSXFormulaLocationи TXLSXFormulaIssue возвращаются методом TXLSXWorkbook.AnalyzeFormulaIssues для отсутствующих функций, внешних ссылок и компонентов циклических зависимостей

Проверка макрос-листов

TXLSSheetKind различает лист, макрос-лист, лист диаграммы, модуль VBA и неизвестные записи листа через TXLSWorksheet.SheetKind; TXLSMacroRisk, TXLSMacroCommandInfoи TXLSMacroCommandArray описывают типизированные результаты TXLSWorksheet.ScanMacroCommands

Объединённый автоподбор и типы сортировки

TXLSMergedAutoFitStrategy и TXLSXMergedAutoFitStrategy выбирают рост первого, последнего или сбалансированный для объединённых диапазонов, а TXLSSortOrientation, TXLSSortFormulaModeи TXLSSortCompareEvent управляют вертикальной или горизонтальной устойчивой сортировкой и перемещением формул

См. также