L'unité lxOutline fournit une géométrie et une planification de mutations indépendantes du moteur pour les plans de lignes et de colonnes
Elle ne stocke que les étendues matérialisées, reconnaît les nœuds de synthèse à partir des transitions adjacentes de niveaux de plan et crée des changements d'état compressés pour les dispositions synthèse-après et synthèse-avant sans allouer d'entrée pour chaque coordonnée de la feuille de calcul
Types de base
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;
Les indices de lignes et de colonnes sont en base 1, les niveaux de plan sont non négatifs et les étendues doivent être ajoutées dans un ordre strictement croissant et sans chevauchement
Les étendues adjacentes de même niveau, de même état masqué et de même état réduit sont fusionnées automatiquement ; les indices omis ont un niveau zéro implicite, un état visible et aucun marqueur de réduction
Les deux classes mémorisent leur Axis depuis la construction, Clear vide un plan ou une géométrie pour réutilisation sans réallouer les tampons internes, et SpanCount indique le nombre d'étendues fusionnées que la géométrie contient actuellement
Sémantique des nœuds
| NodeIndex | La ligne ou colonne de synthèse physique interrogée par l'appelant |
| FirstDetailIndex / LastDetailIndex | La plage de détails contiguë dont le niveau est plus profond que l'élément de synthèse |
| SummaryLevel | Le niveau de plan stocké sur l'élément de synthèse, ou zéro lorsque cet élément n'est pas matérialisé |
| Level | Le niveau de groupe représenté par le nœud, égal à SummaryLevel + 1 |
| SummaryHidden | L'état masqué stocké sur l'élément de synthèse |
| Collapsed | Le marqueur de réduction explicite stocké sur l'élément de synthèse |
| SummaryAfter | True lorsque les détails précèdent l'élément de synthèse, false lorsqu'ils le suivent |
Les groupes imbriqués restent indépendants car chaque requête s'arrête à la première étendue adjacente dont le niveau n'est pas plus profond que l'élément de synthèse sélectionné
Un vide termine également la plage de détails, de sorte que des métadonnées clairsemées ne peuvent pas relier accidentellement des coordonnées inutilisées en un seul groupe
Plans de mutation
Un plan de mutation contient des plages ordonnées en base 1 et un masque de champs indiquant si chaque plage modifie l'état masqué, l'état réduit ou les deux ; les changements équivalents adjacents sont fusionnés automatiquement
| xocPreserve | Modifie le nœud sélectionné en conservant les marqueurs de réduction des descendants, ce qui constitue le comportement par défaut des groupes imbriqués |
| xocCollapse | Marque comme réduits les nœuds descendants situés à l'intérieur du nœud sélectionné ou masqués sous le niveau d'affichage demandé |
| xocExpand | Efface les marqueurs de réduction des nœuds descendants situés à l'intérieur du nœud sélectionné ou masqués sous le niveau d'affichage demandé |
Développer un parent avec xocPreserve révèle les détails immédiats tandis que les détails appartenant à des enfants réduits restent masqués ; développer un enfant à l'intérieur d'un ancêtre réduit n'expose pas le contenu à travers cet ancêtre
Les niveaux d'affichage sont en base 1 : le niveau 1 réduit chaque groupe de premier niveau, et chaque valeur supérieure révèle un niveau de plan supplémentaire tout en définissant les marqueurs des nœuds limites correspondants
Construire le même état demandé à partir d'une géométrie qui le contient déjà produit un plan vide, et interroger un non-nœud renvoie false avec un plan vide
Les opérations sur les nœuds laissent inchangé l'état masqué indépendant de l'élément de synthèse sélectionné, et les plans de niveau d'affichage ne rendent pas visibles les éléments de niveau zéro qui ont été masqués en dehors d'un groupe de plan
Adaptateurs de feuille de calcul
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 et TXLSXWorksheet exposent les trois mêmes méthodes, de sorte que les appelants peuvent interroger ou modifier un nœud de synthèse de ligne ou de colonne en base 1 sans construire la géométrie manuellement
L'adaptateur classique ne lit que les blocs de lignes alloués et les métadonnées de colonnes assignées, tandis que l'adaptateur XLSX fusionne ses listes clairsemées de niveaux de plan, d'états masqués et de réductions avant d'appliquer un plan de mutation compressé dans une seule transaction d'écriture
Les groupes de lignes et de colonnes OpenDocument conservent leur état natif imbriqué table:display ; les modifications directes de métadonnées et les changements structurels de lignes ou de colonnes projettent cet état en toute sécurité vers le nœud de synthèse logique, et la conversion vers XLSX écrit le marqueur de réduction sur l'élément de synthèse XLSX plutôt que sur chaque membre du groupe
Les méthodes TXLSXWorksheet.ToggleRowGrouped et ToggleColGrouped existantes restent disponibles comme wrappers de compatibilité ; leur argument est la première ligne ou colonne de détails, et le wrapper résout le nœud de synthèse tenant compte de la direction avant de le basculer
Exemple 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;
Exemple 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;
}
Performances et portée
La recherche de nœud utilise une recherche binaire suivie uniquement des étendues matérialisées adjacentes traversées par le groupe sélectionné, soit un travail de O(log n + k) pour n étendues et k étendues visitées
La planification des mutations en masse découvre chaque nœud matérialisé avec un parcours linéaire à pile monotone, fusionne les intervalles de visibilité réduite et émet des changements de plages compressés sans visiter les coordonnées inutilisées
Le générateur accepte la dernière ligne de feuille de calcul XLSX tout en ne retenant que les étendues fournies, de sorte qu'une coordonnée élevée n'implique ni allocation ni balayage d'un million d'entrées
Le garde-fou de régression des adaptateurs de feuille de calcul exécute les mêmes 32,768 requêtes de nœuds et 2,048 mutations de réduction ou de développement sur six entrées de lignes matérialisées près de la ligne 8 et de la ligne 1,048,576, exige zéro matérialisation de cellules et borne le coût des coordonnées élevées par rapport à la référence à basse coordonnée
TXLSOutlineGeometry n'écrit jamais directement les données du classeur ; les adaptateurs de moteur valident et appliquent le plan renvoyé, ce qui permet de maintenir séparées l'analyse de géométrie et la mutation d'état
Voir aussi