Teknik Makale

Delphi ve HotXLS ile Excel Dosyalarında Sıralı Yorumlar

Delphi'den bir çalışma kitabı oluşturun, klasik yorum API'si ile bir hücreye açıklama ekleyin; Excel 365 metninizi Notlar (Notes) altına kaydeder: Yanıtla (Reply) alanı olmayan, yazar avatarı olmayan, çözümle butonu olmayan eski tarz sarı bir kutu. HotXLS, XLSX motorundaki AddThreadedComment ve AddThreadedReply aracılığıyla gerçek Excel 365 sıralı yorumlarını (threaded comments) yazar; sayfa başına ayrılmış xl/threadedComments/threadedCommentN.xml parçasını yayar ve her yazarı çalışma kitabı düzeyindeki kişi (person) parçasına kaydeder, böylece kodunuzun yazdığı konuşma, bir incelemecinin Excel'de yanıt verdiği nesnenin aynısı olur

Ayrım önemlidir çünkü iki özellik sadece birbirine benzer. Bir not, kayan bir metin kutusudur; sıralı yorum ise kararlı tanımlayıcıları, yanıt ağacı, yazar kaydı ve çözümlenmiş (resolved) bayrağı olan bir konuşma kaydıdır — bir inceleme iş akışının fiilen üzerinde çalıştığı şeylerdir. Bu makale ilk olarak OOXML yapısını incelemektedir, çünkü iki depolama modelini yan yana gördükten sonra Excel'deki her davranış farkı gizemli olmaktan çıkacaktır

Yorumlarım neden Excel 365'te not olarak görünüyor?

AddComment'in hedeflediği eski model, metni xl/comments1.xml (içerik türü application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml) içinde saklar ve balonu eşlik eden bir VML çizim parçası (xl/drawings/vmlDrawing1.vml) aracılığıyla konumlandırır. Bu çift şeritten (ribbon) öncesine dayanır; Excel 365 hala onu sadık bir şekilde okur, ancak sonucu bir "not" olarak işler ve üzerinde hiçbir sıralı konuşma arayüzü sunmaz, çünkü depolamada sıralı hale getirilecek hiçbir şey yoktur. Yazar bir görüntüleme dizesidir, konum bir VML şeklidir ve tüm model bundan ibarettir

Excel 365 ile sunulan sıralı yorumlar, VML katmanını tamamen göz ardı eder. Konuşma içeren her sayfa, application/vnd.openxmlformats-officedocument.spreadsheetml.threadedComments+xml içerik türü altında kendi xl/threadedComments/threadedCommentN.xml parçasını taşır ve çalışma kitabı, her katılımcıyı bir kez listeleyen tek bir xl/person/person.xml parçası (içerik türü ...spreadsheetml.people+xml) taşır. HotXLS her iki modeli de aynı çalışma sayfasında sunar: AddComment eski çifti yazmaya devam eder, AddThreadedComment ise yeni parçaları yazar. Çıktınız not olarak görünüyorsa, ilk API'yi çağırmışsınız demektir oysa ikincisini istiyordunuz. Eski model hala bazı işler için doğru araçtır — inceleme iş akışlarında hücre yorumları ve köprüler hakkındaki önceki makale XLS tarafı da dahil olmak üzere bunu derinlemesine ele alır — ancak içindeki hiçbir şey sıralı bir konuşmaya yükseltilemez

HotXLS pakete ne yazar?

HotXLS, her yanıtı bir hücre çapası (Ref), GUID tarzı bir tanımlayıcı (Id), isteğe bağlı bir ParentId, kişi listesi üzerinden çözümlenen bir AuthorId, bir DisplayName aynası, metin gövdesi, bir Done bayrağı ve bir ISO-8601 DateTime taşıyan bir TXLSXThreadedComment nesnesi olarak modeller. Kaydetme sırasında her giriş, t özniteliği tanımlayıcıyı, dT özniteliği zaman damgasını tutan ve parentT özniteliği — yalnızca çocuk yanıtlarda bulunur — ana tanımlayıcıyı adlandıran bir <threadedComment> öğesi haline gelir. Excel, parentT'yi t ile eşleştirerek konuşma ağacını yeniden oluşturur; XML'de iç içe geçme yoktur, sadece düz bir liste ve referanslar vardır

