Deleting styles with leading spaces in their names

L

larrysulky

I need to programmatically delete styles whose names begin with a
space character. I know that it's not possible for a user to create
such a thing intentionally -- the style modification/creation dialogue
suppresses such leading spaces. But the paragraph/character hybrid
style logic that Word 2003 and later uses can lead users to
accidentally create styles with names of " Char Char", " Char Char
Char", and so on.

If you record a macro, delete a " Char Char" style by hand, and then
look at what you have recorded, you'll see:

ActiveDocument.Styles(" Char Char").Delete

But simply running this as a VBA command does not actually work: "The
requested member of the collection does not exist".

It also does not work to declare a style variable and use For Each
logic to try to catch it:

Dim myStyle As Style
For Each myStyle In ActiveDocument.Styles
If (myStyle.NameLocal = " Char Char") Then
Debug.Print "", "_Deleting " & myStyle.NameLocal
myStyle.Delete
End If
Next

(Interestingly, myStyle.NameLocal does resolve correctly in the
debug.print statement.)

I've tried escaping the space in the style name, and using a character
reference instead of a literal space, but I can't find the magic
bullet. Any ideas out there?

TIA....
 
K

Klaus Linke

Hi Larry,

I don't think there is a way, short of re-building the doc (i.e., copying
everything into a clean doc, leaving the buggy style definitions behind).

Wouldn't mind to be proven wrong, though...

Regards,
Klaus
 
K

Klaus Linke

Hi Lene,

Yes, but not if the name starts with a blank, as in Larry's case.

Regards,
Klaus
 
L

larrysulky

Hi Lene,

Yes, but not if the name starts with a blank, as in Larry's case.

Regards,
Klaus

That's right, Klaus. I have a macro already (which, if I remember
correctly, you mostly provided, Klaus) that does a great job of
removing "Char" styles. But nothing seems to deal with these very odd
cases of " Char", " Char Char", etc. That leading blank ruins
everything. For the moment I can remove them by hand but really need a
programmatic solution. And unfortunately, copying the file into a
blank document simply carries along the bad stylename.

It's amazing that I can delete the style by hand, record a macro to
reveal how it was done, and the resulting command actually fails and
throws an error. But I suppose nothing MSWord does should surprise me
anymore....

---larry
 
R

Russ

Larry,
In MacWord 2004,
I created a character style named " Char Char" and applied it to some text.
I was able to successfully delete it with the code:
ActiveDocument.Styles(" Char Char").Delete
in the immediate window. Note leading space in delete command.

Then I also successfully deleted another new style named " Char Char" using
Organizer code in a recorded macro:
Application.OrganizerDelete Source:="Document3", Name:="Char Char", Object _
:=wdOrganizerObjectStyles
That's when I noticed that it ignores the leading space for a name and there
was no leading space in the Styles dialog list although I clearly tried to
name it with a leading space character.

Try something like asc( myStyle.NameLocal ) in your debug print code and see
if that is really a code 32 for a space character at the beginning of the
string.

Or I'm wondering if you have the styles you are trying to delete still
**dependent on another style** or if your document is corrupt.
 
K

Klaus Linke

[...] And unfortunately, copying the file into a blank
document simply carries along the bad stylename.


Hi Larry,

It should work if you do what's called a "Maggie" on these newsgroups.
Copy everything *except the last paragraph mark*, then paste into a new doc.

Beforehand, you'd have to remove the offending Char styles with some other
character style.

The "Maggie" leaves unused styles behind (...also other unused stuff, such
as unused list templates).

It's a bit of work though, and I usually just replace these styles, and then
try to ignore them...

Regards,
Klaus
 
K

Klaus Linke

Hi Russ,

I don't know how those weird styles are created... Maybe it has to do
something with different language versions.
It seems I find them in every other doc... say
http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/pecoff_v8.doc


When I run this macro with the doc open:

Dim myStyle As Style
For Each myStyle In ActiveDocument.Styles
If left(myStyle.NameLocal, 1) = " " Then
MsgBox Chr(34) & myStyle.NameLocal & Chr(34), _
vbInformation, "Example style:"
End If
Next myStyle

....it reports a style " Zchn Zchn" (... Zchn is German for "Char").

Regards,
Klaus
 
R

Russ

