HotXLS ドキュメント

スパース アウトライン ジオメトリ

lxOutline ユニットは、行と列のアウトラインについてエンジンに依存しないジオメトリと変更計画を提供します
実体化されたスパンだけを格納し、隣接するアウトライン レベルの遷移から集計ノードを認識し、すべてのワークシート座標にエントリを割り当てることなく、summary-after および summary-before のレイアウト用に圧縮された状態変更を作成します

中核となる型

TXLSOutlineAxis = (xoaRows, xoaColumns);

TXLSOutlineChildMode = (xocPreserve, xocCollapse, xocExpand);

TXLSOutlineMutationPlan = class
  constructor Create(AAxis: TXLSOutlineAxis);
  procedure Clear;
  property Axis: TXLSOutlineAxis;
  property Count: Integer;
  property Changes[Index: Integer]: TXLSOutlineStateChange;
end;

TXLSOutlineGeometry = class
  constructor Create(AAxis: TXLSOutlineAxis;
    ASummaryAfter: Boolean);
  procedure Clear;
  property Axis: TXLSOutlineAxis;
  property SpanCount: Integer;
  procedure AddSpan(AFirstIndex, ALastIndex, ALevel: Integer;
    AHidden, ACollapsed: Boolean);
  function TryGetNode(ANodeIndex: Integer;
    out ANode: TXLSOutlineNode): Boolean;
  function TryBuildNodeCollapsePlan(ANodeIndex: Integer;
    ACollapsed: Boolean; AChildMode: TXLSOutlineChildMode;
    APlan: TXLSOutlineMutationPlan): Boolean;
  procedure BuildDisplayLevelPlan(ADisplayLevel: Integer;
    AChildMode: TXLSOutlineChildMode;
    APlan: TXLSOutlineMutationPlan);
end;
行と列のインデックスは 1 始まり、アウトライン レベルは 0 以上であり、スパンは重なりなく厳密に増加する順序で追加しなければなりません
レベル、非表示、折りたたみの状態が同一である隣接するスパンは自動的に統合されます。省略されたインデックスは、暗黙のレベル 0、表示状態、折りたたみマーカーなしになります
両方のクラスは構築時に Axis を記憶し、Clear は内部バッファーを再割り当てせずにプランまたはジオメトリを空にして再利用できるようにし、SpanCount はジオメトリが現在保持している統合済みスパンの数を報告します

ノードのセマンティクス

NodeIndex呼び出し側が照会した、物理的な集計行または集計列
FirstDetailIndex / LastDetailIndex集計項目より深いレベルを持つ、連続した詳細範囲
SummaryLevel集計項目に格納されたアウトライン レベル。その項目が実体化されていない場合は 0
Levelノードが表すグループ レベル。SummaryLevel + 1 に等しい
SummaryHidden集計項目に格納された非表示状態
Collapsed集計項目に格納された明示的な折りたたみマーカー
SummaryAfter詳細が集計項目より前にある場合は true、後ろにある場合は false
各照会は、選択された集計項目より深くないレベルを持つ最初の隣接スパンで停止するため、入れ子になったグループは互いに独立したままです
ギャップも詳細範囲を終了させるため、スパースなメタデータが未使用の座標を誤って 1 つのグループにまたがることはありません

変更プラン

変更プランは、順序付けられた 1 始まりの範囲と、各範囲が非表示状態、折りたたみ状態、またはその両方のどれを変更するかを示すフィールド マスクを含みます。隣接する等価な変更は自動的に統合されます
xocPreserve子孫の折りたたみマーカーを保持しながら選択されたノードを変更します。これは既定の入れ子グループ動作です
xocCollapse選択されたノードの内側にある子孫ノード、または要求された表示レベルより下で非表示になっている子孫ノードを、折りたたまれたものとしてマークします
xocExpand選択されたノードの内側にある子孫ノード、または要求された表示レベルより下で非表示になっている子孫ノードの、折りたたみマーカーを解除します
xocPreserve で親を展開すると直下の詳細が表示されますが、折りたたまれた子に属する詳細は非表示のままです。折りたたまれた祖先の内側にある子を展開しても、その祖先を通じて内容が露出することはありません
表示レベルは 1 始まりです。レベル 1 はすべての最上位グループを折りたたみ、より大きい値はそれぞれ 1 つのアウトライン レベルを追加で表示しながら、対応する境界ノードのマーカーを設定します
すでに要求された状態を含むジオメトリから同じ状態を構築すると空のプランが生成され、ノード以外の照会は false と空のプランを返します
ノード操作は、選択された集計項目の独立した非表示状態を変更しません。また、表示レベルのプランは、アウトライン グループの外側で非表示にされたレベル 0 の項目を再表示しません