Kişi (person) parçası, çoğu elle yazılmış uygulamanın unuttuğu parçadır. Sıralı bir yorumdaki her authorId, kendi içerik türü geçersiz kılmasıyla (override) birlikte çalışma kitabı ilişkilerine bağlı olan xl/person/person.xml içindeki bir <person> girişine çözümlenmelidir — aksi takdirde Excel'in gösterecek bir görüntü adı olmaz. HotXLS kayıt işlemini otomatik olarak gerçekleştirir: AddThreadedComment yazarı çalışma kitabının Persons listesinde görüntü adına göre arar ve hiç yoksa yeni bir GUID ile bir giriş oluşturur; böylece aynı yazarın ardışık yorumları tek bir kimliği paylaşır. Çalışma sayfası ilişkileri threadedComments ilişkisini alır, çalışma kitabı ilişkileri kişi ilişkisini alır ve içerik türleri bildirimi (manifest), bunların hiçbiri kodunuzda görünmeden her iki geçersiz kılmayı da alır

AddThreadedComment ve AddThreadedReply ile bir yanıt zinciri oluşturma

AddThreadedComment konuşma kökünü oluşturur: ParentId boş kalır, bu da onu sıranın (thread) tepesi olarak işaretler. AddThreadedReply bir ParentRef parametresi alır — kökün yaşadığı hücre referansı — o çapadaki kökü bulur ve yeni yanıtın ParentId değerini kökün Id değeriyle damgalar. Her ikisi de yeni TXLSXThreadedComment nesnesini döndürür, böylece az önce oluşturduğunuz nesne üzerinde zaman damgasını veya çözümlenmiş durumu ayarlayabilirsiniz:

var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
  Root: TXLSXThreadedComment;
begin
  Book := TXLSXWorkbook.Create;
  try
    Book.Open('forecast.xlsx');
    Sheet := Book.Sheets[0];

    // Konuşma kökü; ParentId boş kalır
    Root := Sheet.AddThreadedComment(8, 3,
      'Q3 figure looks low against the pipeline export', 'Maria Ortiz');
    Root.DateTime := '2026-07-06T09:12:00Z';

    // Yanıtlar aynı hücreye sabitlenir; ParentRef kök hücreyi adlandırır
    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;

Bu listedeki iki ayrıntı dikkat çekicidir. İlk olarak, elle oluşturulmuş bir dize yerine Root.Ref geçirilir: Kütüphanenin oluşturduğu referansın, AddThreadedReply işlevinin arayacağı referansla eşleşmesi garantilenir; bu da hücre kaydırma hatalarını (off-by-one anchor bugs) tamamen ortadan kaldırır. İkinci olarak, her iki yazar da düz görüntü adları olarak geçirildi — kişi kaydı, GUID kimlikleri ve authorId kablolaması çağrıların arkasında gerçekleşti. Kaydedilen dosyayı Excel 365'te açtığınızda hücre sabitleme, yanıt sırası ve iki farklı katılımcı canlıdır: Yanıtla'yı tıklayın ve Excel, kodunuzun başlattığı aynı sıraya ekleme yapsın

Bir konuşmayı geri okuma: Gidiş-dönüş davranışı

HotXLS, sürüm 2.122.0 itibariyle sıralı yorumları gidiş-dönüş yaptırır: Kaydedilmiş bir paketi yeniden açmak, her sayfanın konuşma listesini ve çalışma kitabı katılımcı listesini parçalardan yeniden oluşturur; böylece tanımlayıcılar, yanıt bağlantıları ve görüntüleme adları tam bir okuma→yazma döngüsünden sağ çıkar. Ayrıştırıcı, person.xml dosyasını herhangi bir sayfa içeriğinden önce ayrıştırır, bu da her authorId'nin yükleme zamanında bir görüntü adına çözümlenmesini sağlar; ayrıştırılan kişi tanımlayıcıları yeniden oluşturulmak yerine olduğu gibi korunur, böylece kodunuz ile Excel arasında mekik dokuyan bir çalışma kitabı, isteğe bağlı olarak birçok gidiş-dönüşte kararlı yazar kimliklerini korur

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('Kök hücre: ', Cmt.Ref, ' yazan: ', Cmt.DisplayName, ': ', Cmt.Text)
    else
      Writeln('  yanıt yazan: ', Cmt.DisplayName, ': ', Cmt.Text);
  end;
  Writeln('Katılımcılar: ', Book.Persons.Count);
end;

Düz liste artı referanslar depolaması burada bilerek kendini gösterir: ThreadedComments yanıtları parça sırasına göre numaralandırır ve boş bir ParentId her kökü tanımlar. Ağaç şekline ihtiyacınız varsa — örneğin bir inceleme günlüğünü dışa aktarmak için — önce Ref'e göre gruplandırın ve ardından her hücrenin grubu içindeki ParentId'yi Id'ye zincirleyin. Bu "ayrıştırdığını koru" davranışı, kütüphanedeki daha geniş bir politikanın bir örneğidir; temaların, uzantı listelerinin ve hesaplama zincirinin kayıpsız gidiş-dönüşü hakkındaki makale, aynı ilkenin paketin geri kalanına nasıl uygulandığını kapsar

