Since one can color a Word document at the character level, you would have to loop through the characters in the document and look at their color, but it would be very slow.
Moreover, for many characters, VBA will return the numeric value of the theme color, not the RGB color
I think all font related styles saved inside the word file as xml data. (Such as style sheet in a web page) But, unfortunately it's much hard to determine a color value.
Basically I planned to extract all RGB color values from a Word document. Currently I've to select the headings, paragraphs one by one and make a note for RGB color. It'll take few minutes. That's the actual reason for this. As you said earlier it'll take too much time to complete the process.
In my documents, I need to match all colors consistently. And I've to fix all inconsistencies in through the document. If I extracted the color codes with count then It'll help me to fix inconsistencies. And some times, I've to match pdf RGB color codes with Word file. Earlier you provided few codes to find and replace table shading, font color... etc. Those macros are really helpful for my work.
If you need to remove inconsistencies, it's best to remove all directly applied formatting by selecting the entire document and pressing Ctrl+spacebar and Ctrl+Q, or in VBA:
No, if you select the entire document, Ctrl+Shift+N applies the Normal style to the document, but leaves directly applied font formatting alone. Ctrl+spacebar removes all directly applied font formatting.
Now I got your point exactly. But my documents formatted by 100% direct formatting. It's never use styles. That's the main problem in my docs. Anyway thank you for sharing with your experience.
I recommend using styles instead of direct formatting. See Tips for Understanding Styles in Word, in particular the section 'What is the advantage of modifying a style as opposed to formatting my text directly?'
When I try your code on a document that contains several colors, the effect is that (1) all text in the document is hidden, and (2) an empty message box is displayed.
Sub FindRGBColours()
Application.ScreenUpdating = False
Dim StrClrArr As String, StrClr As String, lngColor As Long
With ActiveDocument.Range
.Font.Hidden = False
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.MatchWildcards = True
.Text = "?"
.Forward = True
.Format = True
.Font.Hidden = False
.Wrap = wdFindStop
.Execute
End With
Do While .Find.Found
lngColor = .Font.TextColor
Select Case .Font.TextColor.Type
Case msoColorTypeRGB
StrClr = GetRGB(.Font.TextColor.RGB)
Case msoColorTypeScheme
StrClr = GetThemeColor(.Font.TextColor.ObjectThemeColor)
Case Else
StrClr = "Other"
End Select
StrClrArr = StrClrArr & vbCr & StrClr
With .Duplicate.Find
.ClearFormatting
.Replacement.ClearFormatting
.Font.Color = lngColor
.Replacement.Font.Hidden = True
.Wrap = wdFindStop
.Execute Replace:=wdReplaceAll
End With
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
ActiveDocument.Range.Font.Hidden = False
Application.ScreenUpdating = True
MsgBox StrClrArr
End Sub
Function GetRGB(RGBvalue As Long) As String
Dim StrTmp As String
If RGBvalue < 0 Or RGBvalue > 16777215 Then RGBvalue = 0
StrTmp = "R: " & RGBvalue \ 256 ^ 0 Mod 256
StrTmp = StrTmp & " G: " & RGBvalue \ 256 ^ 1 Mod 256
StrTmp = StrTmp & " B: " & RGBvalue \ 256 ^ 2 Mod 256
GetRGB = StrTmp
End Function
Function GetThemeColor(ThemeColor As Long) As String
Select Case ThemeColor
Case wdThemeColorAccent1
GetThemeColor = "Accent color 1"
Case wdThemeColorAccent2
GetThemeColor = "Accent color 2"
Case wdThemeColorAccent3
GetThemeColor = "Accent color 3"
Case wdThemeColorAccent4
GetThemeColor = "Accent color 4"
Case wdThemeColorAccent5
GetThemeColor = "Accent color 5"
Case wdThemeColorAccent6
GetThemeColor = "Accent color 6"
Case wdThemeColorBackground1
GetThemeColor = "Background color 1"
Case wdThemeColorBackground2
GetThemeColor = "Background color 2"
Case wdThemeColorHyperlink
GetThemeColor = "Hyperlink color"
Case wdThemeColorHyperlinkFollowed
GetThemeColor = "Followed hyperlink color"
Case wdThemeColorMainDark1
GetThemeColor = "Dark main color 1"
Case wdThemeColorMainDark2
GetThemeColor = "Dark main color 2"
Case wdThemeColorMainLight1
GetThemeColor = "Light main color 1"
Case wdThemeColorMainLight2
GetThemeColor = "Light main color 2"
Case wdThemeColorText1
GetThemeColor = "Text color 1"
Case wdThemeColorText2
GetThemeColor = "Text color 2"
End Select
End Function
Unfortunately, it doesn\t distinguish between the lighter and darker shades of a theme color, nor do I know how to convert theme colors and their shades to RGB colors.
Earlier I think about this way. Track changes on >> Find black color and automatic color (more than 95% use this two colors in my documents) >> If found black or, and automatic color then delete all characters >> Find the rest of the characters for RGB color >> Reject all to restore the document.
But I think your method is the best one.
May I know how to get color codes from selected text range? I changed line 4 as follows. But I got a run time error.
Sub FindRGBColours()
Application.ScreenUpdating = False
Dim Rng As Range, StrClrArr As String, StrClr As String
Set Rng = Selection.Range
With Selection.Range
.Font.Hidden = True
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.MatchWildcards = True
.Text = "?"
.Forward = True
.Format = True
.Font.Hidden = True
.Wrap = wdFindStop
.Execute
End With
Do While .Find.Found
If Not .InRange(Rng) Then Exit Do
StrClr = .Font.Color
StrClrArr = StrClrArr & vbCr & GetRGB(CLng(StrClr))
With .Duplicate
.End = Rng.End
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Font.Color = StrClr
.Replacement.Font.Hidden = False
.Wrap = wdFindStop
.Execute Replace:=wdReplaceAll
End With
End With
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
Application.ScreenUpdating = True
MsgBox StrClrArr
End Sub
Function GetRGB(RGBvalue As Long) As String
Dim StrTmp As String
If RGBvalue < 0 Or RGBvalue > 16777215 Then RGBvalue = 0
StrTmp = StrTmp & " R: " & RGBvalue \ 256 ^ 0 Mod 256
StrTmp = StrTmp & " G: " & RGBvalue \ 256 ^ 1 Mod 256
StrTmp = StrTmp & " B: " & RGBvalue \ 256 ^ 2 Mod 256
GetRGB = StrTmp
End Function