Śledzenie zmian w dokumencie

Funkcja śledzenia zmian, znana również jako przeglądanie, umożliwia śledzenie zmian w treści i formatowaniu wprowadzonych przez Ciebie lub innych użytkowników. Ta funkcja zmiany ścieżki z Aspose.Words obsługuje zmiany ścieżki w Microsoft Word. Dzięki tej funkcji możesz uzyskać dostęp do poszczególnych wersji dokumentu i zastosować do nich różne właściwości.

Po włączeniu funkcji Śledź zmiany wszystkie wstawione, usunięte i zmodyfikowane elementy dokumentu zostaną wizualnie wyróżnione informacjami o tym, kto, kiedy i co zostało zmienione. Obiekty, które przenoszą informacje o tym, co zostało zmienione, nazywane są “śledzeniem zmian”. Załóżmy na przykład, że chcesz przejrzeć dokument i wprowadzić ważne zmiany – może to oznaczać, że musisz wprowadzić poprawki. Może być również konieczne wstawienie komentarzy, aby omówić niektóre zmiany. W tym miejscu pojawia się śledzenie zmian w dokumentach.

W tym artykule wyjaśniono, jak zarządzać i śledzić zmiany utworzone przez wielu recenzentów w tym samym dokumencie, a także właściwości śledzenia zmian.

Co to jest rewizja

Zanim przejdziemy do wersji, wyjaśnijmy znaczenie wersji. Za revision to zmiana, która występuje w jednym węźle dokumentu, podczas gdy grupa rewizji, reprezentowana przez klasę RevisionGroup, to grupa kolejnych rewizji, które występują w wielu węzłach dokumentu. Zasadniczo wersja jest narzędziem do śledzenia zmian.

Zmiany są używane w funkcji śledzenia zmian oraz w funkcji porównywania dokumentów, gdzie zmiany pojawiają się w wyniku porównania. Tak więc zmiany w funkcji śledzenia zmian pokazują, przez kogo i co zostało zmienione.

Aspose.Words obsługuje różne typy wersji, a także w Microsoft Word, takie jak wstawianie, usuwanie, FormatChange, StyleDefinitionChange i przenoszenie. Wszystkie typy wersji są reprezentowane za pomocą wyliczenia RevisionType.

Rozpocznij i Zatrzymaj śledzenie zmian

Edycja dokumentu zwykle nie liczy się jako wersja, dopóki nie zaczniesz go śledzić. Aspose.Words umożliwia automatyczne śledzenie wszystkich zmian w dokumencie za pomocą prostych kroków. Możesz łatwo rozpocząć proces śledzenia zmian za pomocą metody StartTrackRevisions. Jeśli chcesz zatrzymać proces śledzenia zmian, aby wszelkie przyszłe zmiany nie były uważane za zmiany, musisz użyć metody StopTrackRevisions.

Po zakończeniu procesu śledzenia zmian w dokumencie będziesz mógł nawet zaakceptować wszystkie poprawki lub odrzucić je, aby przywrócić dokument do pierwotnej formy. Można to osiągnąć za pomocą metody AcceptAllRevisions lub RejectAll. Ponadto możesz zaakceptować lub odrzucić każdą wersję osobno, używając metody Accept lub Reject.

Wszystkie zmiany będą śledzone przez jedną iterację od momentu rozpoczęcia procesu do momentu jego zatrzymania. Połączenie między różnymi iteracjami jest przedstawione w następującym scenariuszu: Zakończ proces śledzenia, następnie wprowadź pewne zmiany i ponownie rozpocznij śledzenie zmian. W tym scenariuszu wszystkie zmiany, których nie zaakceptowałeś lub odrzuciłeś, zostaną ponownie wyświetlone.

