I'm having trouble with VBA commands to find a certain phrase, then select the 1 or 2 words before it, and then italicize the entire thing.
I'm able to use the Selection.Find, Font.Italicise, and wdExtend commands independently of each other, but when I combine them to perform this task, the macro just crashes. Any help?
Selection.Find.ClearFormatting
With Selection.Find
.Text = "Michael"
.Replacement.Text = "Michael"
.Forward = True
.Wrap = wdFindStop
Do While .Execute() = True
Selection.TypeParagraph
Selection.MoveLeft Unit:=wdWord, Count:=2, Extend:=wdExtend
Selection.Find.Replacement.Font.Italic = True
Selection.Font.Bold = True
Selection.Collapse Direction:=wdCollapseEnd
Loop
End With
The following code will do what you want. However, I wrote it in such a way as I think will enable you best to understand it.
Private Sub SelFind()
' 08 Apr 2017
Dim Rng As Range
Dim Fnd As Boolean
Set Rng = Selection.Range
With Rng.Find
.ClearFormatting
.Execute FindText:="Michael", Forward:=True, _
Format:=False, Wrap:=wdFindStop
Fnd = .Found
End With
If Fnd = True Then
With Rng
.MoveStart wdWord, -2
With .Font
.Italic = True
.Bold = True
End With
End With
End If
End Sub
Start with imagining all the characters in your document strung into a single line, interspersed with formatting codes which are also treated like characters. This long string of characters is called a range, in code, ActiveDocument.Range.
You can select any part of the document's entire range. That would be the Selection.Range which, like all ranges, has a Start (the first byte) and an End (the last byte. Start and End are properties of the Range represented by numbers, counting from the first byte. My code creates a new Range object which is called Rng. The Selection.Range is assigned to that new object. Rng and Selection.Range are identical at this point, but as you manipulate the Rng object, the Selection.Range will not change.
The code now looks for "Michael" in the Rng object. Your syntax for setting up the search is perfect. I used different syntax because I find it easier to grasp. The .Found property returns True if the search was successful. In that case the search range is changed to include only the found sub-range. Had the search been conducted in the Selection.Range you would see "Michael" highlighted on the screen. But since the search was conducted in memory (on the Rng object) the Selection.Range remains unchanged while the Rng object now contains only the word "Michael".
So, going back to the ActiveDocument.Range, of which Rng is a part, we now move the Start property two words to the left. A positive number would move it 2 words to the right. There is no need for Extend because the command is perfectly clear: "Move Start", meaning the End remains where it is.
Now the Rng object starts 2 word before "Michael" and ends with the word "Michael". You can copy this range or delete it, or modify it as you wish. Bear in mind that your screen still shows the original Selection.Range. MS Word will not allow you to assign Set Selection.Range = Rng, but there is an even easier way to realign the display with what the code has done. By adding the line .Select after modifying the Font (before the outer End With), the modified Rng would become the Selection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With