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