Generér en arbejdsbog fra Delphi, annotér en celle med det klassiske kommentar-API, og Excel 365 arkiverer din tekst under Noter: en gammeldags gul boks uden svarfelt, uden forfatteravatar, uden knap til at markere som løst. HotXLS skriver ægte trådede Excel 365-kommentarer gennem AddThreadedComment og AddThreadedReply på XLSX-motoren, udsender den dedikerede del xl/threadedComments/threadedCommentN.xml pr. ark og registrerer hver forfatter i person-delen på arbejdsbogsniveau, så den samtale, din kode skriver, er det samme objekt, som en korrekturlæser svarer på i Excel
Skelnen betyder noget, fordi de to funktioner kun ligner hinanden. En note er en flydende tekstboks; en trådet kommentar er en samtalepost med stabile identifikatorer, et svartræ, et forfatterregister og et løst-flag — netop det, en gennemgangsproces rent faktisk kører på. Denne artikel gennemgår OOXML-strukturen først, for når du ser de to lagringsmodeller side om side, holder hver eneste adfærdsforskel i Excel op med at være et mysterium
Hvorfor vises mine kommentarer som noter i Excel 365?
Det korte svar: to generationer af kommentarer deler ét gitter, og de bor i helt forskellige dele af pakken. Den gamle model — den, AddComment rammer — gemmer tekst i xl/comments1.xml (indholdstype application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml) og placerer boblen gennem en tilhørende VML-tegningsdel, xl/drawings/vmlDrawing1.vml. Det par er ældre end båndet; Excel 365 læser det stadig trofast, men gengiver resultatet som en note og tilbyder ingen tråd-brugerflade på det, fordi der ikke er noget i lagringen at tråde. Forfatter er en visningsstreng, position er en VML-form, og det er hele modellen
Trådede kommentarer, der kom med Excel 365, ignorerer VML-laget fuldstændigt. Hvert ark med en samtale bærer sin egen del xl/threadedComments/threadedCommentN.xml under indholdstypen application/vnd.openxmlformats-officedocument.spreadsheetml.threadedComments+xml, og arbejdsbogen bærer én enkelt del xl/person/person.xml (indholdstype ...spreadsheetml.people+xml), der lister hver deltager én gang. HotXLS eksponerer begge modeller på det samme regneark: AddComment bliver ved med at skrive det gamle par, AddThreadedComment skriver de nye dele. Hvis dit output dukker op som noter, kaldte du det første API og ville have det andet. Den gamle model er stadig det rigtige værktøj til visse opgaver — den tidligere artikel om cellekommentarer og hyperlinks i gennemgangsprocesser dækker den i dybden, inklusive XLS-siden — men intet i den opgraderer til en tråd
Hvad HotXLS skriver ind i pakken
HotXLS modellerer hvert svar som et TXLSXThreadedComment-objekt, der bærer et celleanker (Ref), en GUID-agtig identifikator (Id), et valgfrit ParentId, et AuthorId, der slås op i personlisten, et DisplayName-spejl, selve teksten, et Done-flag og en ISO-8601-DateTime. Ved gemning bliver hver post til et <threadedComment>-element, hvis t-attribut rummer identifikatoren, hvis dT-attribut rummer tidsstemplet, og hvis parentT-attribut — kun til stede på svar-børn — navngiver forælderens identifikator. Excel rekonstruerer samtaletræet ved at matche parentT mod t; der er ingen indlejring i XML-koden, bare en flad liste plus referencer
Person-delen er den brik, de fleste hjemmestrikkede implementeringer glemmer. Hvert authorId i en trådet kommentar skal kunne slås op i en <person>-post i xl/person/person.xml, koblet ind i arbejdsbogsrelationerne, med sin egen tilsidesættelse af indholdstypen — ellers har Excel intet visningsnavn at vise. HotXLS klarer registreringen automatisk: AddThreadedComment slår forfatteren op på arbejdsbogens Persons-liste efter visningsnavn og opretter en post med en frisk GUID, når ingen findes, så på hinanden følgende kommentarer fra samme forfatter deler én identitet. Regnearksrelationerne får threadedComments-relationen, arbejdsbogsrelationerne får person-relationen, og content-types-manifestet får begge tilsidesættelser, uden at noget af det dukker op i din kode
Sådan bygger du en svarkæde med AddThreadedComment og AddThreadedReply
AddThreadedComment opretter samtalens rod: dens ParentId forbliver tom, og det er netop det, der markerer den som toppen af tråden. AddThreadedReply tager en ParentRef-parameter — cellereferencen, hvor roden bor — finder roden ved det anker og stempler det nye svars ParentId med rodens Id. Begge returnerer det nye TXLSXThreadedComment, så du kan sætte tidsstempel eller løst-tilstand på det objekt, du netop har oprettet:
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
Root: TXLSXThreadedComment;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('forecast.xlsx');
Sheet := Book.Sheets[0];
// Samtalens rod; ParentId forbliver tom
Root := Sheet.AddThreadedComment(8, 3,
'Q3 figure looks low against the pipeline export', 'Maria Ortiz');
Root.DateTime := '2026-07-06T09:12:00Z';
// Svar forankres i den samme celle; ParentRef navngiver rodcellen
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 listning fortjener opmærksomhed. For det første sendes Root.Ref i stedet for en håndbygget streng: den reference, biblioteket genererede, matcher med garanti det, AddThreadedReply vil slå op, hvilket fjerner en hel klasse af off-by-one-ankerfejl. For det andet blev begge forfattere sendt som almindelige visningsnavne — personregistret, GUID-identiteterne og authorId-koblingen skete alt sammen bag kaldene. Åbn den gemte fil i Excel 365, og celleforankringen, svarrækkefølgen og de to forskellige deltagere er alle levende: klik på Svar, og Excel føjer til den samme tråd, som din kode startede
At læse en samtale tilbage: adfærd ved rundtur
HotXLS rundturer trådede kommentarer fra og med version 2.122.0: at genåbne en gemt pakke genopbygger hvert arks samtaleliste og arbejdsbogens deltagerliste ud fra delene, så identifikatorer, svarlinks og visningsnavne overlever en fuld læs→skriv-cyklus. Læseren parser person.xml før alt arkindhold, og det er netop det, der lader hvert authorId slå op i et visningsnavn ved indlæsning; parsede personidentifikatorer bevares, som de er, i stedet for at blive genereret på ny, så en arbejdsbog, der pendler mellem din kode og Excel, holder stabile forfatteridentiteter gennem vilkårligt mange rundture
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;
Lagringen som flad liste plus referencer skinner bevidst igennem her: ThreadedComments opregner svar i delens rækkefølge, og et tomt ParentId identificerer hver rod. Har du brug for træformen — for eksempel til at eksportere en gennemgangslog — så gruppér først efter Ref og kæd derefter ParentId til Id inden for hver celles gruppe. Denne bevar-det-du-parsede-adfærd er ét eksempel på en bredere politik i biblioteket; artiklen om tabsfri rundtur af temaer, udvidelseslister og beregningskæden dækker, hvordan det samme princip gælder for resten af pakken
Løst-tilstand, tidsstempler og forfatteridentitet
Tre attributter bærer gennemgangssemantikken, og alle tre kan skrives på de returnerede objekter. Done mapper til done-attributten — Excel viser en løst tråd klappet sammen med et Genåbn-link. DateTime er ISO-8601-UTC-oprettelsesstemplet (dT); HotXLS indsætter en fast pladsholder, når du lader den stå tom, så delen altid validerer, men et rigtigt tidsstempel er det, der gør trådens historik læsbar, så sæt det. På identitetssiden eksponerer hvert TXLSXPerson et ProviderId — typisk None for lokalt oprettede poster — og et UserId, du kan udfylde med et UPN eller en e-mailadresse, når din applikation kender den:
var
Root: TXLSXThreadedComment;
Person: TXLSXPerson;
begin
Root := Sheet.ThreadedComments.FindAt('D9');
if Root <> nil then
Root.Done := True; // gemmes som done="1"; Excel viser tråden som løst
Person := Book.Persons.FindByDisplayName('Maria Ortiz');
if Person <> nil then
Person.UserId := '[email protected]';
end;
Én grænse skal siges ligeud: HotXLS skriver <mentions>-elementet tomt. Poster for @-omtaler — maskineriet, der lyser en kollegas navn op inde i kommentarteksten og udløser en notifikation i Microsoft 365 — er ikke modelleret, så tekst med et @-tegn gemmes som ren tekst. For en genereret gennemgangsarbejdsbog er det sjældent et tab, men hvis din arbejdsgang afhænger af notifikationer om omtaler, så regn med, at et menneske tilføjer dem inde i Excel. Forfatteridentitet i person-delen hænger naturligt sammen med proveniensfelterne på arbejdsbogsniveau, der er dækket i arbejdsbogsmetadata og dokumentegenskaber, hvor resten af en genereret fils revisionsspor bor
Hvad gør ældre Excel-versioner med trådede kommentarer?
Excel 2016 og tidligere er ældre end trådmodellen, og de ignorerer ganske enkelt dele, de ikke forstår. Når Excel 365 selv gemmer en trådet samtale, skriver den også en gammeldags kommentarskygge — en pladsholdernote, der lyder "[Threaded comment]…" — netop for at ældre versioner viser noget ved den forankrede celle. HotXLS udsender kun de trådede dele, uden gammel skygge, så en fil skrevet af din kode viser slet ingen kommentarindikator, når den åbnes i Excel 2016. Hvis dit publikum omfatter installationer fra før 365, og annotationen skal være synlig dér, er det gamle AddComment-API stadig den kompatible kanal; bare undgå at stable begge modeller på den samme celle uden at teste hver eneste Excel-version, du leverer til, for hvordan en læser forener en note og en tråd på én celle, er læserens beslutning, ikke din
Den anden hårde grænse er selve filformatet. Trådede kommentarer er en OOXML-struktur uden modstykke i BIFF8, så .xls-siden af HotXLS har intet tråd-API — en arbejdsbog, der skal blive i det gamle binære format, er begrænset til klassiske noter. I praksis er beslutningstabellen kort: skriver du .xlsx til Excel 365 eller til Excel på web og mobil, så brug AddThreadedComment og få rigtige samtaler; sigter du efter Excel 2016 eller .xls, så brug AddComment og accepter notemodellen; auditerer du en fil, du har modtaget, så tjek både ThreadedComments og Comments, for en arbejdsbog, der har levet i begge verdener, kan med rette bære begge dele. Den fulde API-flade for begge generationer er dokumenteret på produktsiden HotXLS Delphi Excel Component