Hasilkan buku kerja dari Delphi, beri anotasi pada sel dengan API komentar klasik, and Excel 365 akan menyimpan teks Anda di bawah Notes: kotak kuning gaya lama tanpa kolom Balas (Reply), tanpa avatar penulis, tanpa tombol selesaikan (resolve). HotXLS menulis threaded comment Excel 365 asli melalui AddThreadedComment dan AddThreadedReply pada mesin XLSX, memancarkan bagian xl/threadedComments/threadedCommentN.xml khusus per lembar kerja dan mendaftarkan setiap penulis di bagian person tingkat buku kerja, sehingga percakapan yang ditulis oleh kode Anda adalah objek yang sama yang dibalas oleh peninjau di Excel
Perbedaan ini penting karena kedua fitur tersebut hanya terlihat mirip. Catatan (note) adalah kotak teks melayang; threaded comment adalah rekaman percakapan dengan pengidentifikasi yang stabil, pohon balasan, registri penulis, dan bendera penyelesaian (resolved flag) — hal-hal yang sebenarnya dijalankan dalam alur kerja peninjauan. Artikel ini membahas struktur OOXML terlebih dahulu, karena begitu Anda melihat kedua model penyimpanan ini berdampingan, setiap perbedaan perilaku di Excel tidak lagi menjadi misterius
Mengapa komentar saya muncul sebagai catatan (notes) di Excel 365?
Jawaban singkatnya: dua generasi komentar berbagi satu kisi, dan mereka tinggal di bagian paket yang sama sekali berbeda. Model lama — yang ditargetkan oleh AddComment — menyimpan teks di xl/comments1.xml (tipe konten application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml) dan memposisikan balon komentar melalui bagian gambar VML pendamping, xl/drawings/vmlDrawing1.vml. Pasangan tersebut mendahului pita menu (ribbon); Excel 365 masih membacanya dengan setia, tetapi merender hasilnya sebagai "catatan" (note) dan tidak menawarkan UI threading pada catatan tersebut, karena tidak ada yang perlu di-thread di dalam penyimpanan. Penulis adalah string tampilan, posisi adalah bentuk VML, dan itulah seluruh modelnya
Threaded comment, yang diperkenalkan bersama Excel 365, mengabaikan lapisan VML sepenuhnya. Setiap lembar kerja dengan percakapan membawa bagian xl/threadedComments/threadedCommentN.xml miliknya sendiri di bawah tipe konten application/vnd.openxmlformats-officedocument.spreadsheetml.threadedComments+xml, dan buku kerja membawa satu bagian xl/person/person.xml (tipe konten ...spreadsheetml.people+xml) yang mencantumkan setiap peserta sekali. HotXLS mengekspos kedua model pada lembar kerja yang sama: AddComment tetap menulis pasangan lama, AddThreadedComment menulis bagian baru. Jika keluaran Anda muncul sebagai catatan, Anda memanggil API pertama padahal menginginkan yang kedua. Model lama masih menjadi alat yang tepat untuk beberapa pekerjaan — artikel sebelumnya tentang komentar sel dan hipertautan dalam alur kerja peninjauan membahasnya secara mendalam, termasuk sisi XLS — tetapi tidak ada apa pun di dalamnya yang dapat ditingkatkan menjadi thread
Apa yang ditulis HotXLS ke dalam paket
HotXLS memodelkan setiap balasan sebagai objek TXLSXThreadedComment yang membawa jangkar sel (Ref), pengidentifikasi gaya GUID (Id), ParentId opsional, AuthorId yang diselesaikan melalui daftar orang (person list), cermin DisplayName, isi teks, bendera Done, dan DateTime ISO-8601. Saat disimpan, setiap entri menjadi elemen <threadedComment> yang atribut t-nya menampung pengidentifikasi, atribut dT-nya menampung stempel waktu, dan atribut parentT-nya — hanya ada pada balasan anak — menyebutkan pengidentifikasi induk. Excel membangun kembali pohon percakapan dengan mencocokkan parentT ke t; tidak ada bersarang di XML, hanya daftar datar ditambah referensi
Bagian person adalah bagian yang paling sering dilupakan oleh implementasi buatan sendiri. Setiap authorId dalam threaded comment harus diselesaikan ke entri <person> di xl/person/person.xml, yang dihubungkan ke relasi buku kerja, dengan override tipe kontennya sendiri — jika tidak, Excel tidak memiliki nama tampilan untuk ditunjukkan. HotXLS menangani pendaftaran secara otomatis: AddThreadedComment mencari penulis pada daftar Persons buku kerja berdasarkan nama tampilan dan membuat entri dengan GUID baru ketika tidak ada yang cocok, sehingga komentar berturut-turut oleh penulis yang sama berbagi satu identitas. Hubungan lembar kerja mendapatkan hubungan threadedComments, hubungan buku kerja mendapatkan hubungan orang (person relationship), dan manifes tipe konten mendapatkan kedua override tersebut, tanpa ada yang muncul dalam kode Anda
Membangun rantai balasan dengan AddThreadedComment dan AddThreadedReply
AddThreadedComment membuat akar percakapan: ParentId-nya tetap kosong, yang menandainya sebagai bagian atas thread. AddThreadedReply mengambil parameter ParentRef — referensi sel tempat akar berada — menemukan akar pada jangkar tersebut, dan membubuhkan ParentId balasan baru dengan Id milik akar. Keduanya mengembalikan TXLSXThreadedComment yang baru, sehingga Anda dapat mengatur stempel waktu atau status terselesaikan pada objek yang baru saja Anda buat:
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
Root: TXLSXThreadedComment;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('forecast.xlsx');
Sheet := Book.Sheets[0];
// Akar percakapan; ParentId tetap kosong
Root := Sheet.AddThreadedComment(8, 3,
'Q3 figure looks low against the pipeline export', 'Maria Ortiz');
Root.DateTime := '2026-07-06T09:12:00Z';
// Balasan berjangkar di sel yang sama; ParentRef menyebutkan sel akar
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;
Dua detail dalam daftar itu patut diperhatikan. Pertama, Root.Ref diteruskan alih-alih string buatan sendiri: referensi yang dihasilkan pustaka dijamin cocok dengan apa yang akan dicari AddThreadedReply, yang menghilangkan seluruh kelas bug jangkar yang meleset satu sel. Kedua, kedua penulis diteruskan sebagai nama tampilan biasa — pendaftaran orang, identitas GUID, dan kabel authorId semuanya terjadi di belakang panggilan. Buka berkas yang disimpan di Excel 365 dan penjangkaran sel, urutan balasan, dan dua peserta yang berbeda semuanya aktif: klik Balas (Reply) dan Excel menambahkan ke thread yang sama dengan yang dimulai oleh kode Anda
Membaca kembali percakapan: perilaku round-trip
HotXLS melakukan round-trip pada threaded comment sejak versi 2.122.0: membuka kembali paket yang disimpan akan membangun kembali daftar percakapan setiap lembar kerja dan daftar peserta buku kerja dari bagian-bagiannya, sehingga pengidentifikasi, tautan balasan, dan nama tampilan bertahan dalam siklus baca→tulis lengkap. Pembaca mengurai person.xml sebelum konten lembar kerja apa pun, yang memungkinkan setiap authorId diselesaikan ke nama tampilan pada saat pemuatan; pengidentifikasi orang yang diurai dipertahankan apa adanya alih-alih dibuat ulang, sehingga buku kerja yang berpindah-pindah antara kode Anda dan Excel mempertahankan identitas penulis yang stabil di banyak round-trip
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;
Penyimpanan daftar datar ditambah referensi terlihat di sini dengan sengaja: ThreadedComments mencantumkan balasan dalam urutan bagian, dan ParentId yang kosong mengidentifikasi setiap akar. Jika Anda membutuhkan bentuk pohon — misalnya, untuk mengekspor log tinjauan — kelompokkan berdasarkan Ref terlebih dahulu lalu hubungkan ParentId ke Id di dalam grup masing-masing sel. Perilaku mempertahankan-apa-yang-Anda-urai ini adalah salah satu contoh kebijakan yang lebih luas dalam pustaka; artikel tentang round-trip lossless dari tema, daftar ekstensi, dan rantai perhitungan (calc chain) membahas bagaimana prinsip yang sama berlaku untuk sisa paket lainnya
Status diselesaikan, stempel waktu, dan identitas penulis
Tiga atribut membawa semantik peninjauan, dan ketiganya dapat ditulis pada objek yang dikembalikan. Properti Done memetakan ke atribut done — Excel menampilkan thread yang diselesaikan secara diciutkan dengan tautan Buka Kembali (Reopen). DateTime is stempel pembuatan UTC ISO-8601 (dT); HotXLS menggantinya dengan placeholder tetap ketika Anda membiarkannya kosong sehingga bagian tersebut selalu memvalidasi, tetapi stempel waktu yang nyata adalah hal yang membuat riwayat thread dapat dibaca, jadi aturlah. Di sisi identitas, masing-masing TXLSXPerson mengekspos ProviderId — biasanya None untuk entri yang ditulis secara lokal — dan UserId yang dapat Anda isi dengan UPN atau email ketika aplikasi Anda mengetahuinya:
var
Root: TXLSXThreadedComment;
Person: TXLSXPerson;
begin
Root := Sheet.ThreadedComments.FindAt('D9');
if Root <> nil then
Root.Done := True; // disimpan sebagai done="1"; Excel menampilkan thread diselesaikan
Person := Book.Persons.FindByDisplayName('Maria Ortiz');
if Person <> nil then
Person.UserId := 'maria.ortiz@example.com';
end;
Satu detail lagi yang perlu dinyatakan dengan jelas: HotXLS menulis elemen <mentions> kosong. Catatan @-mention — mekanisme yang menyoroti nama kolega di dalam teks komentar dan memicu pemberitahuan di Microsoft 365 — tidak dimodelkan, sehingga teks yang mengandung tanda @ disimpan sebagai teks biasa. Untuk buku kerja peninjauan yang dihasilkan secara otomatis, hal ini jarang menjadi kerugian, tetapi jika alur kerja Anda bergantung pada pemberitahuan penyebutan (mention notifications), rencanakan agar manusia menambahkannya di dalam Excel. Identitas penulis di bagian person berpasangan secara alami dengan bidang pembuktian tingkat buku kerja (workbook-level provenance fields) yang dibahas dalam metadata buku kerja dan properti dokumen, yang merupakan tempat sisa jejak audit dari berkas yang dihasilkan berada
Apa yang dilakukan versi Excel lama terhadap threaded comment?
Excel 2016 dan versi sebelumnya mendahului model threaded comment, dan mereka mengabaikan bagian yang tidak mereka pahami begitu saja. Ketika Excel 365 sendiri menyimpan percakapan berulir, ia juga menulis bayangan komentar lama (legacy comment shadow) — catatan placeholder bertuliskan "[Threaded comment]…" — tepatnya agar versi yang lebih lama menampilkan sesuatu pada sel yang dijangkar. HotXLS hanya memancarkan bagian threaded comment saja, tanpa bayangan komentar lama, sehingga berkas yang ditulis oleh kode Anda tidak menampilkan indikator komentar sama sekali saat dibuka di Excel 2016. Jika audiens Anda menyertakan instalasi pra-365 dan anotasi harus terlihat di sana, API AddComment lama tetap menjadi saluran yang kompatibel; hanya saja hindari menumpuk kedua model pada sel yang sama tanpa menguji setiap versi Excel yang Anda kirimkan, karena bagaimana pembaca mendamaikan catatan dan thread pada satu sel adalah keputusan pembaca, bukan keputusan Anda
Batasan ketat lainnya adalah format berkas itu sendiri. Threaded comment adalah struktur OOXML tanpa padanan BIFF8, sehingga sisi .xls dari HotXLS tidak memiliki API threaded — buku kerja yang harus tetap dalam format biner lama terbatas pada catatan klasik. Dalam praktiknya, tabel keputusan sangat singkat: menulis .xlsx untuk Excel 365 atau pembaca Excel web/seluler, gunakan AddThreadedComment dan dapatkan percakapan nyata; menargetkan Excel 2016 atau .xls, gunakan AddComment dan terima model catatan; mengaudit berkas yang Anda terima, periksa ThreadedComments dan Comments, karena buku kerja yang telah hidup di kedua dunia dapat secara sah membawa keduanya. Seluruh permukaan API untuk kedua generasi didokumentasikan di halaman produk HotXLS Delphi Excel Component