Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can simulate transactional behavior in Word by overwriting the Undo and Redo command routines in VBA (I don't think that overwriting built-in Word commands is possible using VSTO alone, though). The start of a transaction is marked by adding a bookmark, the end is marked by removing the bookmark.</p> <p>When calling undo, we check whether the transaction mark bookmark is present and repeat the undo until the marker is gone. Redo is working the same way. This mechanism supports transactional undo/redo of all modifications done to the document content. However, to allow undo/redo of modifications to the document properties a special mechanism needs to be implemented using the SetCustomProp macro. Document properties should not be set directly but via this macro only.</p> <p>Update: I forgot to clearly mention that this approach only works with the keyboard shortcuts and the menu commands, clicking the toolbar button still does a single-step undo. We therefore decided to replace the toolbar buttons with custom ones. The code has been in use for quite a while With Word 2003 (it's not tested with Word 2007, so be prepared for surprise ;)</p> <pre><code>Option Explicit ' string constants for Undo mechanism Public Const BM_IN_MACRO As String = "_InMacro_" Public Const BM_DOC_PROP_CHANGE As String = "_DocPropChange_" Public Const BM_DOC_PROP_NAME As String = "_DocPropName_" Public Const BM_DOC_PROP_OLD_VALUE As String = "_DocPropOldValue_" Public Const BM_DOC_PROP_NEW_VALUE As String = "_DocPropNewValue_" '----------------------------------------------------------------------------------- ' Procedure : EditUndo ' Purpose : Atomic undo of macros ' Note: This macro only catches the menu command and the keyboard shortcut, ' not the toolbar command '----------------------------------------------------------------------------------- Public Sub EditUndo() ' Catches Ctrl-Z 'On Error Resume Next Dim bRefresh As Boolean bRefresh = Application.ScreenUpdating Application.ScreenUpdating = False Do If ActiveDocument.Bookmarks.Exists(BM_DOC_PROP_CHANGE) Then Dim strPropName As String Dim strOldValue As String strPropName = ActiveDocument.Bookmarks(BM_DOC_PROP_NAME).Range.Text strOldValue = ActiveDocument.Bookmarks(BM_DOC_PROP_OLD_VALUE).Range.Text ActiveDocument.CustomDocumentProperties(strPropName).Value = strOldValue End If Loop While (ActiveDocument.Undo = True) _ And ActiveDocument.Bookmarks.Exists(BM_IN_MACRO) Application.ScreenUpdating = bRefresh End Sub '----------------------------------------------------------------------------------- ' Procedure : EditRedo ' Purpose : Atomic redo of macros ' Note: This macro only catches the menu command and the keyboard shortcut, ' not the toolbar command '----------------------------------------------------------------------------------- Public Sub EditRedo() ' Catches Ctrl-Y Dim bRefresh As Boolean bRefresh = Application.ScreenUpdating Application.ScreenUpdating = False Do If ActiveDocument.Bookmarks.Exists(BM_DOC_PROP_CHANGE) Then Dim strPropName As String Dim strNewValue As String strPropName = ActiveDocument.Bookmarks(BM_DOC_PROP_NAME).Range.Text strNewValue = ActiveDocument.Bookmarks(BM_DOC_PROP_NEW_VALUE).Range.Text ActiveDocument.CustomDocumentProperties(strPropName).Value = strNewValue End If Loop While (ActiveDocument.Redo = True) _ And ActiveDocument.Bookmarks.Exists(BM_IN_MACRO) Application.ScreenUpdating = bRefresh End Sub '----------------------------------------------------------------------------------- ' Procedure : SetCustomProp ' Purpose : Sets a custom document property '----------------------------------------------------------------------------------- Public Function SetCustomProp(oDoc As Document, strName As String, strValue As String) Dim strOldValue As String On Error GoTo existsAlready strOldValue = "" oDoc.CustomDocumentProperties.Add _ Name:=strName, LinkToContent:=False, Value:=Trim(strValue), _ Type:=msoPropertyTypeString GoTo exitHere existsAlready: strOldValue = oDoc.CustomDocumentProperties(strName).Value oDoc.CustomDocumentProperties(strName).Value = strValue exitHere: ' support undo / redo of changes to the document properties 'On Error Resume Next Dim bCalledWithoutUndoSupport As Boolean If Not ActiveDocument.Bookmarks.Exists(BM_IN_MACRO) Then ActiveDocument.Range.Bookmarks.Add BM_IN_MACRO, ActiveDocument.Range bCalledWithoutUndoSupport = True End If Dim oRange As Range Set oRange = ActiveDocument.Range oRange.Collapse wdCollapseEnd oRange.Text = " " oRange.Bookmarks.Add "DocPropDummy_", oRange oRange.Collapse wdCollapseEnd oRange.Text = strName oRange.Bookmarks.Add BM_DOC_PROP_NAME, oRange oRange.Collapse wdCollapseEnd oRange.Text = strOldValue oRange.Bookmarks.Add BM_DOC_PROP_OLD_VALUE, oRange oRange.Collapse wdCollapseEnd oRange.Text = strValue oRange.Bookmarks.Add BM_DOC_PROP_NEW_VALUE, oRange oRange.Bookmarks.Add BM_DOC_PROP_CHANGE ActiveDocument.Bookmarks(BM_DOC_PROP_CHANGE).Delete Set oRange = ActiveDocument.Bookmarks(BM_DOC_PROP_NEW_VALUE).Range ActiveDocument.Bookmarks(BM_DOC_PROP_NEW_VALUE).Delete If Len(oRange.Text) &gt; 0 Then oRange.Delete Set oRange = ActiveDocument.Bookmarks(BM_DOC_PROP_OLD_VALUE).Range ActiveDocument.Bookmarks(BM_DOC_PROP_OLD_VALUE).Delete If Len(oRange.Text) &gt; 0 Then oRange.Delete Set oRange = ActiveDocument.Bookmarks(BM_DOC_PROP_NAME).Range ActiveDocument.Bookmarks(BM_DOC_PROP_NAME).Delete If Len(oRange.Text) &gt; 0 Then oRange.Delete Set oRange = ActiveDocument.Bookmarks("DocPropDummy_").Range ActiveDocument.Bookmarks("DocPropDummy_").Delete If Len(oRange.Text) &gt; 0 Then oRange.Delete If bCalledWithoutUndoSupport And ActiveDocument.Bookmarks.Exists(BM_IN_MACRO) Then ActiveDocument.Bookmarks(BM_IN_MACRO).Delete End If End Function '----------------------------------------------------------------------------------- ' Procedure : SampleUsage ' Purpose : Demonstrates a transaction '----------------------------------------------------------------------------------- Private Sub SampleUsage() On Error Resume Next ' mark begin of transaction ActiveDocument.Range.Bookmarks.Add BM_IN_MACRO Selection.Text = "Hello World" ' do other stuff ' mark end of transaction ActiveDocument.Bookmarks(BM_IN_MACRO).Delete End Sub </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload