Seguimiento de cambios en un documento

La funcionalidad de seguimiento de cambios, también conocida como revisión, le permite realizar un seguimiento de los cambios en el contenido y el formato realizados por usted u otros usuarios. Esta función de seguimiento de cambios con Aspose.Words admite seguimiento de cambios en Microsoft Word. Con esta funcionalidad, puede acceder a revisiones individuales en su documento y aplicarles diferentes propiedades.

Cuando habilita la función de seguimiento de cambios, todos los elementos insertados, eliminados y modificados del documento se resaltarán visualmente con información sobre quién, cuándo y qué se modificó. Los objetos que contienen información sobre lo que se cambió se denominan “seguimiento de cambios”. Por ejemplo, supongamos que desea revisar un documento y realizar cambios importantes; esto puede significar que necesita realizar revisiones. Además, es posible que necesite insertar comentarios para analizar algunos de los cambios. Ahí es donde entra en juego el seguimiento de cambios en los documentos.

Este artículo explica cómo administrar y realizar un seguimiento de los cambios creados por muchos revisores en el mismo documento, así como las propiedades para realizar un seguimiento de los cambios.

¿Qué es una revisión?

Antes de sumergirnos en las revisiones, expliquemos el significado de las revisiones. Un Revision es un cambio que ocurre en un nodo de un documento, mientras que un grupo de revisión, representado por la clase RevisionGroup, es un grupo de revisiones secuenciales que ocurren en muchos nodos de un documento. Básicamente, la revisión es una herramienta para rastrear cambios.

Las revisiones se utilizan en la función de seguimiento de cambios y dentro de la función de comparación de documentos, donde las revisiones aparecen como resultado de la comparación. Por lo tanto, las revisiones dentro de la función de seguimiento de cambios muestran quién y qué se modificó.

Aspose.Words admite diferentes tipos de revisión, así como en Microsoft Word, como inserción, eliminación, cambio de formato, cambio de definición de estilo y movimiento. Todos los tipos de revisión se representan con la enumeración RevisionType.

Iniciar y detener el seguimiento de cambios

La edición de un documento generalmente no cuenta como revisión hasta que comienzas a realizarle seguimiento. Aspose.Words le permite realizar un seguimiento automático de todos los cambios en su documento con pasos simples. Puede iniciar fácilmente el proceso de seguimiento de cambios utilizando el método start_track_revisions. Si necesita detener el proceso de seguimiento de cambios para que cualquier edición futura no se considere revisión, deberá utilizar el método stop_track_revisions.

Al final del proceso de seguimiento de cambios en su documento, podrá incluso aceptar todas las revisiones o rechazarlas para revertir el documento a su forma original. Esto se puede lograr utilizando el método accept_all_revisions o reject_all. Además, puede aceptar o rechazar cada revisión por separado utilizando el método accept o reject.

Se realizará un seguimiento de todos los cambios durante una iteración desde el momento en que inicia el proceso hasta el momento en que lo detiene. La conexión entre diferentes iteraciones se representa en el siguiente escenario: usted completa el proceso de seguimiento, luego realiza algunos cambios y comienza a realizar el seguimiento de los cambios nuevamente. Con este escenario, todos los cambios que no aceptó o rechazó se mostrarán nuevamente.

El siguiente ejemplo de código muestra cómo trabajar con el seguimiento de cambios:

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
doc = aw.Document()
body = doc.first_section.body
para = body.first_paragraph
# Add text to the first paragraph, then add two more paragraphs.
para.append_child(aw.Run(doc, "Paragraph 1. "))
body.append_paragraph("Paragraph 2. ")
body.append_paragraph("Paragraph 3. ")
# We have three paragraphs, none of which registered as any type of revision
# If we add/remove any content in the document while tracking revisions,
# they will be displayed as such in the document and can be accepted/rejected.
doc.start_track_revisions("John Doe", datetime.today())
# This paragraph is a revision and will have the according "IsInsertRevision" flag set.
para = body.append_paragraph("Paragraph 4. ")
self.assertTrue(para.is_insert_revision)
# Get the document's paragraph collection and remove a paragraph.
paragraphs = body.paragraphs
self.assertEqual(4, paragraphs.count)
para = paragraphs[2]
para.remove()
# Since we are tracking revisions, the paragraph still exists in the document, will have the "IsDeleteRevision" set
# and will be displayed as a revision in Microsoft Word, until we accept or reject all revisions.
self.assertEqual(4, paragraphs.count)
self.assertTrue(para.is_delete_revision)
# The delete revision paragraph is removed once we accept changes.
doc.accept_all_revisions()
self.assertEqual(3, paragraphs.count)
# Stopping the tracking of revisions makes this text appear as normal text.
# Revisions are not counted when the document is changed.
doc.stop_track_revisions()
# Save the document.
doc.save(docs_base.artifacts_dir + "WorkingWithRevisions.accept_revisions.docx")

