Consulting

Results 1 to 7 of 7

Thread: Who can explain to me the revisions object?

  1. #1
    VBAX Regular
    Joined
    Oct 2010
    Location
    Berlin
    Posts
    46
    Location

    Who can explain to me the revisions object?

    Dear all,

    although I have been working with revisions for years, I still encounter cases in which I seem to be working according to a concept that does not fully match the reality of what WinWord really does.

    For example:
    I have a document with many revision marks and to reduce the revision marks to those which carry important information I want a VBA-program to find and accept all revisions within that document where a certain text string has been inserted. All other revisions, in which text has been formated, deleted or in which another text string has been inserted should be left untouched. It is easy to search for those text strings in question and once I have found such a string, my VBA-Code is:

    [vba]
    If Selection.Range.Revisions.Count = 0 Then 'no revision marks here
    Selection.Collapse (wdCollapseEnd)
    ElseIf Selection.Range.Revisions(1).Type = wdRevisionInsert Then 'inserted text
    Selection.Range.Revisions(1).Accept
    Else
    Stop 'Ask for a user decision
    End If
    [/vba]
    My understanding is, that

    [vba]Selection.Range.Revisions(1).Type[/vba]
    informs me about the 1st revision found within the range of selected text.

    If my understanding is right, how come, that I get a

    [vba]Selection.Range.Revisions(1).Type = wdRevisionDelete[/vba]
    when the selected text itself does not contain any revision, but is surrounded by text which is marked as deleted.

    [text marked as being deleted][selected string of normal text][text marked as being deleted]

    Similarly, if inside a string which is marked as inserted text, I select a shorter string and only want to accept the revision of this shorter string
    [text marked as being inserted][selected text marked as being inserted, which I want to accept][text marked as being inserted]
    and I am trying to do this via VBA by writing

    [VBA]Selection.Range.Revisions(1).Accept[/VBA]

    this VBA line will accept not only the revision inside the selected text but right and left as well.

    Is there ANYWHERE a really good documentation about the revisions object and how to precisely work with it? The online and offline-help has not been enlightening me any further, nor did any other "explanation" I found on the web so far.

    Thanks for giving this a thought.
    Marcel
    Last edited by marcelma; 01-29-2013 at 04:10 AM.

  2. #2
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    I will deal with the second question first.

    "inside a string which is marked as inserted text, I select a shorter string and only want to accept the revision of this shorter string"

    Nope, sorry. Accept/Reject is boolean. Not really, as it is a method, but essentially it is boolean in that the whole thing is either accepted or rejected. You can not do a partial acceptance or rejection.

    Now as for the first question:

    "when the selected text itself does not contain any revision, but is surrounded by text which is marked as deleted."

    Conceptual problem. IF the selected text does NOT contain any revisions, then:
    [vba]Selection.Range.Revisions(1).Type = wdRevisionDelete [/vba]is not possible.

    So....what is selected DOES have its range into the revised text. And that is the issue. When you select the text its Start touches the previous range of the deleted text (and likely the following as well).

    Does this make sense? To put it graphically:

    [text marked as being deleted][selected string of normal text][text marked as being deleted]

    Word is seeing the bolded range (it is not bold, I am using that to show things). The selected text INCLUDES the range of the last of the previous revision, and first of following revision range.

    Can you get it so it does not? Yes, with some effort. Put the cursor in the text with no revision, move it character by character to the start, then hold down Shift and move it character by character to the last character of the non-revisied text...but why do this in the first place???

    What exactly are you attempting to do?

    As for documentation, forget it. It is sloppy out there at best. BTW: what version of Word are you dealing with?

  3. #3
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    BTW: do not use a For Each loop for revisions.

  4. #4
    VBAX Regular
    Joined
    Oct 2010
    Location
    Berlin
    Posts
    46
    Location
    Thanks a lot for your answer fumei.

    You are confirming my own observations. Still, I'm not quite clear about how the whole thing works.

    Let's say I select text within a longer inserted string, as in:
    [text marked as being inserted][selected text marked as being inserted, which I want to accept][text marked as being inserted]
    and additionally I format the words "text" and "as" as red.

    then I write:
    [vba]Selection.Range.Revisions.AcceptAll[/vba] this will accept exactly the selected part of the revision and leave right and left untouched. Unfortunately it will accept EVERY revision within the selected string.

    On the other hand, having several revisions within the selected string, which, in this example would gives me a:
    [vba]Selection.Range.Revisions.Count[/vba] of 3, I can address some of those revisions individually, by saying, for example:
    [vba]Selection.Range.Revisions(2).Accept[/vba] which would accept only the red formating of the word "text" and leave the other revisions untouched.

    What could possibly be the logic behind that?


    Regarding your first answer, I agree, that somehow the selected text must include a revision. But how can that be, if within WinWord the smalles selectable unit is a character and I select only characters which do not contain any revision? What kind of logic does WinWord follow here?

    What I am trying to achieve is to run a VBA-program on a text with many revisions and accept those which can be savely accepted without important information getting lost. For example, sometimes change of format does not matter, so I'd like to accept all revisions which mark a change of formating, but still leave all insertions and deletions marked as revision. Another time someone has made a global replacement of a string. That can leave hundreds of revision marks, which really carry no important information. In such a case I'd like to accept just those insertions and deletions without touching anything else, including change of formatting.

    My basic understanding up to now was, that I can define selected text as range and then deal with those revisions which are within that range - but it just doesn't work like that.

    What did you have in mind with your recommendation that I don't use a For Each ... Loop for revisions? I agree, that the loop behaves sometimes other than expected, but I haven't figured out the reason for it either.

    There is another issue I have with revisions, but I'll write another post about it.

    Thanks again for taking time for this.

    greetings,
    Marcel

  5. #5
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    "Unfortunately it will accept EVERY revision within the selected string."

    That is what AcceptAll means.

    "On the other hand, having several revisions within the selected string"

    I am not quite following. Are you talking about MORE revisions within a revision?

    This is text.

    This is some extra inserted text.

    Where "some extra inserted" is the inserted, and AFTER the fact you bold in the revision - say, "extra".

    This is some extra inserted text.

    which would accept only the red formating of the word "text" and leave the other revisions untouched.

    What could possibly be the logic behind that?
    Does it not make sense? You are accepingt ONE revision, the one that points to the red formatting.

    and I select only characters which do not contain any revision
    Well try this.

    "This is some text".

    Select the "s" of "some". Run:[vba]Debug.Print Selection.Start[/vba] You get a number. let's call it 100.

    Now move the Selection to a point (SelectionIP), just BEFORE the "s" of "some".

    Run Debug.Print Selection.Start again. You STILL get 100.

    Perhaps a better demonstration. Select the "s" - the character is selected. Run Selection.Start. It = 100. Now use the arrow keys to MOVE the selection one "character" to the left. You would think it would be 99...it is not. It is still 100. SelectionIP (a point) takes its value from the character to the right.

    My point is that when you say "selected text", it can be tricky. It also makes a huge difference in how you inserted the text of the revision.

    This is some text.

    Putting the cursor just before the s of some, and type "blah " - blah AND A SPACE.
    Put the cursor just after the s of "is" and type " yadda" - space and yadda.

    This is yadda blah some text. TWO revisions.

    Now reverse the order.

    This is yadda blah some text. ONE revision, even though it was done as two operations. The space merges the revisions.
    Last edited by fumei; 01-30-2013 at 04:26 PM.

  6. #6
    marcelma,

    Not sure what your entire code is, but based on what you provided, this seems to work for me (in Word 2010). For an inserted string "ABCDEFG", the code below will accept the sub string "BCD" and leave "A" and "EFG" as inserted text. If the string is not identified as an insertion, then the it will ask the user to accept or not.


    Quote Originally Posted by marcelma View Post
    I want a VBA-program to find and accept all revisions within that document where a certain text string has been inserted. All other revisions, in which text has been formated, deleted or in which another text string has been inserted should be left untouched.


    Sub Revisions_Accept_String()

    Selection.HomeKey Unit:=wdStory
    With Selection.Find
    .ClearFormatting
    .Text = "BCD" 'Text string of revision to accept
    Do While .Execute(Forward:=True) = True
    If Selection.range.Revisions.count = 0 Then 'no revision marks here
    Selection.Collapse (wdCollapseEnd)
    ElseIf Selection.range.Revisions(1).Type = wdRevisionInsert Then 'inserted text
    Selection.range.Revisions.AcceptAll
    Else
    'Ask for a user decision
    If MsgBox("Accept this revision?", vbYesNo) = vbYes Then
    Selection.range.Revisions.AcceptAll
    End If
    End If
    Loop
    End With
    End Sub

  7. #7
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,340
    Location
    j,

    I think your code needs to be tempered a little to keep it under control:

    Sub Revisions_Accept_String()
    Dim oRng As Word.Range
     Set oRng = Selection.Range
     Selection.HomeKey Unit:=wdStory
     With Selection.Find
       .ClearFormatting
       .Text = oRng.Text
       .Forward = True
       Do While .Execute
         Select Case True
           Case Selection.Range.InRange(oRng) = True And _
                Selection.Range.Revisions.Count > 0 And _
                Selection.Range.Revisions(1).Type = wdRevisionInsert
             Selection.Range.Revisions.AcceptAll
             Exit Do
           Case Selection.Range.Revisions(1).Type <> wdRevisionInsert
             If MsgBox("Accept this revision?", vbYesNo) = vbYes Then
                Selection.Range.Revisions.AcceptAll
             End If
         End Select
         Selection.Collapse wdCollapseEnd
       Loop
     End With
     End Sub
    Sub Revisions_Accept_DeleteString()
    Dim oRng As Word.Range
     Set oRng = Selection.Range
     Selection.HomeKey Unit:=wdStory
     With Selection.Find
       .ClearFormatting
       .Text = oRng.Text
       .Forward = True
       Do While .Execute
         Select Case True
           Case Selection.Range.InRange(oRng) = True And _
                Selection.Range.Revisions.Count > 0 And _
                Selection.Range.Revisions(1).Type = wdRevisionDelete
             Selection.Range.Revisions.AcceptAll
             Exit Do
           Case Selection.Range.Revisions(1).Type <> wdRevisionDelete
             If MsgBox("Accept this revision?", vbYesNo) = vbYes Then
                Selection.Range.Revisions.AcceptAll
             End If
         End Select
         Selection.Collapse wdCollapseEnd
       Loop
     End With
     End Sub
    Greg

    Visit my website: http://gregmaxey.com

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •