PDA

View Full Version : Who can explain to me the revisions object?



marcelma
01-29-2013, 03:47 AM
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:


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

My understanding is, that

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

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

Selection.Range.Revisions(1).Type = wdRevisionDelete
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

Selection.Range.Revisions(1).Accept

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

fumei
01-29-2013, 04:23 PM
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:
Selection.Range.Revisions(1).Type = wdRevisionDelete 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?

fumei
01-29-2013, 04:25 PM
BTW: do not use a For Each loop for revisions.

marcelma
01-29-2013, 06:20 PM
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:
Selection.Range.Revisions.AcceptAll 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:
Selection.Range.Revisions.Count of 3, I can address some of those revisions individually, by saying, for example:
Selection.Range.Revisions(2).Accept 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

fumei
01-30-2013, 04:00 PM
"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:Debug.Print Selection.Start 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.

jlotterer
03-04-2015, 11:47 AM
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.



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

gmaxey
03-04-2015, 02:52 PM
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