Genere un libro de trabajo desde Delphi, anote una celda con la API clásica de comentarios, y Excel 365 archivará su texto bajo Notas: un cuadro amarillo de estilo antiguo sin campo de respuesta (Reply), sin avatar de autor ni botón de resolución. HotXLS escribe comentarios con hilos genuinos de Excel 365 a través de AddThreadedComment y AddThreadedReply en el motor XLSX, emitiendo la parte dedicada xl/threadedComments/threadedCommentN.xml por hoja y registrando a cada autor en la parte person a nivel de libro de trabajo, de modo que la conversación que escribe su código sea el mismo objeto al que un revisor responde en Excel
La distinción es importante porque ambas características solo se parecen en apariencia. Una nota es un cuadro de texto flotante; un comentario con hilos es un registro de conversación con identificadores estables, un árbol de respuestas, un registro de autores y una bandera de resolución; los elementos sobre los cuales se ejecuta realmente un flujo de trabajo de revisión. Este artículo analiza primero la estructura OOXML, porque una vez que se observan ambos modelos de almacenamiento frente a frente, cada diferencia de comportamiento en Excel deja de ser misteriosa
¿Por qué mis comentarios aparecen como notas en Excel 365?
La respuesta corta: dos generaciones de comentarios comparten una misma cuadrícula, y residen en partes completamente distintas del paquete. El modelo heredado (al que apunta AddComment) almacena texto en xl/comments1.xml (tipo de contenido application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml) y posiciona el globo a través de una parte de dibujo VML complementaria, xl/drawings/vmlDrawing1.vml. Esa pareja es anterior a la cinta de opciones; Excel 365 todavía la lee fielmente, pero renderiza el resultado como una "nota" y no ofrece una interfaz de usuario para hilos en ella, debido a que no hay nada en el almacenamiento que se pueda organizar en hilos. El autor es una cadena de visualización, la posición es una forma VML, y ese es todo el modelo
Los comentarios con hilos, introducidos con Excel 365, ignoran por completo la capa VML. Cada hoja con una conversación lleva su propia parte xl/threadedComments/threadedCommentN.xml bajo el tipo de contenido application/vnd.openxmlformats-officedocument.spreadsheetml.threadedComments+xml, y the el libro de trabajo contiene una única parte xl/person/person.xml (tipo de contenido ...spreadsheetml.people+xml) que enumera a cada participante una vez. HotXLS expone ambos modelos en la misma hoja de trabajo: AddComment sigue escribiendo la pareja heredada, mientras que AddThreadedComment escribe las nuevas partes. Si su resultado aparece como notas, significa que llamó a la primera API en lugar de la segunda. El modelo heredado sigue siendo la herramienta adecuada para ciertas tareas (el artículo anterior sobre comentarios de celdas e hipervínculos en flujos de trabajo de revisión lo detalla, incluido el lado XLS), pero nada en él se convierte en un hilo
Qué escribe HotXLS en el paquete
HotXLS modela cada respuesta como un objeto TXLSXThreadedComment que contiene un anclaje de celda (Ref), un identificador estilo GUID (Id), un ParentId opcional, un AuthorId que se resuelve a través de la lista de personas, un espejo de DisplayName, el cuerpo del texto, una bandera Done y un DateTime ISO-8601. Al guardar, cada entrada se convierte en un elemento <threadedComment> cuyo atributo t almacena el identificador, su atributo dT almacena la marca de tiempo, y su atributo parentT (presente solo en respuestas secundarias) identifica al identificador principal. Excel reconstruye el árbol de conversación asociando parentT con t; no hay anidación en el XML, solo una lista plana más referencias
La parte de persona (person) es el elemento que la mayoría de las implementaciones manuales olvidan. Cada authorId en un comentario con hilos debe resolverse en una entrada <person> en xl/person/person.xml, vinculada a las relaciones del libro de trabajo, con su propia invalidación de tipo de contenido; de lo contrario, Excel no tiene un nombre para mostrar. HotXLS gestiona el registro automáticamente: AddThreadedComment busca al autor en la lista Persons del libro por nombre de visualización y crea una entrada con un GUID nuevo cuando no existe ninguna, de modo que los comentarios consecutivos del mismo autor compartan una sola identidad. Las relaciones de la hoja de trabajo obtienen la relación threadedComments, las relaciones del libro obtienen la relación de persona y el manifiesto de tipos de contenido obtiene ambas invalidaciones, sin que nada de esto aparezca en su código
Construir una cadena de respuestas con AddThreadedComment y AddThreadedReply
AddThreadedComment crea la raíz de la conversación: su ParentId se mantiene vacío, que es lo que la identifica como el inicio del hilo. AddThreadedReply toma un parámetro ParentRef (la referencia de celda donde reside la raíz), busca la raíz en ese anclaje y sella el ParentId de la nueva respuesta con el Id de la raíz. Ambas devuelven el nuevo TXLSXThreadedComment, por lo que puede definir la marca de tiempo o el estado de resolución en el objeto que acaba de crear:
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;
Dos detalles en ese código merecen atención. Primero, se pasa Root.Ref en lugar de una cadena construida a mano: se garantiza que la referencia generada por la biblioteca coincida con la que AddThreadedReply buscará, lo que elimina toda una categoría de errores de anclaje desviados por uno. Segundo, ambos autores se pasaron como nombres de visualización simples; el registro de personas, las identidades GUID y la vinculación de authorId ocurrieron en segundo plano tras las llamadas. Abra el archivo guardado en Excel 365 y el anclaje de celdas, el orden de las respuestas y los dos participantes distintos estarán activos: haga clic en Responder (Reply) y Excel agregará al mismo hilo que su código inició
Leer una conversación de vuelta: comportamiento de ida y vuelta
HotXLS realiza el viaje de ida y vuelta de los comentarios con hilos a partir de la versión 2.122.0: reabrir un paquete guardado reconstruye la lista de conversaciones de cada hoja y la lista de participantes del libro a partir de las partes, por lo que los identificadores, los enlaces de respuesta y los nombres de visualización sobreviven a un ciclo completo de lectura→escritura. El analizador lee person.xml antes que cualquier contenido de la hoja, lo que permite que cada authorId se resuelva en un nombre de visualización al momento de la carga; los identificadores de personas analizados se conservan tal cual en lugar de regenerarse, por lo que un libro de trabajo que viaje entre su código y Excel mantiene identidades de autor estables durante cualquier cantidad de viajes de ida y vuelta
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;
El almacenamiento de lista plana más referencias se expone aquí deliberadamente: ThreadedComments enumera las respuestas en el orden de las partes, y un ParentId vacío identifica cada raíz. Si necesita la estructura en árbol (por ejemplo, para exportar un registro de revisión), agrupe primero por Ref y luego encadene ParentId con Id dentro del grupo de cada celda. Este comportamiento de conservar lo analizado es un ejemplo de una política más amplia en la biblioteca; el artículo sobre la ida y vuelta sin pérdidas de temas, listas de extensiones y la cadena de cálculo (calc chain) describe cómo se aplica el mismo principio al resto del paquete
Estado resuelto, marcas de tiempo e identidad del autor
Tres atributos representan la semántica de la revisión, y los tres son modificables en los objetos devueltos. Done se asocia con el atributo done (Excel muestra un hilo resuelto contraído con un enlace Volver a abrir - Reopen). DateTime es la marca de creación UTC ISO-8601 (dT); HotXLS coloca un marcador de posición fijo cuando lo deja vacío para que la parte siempre sea válida, pero una marca de tiempo real es lo que hace legible el historial del hilo, así que defínala. En cuanto a la identidad, cada TXLSXPerson expone ProviderId (normalmente None para entradas de creación local) y un UserId que puede completar con un UPN o correo electrónico cuando su aplicación lo conozca:
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;
Un límite a declarar claramente: HotXLS escribe el elemento <mentions> vacío. Los registros de menciones con @ (el mecanismo que resalta el nombre de un colega dentro del texto del comentario y activa una notificación en Microsoft 365) no están modelados, por lo que el texto que contiene un símbolo @ se almacena como texto sin formato. Para un libro de trabajo de revisión generado esto rara vez representa una pérdida, pero si su flujo de trabajo depende de las notificaciones de mención, planifique que un humano las agregue dentro de Excel. La identidad del autor en la parte de persona se asocia naturalmente con los campos de procedencia a nivel de libro de trabajo analizados en metadatos del libro de trabajo y propiedades del documento, que es donde reside el resto del registro de auditoría de un archivo generado
¿Qué hacen las versiones anteriores de Excel con los comentarios con hilos?
Excel 2016 y versiones anteriores son previas al modelo de hilos, y simplemente ignoran las partes que no comprenden. Cuando el propio Excel 365 guarda una conversación con hilos, también escribe una sombra de comentario heredado (una nota de marcador de posición que dice "[Threaded comment]...") precisamente para que las versiones anteriores muestren algo en la celda anclada. HotXLS emite únicamente las partes con hilos, sin sombra heredada, por lo que un archivo escrito por su código no muestra ningún indicador de comentario en absoluto cuando se abre en Excel 2016. Si su audiencia incluye instalaciones anteriores a Office 365 y la anotación debe ser visible allí, la API heredada AddComment sigue siendo el canal compatible; simplemente evite apilar ambos modelos en la misma celda sin realizar pruebas en cada versión de Excel a la que realice envíos, ya que la forma en que un lector concilia una nota y un hilo en una celda representa una decisión del lector, no la suya
El otro límite estricto es el propio formato del archivo. Los comentarios con hilos representan una estructura OOXML sin contraparte en BIFF8, por lo que el lado .xls de HotXLS no tiene una API de hilos; un libro de trabajo que deba mantenerse en el formato binario heredado está limitado a las notas clásicas. En la práctica, la tabla de decisión es corta: si escribe en .xlsx para Excel 365 o lectores de Excel web/móvil, utilice AddThreadedComment para obtener conversaciones reales; si apunta a Excel 2016 o .xls, utilice AddComment y acepte el modelo de notas; si audita un archivo que recibió, compruebe tanto ThreadedComments como Comments, ya que un libro de trabajo que ha existido en ambos mundos puede contener legítimamente ambos. Toda la superficie de la API para ambas generaciones está documentada en la página del producto Componente HotXLS Delphi Excel