Dokumentacja HotXLS

Rozrzedzona geometria konspektu

Jednostka lxOutline dostarcza neutralną wobec silników geometrię oraz planowanie modyfikacji dla konspektów wierszy i kolumn
Przechowuje wyłącznie zmaterializowane segmenty, rozpoznaje węzły podsumowujące po sąsiednich przejściach poziomów konspektu i tworzy skompresowane zmiany stanu dla układów z podsumowaniem po i przed, bez przydzielania wpisu dla każdej współrzędnej arkusza

Typy podstawowe

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;
Indeksy wierszy i kolumn są numerowane od jedynki, poziomy konspektu są nieujemne, a segmenty muszą być dodawane w ściśle rosnącej kolejności bez nakładania się
Sąsiednie segmenty o identycznym poziomie, stanie ukrycia i zwinięcia są automatycznie scalane; pominięte indeksy mają niejawny poziom zerowy, stan widoczny i nie mają znacznika zwinięcia
Obie klasy pamiętają swój Axis od chwili konstrukcji, Clear opróżnia plan lub geometrię w celu ponownego użycia bez ponownego przydzielania buforów wewnętrznych, a SpanCount zgłasza, ile scalonych segmentów geometria obecnie przechowuje

Semantyka węzłów

NodeIndexFizyczny wiersz lub kolumna podsumowująca odpytana przez wywołującego
FirstDetailIndex / LastDetailIndexCiągły zakres szczegółów, którego poziom jest głębszy od elementu podsumowującego
SummaryLevelPoziom konspektu zapisany na elemencie podsumowującym lub zero, gdy ten element nie jest zmaterializowany
LevelPoziom grupy reprezentowany przez węzeł, równy SummaryLevel + 1
SummaryHiddenStan ukrycia zapisany na elemencie podsumowującym
CollapsedJawny znacznik zwinięcia zapisany na elemencie podsumowującym
SummaryAfterTrue, gdy szczegóły poprzedzają element podsumowujący, false, gdy szczegóły następują po nim
Grupy zagnieżdżone pozostają niezależne, ponieważ każde zapytanie zatrzymuje się na pierwszym sąsiednim segmencie, którego poziom nie jest głębszy od wybranego elementu podsumowującego
Luka również kończy zakres szczegółów, dzięki czemu rozrzedzone metadane nie mogą przypadkowo spiąć nieużywanych współrzędnych w jedną grupę

Plany modyfikacji

Plan modyfikacji zawiera uporządkowane zakresy numerowane od jedynki oraz maskę pól wskazującą, czy każdy zakres zmienia stan ukrycia, stan zwinięcia czy oba; sąsiednie równoważne zmiany są scalane automatycznie
xocPreserveZmienia wybrany węzeł, zachowując znaczniki zwinięcia potomków — jest to domyślne zachowanie dla grup zagnieżdżonych
xocCollapseOznacza węzły potomne jako zwinięte, gdy znajdują się wewnątrz wybranego węzła lub są ukryte poniżej żądanego poziomu wyświetlania
xocExpandZdejmuje znaczniki zwinięcia potomków, gdy znajdują się wewnątrz wybranego węzła lub są ukryte poniżej żądanego poziomu wyświetlania
Rozwijanie rodzica z xocPreserve ujawnia bezpośrednie szczegóły, podczas gdy szczegóły należące do zwiniętych potomków pozostają ukryte; rozwijanie potomka wewnątrz zwiniętego przodka nie ujawnia zawartości przez tego przodka
Poziomy wyświetlania są numerowane od jedynki: poziom 1 zwija każdą grupę najwyższego poziomu, a każda większa wartość ujawnia jeden dodatkowy poziom konspektu, ustawiając pasujące znaczniki węzłów granicznych
Zbudowanie tego samego żądanego stanu z geometrii, która już go zawiera, daje pusty plan, a odpytanie nieistniejącego węzła zwraca false z pustym planem
Operacje na węzłach pozostawiają niezależny stan ukrycia wybranego elementu podsumowującego bez zmian, a plany poziomów wyświetlania nie czynią ponownie widocznymi elementów poziomu zerowego ukrytych poza grupą konspektu

Adaptery arkuszy

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 i TXLSXWorksheet udostępniają te same trzy metody, dzięki czemu wywołujący może odpytać lub zmienić węzeł podsumowujący wiersza lub kolumny numerowany od jedynki bez ręcznego budowania geometrii
Adapter klasyczny czyta wyłącznie przydzielone bloki wierszy i przypisane metadane kolumn, natomiast adapter XLSX scala swoje rozrzedzone listy poziomów konspektu, ukrycia i zwinięcia przed zastosowaniem jednego skompresowanego planu modyfikacji w pojedynczej transakcji zapisu
Grupy wierszy i kolumn OpenDocument zachowują swoje natywne zagnieżdżone wartości table:display; bezpośrednie edycje metadanych i strukturalne zmiany wierszy lub kolumn bezpiecznie projektują ten stan na logiczny węzeł podsumowujący, a konwersja na XLSX zapisuje znacznik zwinięcia na elemencie podsumowującym XLSX, a nie na każdym członku grupy
Istniejące metody TXLSXWorksheet.ToggleRowGrouped i ToggleColGrouped pozostają dostępne jako wrappery zgodności; ich argumentem jest pierwszy wiersz lub kolumna szczegółów, a wrapper rozwiązuje uwzględniający kierunek węzeł podsumowujący przed jego przełączeniem

Przykład dla 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;

Przykład dla 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;
}

Wydajność i zakres zastosowania

Wyszukiwanie węzła używa wyszukiwania binarnego, po którym następują wyłącznie sąsiednie zmaterializowane segmenty przecinane przez wybraną grupę, co daje pracę O(log n + k) dla n segmentów i k odwiedzonych segmentów
Masowe planowanie modyfikacji odnajduje każdy zmaterializowany węzeł liniowym przebiegiem ze stosem monotonicznym, scala przedziały widoczności stanów zwiniętych i emituje skompresowane zmiany zakresów bez odwiedzania nieużywanych współrzędnych
Konstruktor przyjmuje ostatni wiersz arkusza XLSX, zachowując wyłącznie dostarczone segmenty, więc duża współrzędna nie oznacza przydziału ani skanowania o milionie wpisów
Regresyjna bramka adaptera arkuszy wykonuje te same 32,768 zapytań o węzły i 2,048 modyfikacji zwinięcia lub rozwinięcia na sześciu zmaterializowanych wpisach wierszy w pobliżu wiersza 8 i wiersza 1,048,576, wymaga zerowej materializacji komórek i ogranicza koszt dużych współrzędnych względem punktu odniesienia małych współrzędnych
TXLSOutlineGeometry nigdy nie zapisuje bezpośrednio danych skoroszytu; adaptery silników walidują i stosują zwrócony plan, pozwalając analizie geometrii i modyfikacji stanu pozostać rozdzielnymi

Zobacz także

Dodatkowe elementy API klasycznego XLS
Zaawansowane elementy API XLSX
Dodatkowe elementy API biblioteki