ワークシート アダプター

function TryGetOutlineNode(AAxis: TXLSOutlineAxis;
  ANodeIndex: Integer; out ANode: TXLSOutlineNode): Boolean;
function SetOutlineNodeCollapsed(AAxis: TXLSOutlineAxis;
  ANodeIndex: Integer; ACollapsed: Boolean;
  AChildMode: TXLSOutlineChildMode = xocPreserve): Boolean;
procedure SetOutlineDisplayLevel(AAxis: TXLSOutlineAxis;
  ADisplayLevel: Integer;
  AChildMode: TXLSOutlineChildMode = xocPreserve);
TXLSWorksheet と TXLSXWorksheet は同じ 3 つのメソッドを公開するため、呼び出し側はジオメトリを手動で構築せずに、1 始まりの行または列の集計ノードを照会または変更できます
クラシック アダプターは割り当て済みの行ブロックと代入済みの列メタデータのみを読み取り、XLSX アダプターは、スパースなアウトライン レベル、非表示、折りたたみの各リストをマージした後、1 回の書き込みトランザクションで 1 つの圧縮された変更プランを適用します
OpenDocument の行と列のグループは、ネイティブな入れ子の table:display 状態を保持します。直接のメタデータ編集や構造的な行と列の変更は、その状態を論理的な集計ノードへ安全に投影し、XLSX への変換では、すべてのグループ メンバーではなく XLSX の集計項目に折りたたみマーカーを書き込みます
既存の TXLSXWorksheet.ToggleRowGrouped および ToggleColGrouped メソッドは互換性ラッパーとして引き続き利用できます。引数は最初の詳細行または詳細列であり、ラッパーは方向を考慮した集計ノードを解決してから切り替えます

Delphi の例

Geometry := TXLSOutlineGeometry.Create(xoaRows, True);
Plan := TXLSOutlineMutationPlan.Create(xoaRows);
try
  Geometry.AddSpan(2, 4, 1, False, False);
  Geometry.AddSpan(5, 5, 0, False, False);

  if Geometry.TryGetNode(5, Node) then
    UseOutlineNode(Node.FirstDetailIndex,
      Node.LastDetailIndex, Node.Collapsed);

  if Geometry.TryBuildNodeCollapsePlan(5, True,
    xocPreserve, Plan) then
    ApplyOutlineChanges(Plan);
finally
  Plan.Free;
  Geometry.Free;
end;

C++Builder の例

Lxoutline::TXLSOutlineGeometry *geometry =
  new Lxoutline::TXLSOutlineGeometry(Lxoutline::xoaColumns, false);
try {
  geometry->AddSpan(3, 3, 0, false, true);
  geometry->AddSpan(4, 7, 1, true, false);

  Lxoutline::TXLSOutlineNode node;
  if (geometry->TryGetNode(3, node))
    UseOutlineNode(node.FirstDetailIndex, node.LastDetailIndex,
      node.Collapsed);
}
__finally {
  delete geometry;
}

パフォーマンスとスコープ

ノードの検索はバイナリ検索を使用し、その後は選択されたグループが横断する隣接する実体化スパンだけをたどるため、n 個のスパンと k 個の訪問スパンに対して O(log n + k) の作業量になります
一括変更計画は、線形の単調スタック パスですべての実体化ノードを検出し、折りたたまれた可視性の区間をマージし、未使用の座標を訪れることなく圧縮された範囲変更を出力します
ビルダーは、指定されたスパンだけを保持しながら XLSX ワークシートの最終行を受け入れるため、大きな座標が百万エントリ規模の割り当てや走査を意味することはありません
ワークシート アダプターのリグレッション ゲートは、行 8 と行 1,048,576 の近くにある 6 個の実体化行エントリに対して、同じ 32,768 回のノード照会と 2,048 回の折りたたみまたは展開の変更を実行し、セルの実体化が 0 であることを要求し、高座標のコストを低座標のベースラインに対して上限付けします
TXLSOutlineGeometry はワークブック データを直接書き込むことはありません。エンジン アダプターが返されたプランを検証して適用するため、ジオメトリの解析と状態の変更は分離されたままです

関連項目

クラシック XLS API の追加メンバー
高度な XLSX API メンバー
ライブラリの追加 API メンバー