El siguiente ejemplo de código muestra cómo se generan las revisiones cuando se mueve un nodo dentro de un documento rastreado:

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
doc = aw.Document()
builder = aw.DocumentBuilder(doc)
builder.writeln("Paragraph 1")
builder.writeln("Paragraph 2")
builder.writeln("Paragraph 3")
builder.writeln("Paragraph 4")
builder.writeln("Paragraph 5")
builder.writeln("Paragraph 6")
body = doc.first_section.body
print(f"Paragraph count: {body.paragraphs.count}")
# Start tracking revisions.
doc.start_track_revisions("Author", datetime(2020, 12, 23, 14, 0, 0))
# Generate revisions when moving a node from one location to another.
node = body.paragraphs[3]
endNode = body.paragraphs[5].next_sibling
referenceNode = body.paragraphs[0]
while (node != endNode) :
nextNode = node.next_sibling
body.insert_before(node, referenceNode)
node = nextNode
# Stop the process of tracking revisions.
doc.stop_track_revisions()
# There are 3 additional paragraphs in the move-from range.
print("Paragraph count: 0", body.paragraphs.count)
doc.save(docs_base.artifacts_dir + "WorkingWithRevisions.move_node_in_tracked_document.docx")

Administrar y almacenar cambios como revisiones

Con la función de seguimiento de cambios anterior, puede comprender qué cambios se realizaron en su documento y quién los realizó. Mientras utiliza la función track_revisions, fuerza que cualquier cambio dentro de su documento se almacene como revisiones.

Aspose.Words permite comprobar si un documento tiene revisión o no mediante la propiedad has_revision. Si no necesita realizar un seguimiento automático de los cambios en su documento a través de los métodos start_track_revisions y stop_track_revisions, puede utilizar la propiedad track_revisions para comprobar si se realiza un seguimiento de los cambios mientras se edita un documento en Microsoft Word y se almacena como revisiones.

La función track_revisions realiza revisiones en lugar de cambios reales de DOM. Pero las revisiones en sí son independientes. Por ejemplo, si elimina un párrafo, Aspose.Words lo convierte en una revisión y lo marca como eliminado, en lugar de eliminarlo.

Además, Aspose.Words le permite verificar si un objeto se insertó, eliminó o cambió de formato utilizando las propiedades is_delete_revision, is_format_revision, is_insert_revision, is_move_from_revision y is_move_to_revision.

El siguiente ejemplo de código muestra cómo aplicar diferentes propiedades con revisiones:

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
doc = aw.Document()
# Insert an inline shape without tracking revisions.
self.assertFalse(doc.track_revisions)
shape = aw.drawing.Shape(doc, aw.drawing.ShapeType.CUBE)
shape.wrap_type = aw.drawing.WrapType.INLINE
shape.width = 100
shape.height = 100
doc.first_section.body.first_paragraph.append_child(shape)
# Start tracking revisions and then insert another shape.
doc.start_track_revisions("John Doe")
shape = aw.drawing.Shape(doc, aw.drawing.ShapeType.SUN)
shape.wrap_type = aw.drawing.WrapType.INLINE
shape.width = 100.0
shape.height = 100.0
doc.first_section.body.first_paragraph.append_child(shape)
# Get the document's shape collection which includes just the two shapes we added.
shapes = doc.get_child_nodes(aw.NodeType.SHAPE, True)
self.assertEqual(2, shapes.count)
# Remove the first shape.
shape0 = shapes[0].as_shape()
shape0.remove()
# Because we removed that shape while changes were being tracked, the shape counts as a delete revision.
self.assertEqual(aw.drawing.ShapeType.CUBE, shape0.shape_type)
self.assertTrue(shape0.is_delete_revision)
# And we inserted another shape while tracking changes, so that shape will count as an insert revision.
shape1 = shapes[1].as_shape()
self.assertEqual(aw.drawing.ShapeType.SUN, shape1.shape_type)
self.assertTrue(shape1.is_insert_revision)
# The document has one shape that was moved, but shape move revisions will have two instances of that shape.
# One will be the shape at its arrival destination and the other will be the shape at its original location.
doc = aw.Document(docs_base.my_dir + "Revision shape.docx")
shapes = doc.get_child_nodes(aw.NodeType.SHAPE, True)
self.assertEqual(2, shapes.count)
# This is the move to revision, also the shape at its arrival destination.
shape0 = shapes[0].as_shape()
self.assertFalse(shape0.is_move_from_revision)
self.assertTrue(shape0.is_move_to_revision)
# This is the move from revision, which is the shape at its original location.
shape1 = shapes[1].as_shape()
self.assertTrue(shape1.is_move_from_revision)
self.assertFalse(shape1.is_move_to_revision)