Pervadinkite sugeneruotos darbo knygos lapą iš „Summary“ į „Overview“, ir kiekvienas vidinis hipersaitas, rodęs į Summary!A1, nustos kur nors vesti. Jokios išimties išsaugant, jokios atveriant. Nuoroda vis dar atvaizduojama, vis dar atrodo spustelima ir tyliai išsisprendžia į nieką. Toks pats gedimas išlenda po išsaugojimo kitu formatu arba po .xls ir .xlsx ciklo, kai komentaras atsiduria stulpeliu ne ten arba santykinė nuoroda pameta savo taikinį. Abi šios savybės neša peržiūros būseną, pagal kurią elgiasi tikri žmonės, todėl sugedusios jos lieka nematomos tol, kol recenzentas spusteli ir nieko neįvyksta
Būtent dėl to komentarai ir hipersaitai nusipelno daugiau dėmesio, nei leidžia manyti jų kosmetinė išvaizda. HotXLS suteikia Delphi ir C++Builder kodui tiesioginę rašymo prieigą prie abiejų tiek XLS, tiek XLSX formatuose, be jokios Excel automatizacijos grandinėje. Kita tokios kontrolės pusė yra atsakomybė: biblioteka įrašo būtent tuos taikinius, kuriuos jai paduodate, ir nė vieno jų netikrina, todėl peržiūros darbo eigos vientisumas yra jūsų kodo, o ne Excel reikalas
Langelių komentarai kaip mašinos rašomi peržiūros įrašai
XLSX klasių modelyje komentaras yra darbalapio lygio objektas: jis žino savo eilutę, savo stulpelį, autorių ir teksto turinį. Autoriaus laukas savo vietą pelno. Kai jūsų kodo sugeneruota darbo knyga keliauja peržiūros grandine, pirmas auditoriaus klausimas yra, kas parašė konkrečią pastabą, o pastaba be autoriaus į tą klausimą atsako tuštuma. Žymėkite generuojamus komentarus tarnybos tapatybe, kad kilmė niekada nebūtų dviprasmiška
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
Note: TXLSXComment;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('reconciliation.xlsx');
Sheet := Book.Sheets[0];
// Pastaba su autoriumi prie pakoreguoto skaičiaus
Sheet.AddComment(14, 4, 'Manual adjustment: late FX rate, see ticket FIN-2214',
'recon-service');
// Atnaujinti esamą pastabą, o ne sukrauti antrą
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;
FindAt patikra sveria daugiau, nei atrodo. Paketinė užduotis, kuri kartoja veiksmą po laikino gedimo, mielai antrą kartą iškvies AddComment langeliui, kurį jau anotavo, ir langelyje atsidurs dvi sukrautos pastabos, kurių niekas neprašė. Pirmiausia patikrinkite su FindAt ir atnaujinkite jos grąžintą objektą. Kolekcija Comments taip pat pateikia DeleteAt ir DeleteInRange. To diapazono varianto verta griebtis tada, kai valote darbo knygą prieš jai išeinant iš įmonės: vidinių kokybės kontrolės anotacijų išvalymas iš visos srities yra vienas iškvietimas, o ne ranka rašytas ciklas per langelius
Išoriniai URL ir šuoliai darbo knygos viduje yra skirtingi API
OOXML abi nuorodų rūšis laiko skirtingose vietose. Išorinis URL tampa ryšio įrašu lapo .rels dalyje, o langelis rodo į tą ryšį pagal jo id. Vidinis šuolis ryšių sluoksnio apskritai neliečia; tai paprasta vietos eilutė, tokia kaip Summary!A1, saugoma tiesiai pačioje nuorodoje. HotXLS šį skirtumą palieka matomą API lygyje, užuot perkrovęs vieną metodą, o tai reiškia, kad teisingą iškvietimą pasirenkate žinodami, kur gyvena taikinys:
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');
Gautame TXLSXHyperlink objekte Url ir Location vienas kitą išskiria, o IsInternal pasako, kuris iš jų užpildytas. Būtent šią vėliavėlę tikrinate, kai inventorizuojate atvertos darbo knygos nuorodas ir turite skirtingomis taisyklėmis traktuoti tas, kurios „išeina iš failo“, ir tas, kurios „lieka faile“: išoriniam serveriui gali būti taikomas leidžiamųjų sąrašas, o vidinis taikinys tik privalo įvardyti egzistuojantį lapą. Už vidinių nuorodų nestovi jokios ryšių dalys, todėl jas ir pigiau perrašyti masiškai
Įžangoje minėtas gedimas gyvena vien vidinėje pusėje ir kyla iš vieno fakto: vietos eilutė nėra išanalizuota nuoroda. HotXLS įrašo būtent tą tekstą, kurį jai paduodate, ir niekas to teksto nenukreipia iš naujo, kai lapas vėliau pervadinamas. Praktikoje laikosi dvi gynybos. Pirmoji yra eiliškumo drausmė: pervadinkite visus lapus prieš sugeneruodami bent vieną nuorodą, o tada lapų vardus laikykite užšaldytais identifikatoriais. Antroji yra tvirtesnė ir išgyvena po fakto atliktus pervadinimus. Nukreipkite nuorodą į darbo knygos lygio apibrėžtą vardą, o ne į grynąjį Sheet!Cell adresą, nes Excel perrašo vardo apibrėžimą pasikeitus jo lapui, todėl nuoroda pasitempia kartu automatiškai. Šis antrasis būdas natūraliai dera su metodais, aprašytais straipsnyje apibrėžti vardai ir tarplapinės formulės HotXLS
XLS pusė: tos pačios sąvokos, senesnė mechanika
BIFF8 fasadas komentarus kabina prie diapazonų, o ne prie darbalapio lygio kolekcijos. Kviečiate AddComment ant IXLSRange ir gaunate TXLSComment; diapazono savybė Comment nuskaito esamą pastabą, o ClearComments jas išvalo. Aštrusis kraštas čia yra pozicinis. TXLSComment viešai neatskleidžia savo eilutės ir stulpelio, todėl natūralus ciklas „pereik visus komentarus ir pranešk, kur jie sėdi“ eina prieš API plauką. Pradėti tenka nuo langelių. Arba varykite auditą nuo adresų, kuriuos anotavote, sąrašo, arba rašydami vedžiokite savo pozicijų žurnalą, nes komentaro objektas jums vėliau nepasakys, kur jis gyvena
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; // atverti pastabą iškart pirmą kartą pažiūrėjus
Sheet.AddHyperlink(7, 2, 'https://intranet.example.com/signoff/4821',
'Sign-off form', 'Opens the controller queue');
Book.SaveAs('review.xls');
end;
Visible nustatymas į True yra senasis būdas padaryti pastabą nepraleidžiamą: geltona dėžutė lieka atverta lape, užuot laukusi pelės užvedimo. TXLSComment žengia žingsnį toliau už savo XLSX atitikmenį ir atskleidžia TextRuns, todėl viena pastaba gali nešti paryškintą įspėjimą greta paprasto paaiškinimo — formatavimą, kurio XLSX komentarų API taip neatskleidžia. Hipersaitai šioje pusėje pateikiami trimis laipsniškomis perkrovomis (tik adresas, tada su rodomu tekstu, tada su ekrano patarimu) ir nuskaitomi per darbalapio kolekciją HyperLinks, kurioje kiekviena nuoroda atskleidžia Address, SubAddress, DisplayText ir ScreenTip
Peržiūros rodyklės lapas geriau už išbarstytas pastabas
Peržengus kokį tuziną anotacijų, skaitymas užvedus pelę tyliai nustoja mastelėti. Pastabos kaupiasi lapuose, kurių recenzentas niekada neatveria, o svarbiausias iš jų praleisti lengviausia. Geriausiai laikosi tokia struktūra: sugeneruotas rodyklės lapas su viena eilute kiekvienai anotuotai vietai, kur nurodomas lapo vardas, langelio adresas, autorius ir trumpa pastabos ištrauka. Paskutinis stulpelis neša vidinį hipersaitą, sukurtą su AddHyperlinkToCell, kuris nušoka tiesiai į anotuotą langelį. Dabar recenzentas skaito sąrašą žemyn, o ne medžioja po tinklelį, o tos rodyklės eilučių skaičius kartu tarnauja kaip jūsų komentarų inventorius žemiau aprašytam audito etapui
Rodyklę pigu sukurti, nes jūsų generatorius jau žino kiekvieną paliestą poziciją. Rašydami kiekvieną komentarą, pridėkite prie sąrašo (lapas, eilutė, stulpelis, autorius, santrauka) rinkinį, o rodyklės lapą išveskite paskutinį, kad jo eilučių skaičius prieš išsaugojimą būtų galutinis. Du patobulinimai atsiperka: rikiuokite rodyklę pagal svarbą arba pagal lapą, o ne pagal įterpimo eiliškumą, ir įdėkite grįžimo nuorodą į rodyklės antraštę, kad recenzentas po kiekvieno punkto galėtų atšokti į viršų. Kadangi vidinės nuorodos yra paprastos vietos eilutės, už kurių ryšių sluoksnyje nieko nėra, net tūkstančio eilučių rodyklė beveik nieko neprideda prie failo dydžio ar išsaugojimo laiko
Tas pats lapas atsiperka ir kelionėje atgal. Kai peržiūrėta darbo knyga sugrįžta, jūsų kodas nuskaito būsenos reikšmes, įvestas į langelius greta rodyklės eilučių, užuot iš naujo skenavęs kiekvieną lapą ieškant komentarų, kurie galėjo pasikeisti. Struktūrizuotų būsenos langelių stulpelis išanalizuojamas švariai; laisvo teksto pastabų barstinys — ne
Audito etapas prieš pristatymą, kuris gedimą iš tikrųjų pagauna
Nė vienas iš šių API netikrina taikinio. Nuoroda į lapą, kurį ištrynėte, klaidingai parašytas vidinio tinklo serveris, praėjusį ketvirtį nurašytas failų bendrinys — visa tai išsaugoma be menkiausio garso. ECMA-376 nurodo, kaip nuoroda saugoma, o ne kad ji į ką nors išsisprendžia. Todėl darbo knyga, nešanti peržiūros metaduomenis, nusipelno trumpo jūsų pačių audito etapo, paleidžiamo prieš pat SaveAs:
- Surinkite kiekvieną generavimo metu įrašytą vidinę vietą ir įsitikinkite, kad lapo vardas prieš šauktuką vis dar egzistuoja darbo knygos lapų kolekcijoje
- Patikrinkite išorinius URL pagal leidžiamų schemų ir serverių sąrašą. Gryni
file://ir UNC keliai išduoda aplinkos detales ir lūžta tą pačią akimirką, kai failas išeina iš jūsų tinklo - Suskaičiuokite komentarus kiekviename lape ir palyginkite su tuo, ką jūsų generatorius ketino įrašyti. Pakartojimas, padvigubinęs pastabas, išlįs čia, o ne recenzento pašto dėžutėje
- Pašalinkite tik vidiniam naudojimui skirtas anotacijas su
DeleteInRangevisada, kai gavėjas yra už organizacijos ribų
Komandos, kurios savo darbo knygas stato iš duomenų sluoksnio, gali įterpti šį etapą į tą patį konvejerio žingsnį, kuris jau tikrina duomenis, todėl metaduomenų patikra prisijungia nemokamai. Mechanika yra ta pati, kuri aprašyta straipsnyje duomenų bazės užklausų rezultatų eksportas į Excel ataskaitas, tik pasukta į nuorodas ir komentarus, o ne į eilutes
Viena kabučių detalė žmones parklupdo, kai jie vietos eilutes konstruoja ranka. Lapas, kurio varde yra tarpas, vietos eilutėje turi būti kabutėse lygiai taip, kaip jį kabutėse rašo formulių juosta: 'Quarterly Totals'!A1, o ne Quarterly Totals!A1. HotXLS taiko tas pačias taisykles, kurias formulių variklis naudoja tarplapinėms nuorodoms, todėl jei nuoroda veikia darbalapio formulėje, jos kabutės veiks ir čia. Paduokite jai vardą su tarpu be kabučių ir gausite tą pačią tylią negyvą nuorodą, apie kurią įspėjo įžanga
Komentarai ir hipersaitai yra tos sugeneruotos darbo knygos dalys, pagal kurias recenzentai elgiasi nė nesudvejoję, ir būtent todėl į nieką rodantis taikinys pridaro tikros žalos dar prieš kam nors pastebint. Sukurkite tikrinimo etapą vieną kartą, paleiskite jį kiekvienai darbo knygai prieš išsiuntimą, ir peržiūros darbo eiga išliks sveika per pervadinimus bei konvertavimus. Visas API paviršius abiem — XLS ir XLSX — fasadams aprašytas HotXLS Delphi komponento produkto puslapyje