Sugeneruokite skaičiuoklę iš Delphi aplinkos, pridėkite prie langelio pastabą naudodami klasikinį komentarų API, ir „Excel 365“ patalpins jūsų tekstą skiltyje „Notes“ (pastabos) — seno stiliaus geltoname langelyje be atsakymo lauko, autoriaus atvaizdo ar išsprendimo mygtuko. „HotXLS“ rašo tikrus „Excel 365“ gijinius komentarus (threaded comments) per metodus „AddThreadedComment“ ir „AddThreadedReply“ XLSX variklyje, sukurdama atskirą dalį „xl/threadedComments/threadedCommentN.xml“ kiekvienam lapui ir užregistruodama kiekvieną autorių knygos lygio asmenų (person) dalyje, todėl jūsų kodo sukurta diskusija yra tas pats objektas, į kurį recenzentas atsako programoje „Excel“
Šis skirtumas yra svarbus, nes šios dvi funkcijos tik atrodo panašiai. Pastaba yra plaukiojantis teksto laukelis; gijinis komentaras yra pokalbio įrašas su stabiliais identifikatoriais, atsakymų medžiu, autorių registru ir išsprendimo būsenos žyme — dalykais, kuriais iš tikrųjų remiasi peržiūros darbo eiga. Šiame straipsnyje pirmiausia apžvelgsime OOXML struktūrą, nes pamačius abu saugojimo modelius greta vienas kito, bet kokie „Excel“ elgsenos skirtumai tampa suprantami
Kodėl mano komentarai rodomi kaip pastabos (Notes) programoje „Excel 365“?
Trumpas atsakymas: dvi komentarų kartos dalijasi tuo pačiu tinkleliu, tačiau jos gyvena visiškai skirtingose paketo dalyse. Pasenęs modelis — į kurį kreipiasi „AddComment“ — saugo tekstą faile „xl/comments1.xml“ (turinio tipas „application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml“) ir nustato langelio vietą per susijusią VML piešimo dalį „xl/drawings/vmlDrawing1.vml“. Ši pora atsirado dar prieš programos meniu juostą; „Excel 365“ vis dar patikimai ją skaito, tačiau atvaizduoja rezultatą kaip „pastabą“ (note) ir nesiūlo gijų sąsajos, nes duomenų struktūroje nėra informacijos apie gijas. Autorius čia yra tik tekstinė eilutė, o vieta — VML forma, ir tuo šis modelis baigiasi
Gijiniai komentarai, atsiradę su „Excel 365“, visiškai ignoruoja VML sluoksnį. Kiekvienas lapas, kuriame yra pokalbis, turi savo dalį „xl/threadedComments/threadedCommentN.xml“ (turinio tipas „application/vnd.openxmlformats-officedocument.spreadsheetml.threadedComments+xml“), o pati skaičiuoklės knyga turi vieną bendrą dalį „xl/person/person.xml“ (turinio tipas „...spreadsheetml.people+xml“), kurioje po vieną kartą išvardijami visi dalyviai. „HotXLS“ pateikia abu modelius tame pačiame darbalapyje: „AddComment“ toliau rašo pasenusią porą, o „AddThreadedComment“ rašo naująsias dalis. Jei jūsų rezultatas rodomas kaip pastaba, vadinasi, iškvietėte pirmąjį API, nors norėjote antrojo. Pasenęs modelis vis dar yra tinkamas įrankis tam tikroms užduotims — ankstesniame straipsnyje apie komentarų ir nuorodų naudojimą peržiūros procesuose tai aprašyta išsamiai, įskaitant XLS formatą — tačiau jokie pastabos elementai negali būti paversti gijomis
Ką HotXLS įrašo į paketą
„HotXLS“ modeliuoja kiekvieną atsakymą kaip „TXLSXThreadedComment“ objektą, turintį langelio nuorodą („Ref“), GUID stiliaus identifikatorių („Id“), neprivalomą „ParentId“, per asmenų sąrašą išsprendžiamą „AuthorId“, ekrano pavadinimą („DisplayName“), teksto turinį, atlikimo žymę („Done“) ir ISO-8601 formato laiką („DateTime“). Išsaugant failą, kiekvienas įrašas tampa elementu „<threadedComment>“, kurio atributas „t“ saugo identifikatorių, „dT“ — laiko žymą, o „parentT“ (naudojamas tik atsakymuose) nurodo tėvinį identifikatorių. „Excel“ atkuria pokalbio medį, susiedama „parentT“ su „t“; XML struktūroje nėra jokio įdėtinio (nested) modelio — tik plokščias sąrašas su nuorodomis
Asmenų (person) dalis yra būtent tai, kai pamiršta dauguma rankiniu būdu kuriamų realizacijų. Kiekvienas „authorId“ gijiniame komentare turi būti susietas su „<person>“ įrašu faile „xl/person/person.xml“, įtrauktu į skaičiuoklės knygos ryšius su savo turinio tipo perrašymu — kitaip „Excel“ neturės autoriaus vardo ekrane. „HotXLS“ tvarko šią registraciją automatiškai: „AddThreadedComment“ suranda autorių pagal vardą knygos „Persons“ sąraše ir sukuria naują įrašą su nauju GUID, jei tokio dar nėra, todėl to paties autoriaus komentarai dalijasi viena tapatybe. Darbalapio ryšiai gauna „threadedComments“ ryšį, knygos ryšiai — asmenų ryšį, o turinio tipų manifestas — abu perrašymus, ir jūsų kodo tai niekaip neapkrauna
Atsakymų grandinės kūrimas naudojant AddThreadedComment ir AddThreadedReply
„AddThreadedComment“ sukuria pokalbio šaknį: jos „ParentId“ lieka tuščias, kas nurodo pokalbio pradžią. „AddThreadedReply“ priima „ParentRef“ parametrą — langelio nuorodą, kurioje yra pokalbio pradžia — suranda šaknį tame taške ir pažymi naujo atsakymo „ParentId“ šaknies reikšme „Id“. Abu metodai grąžina naują „TXLSXThreadedComment“ objektą, todėl galite nustatyti laiko žymą ar išsprendimo būseną tiesiai sukurtame objekte:
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
Root: TXLSXThreadedComment;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('forecast.xlsx');
Sheet := Book.Sheets[0];
// Conversation root; ParentId stays empty
Root := Sheet.AddThreadedComment(8, 3,
'Q3 figure looks low against the pipeline export', 'Maria Ortiz');
Root.DateTime := '2026-07-06T09:12:00Z';
// Replies anchor at the same cell; ParentRef names the root cell
Sheet.AddThreadedReply(8, 3, Root.Ref,
'Pipeline export missed the EMEA renewals, re-running', 'Jan Kowalski');
Sheet.AddThreadedReply(8, 3, Root.Ref,
'Confirmed, refreshed figure lands tomorrow', 'Maria Ortiz');
Book.SaveAs('forecast-reviewed.xlsx');
finally
Book.Free;
end;
end;
Pokalbio skaitymas: ciklo (round-trip) elgsena
„HotXLS“ pilnai palaiko gijinių komentarų išsaugojimą ir nuskaitymą nuo v2.122.0 versijos: vėl atidarius išsaugotą paketą, atkuriamas kiekvieno lapo pokalbių sąrašas bei dalyvių sąrašas, todėl identifikatoriai, atsakymų nuorodos ir vardai išlieka per visą nuskaitymo-įrašymo ciklą. Analizatorius nuskaito „person.xml“ failą prieš bet kokį lapo turinį, todėl kiekvienas „authorId“ atidarymo metu yra išsprendžiamas į autoriaus vardą; nuskaityti asmenų identifikatoriai išlaikomi nepakeisti, todėl failas, judantis tarp jūsų programos ir „Excel“, išlaiko stabilias autorių tapatybes per daugybę ciklų
Plokščio sąrašo su nuorodomis saugojimas čia pasirodo tikslingai: „ThreadedComments“ išvardija atsakymus dalies tvarka, o tuščias „ParentId“ nurodo pokalbio pradžią. Jei jums reikia medžio struktūros — pavyzdžiui, eksportuojant peržiūros žurnalą — pirmiausia sugrupuokite pagal „Ref“, o tada susiekite „ParentId“ su „Id“ kiekvieno langelio grupėje. Šis nuskaitytos informacijos išsaugojimo principas yra bendros bibliotekos politikos pavyzdys; straipsnis apie temų, plėtinių sąrašų bei skaičiavimų grandinės saugų išlaikymą (lossless round-trip) aprašo, kaip šis principas taikomas likusiai paketo daliai
Išsprendimo būsena, laiko žymos ir autorių tapatybės
Trys atributai perneša peržiūros semantiką, ir visi trys gali būti keičiami gautuose objektuose. „Done“ atitinka „done“ atributą XML faile — „Excel“ rodo išspręstą pokalbį suskleistą su nuoroda „Reopen“ (atidaryti iš naujo). „DateTime“ yra ISO-8601 UTC formato laiko žyma („dT“); „HotXLS“ naudoja laikiną reikšmę, jei paliekate ją tuščią, kad failas atitiktų specifikaciją, tačiau tikroji laiko žyma daro pokalbio istoriją skaitomą, todėl verta ją nustatyti. Autoriaus tapatybės pusėje kiekvienas „TXLSXPerson“ objektas pateikia „ProviderId“ (paprastai „None“ vietinių autorių atveju) ir „UserId“, kurį galite užpildyti el. pašto adresu, kai jūsų programa jį žino:
var
Root: TXLSXThreadedComment;
Person: TXLSXPerson;
begin
Root := Sheet.ThreadedComments.FindAt('D9');
if Root <> nil then
Root.Done := True; // saved as done="1"; Excel shows the thread resolved
Person := Book.Persons.FindByDisplayName('Maria Ortiz');
if Person <> nil then
Person.UserId := 'maria.ortiz@example.com';
end;
Viena aiški riba: „HotXLS“ įrašo „<mentions>“ elementą tuščią. @-minėjimų įrašai — mechanizmas, kuris pažymi kolegos vardą komentare ir sukelia pranešimą „Microsoft 365“ aplinkoje — nėra modeliuojami, todėl tekstas su „@“ ženklu saugomas kaip paprastas tekstas. Generuojamoms peržiūros skaičiuoklėms tai retai kada yra praradimas, tačiau jei jūsų darbo eigai reikia pranešimų apie paminėjimus, suplanuokite, kad juos rankiniu būdu pridėtų žmogus programoje „Excel“. Autoriaus tapatybė asmenų dalyje natūraliai dera su knygos lygio kilmės laukais, aprašytais skaičiuoklės metaduomenų bei dokumento savybių skyriuose, kur saugoma likusi sugeneruoto failo audito dalis
Ką senesnės „Excel“ versijos daro su gijiniais komentarais?
„Excel 2016“ ir senesnės versijos atsirado prieš gijinių komentarų modelį, todėl jos tiesiog ignoruoja dalis, kurių nesupranta. Kai pati „Excel 365“ išsaugo gijinį pokalbį, ji taip pat įrašo pasenusį komentaro šešėlį (pastabą su tekstu „[Threaded comment]...“), kad senesnės versijos parodytų bent ką nors susijusiame langelyje. „HotXLS“ kuria tik gijines dalis be pasenusio šešėlio, todėl jūsų kodo sukurtame faile nebus rodomas joks komentaro indikatorius, kai jį atidarysite su „Excel 2016“. Jei jūsų naudotojai naudoja senesnes nei 365 versijas ir komentaras turi būti matomas, suderinamu keliu išlieka pasenęs „AddComment“ API; tiesiog venkite dėti abu modelius tam pačiam langeliui be patikrinimo visose naudojamose „Excel“ versijose, nes tai, kaip peržiūros programa suderina pastabą bei giją tame pačiame langelyje, yra pačios programos, o ne jūsų sprendimas
Kita aiški riba yra pats failo formatas. Gijiniai komentarai yra OOXML struktūra, neturinti BIFF8 atitikmens, todėl „HotXLS“ „.xls“ formatas neturi gijinio API — skaičiuoklė, kuri privalo išlikti senajame binariniame formate, yra ribojama tik klasikinėmis pastabomis. Praktinis pasirinkimas paprastas: jei rašote „.xlsx“ failus programai „Excel 365“ ar internetinėms/mobiliosioms „Excel“ versijoms, naudokite „AddThreadedComment“ ir gaukite tikrus pokalbius; jei orientuojatės į „Excel 2016“ ar „.xls“ failus, naudokite „AddComment“ ir susitaikykite su pastabų modeliu; jei atliekate gauto failo auditą, tikrinkite tiek „ThreadedComments“, tiek „Comments“, nes skaičiuoklė, buvusi abiejuose pasauliuose, gali turėti abu elementus. Pilnas abiejų kartų API aprašymas pateikiamas „HotXLS Delphi Excel Component“ produkto puslapyje