Macro to find styles everywhere including headers and footers

J

Jessica Weissman

I may have bitten off more than I can chew, but I am working on a macro that
counts instances of styles in the entire document, including headers and
footers as well as the main body of the document. This is Word 2003.

I run through each paragraph of each storyrange and grab its style, place it
in a Dictionary if it isn't already there and up the count. This ought to
get me a list of styles with a count for each one.

Several questions:

1) Is there an automated way to have this skip the footnote and endnote
related stories other than the brute force thing I used?

2) Is there any way to get it to skip footers and headers that are there but
not visible, such as the left and right page footers for sections that don't
have any such? Word seems to create them and hide them for sections that are
one page long.

3) Why does it find jillions of instances of Normal style that are not
visible? I have a document that claims to have 39 instances of Normal style
in the main text story. But when I use the Word interface to search for the
text in Normal style in the main text, it doesn't find any.

Many thanks for any insights. I'm probably doing this the hard way.

- jessica



Here is the messy code I am using:

Sub FindAllUsedStyles2()

Dim sAllStyles() As String
Dim vStyles As Variant
Dim i As Long
Dim idx As Long
Dim cParas As Long
Dim cStyles As Long
Dim cUsedStyles As Long
Dim sPrevStyle As String
Dim para As Paragraph

Dim aStory As Word.Range
Dim styleDict As New Scripting.Dictionary
Dim aStyle As Style
Dim aStyleName As String
Dim aKey As Long
Dim tempKey As Long
Dim myRange As Range

' put styles from the entire doc including headers and footers into a
dictionary and count occurrences

For Each aStory In ActiveDocument.StoryRanges
getstorytype = Choose(aStory.StoryType, "wdMainTextStory",
"wdFootnotesStory", "wdEndnotesStory", "wdCommentsStory", "wdTextFrameStory",
"wdEvenPagesHeaderStory", "wdPrimaryHeaderStory", "wdEvenPagesFooterStory",
"wdPrimaryFooterStory", "wdFirstPageHeaderStory", "wdFirstPageFooterStory",
"wdFootnoteSeparatorStory", "wdFootnoteContinuationSeparatorStory",
"wdFootnoteContinuationNoticeStory", "wdEndnoteSeparatorStory",
"wdEndnoteContinuationSeparatorStory", "wdEndnoteContinuationNoticeStory")

If ((Left(getstorytype, 9) <> "wdEndnote") And (Left(getstorytype, 10)
<> "wdFootnote")) Then

For Each para In aStory.Paragraphs
Set aStyle = para.Style
aStyleName = aStyle.NameLocal

If styleDict.Exists(aStyleName) Then
tempKey = (styleDict.Item(aStyleName)) + 1
styleDict.Item(aStyleName) = tempKey
Else
styleDict.Add aStyleName, 1

End If


Next para
End If
Do Until aStory.NextStoryRange Is Nothing
Set aStory = aStory.NextStoryRange
For Each para In aStory.Paragraphs
Set aStyle = para.Style

aStyleName = aStyle.NameLocal
If styleDict.Exists(aStyleName) Then
tempKey = (styleDict.Item(aStyleName)) + 1
styleDict.Item(aStyleName) = tempKey
Else
styleDict.Add aStyleName, 1

End If

Next para

Loop

Next aStory


' Count of styles in the styles dictionary
cStyles = styleDict.Count
vStyles = styleDict.Keys


' Create a new document and insert the style names
Documents.Add

For i = 0 To cStyles - 1

Selection.InsertAfter i & " " & vStyles(i) & " " &
styleDict.Item(vStyles(i)) & vbCr
Selection.Collapse wdCollapseEnd
Next i


End Sub
 
S

StevenM

To: Jessica Weissman,

Here is my approach (something I wrote sometime ago).

'
' Macro: ListStylesInUse
' Function: IsStyleInUseInDoc
' Function: IsStyleInRange
'
Sub ListStylesInUse()
Dim oStyle As Style
Dim sStyle As String
Dim actDoc As Document
Dim newDoc As Document

Set actDoc = ActiveDocument
Set newDoc = Documents.Add

For Each oStyle In actDoc.Styles
If oStyle.InUse Then
If IsStyleInUseInDoc(oStyle, actDoc) Then
With oStyle
sStyle = sStyle & "Style: " & .NameLocal & vbCr
sStyle = sStyle & "Font: " & .Font.Name & vbCr
sStyle = sStyle & "Size: " & .Font.Size & vbCr & vbCr
End With
With newDoc.Range
.Text = sStyle
.Collapse wdCollapseEnd
.MoveEnd wdCharacter, 1
End With
End If
End If
Next oStyle
End Sub

Private Function IsStyleInUseInDoc(ByVal oStyle As Style, ByVal oDoc As
Document) As Boolean
Dim oRange As Range
Dim bReturn As Boolean

bReturn = False
For Each oRange In oDoc.StoryRanges
If IsStyleInRange(oStyle, oRange) = True Then
bReturn = True
End If
Do While Not (oRange.NextStoryRange Is Nothing)
Set oRange = oRange.NextStoryRange
If IsStyleInRange(oStyle, oRange) = True Then
bReturn = True
End If
Loop
Next oRange
IsStyleInUseInDoc = bReturn
End Function

Private Function IsStyleInRange(ByVal oStyle As Style, ByVal oRange As
Range) As Boolean
oRange.Collapse Direction:=wdCollapseStart
With oRange.Find
.ClearFormatting
.Style = oStyle
.Forward = True
.Format = True
.Text = ""
.Execute
End With
IsStyleInRange = oRange.Find.Found
End Function

Steven Craig Miller
 
J

Jessica Weissman

Thanks. This is interesting, and opens up lots of possibilities.

It doesn't count the number of paragraphs that use the style, which is part
of what I need to do. But I can probably combine your idea of starting with
the inUse styles and write something that uses the find to find each
paragraph in each story that uses a style that is found among the styles for
that story.

I still wonder why my approach finds so many instances of certain styles
that don't show up for the Find command.

- Jessica
 
S

StevenM

To: Jessica Weissman,

One important point which I discovered when working on this project before
is that the line: "If oStyle.InUse Then" does not work as expected. Indeed,
that is the point of the whole macro. If "oStyle.InUse" worked, we wouldn't
need my macro (or something like it). It turns out that ".InUse" includes any
style once used in one's document. I left the line in my macro since it
seemed to be of some help.

Just out of curiosity, what is the point of counting paragraphs?

Steven Craig Miller
 
J

Jessica Weissman

I'm counting the paragraphs partly out of curiosity, and partly because there
is at least one instance of a paragraph that uses Normal style invisibly in
every doc, for some reason. Or at least one that I can't find. So I don't
want to bug authors unless they are actually using Normal voluntarily.

- Jessica
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top