PDA

View Full Version : Solved: Conditional Format of Selected Text



Bernadette
10-15-2012, 06:47 AM
If the selected text contains black or automatic font colour it needs to be changed to blue. If it contains red font colour then it needs to retain it. Any suggestions?

I tried this but it failed:

Sub ChangeBlackToBlue()
Dim BIStatus As Integer
BIStatus = 0
If Selection.Font.Color = wdColorRed Then BIStatus = BIStatus + 1
If BIStatus = 0 Then
Selection.Font.Color = wdColorBlue
End If
If BIStatus = 1 Then
Selection.Font.Color = wdColorRed = False
End If
If BIStatus = 2 Then
Selection.Font.Color = wdColorBlue = False
End If
End Sub

Thank you!

fumei
10-15-2012, 12:18 PM
Sub ChangeColour()
Select Case Selection.Font.Color
Case wdColorAutomatic Or wdColorBlack
Selection.Font.Color = wdColorBlue
Case wdColorRed
'do nothing
Case Else
' anything????
End Select
End SubNote: this applies to the entire Selection. If SOME of the Selection is not auto/black (or any other color as there is nothing for Else) then nothing happens.

Bernadette
10-15-2012, 12:50 PM
Thanks Fumei! It works if there is no red text in the selection. I would like it to change the font colour of the black or automatic to blue whether there is red text or not.

gmaxey
10-15-2012, 01:02 PM
One way is to process every character in the selected range:

Sub ChangeColour()
Dim oChr As Range
For Each oChr In Selection.Range.Characters
Select Case oChr.Font.Color
Case wdColorAutomatic Or wdColorBlack
oChr.Font.Color = wdColorBlue
Case wdColorRed
'do nothing
Case Else
' anything????
End Select
Next oChr
End Sub

fumei
10-15-2012, 04:12 PM
Bernadette, you will have to test every character as Greg suggests if there is an additional condition of red within a larger selection.

Bernadette
10-15-2012, 04:54 PM
Hello Greg & Fumei, thank you for your help. Fumei's first code works so well and is easy to undo. Greg's does what I need it to do but if the user wants to undo it is character by character. Is there any way to get Fumei's code to work and change the selected text to blue but leave the red? If not thank you so much anyway.

gmaxey
10-15-2012, 06:45 PM
Try:
Sub ScratchMacro()
'A quick macro scratch pad created by Greg Maxey
Dim oRng As Word.Range
Set oRng = Selection.Range
With oRng.Find
.ClearFormatting
.Font.Color = wdColorAutomatic
.Replacement.ClearFormatting
.Replacement.Font.Color = wdColorBlue
.Text = ""
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Execute Replace:=wdReplaceAll
End With
Set oRng = Selection.Range
With oRng.Find
.ClearFormatting
.Font.Color = wdColorBlack
.Replacement.ClearFormatting
.Replacement.Font.Color = wdColorBlue
.Text = ""
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Execute Replace:=wdReplaceAll
End With
End Sub

Bernadette
10-16-2012, 05:33 AM
Hi Greg,

This macro works great as long as there is some text in the selected text that has a color other than black or automatic. If there isn't then it changes the color to blue for the rest of the document.

This macro will be used more than once in the same document.

Thanks again for everyone's help!

gmaxey
10-16-2012, 02:44 PM
Bernadette,

As you have probably surmissed, the VBA Find method can demonstrate some quirky behavior (i.e., why would it alter text that is not in the defined search range and skip text that is.).

Well, I'm not formally trained in computer programing, so all that follows could be just a lot of hot gas and you can dismiss it out right if you chose.

The main thing to remember is that in order for .Find to find anything, that thing "must" be "in" the search range. It can't "be" the search range. You might find a chick in a egg or a barn in a field, but you won't find an egg in and egg or a barn in a barn.

Type Test Test Test in a document and select the first instance and run this code:

Sub ScratchMacroI()
Dim oRng As Word.Range
Set oRng = Selection.Range
With oRng.Find
.Text = "Test"
While .Execute
oRng.Font.ColorIndex = wdBrightGreen
Wend
End With
End Sub

As you have already seen, the selected "Test" is not affected, but other two instances are. The anology above should explain the first part. You can't find "Test" in "Test"

The second part is a little more complicated, but in a nutshell, when the thing to find = the thing being search, Word automatically redefines the search range from the end of the thing being search to the end of the document. You could see that if you type Test Test Test again and select the middle Test and run the code. This time both the selected Test and the first Test are left alone and only the last Test is changed.

One way to stop the seemingly run away search range is to verify that whatever is found is withing the orignal search range. Again usinge Test Test Test with the first instance selected, run this code:

Sub ScratchMacroII()
Dim oRng As Word.Range
Dim oRngSrch As Word.Range
Set oRng = Selection.Range
Set oRngSrch = oRng.Duplicate
With oRng.Find
.Text = "Test"
While .Execute
'It beeps.
Beep
'But it don't change text outside the search range.
If oRng.InRange(oRngSrch) Then
oRng.Font.ColorIndex = wdDarkRed
End If
Wend
End With
End Sub


If you step through this code you should see that sure enough Word is still moving beyond the defined search range but since the condition being within the original search range isn't met nothing is affected.

So how to we find "Test" in "Test" and change "Test" to blue font? We can't. You've mentioned a work around though. If you alter the search range so that it isn't the same thing you are search for, then you can find it (think egg in eggs or barn in barney)

Sub ScratchMacroIII()
'A quick macro scratch pad created by Greg Maxey
Dim oRng As Word.Range
Dim oRngToSrch As Word.Range
Set oRng = Selection.Range
Set oRngToSrch = oRng.Duplicate
oRng.InsertAfter "*"
oRng.Characters.Last.Font.ColorIndex = wdBrightGreen
With oRng.Find
.ClearFormatting
.Font.Color = wdColorAutomatic
.Replacement.ClearFormatting
.Replacement.Font.Color = wdColorBlue
.Text = ""
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Execute Replace:=wdReplaceAll
End With
oRng.Characters.Last.Delete
End Sub

With this knowlegde, you should be able to adapt your code to work.

fumei
10-16-2012, 08:14 PM
Pretty good explanation Greg.

"Word automatically redefines the search range from the end of the thing being search to the end of the document"

Annoying ain't it? It is an (IMO) extremely counter-intuitive thing, especially when the original range is a table. Why the heck Word continues on beyond the original table range is super annoying and does not makes any sense. It is something some of us have complained about to Microsoft for more than 10 years. To no avail.

Hopefully Bernadette can take your post and come up with a viable workaround.

Bernadette
10-18-2012, 06:07 AM
Greg, what a great explanation and it works perfectly. I am so happy! Thank you so much to everyone for your help.