Hi drkestrel,
I took the opportunity offered by your question to do something I’ve been meaning to do for some time and have a play with the Word Object model. There are plenty people out there who know Word far better than I do but as no-one has come forward with anything I offer up the results of my investigations for what they’re worth.
Despite the fact that Word maintains a list of used fonts (use a text editor to look at a document and you will see it) there doesn’t seem, as you say, to be any way to access it via VBA and the only alternative I can see is the one you suggest yourself of spinning through the text; you can, however, make it a little less tedious by using text elements without selecting them.
Documents consist of a variety of elements. At the top of the hierarchy there are
stories; the main story is the body of the document not including headers, footers, footnotes and the like (if you want details of the fonts used in these you’ll need to examine them separately). Stories consist of
paragraphs, paragraphs consist of
sentences, sentences consist of
words and words consist of
characters (all of these terms appear to have their normal English meanings). It is worth noting that, for example, paragraphs also consist of characters – it is not necessary to work through every level.
The code below loops through all the paragraphs in a document. If a paragraph has a single font we save it; if it doesn’t then we look at each sentence within the paragraph. Again, if the sentence has a single font it is saved, otherwise we look at words and only if a word has multiple fonts is it necessary to look at individual characters (I believe a single character must have a single font).
A couple of points before the code – (1) a font is a property of a range (loosely translated from Word this means a block of text) but a paragraph is a special type of block of text which is not itself a range so we need to use the range which is the paragraph to get the font (does that make sense?) – (2) I chose to use a Collection to keep track of the fonts because I could easily avoid duplicates by ignoring errors when adding to it, but there are other ways.
OK - here it is - hope it helps -
Code:
Sub BuildFontList()
Dim pParagraph As Paragraph
Dim rParagraph As Range
Dim rSentence As Range
Dim rWord As Range
Dim rCharacter As Range
Dim FontList As New Collection
For Each pParagraph In ActiveDocument.Paragraphs
Set rParagraph = pParagraph.Range
If rParagraph.Font.Name = "" Then
For Each rSentence In rParagraph.Sentences
If rSentence.Font.Name = "" Then
For Each rWord In rSentence.Words
If rWord.Font.Name = "" Then
For Each rCharacter In rWord.Characters
SaveFontName FontList, rCharacter
Next
Else
SaveFontName FontList, rWord
End If
Next
Else
SaveFontName FontList, rSentence
End If
Next
Else
SaveFontName FontList, rParagraph
End If
Next
For Each FontName In FontList
MsgBox FontName
Next
End Sub
Sub SaveFontName(cCollection As Collection, rRange As Range)
On Error Resume Next
cCollection.Add Item:=rRange.Font.Name, Key:=rRange.Font.Name
On Error GoTo 0
End Sub
Enjoy,
Tony