Återanropet OnUserFunction gör att programkoden kan beräkna
anpassade eller på annat sätt ej stödda kalkylbladsfunktioner under
Calculate. Tilldela det på TXLSWorkbook eller
TXLSXWorkbook innan du anropar Calculate
Använd OnUserFunctionEx när återanropet behöver den aktuella formelkontexten. Kontexten rapporterar det 1-baserade kalkylbladsindexet samt den 1-baserade raden och kolumnen för formelcellen; Calculate-anrop på arbetsboksnivå som inte beräknar en cell rapporterar rad och kolumn som 0
Syntax
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;
Argument
| FunctionName |
Funktionsnamnet från formeltexten |
| Args |
En nollbaserad Variant-array som innehåller beräknade
argumentvärden. För funktioner utan argument är detta värde
Null |
| Context |
För OnUserFunctionEx rapporteras SheetIndex, Row och Col, plus argumentbeskrivningen: ArgCount matchar längden på arrayen Args (0 för anrop utan argument) och ArgKinds klassificerar varje argument som akuValue (literalvärde), akuRangeRef (cell- eller områdesreferens) eller akuArray (arraykonstant). Kalkylblads-, rad- och kolumnvärden är 1-baserade för cellformler; rad och kolumn är 0 när ingen cell beräknas. Typerna fångas innan argumenten utvärderas, så en hanterare i SUM- eller MAP-stil kan se att anroparen skrev en referens även om det utvärderade Args-värdet bara bär värdet |
| Value |
Ange detta till funktionsresultatet |
| Handled |
Ange True när återanropet tillhandahåller
ett resultat. Lämna False för att behålla det normala beteendet för ej stödda funktioner |
Säkerhetspolicy för callbacks
AllowUnsafeFormulaCallbacks är som standard False i Classic XLS- och XLSX-arbetsböcker, så att bevarande av en formel aldrig ger programkoden i värdapplikationen tillstånd att hantera ett farligt externt eller makroliknande funktionsnamn
Standardspärren täcker 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 och FILE.DELETE efter att ett känt prefix för framtida funktioner normaliserats
Nekandet sker innan argumenten utvärderas och innan callbacks för arbetsbok, process, resolver eller händelser körs; vanliga anpassade och ej stödda funktionsnamn behåller sitt befintliga callback-beteende
Sätt arbetsboksegenskapen till True bara när varje formel och varje registrerad hanterare är betrott; kontextuell utvärdering kan i stället välja in det för ett enskilt anrop via TXLSFormulaEvaluationOptions.AllowUnsafeFormulaCallbacks, medan en uttryckligt angiven False åsidosätter en arbetsboksomfattande opt-in
Exempel
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)');
Exempel med kontext
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');
Ta emot områdeargument
När ett argument utvärderas till ett kalkylbladsområde är Args-posten en varUnknown-Variant som bär en ICalcRangeList; det utvärderade värdet för varje täckt cell kopieras inte in i Varianten. Testa och extrahera den med VarIsRange-överlagringen som returnerar listan, och läs sedan de upplösta rektanglarna via 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;
Koordinaterna följer TXLSGetValue-konventionen: nollbaserade och inkluderande. En hanterare som själv vill returnera ett område bygger en TXLSCalcRangeList och lindar in den med RangeToVariant innan Value tilldelas; motorn behåller då områdesreferensen för beroende formler i stället för en skalär ögonblicksbild
Se även