Çözümlenmiş durum (resolved state), zaman damgaları ve yazar kimliği

Üç öznitelik inceleme semantiğini taşır ve her üçü de döndürülen nesneler üzerinde yazılabilirdir. Done, done özniteliğiyle eşleşir — Excel çözümlenmiş (resolved) bir sırayı Yeniden Aç (Reopen) bağlantısıyla daraltılmış olarak gösterir. DateTime, ISO-8601 UTC oluşturma damgasıdır (dT); HotXLS, boş bıraktığınızda parçanın her zaman doğrulanması için sabit bir yer tutucu koyar, ancak gerçek bir zaman damgası sıranın geçmişini okunabilir kılan şeydir, bu yüzden bunu ayarlayın. Kimlik tarafında, her TXLSXPerson, ProviderId (yerel olarak yazılmış girişler için genellikle None) ve uygulamanız bildiğinde bir UPN veya e-posta ile doldurabileceğiniz bir UserId sunar:

var
  Root: TXLSXThreadedComment;
  Person: TXLSXPerson;
begin
  Root := Sheet.ThreadedComments.FindAt('D9');
  if Root <> nil then
    Root.Done := True;   // done="1" olarak kaydedilir; Excel sırayı çözümlenmiş gösterir

  Person := Book.Persons.FindByDisplayName('Maria Ortiz');
  if Person <> nil then
    Person.UserId := 'maria.ortiz@example.com';
end;

Açıkça belirtilmesi gereken bir sınır: HotXLS, <mentions> öğesini boş yazar. @-bahsetme (mention) kayıtları — yorum metninin içindeki bir meslektaşın adını aydınlatan ve Microsoft 365'te bir bildirim tetikleyen mekanizma — modellenmemiştir, bu nedenle @ işareti içeren metinler düz metin olarak saklanır. Oluşturulan bir inceleme çalışma kitabı için bu nadiren bir kayıptır, ancak iş akışınız bahsetme bildirimlerine dayanıyorsa, bir insanın bunları Excel içinde eklemesini planlayın. Kişi parçasındaki yazar kimliği, oluşturulan bir dosyanın denetim izinin geri kalanının yaşadığı yer olan, çalışma kitabı meta verileri ve belge özellikleri altında ele alınan çalışma kitabı düzeyindeki kaynak alanlarıyla doğal olarak eşleşir

Eski Excel sürümleri sıralı yorumlarla ne yapar?

Excel 2016 ve öncesi, sıralı modelden öncesine dayanır ve anlamadıkları parçaları göz ardı ederler. Excel 365 sıralı bir konuşmayı kaydettiğinde, eski sürümlerin sabitlenmiş hücrede bir şey göstermesi için tam olarak "[Threaded comment]..." okuyan eski bir yorum gölgesi (legacy comment shadow) de yazar. HotXLS, eski bir gölge olmaksızın yalnızca sıralı parçaları yayar; bu nedenle kodunuz tarafından yazılan bir dosya Excel 2016'da açıldığında hiçbir yorum göstergesi göstermez. Hedef kitleniz 365 öncesi kurulumları içeriyorsa ve açıklamanın orada görünür olması gerekiyorsa, eski AddComment API'si uyumlu kanal olmaya devam eder; gönderdiğiniz her Excel sürümünü test etmeden iki modeli de aynı hücreye yığmaktan kaçının, çünkü bir okuyucunun tek bir hücre üzerindeki bir notu ve bir sırayı nasıl uzlaştıracağı okuyucunun kararıdır, sizin değil

Diğer katı sınır ise dosya biçiminin kendisidir. Sıralı yorumlar, BIFF8 karşılığı olmayan bir OOXML yapısıdır, bu nedenle HotXLS'in .xls tarafında sıralı bir API yoktur — eski ikili biçimde kalması gereken bir çalışma kitabı klasik notlarla sınırlıdır. Pratik olarak karar tablosu kısadır: Excel 365 veya web/mobil Excel okuyucuları için .xlsx yazarken AddThreadedComment kullanın ve gerçek konuşmalar elde edin; Excel 2016 veya .xls'i hedeflerken AddComment kullanın ve not modelini kabul edin; aldığınız bir dosyayı denetlerken hem ThreadedComments hem de Comments listelerini kontrol edin, çünkü her iki dünyada da yaşamış bir çalışma kitabı meşru olarak her ikisini de taşıyabilir. Her iki nesil için de tam API yüzeyi HotXLS Delphi Excel Bileşeni ürün sayfasında belgelenmiştir