クラシック XLS と XLSX は、呼び出し元がセルを変更する前に数式入力を分類するための、同じ副作用のない契約を公開しています
共通ポリシー
TXLSFormulaEmptyStringMode =
(xlfesmClearCell, xlfesmPreserveString);
TXLSFormulaUnknownSymbolMode =
(xlfusmReject, xlfusmPreserve);
TXLSFormulaEntryPolicy = record
EmptyStringMode: TXLSFormulaEmptyStringMode;
UnknownFunctionMode: TXLSFormulaUnknownSymbolMode;
UnknownNameMode: TXLSFormulaUnknownSymbolMode;
end;
property FormulaEntryPolicy: TXLSFormulaEntryPolicy;
クラシックの IXLSWorkbook と TXLSWorkbook は、 TXLSXWorkbookと共にこのプロパティを公開します。 XLSDefaultFormulaEntryPolicy は空の入力をクリアし、未知の関数と未知の定義名を拒否します
ワークブックのプロパティは値でコピーされ、代入時にアトミックに検証されるため、サポートされていない列挙値は以前のポリシーを変更することなく EArgumentOutOfRangeException を発生させます
検証結果
function ValidateFormulaEntry(Row, Col: Integer;
const Formula: WideString): TXLSFormulaEntryValidationResult;
TXLSFormulaEntryValidationResult = record
Issue: TXLSFormulaEntryIssue;
Action: TXLSFormulaEntryAction;
Symbol: WideString;
end;
Issue は、エラーなし、未知の関数、未知の名前、構文エラー、ターゲット形式の制限、無効なターゲット座標を区別します
Action は、セルのクリア、文字列の保存、数式の保存、拒否のいずれかを選択します。未知の関数または名前が認識された場合、 Symbol がそれを特定します
空のテキストと数式
完全に空の入力は、 xlfeaClearCell に応じて xlfeaStoreString または EmptyStringMode
たとえば =""のように空の文字列を返す数式は数式のままであり、ターゲット形式がそれを表現できる場合は xlfeaStoreFormula を返します
数式テキストは、先頭の等号を含めても省略してもかまいません
通常のクラシック XLS または XLSX のセル Value プロパティを通じて完全に空の文字列を代入すると、このモードが直接適用されるようになりました。既定では既存の値や数式が削除され、 xlfesmPreserveString の場合は長さゼロの定数文字列でセルの内容が置き換えられます
Null と Unassigned はどちらのモードでも常にセルをクリアします。一方、 ="" のような実際の数式は数式のままであり、独立して保存または計算された空文字列の結果を持ちます
XLSX の文字列および Variant の行・列ライターは、クリアされた穴を具体化することなく同じ規則を適用し、残りの値がそこで表現できる限りパックされたストレージを維持します
ネイティブの XLS、XLSX、ODS リーダー、および XLS から XLSX、XLSX から XLS へのコンバーターは、保存された値を信頼できる入力として扱うため、ターゲットのワークブックが既定のユーザー入力ポリシーを維持していても、ファイルレベルの定数空文字列は保持されます
未知のシンボルとターゲット形式
ワークブック ローカルまたはプロセス全体に登録されたユーザー関数と、割り当てられた OnUserFunction または OnUserFunctionEx コールバックは、ハンドラーを呼び出すことなく検証時には既知として扱われます。未登録の呼び出しは、関数名を Symbol
厳格モードは、未知の関数や名前に対して xlfeaReject を返します。通常のセル Formula プロパティを通じた代入は、値、数式キャッシュ、依存関係を変更する前に拒否します
保持モードは診断を保持し、通常のセル API を通じて数式を保存します。クラシック XLS は、BIFF アドイン ユーザー関数トークンを通じて未知の呼び出しをシリアル化し、保存、再オープン、XLS/XLSX 変換を通じて未知の名前のテキストを保持します
クラシック XLS はさらに、BIFF ライターを通じて既知の数式をコンパイルし、式を表現できない場合は xlfeiTargetFormatUnsupported を返します。XLSX は、その数式モデルがサポートする既知の最新の数式関数を受け入れます
XLSX の検証は、 LAMBDA、字句的な LET 呼び出し可能要素、ラムダを参照する定義名、レポート プレースホルダー、登録された外部ワークブック リンク、およびネスト形式や現在行形式を含む有効な修飾または非修飾の構造化参照を認識します
互換モードでは、未解決の外部構造化参照を後続の処理のために保持することもできますが、厳格モードは未解決のテーブル名を引き続き拒否します
計算と一括監査
ラムダおよびユーザー関数へのディスパッチ後も未処理のままの保持された未知の関数、または保持された未知の名前は、コード $1Dの Variant エラー、すなわち Excel の #NAME? エラーとして評価されます。同じ型付きエラーは依存する数式およびコンテキスト依存の評価に伝播します
実装されていない既知の組み込み関数は、未知の呼び出しとは区別されたままです。一方、ワークブック ローカルまたはプロセス全体のユーザー関数の登録、置き換え、削除、クリア、および定義名の数式の変更は、古い依存関係および計算状態を無効化します
function AuditFormulaSymbols: TXLSFormulaSymbolIssues; overload;
function AuditFormulaSymbols(
out AStats: TXLSFormulaSymbolAuditStats):
TXLSFormulaSymbolIssues; overload;
TXLSFormulaSymbolIssueKind = (xlfsiUnknownFunction, xlfsiUnknownName,
xlfsiSyntaxError);
TXLSFormulaSymbolLocationKind = (xlfslCell, xlfslDefinedName);
TXLSFormulaSymbolIssue = record
Kind: TXLSFormulaSymbolIssueKind;
LocationKind: TXLSFormulaSymbolLocationKind;
Sheet: Integer;
Row: Integer;
Col: Integer;
DefinedNameIndex: Integer;
DefinedName: WideString;
Formula: WideString;
Symbol: WideString;
end;
TXLSWorkbook and TXLSXWorkbook は同じ一括監査オーバーロードを提供します。各問題は、未知の関数、未知の名前、または構文エラーのいずれかに、ワークシート セル位置(LocationKind = xlfslCellとLocationKind = xlfslDefinedNameは同じ一括監査オーバーロードを提供します。各問題は、未知の関数、未知の名前、または構文エラーを、ワークシート セル位置または定義名位置、ソース数式、未解決のシンボルとともに特定します
監査はテキストをスキャンするのではなく、解析済みの数式ツリーまたは保存された BIFF トークンをたどるため、文字列内の関数のようなテキストは報告されません。XLSX のコンパイルは、解決済みの数式テキスト、ワークシート、ロケール、定義名の世代、ユーザー関数レジストリの世代、コールバックの可用性をキーとする操作ローカルのキャッシュを使用します
EntryCount は監査された数式を報告し、 UniqueFormulaCount は独立してコンパイルまたは検査された数式を報告し、 CacheHitCount は操作キャッシュによって処理された重複エントリを報告します
ワークシートの変更なし
検証はセルを作成または編集せず、キャッシュされた値を変更せず、依存関係グラフを更新せず、ワークブックをダーティとしてマークせず、登録されたユーザー関数ハンドラーを呼び出しません
直接検証は変更フリーのままです。通常の数式代入は内部で同じ決定を適用し、検証とターゲット形式の準備が成功した後にのみコミットします
Delphi の例
Policy := Workbook.FormulaEntryPolicy;
Policy.UnknownFunctionMode := xlfusmReject;
Policy.UnknownNameMode := xlfusmReject;
Workbook.FormulaEntryPolicy := Policy;
Validation := Sheet.ValidateFormulaEntry(4, 2, FormulaText);
if Validation.Action = xlfeaStoreFormula then
Sheet.Cells[4, 2].Formula := FormulaText;
Issues := Workbook.AuditFormulaSymbols(Stats);
for I := 0 to High(Issues) do
if Issues[I].Kind = xlfsiUnknownFunction then
LogUnknownSymbol(Issues[I].Symbol);関連項目