Обратный вызов OnUserFunction позволяет коду приложения вычислять пользовательские или иные неподдерживаемые функции листа в процессе выполнения
Calculate. Назначьте его для TXLSWorkbook или
TXLSXWorkbook перед вызовом Calculate
Используйте OnUserFunctionEx , когда обратному вызову требуется текущий контекст формулы. Контекст сообщает индекс листа с отсчётом от 1, а также строку и столбец ячейки с формулой с отсчётом от 1; вызовы Calculate на уровне рабочей книги, не вычисляющие ячейку, сообщают строку и столбец как 0
Синтаксис
type
TXLSUserArgKind = (akuValue, akuRangeRef, akuArray);
TXLSUserFunctionContext = record
SheetIndex: Integer;
Row: Integer;
Col: Integer;
ArgCount: Integer;
ArgKinds: array of TXLSUserArgKind;
end;
TXLSUserFunctionEvent = procedure(
Sender: TObject;
const FunctionName: WideString;
const Args: Variant;
var Value: Variant;
var Handled: Boolean) of object;
TXLSUserFunctionExEvent = procedure(
Sender: TObject;
const FunctionName: WideString;
const Args: Variant;
const Context: TXLSUserFunctionContext;
var Value: Variant;
var Handled: Boolean) of object;
property OnUserFunction: TXLSUserFunctionEvent;
property OnUserFunctionEx: TXLSUserFunctionExEvent;
property AllowUnsafeFormulaCallbacks: Boolean;
Аргументы
| FunctionName | функция имя из формула текст |
| Args | zero-основанный Variant array containing evaluated
argument значения. для zero-argument функции этот значение является
Null |
| Context | для OnUserFunctionEx, reports SheetIndex, Row, и Col. лист, строка и столбец значения являются 1-основанный для ячейка формулы; строка и столбец являются ArgCount когда no ячейка является being evaluated Args — длина массива (0 для вызовов без аргументов) и ArgKinds classifies each argument as akuValue (literal value), akuRangeRef (cell or range reference), or akuArray (константа-массив). Значения листа, строки и столбца отсчитываются с единицы для формул ячеек; строка и столбец равны 0 , когда не вычисляется ни одна ячейка. Виды захватываются до вычисления аргументов, поэтому обработчик в стиле SUM или MAP может понять, что вызывающий написал ссылку, даже если вычисленный Args entry carries only the value |
| Value | задать этот к функция result |
| Handled | задать к True когда callback supplies
result. Leave False к keep normal unsupported
функция behavior |
Пример
AllowUnsafeFormulaCallbacks defaults to False в книгах Classic XLS и XLSX, поэтому сохранение формулы никогда не разрешает коду приложения-хозяина обрабатывать опасное внешнее или макро-имя функции
The default gate covers DDE, CALL, REGISTER, REGISTER.ID, WEBSERVICE, RTD, SQL.REQUEST, EXEC, RUN, CREATE.OBJECT, APP.ACTIVATE, SEND.KEYS, OPEN, SAVE, SAVE.AS, FOPEN, FWRITE, FWRITELN, FCLOSE, and FILE.DELETE после нормализации любого распознанного префикса future-функции
Отказ происходит до вычисления аргументов и до запуска колбэков уровня книги, процесса, резолвера или событий; обычные пользовательские и неподдерживаемые имена функций сохраняют существующее поведение колбэков
Set the workbook property to True только когда каждая формула и зарегистрированный обработчик доверенные; контекстное вычисление может вместо этого включить разрешение на один вызов через TXLSFormulaEvaluationOptions.AllowUnsafeFormulaCallbacks, while an explicitly supplied False overrides a workbook-wide opt-in
Example
procedure TForm1.WorkbookUserFunction(Sender: TObject;
const FunctionName: WideString; const Args: Variant;
var Value: Variant; var Handled: Boolean);
begin
if SameText(FunctionName, 'DOUBLEPLUS') then
begin
Value := Double(Args[0]) * 2 + Double(Args[1]);
Handled := True;
end;
end;
Workbook.OnUserFunction := WorkbookUserFunction;
Value := Workbook.Calculate('=DOUBLEPLUS(A1;5)');
Пример с контекстом
procedure TForm1.WorkbookUserFunctionEx(Sender: TObject;
const FunctionName: WideString; const Args: Variant;
const Context: TXLSUserFunctionContext;
var Value: Variant; var Handled: Boolean);
begin
if SameText(FunctionName, 'ROWBONUS') then
begin
Value := Double(Args[0]) + Context.Row + Context.Col;
Handled := True;
end;
end;
Workbook.OnUserFunctionEx := WorkbookUserFunctionEx;
Value := Worksheet.Calculate('=C2');
Receiving range arguments
Когда аргумент вычисляется в диапазон листа, Args entry is a varUnknown Variant that holds an ICalcRangeList; вычисленное значение каждой покрытой ячейки не копируется в Variant. Проверьте и извлеките его через VarIsRange перегрузку, возвращающую список, затем прочтите разрешённые прямоугольники через TXLSCalcRange
type
TXLSCalcRange = class
property row1: Integer; { 0-based, inclusive }
property col1: Integer; { 0-based, inclusive }
property row2: Integer;
property col2: Integer;
property SheetIndex: Integer;
end;
ICalcRangeList = interface
property Count: Integer;
property Item[Index: Integer]: TXLSCalcRange;
end;
function VarIsRange(Value: Variant): Boolean; overload;
function VarIsRange(Value: Variant; var Int: ICalcRangeList): Boolean; overload;
function RangeToVariant(Value: TXLSCalcRangeList): Variant;
Coordinates match the TXLSGetValue соглашение: с нулевой базой и включительно. Обработчик, который хочет сам вернуть диапазон, строит TXLSCalcRangeList and wraps it with RangeToVariant before assigning Value; движок затем сохраняет ссылку на диапазон для зависимых формул вместо скалярного снимка
См. также