L
larrysulky
Background: When a user selects part of a paragraph and applies a
paragraph style to the selection, Word (as of Word 2002) creates a
character style to match it, and gives it a linked name that's the
same as the paragraph style, but with " Char" appended. Getting rid of
these linked character styles is ridiculously difficult, but necessary
in my case because many other macros in our production systems will
fail when trying to deal with these styles, and because the users in
this particular system are not supposed to create new styles. The best
solution would be to prevent users from inadvertently creating these
styles in the first place but this seems to be impossible (and yes,
I've tried un-checking the Keep Track of Formatting box).
So I've created a macro to get rid of these styles, and appended it
below. It works, but it can be bloody slow. Does anyone have a more
elegant way of doing this???
Thanks in advance ----
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub RemoveAutoCharStyles()
' PURPOSE:
' Remove character styles that Word has "helpfully" created when
users
' inadvertently apply a paragraph style to a sub-paragraph.
' IMPORTANT:
' Set Tools > References to include library: Microsoft Scripting
Runtime
' LOGIC:
' Create a "swap-style" for every user paragraph style, whether
it's in
' use or not. (The swap-style name is the original name prefixed
by "[!]".)
' Base the swap-style on the original style.
' Then paddle through every paragraph in every story.
' If it's a user paragraph style, apply the corresponding swap-
style.
' Then delete each original user paragraph style and rename the
corresponding
' swap-style to the original name.
' ISSUES:
' (1) If there is already a style that begins "[!]", look out!
' (2) If a user has used a BUILT-IN paragraph style as a character
style,
' this logic won't work. (Hopefully it won't need to; the Apply
Template
' code shouldn't deal with built-in styles anyway.)
' However, a different routine could go through character by
character
' (slowly!) and Clear Formatting on any such styles (the logic
' is available in my DeleteUnusedStyles routine), and when
' all done, the "paragraph and character" style type would revert
back to
' "paragraph". Weirdly, this is NOT the behaviour of non-built-in
styles;
' that is, they will NOT revert back to pure "paragraph" just
because all
' usage of them as character styles has been removed.
On Error GoTo Error_Handler
Dim mySwapStyles As New Scripting.Dictionary ' The long-sought
hash table capability.
Dim myDeleteStyles As New Scripting.Dictionary ' The long-sought
hash table capability.
Dim myStyle As Style
Dim mySwapStyle As Variant ' Must be variant to hold hash key.
Dim myDeleteStyle As Variant ' Must be variant to hold hash key.
Dim myStory As Word.Range
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Define swap styles ("[!]") for all the user paragraph styles.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
For Each myStyle In ActiveDocument.Styles
If (myStyle.Type = wdStyleTypeParagraph) And Not
(myStyle.BuiltIn) Then
mySwapStyles.Add myStyle.NameLocal, 1
End If
Next
For Each mySwapStyle In mySwapStyles.keys
ActiveDocument.Styles.Add Name:="[!]" & mySwapStyle,
Type:=wdStyleTypeParagraph
ActiveDocument.Styles("[!]" & mySwapStyle).BaseStyle =
mySwapStyle
Application.StatusBar = "Declared " & mySwapStyle
Next
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Apply swap styles for every usage of user paragraph styles.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
For Each myStory In ActiveDocument.StoryRanges
Do
For Each myText In myStory.Paragraphs
If (myText.Style.BuiltIn = False) Then
myText.Style = ActiveDocument.Styles("[!]" &
myText.Style.NameLocal)
Application.StatusBar = "Applied " &
myText.Style.NameLocal
End If
Next myText
Set myStory = myStory.NextStoryRange
Loop Until myStory Is Nothing
Next
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Delete all user paragraph styles and rename swap styles back
''' to original names.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
For Each mySwapStyle In mySwapStyles.keys
ActiveDocument.Styles(mySwapStyle).Delete
Application.OrganizerRename Source:=ActiveDocument.FullName, _
Name:="[!]" & mySwapStyle, _
NewName:=mySwapStyle, _
Object:=wdOrganizerObjectStyles
Application.StatusBar = "Swapped " & mySwapStyle
Next
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Delete all user styles that end in " Char".
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
For Each myStyle In ActiveDocument.Styles
If (Right(myStyle.NameLocal, 5) = " Char") And Not
(myStyle.BuiltIn) Then
myDeleteStyles.Add myStyle.NameLocal, 1
Application.StatusBar = "Deleted " & myStyle.NameLocal
End If
Next
For Each myDeleteStyle In myDeleteStyles.keys
ActiveDocument.Styles(myDeleteStyle).Delete
Next
GoTo bye
Error_Handler:
If Err.Number <> 0 Then
' 424 just means cursor wasn't in a shape
' 5941 means it wasn't in a table
Err.Raise Err.Number, Description:="cleanup.bas |
RemoveAutoCharStyles(): " & Err.Description
End If
bye:
End Sub
paragraph style to the selection, Word (as of Word 2002) creates a
character style to match it, and gives it a linked name that's the
same as the paragraph style, but with " Char" appended. Getting rid of
these linked character styles is ridiculously difficult, but necessary
in my case because many other macros in our production systems will
fail when trying to deal with these styles, and because the users in
this particular system are not supposed to create new styles. The best
solution would be to prevent users from inadvertently creating these
styles in the first place but this seems to be impossible (and yes,
I've tried un-checking the Keep Track of Formatting box).
So I've created a macro to get rid of these styles, and appended it
below. It works, but it can be bloody slow. Does anyone have a more
elegant way of doing this???
Thanks in advance ----
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub RemoveAutoCharStyles()
' PURPOSE:
' Remove character styles that Word has "helpfully" created when
users
' inadvertently apply a paragraph style to a sub-paragraph.
' IMPORTANT:
' Set Tools > References to include library: Microsoft Scripting
Runtime
' LOGIC:
' Create a "swap-style" for every user paragraph style, whether
it's in
' use or not. (The swap-style name is the original name prefixed
by "[!]".)
' Base the swap-style on the original style.
' Then paddle through every paragraph in every story.
' If it's a user paragraph style, apply the corresponding swap-
style.
' Then delete each original user paragraph style and rename the
corresponding
' swap-style to the original name.
' ISSUES:
' (1) If there is already a style that begins "[!]", look out!
' (2) If a user has used a BUILT-IN paragraph style as a character
style,
' this logic won't work. (Hopefully it won't need to; the Apply
Template
' code shouldn't deal with built-in styles anyway.)
' However, a different routine could go through character by
character
' (slowly!) and Clear Formatting on any such styles (the logic
' is available in my DeleteUnusedStyles routine), and when
' all done, the "paragraph and character" style type would revert
back to
' "paragraph". Weirdly, this is NOT the behaviour of non-built-in
styles;
' that is, they will NOT revert back to pure "paragraph" just
because all
' usage of them as character styles has been removed.
On Error GoTo Error_Handler
Dim mySwapStyles As New Scripting.Dictionary ' The long-sought
hash table capability.
Dim myDeleteStyles As New Scripting.Dictionary ' The long-sought
hash table capability.
Dim myStyle As Style
Dim mySwapStyle As Variant ' Must be variant to hold hash key.
Dim myDeleteStyle As Variant ' Must be variant to hold hash key.
Dim myStory As Word.Range
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Define swap styles ("[!]") for all the user paragraph styles.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
For Each myStyle In ActiveDocument.Styles
If (myStyle.Type = wdStyleTypeParagraph) And Not
(myStyle.BuiltIn) Then
mySwapStyles.Add myStyle.NameLocal, 1
End If
Next
For Each mySwapStyle In mySwapStyles.keys
ActiveDocument.Styles.Add Name:="[!]" & mySwapStyle,
Type:=wdStyleTypeParagraph
ActiveDocument.Styles("[!]" & mySwapStyle).BaseStyle =
mySwapStyle
Application.StatusBar = "Declared " & mySwapStyle
Next
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Apply swap styles for every usage of user paragraph styles.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
For Each myStory In ActiveDocument.StoryRanges
Do
For Each myText In myStory.Paragraphs
If (myText.Style.BuiltIn = False) Then
myText.Style = ActiveDocument.Styles("[!]" &
myText.Style.NameLocal)
Application.StatusBar = "Applied " &
myText.Style.NameLocal
End If
Next myText
Set myStory = myStory.NextStoryRange
Loop Until myStory Is Nothing
Next
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Delete all user paragraph styles and rename swap styles back
''' to original names.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
For Each mySwapStyle In mySwapStyles.keys
ActiveDocument.Styles(mySwapStyle).Delete
Application.OrganizerRename Source:=ActiveDocument.FullName, _
Name:="[!]" & mySwapStyle, _
NewName:=mySwapStyle, _
Object:=wdOrganizerObjectStyles
Application.StatusBar = "Swapped " & mySwapStyle
Next
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Delete all user styles that end in " Char".
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
For Each myStyle In ActiveDocument.Styles
If (Right(myStyle.NameLocal, 5) = " Char") And Not
(myStyle.BuiltIn) Then
myDeleteStyles.Add myStyle.NameLocal, 1
Application.StatusBar = "Deleted " & myStyle.NameLocal
End If
Next
For Each myDeleteStyle In myDeleteStyles.keys
ActiveDocument.Styles(myDeleteStyle).Delete
Next
GoTo bye
Error_Handler:
If Err.Number <> 0 Then
' 424 just means cursor wasn't in a shape
' 5941 means it wasn't in a table
Err.Raise Err.Number, Description:="cleanup.bas |
RemoveAutoCharStyles(): " & Err.Description
End If
bye:
End Sub