Tilbagekaldet OnUserFunction lader programkode evaluere
brugerdefinerede eller på anden måde ikke-understøttede regnearksfunktioner
under Calculate. Tildel det på TXLSWorkbook eller
TXLSXWorkbook, før du kalder Calculate
Brug OnUserFunctionEx, når tilbagekaldet har brug for den aktuelle formelkontekst. Konteksten rapporterer det 1-baserede arkindeks samt den 1-baserede række og kolonne for formelcellen; Calculate-kald på projektmappeniveau, der ikke evaluerer en celle, rapporterer række og kolonne som 0
Syntaks
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;
Argumenter
| FunctionName |
Funktionsnavnet fra formelteksten |
| Args |
Et 0-baseret Variant-array med evaluerede argumentværdier. For funktioner uden argumenter er værdien Null |
| Context |
For OnUserFunctionEx rapporteres SheetIndex, Row og Col plus argumentbeskrivelsen: ArgCount svarer til længden af Args-arrayet (0 ved kald uden argumenter), og ArgKinds klassificerer hvert argument som akuValue (literal værdi), akuRangeRef (celle- eller områdereference) eller akuArray (arraykonstant). Ark-, række- og kolonneværdier er 1-baserede for celformler; række og kolonne er 0, når der ikke evalueres en celle. Typerne fanges, før argumenterne evalueres, så en SUM- eller MAP-agtig handler kan se, at kalderen skrev en reference, selv om det evaluerede Args-element kun bærer værdien |
| Value |
Sættes til funktionens resultat |
| Handled |
Sættes til True, når callback'en leverer et resultat. Lad den være False for at beholde den normale håndtering af ikke-understøttede funktioner |
Sikkerhedspolitik for callbacks
AllowUnsafeFormulaCallbacks er som standard False i klassiske XLS- og XLSX-projektmapper, så det at bevare en formel aldrig giver værtsprogrammets kode tilladelse til at håndtere et farligt eksternt eller makroagtigt funktionsnavn
Standardporten dækker 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 og FILE.DELETE, efter et genkendt future-function-præfiks er normaliseret
Afvisningen sker, før argumenterne evalueres, og før projektmappe-lokale, procesglobale, resolver- og event-callbacks kører; almindelige tilpassede og ikke-understøttede funktionsnavne bevarer deres eksisterende callback-adfærd
Sæt egenskaben på projektmappen til True kun, når alle formler og registrerede handlers er betroede; kontekstuel evaluering kan i stedet tilvælge for ét kald via TXLSFormulaEvaluationOptions.AllowUnsafeFormulaCallbacks, mens en eksplicit angivet False tilsidesætter et arbejdsbogsomfattende tilvalg
Eksempel
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)');
Kontekstbevidst eksempel
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');
Modtagelse af områdeargumenter
Når et argument evalueres til et regnearksområde, er Args-elementet en varUnknown-Variant, der holder en ICalcRangeList; den evaluerede værdi af hver dækket celle kopieres ikke ind i Varianten. Test og udtræk den med den VarIsRange-overload, der returnerer listen, og læs de opløste rektangler 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;
Koordinaterne følger TXLSGetValue-konventionen: 0-baserede og inklusive. En handler, der selv vil returnere et område, bygger en TXLSCalcRangeList og pakker den med RangeToVariant, før Value tildeles; motoren beholder så områdereferencen til afhængige formler i stedet for et skalar-snapshot
Se også