> An alternative approach is to iterate all the content of the document,
> making a list of all the styles actually used. Then iterate the styles
> collection and delete all that aren't in your list. Just ignore the error on
> the built-ins (and yes, you're stuck with the damned things).
I don't think I understand how to iterate through the content. Would I
grab every character one by one (this has to work for character styles
as well as paragraph styles)?
Also, since VBA doesn't have the concept of an associative array (AKA
"hash table"), how would I look for matching styles in my list? Could I
make the style list a long string with delimiters between style names?
(The files are likely to have around 300 styles in them, with user
style names averaging 15 letters long or so ... could be a very long
string).
Or would I just have to examine every entry in my array one by one for
each style in the style collection? If I have 150 styles actually in
use out of 300 in the style collection, that would require 150 x 300 =
45,000 inspections.
I'm not saying your suggestion won't work, Jezebel; on the contrary, I
think it will, but I'm not smart enough to see how yet.
> Separately, you don't need "Selection.HomeKey Unit:=wdStory" before using
> the Find command if you're using Find on a Range object. Moving to the start
> of the document is necessary only if you're doing a Selection.Find
> (downwards).
Thanks, that did seem fishy to me.
--larry
larrysulky@gmail.com - 23 Nov 2006 22:04 GMT
I think I figured out how to do what Jezebel was suggesting, and it
does work. It's a little slow, but not terrible, and certainly better
than doing this manually. It seems to reliably find every style on
every character of text everywhere. Here's my code:
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sub DeleteUnusedStyles() ' Much of this was nicked from an MVP site,
plus VBA Google groups.
' IMPORTANT: Set Tools > References to include library: Microsoft
Scripting Runtime
Dim docStyles As New Scripting.Dictionary ' The long-sought hash
table capability.
Dim myStyle As Style
Dim rngStory As Word.Range
Dim lngJunk As Long ' Still not sure that I really need this.
lngJunk = ActiveDocument.Sections(1).Headers(1).Range.StoryType
For Each rngStory In ActiveDocument.StoryRanges
Do
For Each myText In rngStory.Paragraphs
' Make sure we get para styles even if they are completely
' masked by char styles. Rare, but it does happen.
If Not (docStyles.Exists(myText.Style.NameLocal)) Then
docStyles.Add myText.Style.NameLocal, 1
End If
Next myText
'For Each myText In rngStory.Words ' Word-wise granularity
isn't good enough.
For Each myText In rngStory.Characters ' This will take a
while *sigh* .
If Not (docStyles.Exists(myText.Style.NameLocal)) Then
docStyles.Add myText.Style.NameLocal, 1
End If
Next myText
Set rngStory = rngStory.NextStoryRange
Loop Until rngStory Is Nothing
Next
For Each myStyle In ActiveDocument.Styles
If (myStyle.BuiltIn = False) And Not
(docStyles.Exists(myStyle.NameLocal)) Then
'StatusBar = "Deleted " & myStyle.NameLocal
myStyle.Delete ' Just delete the blighters; there are too
many to check each one.
'Select Case MsgBox("Delete unused user style?",
vbYesNoCancel + vbInformation, myStyle.NameLocal)
' Case vbYes
' myStyle.Delete
' Case vbCancel
' GoTo bye
'End Select
End If
Next
bye:
MsgBox "Done!", , "Delete Unused Styles"
End Sub