Enheten lxOutline tillhandahåller motoroberoende geometri och mutationsplanering för rad- och kolumndispositioner
Den lagrar endast materialiserade intervall, känner igen sammanfattande noder från angränsande övergångar i dispositionsnivå och skapar komprimerade tillståndsändringar för layouter med sammanfattning efter och sammanfattning före, utan att allokera en post för varje kalkylbladskoordinat
Kärntyper
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;
Rad- och kolumnindex är ettabaserade, dispositionsnivåer är icke-negativa och intervall måste läggas till i strikt stigande, icke-överlappande ordning
Angränsande intervall med identisk nivå, dolt tillstånd och ihopfällt tillstånd slås samman automatiskt; utelämnade index har underförstådd nivå noll, synligt tillstånd och ingen ihopfällningsmarkör
Båda klasserna minns sin Axis från konstruktionen, Clear tömmer en plan eller geometri för återanvändning utan att allokera de interna buffrarna på nytt, och SpanCount rapporterar hur många sammanslagna intervall geometrin för närvarande innehåller
Nodsemantik
| NodeIndex | Den fysiska sammanfattande raden eller kolumnen som anroparen frågar efter |
| FirstDetailIndex / LastDetailIndex | Det sammanhängande detaljområdet som har djupare nivå än sammanfattningselementet |
| SummaryLevel | Dispositionsnivån som är lagrad på sammanfattningselementet, eller noll när elementet inte är materialiserat |
| Level | Gruppnivån som noden representerar, lika med SummaryLevel + 1 |
| SummaryHidden | Det dolda tillståndet som är lagrat på sammanfattningselementet |
| Collapsed | Den explicita ihopfällningsmarkör som är lagrad på sammanfattningselementet |
| SummaryAfter | Sant när detaljerna kommer före sammanfattningselementet, falskt när detaljerna kommer efter det |
Kapslade grupper förblir oberoende eftersom varje fråga stannar vid det första angränsande intervallet som inte har djupare nivå än det valda sammanfattningselementet
En lucka avslutar också detaljområdet, så att gles metadata inte oavsiktligt kan bygga bro över oanvända koordinater till en enda grupp
Mutationsplaner
En mutationsplan innehåller ordnade ettabaserade områden och en fältmask som anger om varje område ändrar dolt tillstånd, ihopfällt tillstånd eller båda; likvärdiga angränsande ändringar slås samman automatiskt
| xocPreserve | Ändrar den valda noden samtidigt som underordnade noders ihopfällningsmarkörer behålls, vilket är standardbeteendet för kapslade grupper |
| xocCollapse | Markerar underordnade noder som ihopfällda när de ligger inuti den valda noden eller är dolda under den begärda visningsnivån |
| xocExpand | Rensar underordnade noders ihopfällningsmarkörer när de ligger inuti den valda noden eller är dolda under den begärda visningsnivån |
Att expandera en överordnad med xocPreserve avslöjar omedelbara detaljer, medan detaljer som tillhör ihopfällda underordnade förblir dolda; att expandera ett underordnat element inuti en ihopfälld överordnad exponerar inte innehåll genom den överordnade
Visningsnivåer är ettabaserade: nivå 1 fäller ihop varje grupp på toppnivå, och varje högre värde avslöjar en ytterligare dispositionsnivå samtidigt som motsvarande gränsnodmarkörer sätts
Att bygga samma begärda tillstånd från en geometri som redan innehåller det ger en tom plan, och frågor mot en icke-nod returnerar falskt med en tom plan
Nodoperationer lämnar den valda sammanfattningselementets oberoende dolda tillstånd oförändrat, och visningsnivåplaner gör inte nollnivåelement synliga igen som dolts utanför en dispositionsgrupp
Kalkylbladsadaptrar
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 och TXLSXWorksheet exponerar samma tre metoder, så att anroparen kan fråga efter eller ändra en ettabaserad rad- eller kolumnsammanfattande nod utan att bygga geometri manuellt
Den klassiska adaptern läser endast allokerade radblock och tilldelade kolumnmetadata, medan XLSX-adaptern sammanfogar sina glesa listor för dispositionsnivå, dolt tillstånd och ihopfällt tillstånd innan en enda komprimerad mutationsplan tillämpas i en enda skrivtransaktion
Rad- och kolumngrupper i OpenDocument behåller sitt inbyggda kapslade table:display-tillstånd; direkta metadataredigeringar och strukturella rad- eller kolumnändringar projicerar det tillståndet säkert till den logiska sammanfattande noden, och konvertering till XLSX skriver ihopfällningsmarkören på XLSX-sammanfattningselementet i stället för på varje gruppmedlem
De befintliga metoderna TXLSXWorksheet.ToggleRowGrouped och ToggleColGrouped förblir tillgängliga som kompatibilitetsomslutningar; deras argument är den första detaljraden eller kolumnen, och omslutningen löser den riktningsmedvetna sammanfattande noden innan den växlar den
Delphi-exempel
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-exempel
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;
}
Prestanda och omfattning
Noduppslag använder en binärsökning följt endast av de angränsande materialiserade intervall som den valda gruppen korsar, vilket ger O(log n + k) arbete för n intervall och k besökta intervall
Massmutationsplanering upptäcker varje materialiserad nod med ett linjärt genomlopp med monotonisk stack, slår samman ihopfällda synlighetsintervall och emitterar komprimerade områdesändringar utan att besöka oanvända koordinater
Byggaren accepterar den sista XLSX-kalkylbladsraden samtidigt som endast de angivna intervallen behålls, så en hög koordinat innebär ingen allokering eller skanning av en miljon poster
Kalkylbladsadapterns regressionsport kör samma 32,768 nodfrågor och 2,048 ihopfällnings- eller utökningsmutationer över sex materialiserade radposter nära rad 8 och rad 1,048,576, kräver noll cellmaterialisering och avgränsar kostnaden för höga koordinater mot baslinjen med låga koordinater
TXLSOutlineGeometry skriver aldrig arbetsboksdata direkt; motoradaptrar validerar och tillämpar den returnerade planen, vilket låter geometrianalys och tillståndsmutation förbli åtskilda
Se även