Klaus,
I downloaded and opened the document and ran your code snippet.
I didn't get any popup message.
I'm using MacWord 2004 American English VB5 based and when I list the styles
in the Format/Styles dialog, all the styles are left justified with no
leading spaces and I am not able to name any new style with leading spaces
and have it keep the leading spaces.
So I think you're right about the different language versions showing or not
showing the problem.
 
L

larrysulky

Klaus,
I downloaded and opened the document and ran your code snippet.
I didn't get any popup message.
I'm using MacWord 2004 American English VB5 based and when I list the styles
in the Format/Styles dialog, all the styles are left justified with no
leading spaces and I am not able to name any new style with leading spaces
and have it keep the leading spaces.
So I think you're right about the different language versions showing or not
showing the problem.

It's true that you cannot manually create styles with leading blanks.
Only Word's various secret machinations, revolving around the creation
of character/paragraph hybrid styles (AKA linked styles), can
sometimes result in such style names.

I'm waiting to run the test you recommended earlier, Russ, until I
encounter another such file... in my haste to get my user on her way,
I had simply fixed the file by hand and foolishly forgot to keep a
copy.

---larry
 
L

larrysulky

Larry, ---SNIP---

Try something like asc( myStyle.NameLocal ) in your debug print code and see
if that is really a code 32 for a space character at the beginning of the
string.

Or I'm wondering if you have the styles you are trying to delete still
**dependent on another style** or if your document is corrupt.

Well, Russ, I finally had a chance to run the test you suggested,
showing the ascii value of the first character in the style name to
see if it is really a blank. And *sigh*, it is: ascii 32. Also checked
for a linked style: none.

Then I tried saving the .doc file as .xml, then reopening it in
Word...

Bingo! The style name changes to "Char Char" (no leading space) in the
opened document. I can open the XML file in a flat-file editor and see
" Char Char" (with space) in the value of the style name, but Word
sees it, _on import_, as having no leading space.

So it's a klugy(*) matter of saving files out to .xml, then opening
them and saving them as .doc, then doing any other processing needed.
Ugly, but doable.

Thanks to all--
--larry

(*) I refuse to spell "kluge" as "kludge", as though it would rhyme
with fudge, judge, grudge, budge, nudge, and smudge. And I was there
when the word was new and there were still two schools of thought on
the issue... unfortunately, the wrong school won. ;-)
 
K

Klaus Linke

Hi Larry,

Tip of the hat for the nice XML kluge (and the info on kluge, a word that
has become a staple item of my vocabulary since I started frequenting these
groups <g>).

Klaus
 
R

Russ

Larry,
Thanks for the feedback. A klugy (klugey?) solution is better than none at
all and this one may apply in other circumstances as well. ;-)
 
M

MadMeg

Hi - there is a method described at this URL:
http://www.windowsdevcenter.com/pub/a/windows/excerpt/wdhks_1/index.html?page=2

Here is the Macro
Sub DeleteCharCharStylesKeepFormatting( )
Dim sty As Style
Dim i As Integer
Dim doc As Document
Dim sStyleName As String
Dim sStyleReName As String
Dim bCharCharFound As Boolean

Set doc = ActiveDocument
Do

bCharCharFound = False
For i = doc.Styles.Count To 1 Step -1
Set sty = doc.Styles(i)
sStyleName = sty.NameLocal
If sStyleName Like "* Char*" Then

bCharCharFound = True
If sty.Type = wdStyleTypeCharacter Then
Call StripStyleKeepFormatting(sty, doc)
On Error Resume Next
'#############################################
' COMMENT OUT THE NEXT LINE IN WORD 2000 OR 97
sty.LinkStyle = wdStyleNormal
sty.Delete
Err.Clear
Else
sStyleReName = Replace(sStyleName, " Char", "")
On Error Resume Next
sty.NameLocal = sStyleReName
If Err.Number = 5173 Then
Call SwapStyles(sty, doc.Styles(sStyleReName), doc)
sty.Delete
Err.Clear
Else
On Error GoTo ERR_HANDLER
End If
End If
Exit For
End If
Set sty = Nothing
Next i
Loop While bCharCharFound = True
Exit Sub
ERR_HANDLER:
MsgBox "An Error has occurred" & vbCr & _
Err.Number & Chr(58) & Chr(32) & Err.Description, _
vbExclamation
End Sub

