Premenujte hárok zo „Summary“ na „Overview“ v generovanom zošite a každý interný hyperodkaz smerujúci na Summary!A1 prestane fungovať. Žiadna výnimka pri ukladaní, žiadna pri otváraní. Odkaz sa stále vykresľuje, stále vyzerá klikateľný, ale potichu neodkazuje nikam. Rovnaký typ poškodenia sa objavuje po konverzii cez „uložiť ako“ alebo po konverzii medzi formátmi .xls a .xlsx, keď sa komentár posunie o stĺpec vedľa alebo keď relatívny odkaz stratí svoj cieľ. Obe tieto funkcie nesú stav revízie, na základe ktorého konajú skutoční ľudia, takže keď sa pokazia, táto chyba je neviditeľná dovtedy, kým recenzent neklikne a nič sa nestane.
To je praktický dôvod, prečo si komentáre a hyperodkazy zaslúžia väčšiu pozornosť, než by naznačoval ich kozmetický vzhľad. HotXLS poskytuje kódu v Delphi a C++Builder priamy prístup na zápis k obom prvkom, a to vo formátoch XLS aj XLSX, bez akejkoľvek automatizácie Excelu. Druhou stranou tejto kontroly je zodpovednosť: knižnica zapisuje presne tie ciele, ktoré jej odovzdáte, a žiadny z nich neoveruje, takže udržanie funkčného procesu revízie je úlohou vášho kódu, nie Excelu.
Komentáre buniek ako strojovo zapisované záznamy revízií
V triednom modeli XLSX je komentár objektom na úrovni hárka: pozná svoj riadok, svoj stĺpec, autora a telo textu. Pole autora má svoje opodstatnenion. Keď zošit vygenerovaný vaším kódom prechádza revíznym reťazcom, prvá otázka audítora je, kto napísal danú poznámku, a poznámka ponechaná bez autora odpovedá na túto otázku prázdnym miestom. Označte vygenerované komentáre identitou služby, aby ich pôvod nebol nikdy nejednoznačný.
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
Note: TXLSXComment;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('reconciliation.xlsx');
Sheet := Book.Sheets[0];
// Authored note on the adjusted figure
Sheet.AddComment(14, 4, 'Manual adjustment: late FX rate, see ticket FIN-2214',
'recon-service');
// Update an existing note instead of stacking a second one
Note := Sheet.Comments.FindAt(14, 4);
if Note <> nil then
Note.Text := Note.Text + ' [verified 2026-06-11]';
Book.SaveAs('reconciliation-reviewed.xlsx');
finally
Book.Free;
end;
end;
Testovanie pomocou FindAt má väčší význam, než sa zdá. Dávková úloha, ktorá sa opakuje po prechodnom zlyhaní, rada zavolá AddComment druhýkrát na bunku, ktorú už anotovala, a bunka skončí s dvoma naskladanými poznámkami, ktoré nikto nežiadal. Najprv otestujte prítomnosť pomocou FindAt a aktualizujte objekt, ktorý vráti. Kolekcia Comments vystavuje aj metódy DeleteAt a DeleteInRange. Tento variant pre rozsah je ten, po ktorom siahnete pri čistení zošita pred jeho odoslaním z budovy: vymazanie interných QA anotácií z celej oblasti je otázkou jediného volania namiesto ručne písaného cyklu cez bunky.
Externé URL adresy a skoky v rámci zošita sú odlišné API
Formát OOXML ukladá tieto dva typy odkazov na rôzne miesta. Externá URL sa stane záznamom vzťahu v časti .rels hárka, pričom bunka ukazuje na daný vzťah pomocou ID. Interný skok sa vrstvy vzťahov vôbec nedotýka; je to obyčajný reťazec umiestnenia, napríklad Summary!A1, uložený priamo v odkaze. HotXLS zachováva tento rozdiel viditeľný v API a nepreťažuje jedinú metódu, čo znamená, že si vyberiete správne volanie podľa toho, kde sa cieľ nachádza:
Sheet.Cells[2, 1].Value := 'Source record';
Sheet.AddHyperlink(2, 1, 'https://intranet.example.com/records/2214',
'Open record 2214', 'ERP source entry');
Sheet.Cells[3, 1].Value := 'Totals';
Sheet.AddHyperlinkToCell(3, 1, 'Overview!B12', 'Jump to totals');
Na výslednom objekte TXLSXHyperlink sú vlastnosti Url a Location navzájom vylučujúce a IsInternal vám povie, ktorá z nich je vyplnená. Tento príznak kontrolujete vtedy, keď inventarizujete odkazy v otvorenom zošite a potrebujete spracovať prípady „opúšťa súbor“ a „zostáva v súbore“ podľa rôznych pravidiel: externý hostiteľ môže čeliť zoznamu povolených adries, zatiaľ čo internému cieľu stačí pomenovať existujúci hárok. Interné odkazy za sebou nenesú žiadne časti vzťahov, čo tiež zlacňuje ich hromadný prepis.
Problém spomenutý v úvode sa týka výhradne internej strany a vyplýva z jedinej skutočnosti: reťazec umiestnenia nie je analyzovaná referencia. HotXLS zapíše presný text, ktorý mu zadáte, a pri neskoršom premenovaní hárka tento text nič neaktualizuje. V praxi fungujú dve obrany. Prvou je disciplína v poradí krokov: premenujte každý hárok pred vygenerovaním akéhokoľvek odkazu a potom považujte názvy hárkov za zmrazené identifikátory. Druhá možnosť je robustnejšia a prežije aj dodatočné premenovania. Nasmerujte odkaz na definovaný názov na úrovni zošita namiesto priamej adresy Sheet!Cell, pretože Excel prepíše definíciu názvu pri zmene podkladového hárka, takže odkaz sa aktualizuje automaticky. Tento druhý prístup sa prirodzene spája s technikami v článku o definovaných názvoch a vzorcoch medzi hárkami v HotXLS.
Strana XLS: rovnaké koncepty, staršie potrubie
Rozhranie BIFF8 viaže komentáre na rozsahy namiesto kolekcie na úrovni hárka. Zavoláte AddComment na objekte IXLSRange a získate späť TXLSComment; vlastnosť Comment rozsahu načíta existujúcu poznámku a ClearComments ich vymaže. Ostrým úskalím je tu poloha. TXLSComment verejne neodhaľuje svoj vlastný riadok a stĺpec, takže prirodzený cyklus typu „prejdi každý komentár a nahlás, kde sa nachádza“ beží opačným smerom proti API. Musíte začať od buniek. Buď riaďte audit zo zoznamu adries, ktoré ste anotovali, alebo si pri zápise veďte vlastný log pozícií, pretože objekt komentára vám dodatočne nepovie, kde sa nachádza.
var
Book: IXLSWorkbook;
Sheet: IXLSWorksheet;
Remark: TXLSComment;
begin
Book := TXLSWorkbook.Create;
Sheet := Book.Sheets.Add;
Sheet.Name := 'Review';
Sheet.Cells.Item[5, 2].Value := 4821.50;
Remark := Sheet.Cells.Item[5, 2].AddComment('Awaiting sign-off from controller');
Remark.Visible := True; // pop the note open on first view
Sheet.AddHyperlink(7, 2, 'https://intranet.example.com/signoff/4821',
'Sign-off form', 'Opens the controller queue');
Book.SaveAs('review.xls');
end;
Nastavenie vlastnosti Visible na hodnotu True je starší spôsob, ako zabezpečiť, aby bola poznámka neprehliadnuteľná: žlté pole zostane na hárku otvorené a nečaká na prejdenie myšou. TXLSComment ide o krok ďalej ako jeho náprotivok v XLSX tým, že sprístupňuje vlastnosť TextRuns, takže jedna poznámka môže obsahovať tučné varovanie vedľa obyčajného vysvetlenia, čo je formátovanie, ktoré API komentárov v XLSX neodhaľuje rovnakým spôsobom. Hyperodkazy na tejto strane prichádzajú prostredníctvom troch postupných preťažení metód (iba adresa, potom s textom na zobrazenie a nakoniec s popisom) a spätne sa načítavajú cez kolekciu HyperLinks hárka, kde každý odkaz sprístupňuje vlastnosti Address, SubAddress, DisplayText a ScreenTip.
Indexový hárok revízií je lepší ako roztrúsené poznámky
Pri viac ako desiatke anotácií prestáva prechádzanie myšou kvôli čítaniu fungovať. Poznámky sa hromadia na hárkoch, ktoré recenzent nikdy neotvorí, a tie najdôležitejšie sú presne tie, ktoré sa najľahšie prehliadnu. Štruktúra, ktorá sa osvedčila najlepšie, je vygenerovaný indexový hárok: jeden riadok na jedno anotované umiestnenie, ktorý obsahuje názov hárka, adresu bunky, autora a krátky úryvok poznámky. Posledný stĺpec obsahuje interný hyperodkaz vytvorený pomocou AddHyperlinkToCell, ktorý skočí priamo na anotovanú bunku. Recenzent teraz číta zoznam namiesto toho, aby prehľadával mriežku, a počet riadkov tohto indexu slúži zároveň ako inventár vašich komentárov pre audit popísaný nižšie.
Tvorba indexu je nenáročná na výkon, pretože váš generátor už pozná každú pozíciu, ktorej sa dotkol. Pri každom zápise komentára pridajte do zoznamu ticu (hárok, riadok, stĺpec, autor, zhrnutie) a potom vygenerujte indexový hárok ako posledný, aby bol jeho počet riadkov pred uložením konečný. Dve vylepšenia sa oplatia: usporiadajte index podľa dôležitosti alebo podľa hárka namiesto poradia vkladania a do hlavičky indexu vložte odkaz na návrat, aby sa recenzent mohol po každej položke vrátiť na začiatok. Keďže interné odkazy sú obyčajné reťazce umiestnenia bez akýchkoľvek prvkov vo vrstve vzťahov, dokonca aj index s tisíckou riadkov nepridá do veľkosti súboru ani času ukladania takmer nič.
Ten istý hárok sa vyplatí znova pri spiatočnej ceste. Keď sa skontrolovaný zošit vráti, váš kód načíta hodnoty stavu zapísané v bunkách vedľa riadkov indexu namiesto opätovného prehľadávania každého hárka a hľadania komentárov, ktoré sa mohli zmeniť. Stĺpec so štruktúrovanými stavovými bunkami sa analyzuje jednoducho, zatiaľ čo roztrúsené poznámky vo forme voľného textu nie.
Kontrola auditu pred odoslaním, ktorá skutočne zachytí poškodenie
Žiadne z týchto API neoveruje cieľ. Odkaz na hárok, ktorý ste vymazali, nesprávne napísaný intranetový hostiteľ, zdieľaný sieťový priečinok vyradený z prevádzky v minulom štvrťroku: to všetko sa uloží bez akéhokoľvek varovania. Špecifikácia ECMA-376 definuje, ako sa odkaz ukladá, nie to, či naozaj na niečo odkazuje. Zošit, ktorý nesie revízne metadáta, si preto zaslúži krátku vlastnú audítorskú fázu spustenú tesne pred volaním SaveAs:
- Zhromaždite každé interné umiestnenie zapísané počas generovania a potvrďte, že názov hárka pred výkričníkom stále existuje v kolekcii hárkov zošita.
- Skontrolujte externé URL adresy voči zoznamu povolených schém a hostiteľov. Samotné cesty typu
file://a UNC cesty odhaľujú podrobnosti o prostredí a prestanú fungovať v momente, keď súbor opustí vašu sieť. - Spočítajte komentáre na hárok a porovnajte ich s tým, čo mal generátor v úmysle zapísať. Opakovaný pokus, ktorý zdvojnásobil poznámky, sa prejaví tu a nie v doručenej pošte recenzenta.
- Odstráňte čisto interné anotácie pomocou
DeleteInRangevždy, keď sa príjemca nachádza mimo organizácie.
Tímy, ktoré zostavujú svoje zošity z dátovej vrstvy, môžu túto fázu začleniť do rovnakého kroku spracovania, ktorý už overuje dáta, takže kontrola metadát sa vykoná automaticky. Mechanika je rovnaká, ako je popísaná v článku o exportovaní výsledkov databázových dopytov do správ v Exceli, ale je zameraná na odkazy a komentáre namiesto riadkov.
Jeden detail týkajúci sa úvodzoviek často potrápi ľudí, ktorí vytvárajú reťazce umiestnenia ručne. Hárok, ktorého názov obsahuje medzeru, musí byť v rámci umiestnenia v jednoduchých úvodzovkách, presne tak, ako ho uvádza riadok vzorcov: 'Quarterly Totals'!A1, nie Quarterly Totals!A1. HotXLS uplatňuje rovnaké pravidlá, aké používa vzorcový engine pre odkazy medzi hárkami, takže ak odkaz funguje vo vzorci na hárku, jeho použitie úvodzoviek bude fungovať aj tu. Ak zadáte neuvedený názov s medzerou, získate rovnaký tichý nefunkčný odkaz, pred ktorým varoval úvod článku.
Komentáre a hyperodkazy sú časti vygenerovaného zošita, na základe ktorých recenzenti konajú bez druhého pohľadu, čo je presne dôvod, prečo cieľ ukazujúci na nič spôsobí skutočné škody skôr, než si to niekto všimne. Vytvorte kontrolu overenia raz, spustite ju na každom zošite pred jeho odoslaním a proces revízie zostane neporušený aj po premenovaniach a konverziách. Celé rozhranie API pre verzie XLS aj XLSX je zdokumentované na produktovej stránke HotXLS Component.