Generer en arbeidsbok fra Delphi, merk en celle med det klassiske comment-API-et, og Excel 365 plasserer teksten din under Notes: en gul boks av gammel type uten svarfelt, ingen forfatter-avatar og ingen løsningsknapp. HotXLS skriver ekte trådede Excel 365-kommentarer via AddThreadedComment og AddThreadedReply på XLSX-motoren, sender ut den dedikerte xl/threadedComments/threadedCommentN.xml-delen per ark og registrerer hver forfatter i person-delen på arbeidsboknivå, slik at samtalen koden din skriver, er det samme objektet en sensor svarer på i Excel
Skillet har betydning fordi de to funksjonene bare ser like ut. Et notat er en flytende tekstboks; en trådet kommentar er en samtalepost med stabile identifikatorer, et svartre, et forfatterregister og et løst-flagg — de tingene en evalueringsarbeidsflyt faktisk kjører på. Denne artikkelen går gjennom OOXML-strukturen først, fordi når du ser de to lagringsmodellene ved siden av hverandre, slutter enhver oppførselsforskjell i Excel å være mystisk
Hvorfor vises kommentarene mine som notater i Excel 365?
Det korte svaret: to generasjoner av kommentarer deler samme rutenett, og de lever i helt forskjellige deler av pakken. Den eldre modellen — den AddComment retter seg mot — lagrer tekst i xl/comments1.xml (innholdstype application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml) og posisjonerer snakkeboblen via en tilhørende VML-tegnedel, xl/drawings/vmlDrawing1.vml. Det paret er eldre enn båndet; Excel 365 leser det fremdeles trofast, men det tegner resultatet som et "notat" og tilbyr ingen trådede grensesnitt på det, fordi det ikke er noe i lagringen å tråde. Forfatter er en visningsstreng, posisjon er en VML-form, og det er hele modellen
Trådede kommentarer, som ble introdusert med Excel 365, ignorerer VML-laget fullstendig. Hvert ark med en samtale bærer sin egen xl/threadedComments/threadedCommentN.xml-del under innholdstypen application/vnd.openxmlformats-officedocument.spreadsheetml.threadedComments+xml, og arbeidsboken bærer en enkelt xl/person/person.xml-del (innholdstype ...spreadsheetml.people+xml) som lister opp hver deltaker én gang. HotXLS eksponerer begge modellene på samme regneark: AddComment fortsetter å skrive det eldre paret, mens AddThreadedComment skriver de nye delene. Hvis utdataene dine vises som notater, kalte du det første API-et og ønsket det andre. Den eldre modellen er fremdeles det riktige verktøyet for enkelte oppgaver — den tidligere artikkelen om cellekommentarer og hyperkoblinger i evalueringsarbeidsflyter dekker den i dybden, inkludert XLS-siden — men ingenting i den oppgraderes til en tråd
Hva HotXLS skriver inn i pakken
HotXLS modellerer hvert svar som et TXLSXThreadedComment-objekt som bærer et celleanker (Ref), en GUID-stil-identifikator (Id), en valgfri ParentId, en AuthorId som løses opp via personlisten, et DisplayName-speil, tekstkroppen, et Done-flagg og en ISO-8601 DateTime. Ved lagring blir hver oppføring et <threadedComment>-element hvis t-attributt inneholder identifikatoren, hvis dT-attributt inneholder tidsstempelet, og hvis parentT-attributt — kun til stede på barnesvar — navngir foreldre-identifikatoren. Excel gjenoppbygger samtaletreet by matching parentT med t; det er ingen nesting i XML-en, bare en flat liste pluss referanser
Person-delen er biten de fleste hjemmesnekrede implementasjoner glemmer. Hver authorId i en trådet kommentar må løses opp til en <person>-oppføring i xl/person/person.xml, kablet inn i arbeidsbok-relasjonene, med sin egen overstyring av innholdstype — ellers har Excel ikke noe visningsnavn å vise. HotXLS håndterer registreringen automatisk: AddThreadedComment slår opp forfatteren i arbeidsbokens Persons-liste etter visningsnavn, og oppretter en oppføring med en ny GUID når ingen eksisterer, slik at påfølgende kommentarer fra samme forfatter deler én identitet. Regneark-relasjonene får relasjonen threadedComments, arbeidsbok-relasjonene får person-relasjonen, og listen over innholdstyper får begge overstyringene, uten at noe av dette vises i koden din
Bygge en svarkjede med AddThreadedComment og AddThreadedReply
AddThreadedComment oppretter samtaleroten: dens ParentId forblir tom, noe som markerer den som toppen av tråden. AddThreadedReply tar en ParentRef-parameter — cellereferansen der roten lever — finner roten ved det ankeret, og stempler det nye svarets ParentId med rotens Id. Begge returnerer det nye TXLSXThreadedComment-objektet, slik at du kan sette tidsstempelet eller den løste tilstanden på objektet du akkurat opprettet:
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;
To detaljer i den koden fortjener oppmerksomhet. For det første sendes Root.Ref inn i stedet for en manuelt bygd streng: referansen biblioteket genererte er garantert å matche det AddThreadedReply vil slå opp, noe som fjerner en hel klasse av off-by-one-ankerfeil. For det andre ble begge forfattere sendt inn som enkle visningsnavn — personregisteret, GUID-identitetene og authorId-koblingen skjedde bak kulissene under kallene. Åpne den lagrede filen i Excel 365, og celleforankringen, svarrekkefølgen og de to forskjellige deltakerne er alle aktive: klikk Svar, og Excel legger til i den samme tråden koden din startet
Lese en samtale tilbake: rundreiseoppførsel
HotXLS kjører rundreiser for trådede kommentarer fra og med versjon 2.122.0: gjenåpning av en lagret pakke gjenoppbygger hvert arks samtaleliste og arbeidsbokens deltakerliste fra delene, slik at identifikatorer, svarlenker og visningsnavn overlever en hel lese→skrive-syklus. Tolkeren analyserer person.xml før regnearkinnholdet, noe som gjør at hver authorId kan løses opp til et visningsnavn ved innlasting; tolkedes personidentifikatorer bevares som de er i stedet for å bli generert på nytt, slik at en arbeidsbok som flyttes frem og tilbake mellom koden din og Excel beholder stabile forfatteridentiteter over vilkårlig mange rundreiser
var
i: Integer;
Cmt: TXLSXThreadedComment;
begin
Book.Open('forecast-reviewed.xlsx');
Sheet := Book.Sheets[0];
for i := 0 to Sheet.ThreadedComments.Count - 1 do
begin
Cmt := Sheet.ThreadedComments[i];
if Cmt.ParentId = '' then
Writeln('Root at ', Cmt.Ref, ' by ', Cmt.DisplayName, ': ', Cmt.Text)
else
Writeln(' reply by ', Cmt.DisplayName, ': ', Cmt.Text);
end;
Writeln('Participants: ', Book.Persons.Count);
end;
Den flate listen-pluss-referanser-lagringen skinner bevisst igjennom her: ThreadedComments lister opp svar i delrekkefølge, og en tom ParentId identifiserer hver rot. Hvis du trenger treformen — for eksempel for å eksportere en evalueringslogg — grupper etter Ref først, og koble deretter ParentId til Id innenfor hver celles gruppe. Denne bevar-det-du-tolket-oppførselen er ett eksempel på en bredere policy i biblioteket; artikkelen om tapsfri rundreise av temaer, utvidelseslister og beregningskjeden dekker hvordan det samme prinsippet gjelder for resten av pakken
Løst tilstand, tidsstempler og forfatteridentitet
Tre attributter bærer evalueringssemantikken, og alle tre er skrivbare på de returnerte objektene. Done kartlegges til attributtet done — Excel viser en løst tråd sammenslått med en Gjenåpne-lenke. DateTime is ISO-8601 UTC-opprettelsesstempelet (dT); HotXLS erstatter dette med en fast plassholder når du lar det varmt, slik at delen alltid validerer, men et reelt tidsstempel er det som gjør trådhistorikken lesbar, så sett det. På identitetssiden eksponerer hver TXLSXPerson en ProviderId — vanligvis None for lokalt skrevne oppføringer — og en UserId du kan fylle med en UPN eller e-post når applikasjonen din kjenner den:
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;
Hva gjør eldre Excel-versjoner med trådede kommentarer?
En begrensning for omtale (@-mentions): HotXLS skriver elementet <mentions> tomt. Omtale-poster — mekanismen som lyser opp en kollegas navn i kommentarteksten og utløser et varsel i Microsoft 365 — er ikke modellert, så tekst som inneholder et @-tegn lagres som ren tekst. For en generert evalueringsarbeidsbok er dette sjelden et tap, men hvis arbeidsflyten din avhenger av omtale-varsler, må du planlegge at et menneske legger til disse inni Excel. Forfatteridentitet i person-delen passer naturlig sammen med herkomstfeltene på arbeidsboknivå dekket i arbeidsbokmetadata og dokumentegenskaper, som er der resten av en generert fils revisjonsspor lever
Excel 2016 og tidligere er eldre enn den trådede modellen, og de ignorerer ganske enkelt deler de ikke forstår. Når Excel 365 selv lagrer en trådet samtale, skriver den også en eldre kommentar-skygge — et plassholder-notat som leser "[Threaded comment]…" — nettopp for at eldre versjoner skal vise noe ved den forankrede cellen. HotXLS sender kun ut de trådede delene, uten den eldre skyggen, så en fil skrevet av koden din viser ingen kommentarindikator i det hele tatt når den åpnes i Excel 2016. Hvis publikummet ditt inkluderer installasjoner før 365 og annoteringen må være synlig der, forblir det eldre API-et AddComment den kompatible kanalen; juster bare unngå å stable begge modeller på samme celle uten å teste hver Excel-versjon du sender til, fordi hvordan en leser forsoner et notat og en tråd på én celle er leserens beslutning, ikke din
Den andre harde grensen er selve filformatet. Trådede kommentarer er en OOXML struktur uten noen BIFF8-motpart, så .xls-siden av HotXLS har ikke noe trådet API — en arbeidsbok som må forbli i det eldre binærformatet, er begrenset til klassiske notater. I praksis er beslutningstabellen kort: hvis du skriver .xlsx for Excel 365 eller web-/mobil-Excel-lesere, bruk AddThreadedComment og få reelle samtaler; retter du deg mot Excel 2016 eller .xls, bruk AddComment og godta notatmodellen; reviderer du en fil du har mottatt, sjekk både ThreadedComments og Comments, fordi en arbeidsbok som har levd i begge verdener legitimt kan bære begge. Den fullstendige API-flaten for begge generasjoner er dokumentert på produktsiden for HotXLS Delphi Excel Component