Function SwapStyles(ByRef styFind As Style, _
ByRef styReplace As Style, _
ByRef doc As Document)
With doc.Range.Find
.ClearFormatting
.Text = ""
.Wrap = wdFindContinue
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Style = styFind
.Replacement.ClearFormatting
.Replacement.Style = styReplace
.Replacement.Text = "^&"
.Execute Replace:=wdReplaceAll
End With
End Function


Function StripStyleKeepFormatting(ByRef sty As Style, _
ByRef doc As Document)
Dim rngToSearch As Range
Dim rngResult As Range
Dim f As Font

Set rngToSearch = doc.Range
Set rngResult = rngToSearch.Duplicate

Do
With rngResult.Find
.ClearFormatting
.Style = sty
.Text = ""
.Forward = True
.Wrap = wdFindStop
.Execute
End With

If Not rngResult.Find.Found Then Exit Do

Set f = rngResult.Font.Duplicate
With rngResult
.Font.Reset
.Font = f
.MoveStart wdWord
.End = rngToSearch.End
End With
Set f = Nothing
Loop Until Not rngResult.Find.Found
End Function
 
F

fumei via OfficeKB.com

I never get this issue as I always carefully use styles properly, but I have
to say I am happy
that link was posted. The hack on the org chart is very interesting.
Hi - there is a method described at this URL:
http://www.windowsdevcenter.com/pub/a/windows/excerpt/wdhks_1/index.html?page=2

Here is the Macro
Sub DeleteCharCharStylesKeepFormatting( )
Dim sty As Style
Dim i As Integer
Dim doc As Document
Dim sStyleName As String
Dim sStyleReName As String
Dim bCharCharFound As Boolean

Set doc = ActiveDocument
Do

bCharCharFound = False
For i = doc.Styles.Count To 1 Step -1
Set sty = doc.Styles(i)
sStyleName = sty.NameLocal
If sStyleName Like "* Char*" Then

bCharCharFound = True
If sty.Type = wdStyleTypeCharacter Then
Call StripStyleKeepFormatting(sty, doc)
On Error Resume Next
'#############################################
' COMMENT OUT THE NEXT LINE IN WORD 2000 OR 97
sty.LinkStyle = wdStyleNormal
sty.Delete
Err.Clear
Else
sStyleReName = Replace(sStyleName, " Char", "")
On Error Resume Next
sty.NameLocal = sStyleReName
If Err.Number = 5173 Then
Call SwapStyles(sty, doc.Styles(sStyleReName), doc)
sty.Delete
Err.Clear
Else
On Error GoTo ERR_HANDLER
End If
End If
Exit For
End If
Set sty = Nothing
Next i
Loop While bCharCharFound = True
Exit Sub
ERR_HANDLER:
MsgBox "An Error has occurred" & vbCr & _
Err.Number & Chr(58) & Chr(32) & Err.Description, _
vbExclamation
End Sub

Function SwapStyles(ByRef styFind As Style, _
ByRef styReplace As Style, _
ByRef doc As Document)
With doc.Range.Find
.ClearFormatting
.Text = ""
.Wrap = wdFindContinue
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Style = styFind
.Replacement.ClearFormatting
.Replacement.Style = styReplace
.Replacement.Text = "^&"
.Execute Replace:=wdReplaceAll
End With
End Function

Function StripStyleKeepFormatting(ByRef sty As Style, _
ByRef doc As Document)
Dim rngToSearch As Range
Dim rngResult As Range
Dim f As Font

Set rngToSearch = doc.Range
Set rngResult = rngToSearch.Duplicate

Do
With rngResult.Find
.ClearFormatting
.Style = sty
.Text = ""
.Forward = True
.Wrap = wdFindStop
.Execute
End With

If Not rngResult.Find.Found Then Exit Do

Set f = rngResult.Font.Duplicate
With rngResult
.Font.Reset
.Font = f
.MoveStart wdWord
.End = rngToSearch.End
End With
Set f = Nothing
Loop Until Not rngResult.Find.Found
End Function
I need to programmatically delete styles whose names begin with a
space character. I know that it's not possible for a user to create
[quoted text clipped - 31 lines]
 

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