Poniższy przykład kodu pokazuje, jak pracować ze śledzeniem zmian:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>();
System::SharedPtr<Body> body = doc->get_FirstSection()->get_Body();
System::SharedPtr<Paragraph> para = body->get_FirstParagraph();
// Add text to the first paragraph, then add two more paragraphs.
para->AppendChild(System::MakeObject<Run>(doc, u"Paragraph 1. "));
body->AppendParagraph(u"Paragraph 2. ");
body->AppendParagraph(u"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->StartTrackRevisions(u"John Doe", System::DateTime::get_Now());
// This paragraph is a revision and will have the according "IsInsertRevision" flag set.
para = body->AppendParagraph(u"Paragraph 4. ");
ASSERT_TRUE(para->get_IsInsertRevision());
// Get the document's paragraph collection and remove a paragraph.
System::SharedPtr<ParagraphCollection> paragraphs = body->get_Paragraphs();
ASSERT_EQ(4, paragraphs->get_Count());
para = paragraphs->idx_get(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.
ASSERT_EQ(4, paragraphs->get_Count());
ASSERT_TRUE(para->get_IsDeleteRevision());
// The delete revision paragraph is removed once we accept changes.
doc->AcceptAllRevisions();
ASSERT_EQ(3, paragraphs->get_Count());
ASSERT_EQ(0, para->get_Count());
// Stopping the tracking of revisions makes this text appear as normal text.
// Revisions are not counted when the document is changed.
doc->StopTrackRevisions();
System::String outputPath = outputDataDir + u"WorkingWithRevisions.AcceptRevisions.doc";
doc->Save(outputPath);

Poniższy przykład kodu pokazuje, jak generowane są wersje, gdy węzeł jest przenoszony w śledzonym dokumencie:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
builder->Writeln(u"Paragraph 1");
builder->Writeln(u"Paragraph 2");
builder->Writeln(u"Paragraph 3");
builder->Writeln(u"Paragraph 4");
builder->Writeln(u"Paragraph 5");
builder->Writeln(u"Paragraph 6");
System::SharedPtr<Body> body = doc->get_FirstSection()->get_Body();
std::cout << "Paragraph count: " << body->get_Paragraphs()->get_Count() << std::endl;
// Start tracking revisions.
doc->StartTrackRevisions(u"Author", System::DateTime(2020, 12, 23, 14, 0, 0));
// Generate revisions when moving a node from one location to another.
System::SharedPtr<Node> node = body->get_Paragraphs()->idx_get(3);
System::SharedPtr<Node> endNode = body->get_Paragraphs()->idx_get(5)->get_NextSibling();
System::SharedPtr<Node> referenceNode = body->get_Paragraphs()->idx_get(0);
while (node != endNode)
{
System::SharedPtr<Node> nextNode = node->get_NextSibling();
body->InsertBefore(node, referenceNode);
node = nextNode;
}
// Stop the process of tracking revisions.
doc->StopTrackRevisions();
// There are 3 additional paragraphs in the move-from range.
std::cout << "Paragraph count: " << body->get_Paragraphs()->get_Count() << std::endl;
System::String outputPath = outputDataDir + u"WorkingWithRevisions.MoveNodeInTrackedDocument.pdf";
doc->Save(outputPath);

Zarządzaj i przechowuj zmiany jako wersje

Dzięki poprzedniej funkcji śledzenia zmian możesz zrozumieć, które zmiany zostały wprowadzone w dokumencie i kto je wprowadził. Korzystając z funkcji TrackRevisions, wymuszasz, aby wszelkie zmiany w dokumencie były przechowywane jako wersje.

Aspose.Words umożliwia sprawdzenie, czy dokument ma wersję, czy nie, za pomocą właściwości HasRevision. Jeśli nie musisz automatycznie śledzić zmian w dokumencie za pomocą metod StartTrackRevisions i StopTrackRevisions, możesz użyć właściwości TrackRevisions, aby sprawdzić, czy zmiany są śledzone podczas edycji dokumentu w Microsoft Word i przechowywane jako wersje.

Funkcja TrackRevisions wprowadza poprawki zamiast rzeczywistych zmian DOM. Ale same poprawki są oddzielne. Na przykład, jeśli usuniesz dowolny akapit, Aspose.Words utwórz go jako wersję, oznaczając go jako usunięcie, zamiast usuwać.

Ponadto Aspose.Words pozwala sprawdzić, czy obiekt został wstawiony, usunięty lub zmieniony formatowanie za pomocą IsDeleteRevision, IsFormatRevision, IsInsertRevision, IsMoveFromRevision, i IsMoveToRevision właściwości.

Poniższy przykład kodu pokazuje, jak zastosować różne właściwości z wersjami:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>();
// Insert an inline shape without tracking revisions.
ASSERT_FALSE(doc->get_TrackRevisions());
auto shape = System::MakeObject<Shape>(doc, ShapeType::Cube);
shape->set_WrapType(WrapType::Inline);
shape->set_Width(100.0);
shape->set_Height(100.0);
doc->get_FirstSection()->get_Body()->get_FirstParagraph()->AppendChild(shape);
// Start tracking revisions and then insert another shape.
doc->StartTrackRevisions(u"John Doe");
shape = System::MakeObject<Shape>(doc, ShapeType::Sun);
shape->set_WrapType(WrapType::Inline);
shape->set_Width(100.0);
shape->set_Height(100.0);
doc->get_FirstSection()->get_Body()->get_FirstParagraph()->AppendChild(shape);
// Get the document's shape collection which includes just the two shapes we added.
auto shapes = doc->GetChildNodes(NodeType::Shape, true)->LINQ_Cast<System::SharedPtr<Shape>>()->LINQ_ToList();
ASSERT_EQ(2, shapes->get_Count());
// Remove the first shape.
shapes->idx_get(0)->Remove();
// Because we removed that shape while changes were being tracked, the shape counts as a delete revision.
ASSERT_EQ(ShapeType::Cube, shapes->idx_get(0)->get_ShapeType());
ASSERT_TRUE(shapes->idx_get(0)->get_IsDeleteRevision());
// And we inserted another shape while tracking changes, so that shape will count as an insert revision.
ASSERT_EQ(ShapeType::Sun, shapes->idx_get(1)->get_ShapeType());
ASSERT_TRUE(shapes->idx_get(1)->get_IsInsertRevision());
// 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 = System::MakeObject<Document>(inputDataDir + u"Revision shape.docx");
shapes = doc->GetChildNodes(NodeType::Shape, true)->LINQ_Cast<System::SharedPtr<Shape>>()->LINQ_ToList();
ASSERT_EQ(4, shapes->get_Count());
// This is the move to revision, also the shape at its arrival destination.
ASSERT_FALSE(shapes->idx_get(0)->get_IsMoveFromRevision());
ASSERT_TRUE(shapes->idx_get(0)->get_IsMoveToRevision());
// This is the move from revision, which is the shape at its original location.
ASSERT_TRUE(shapes->idx_get(1)->get_IsMoveFromRevision());
ASSERT_FALSE(shapes->idx_get(1)->get_IsMoveToRevision());