Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Deleting Unused Styles 1

Status
Not open for further replies.

paperworker

Technical User
Mar 18, 2007
6
US
I'm new at using VBA (using MSWord 2003). I'm trying to create a macro that deletes user-defined styles in ActiveDocument that are no longer needed or used. I've tried various solutions. For example:
ActiveDocument.Styles("1.1")Delete
ActiveDocument.Styles("1.1.1")Delete
and so forth, works until it tries to delete a style that doesn't happen to exist in a particular document. I've tried deleting using Organizer.Delete with loops, If-Then-Else staements, Case-If, and nothing has worked. The documentation has been cryptic and difficult to understand.
Any hints, tips, help would be appreciated...I don't know what else to try.
 
1. It may be helpful if you posted some code.

2. As you did not post code, a suggestion for...
works until it tries to delete a style that doesn't happen to exist
would be On Error Resume Next. That ma keep things going when teh code comes across a style that is not there. Only a suggestion, as you did not post code.

3. Why are you doing this?

4. WHERE are you doing this?

5. HOW are you doing this? As code running from normal.dot and being used on ALL documents? From a template and being used on its documents? If the latter...remove the styles from the template.

In any case, if the real issue is the code has problems with a named style that is not present, then On Error Resume Next should take care of that.



Gerry
My paintings and sculpture
 
Your suggestion to use the "On Error Resume Next" statement made all the difference. My macro now works...here is a sample of the code:

Sub RemoveStylesNow()

ActiveDocument.Styles("1.").Delete
On Error Resume Next
ActiveDocument.Styles("1.1").Delete
On Error Resume Next
ActiveDocument.Styles("1.1.1").Delete
On Error Resume Next
ActiveDocument.Styles("Table Text").Delete
On Error Resume Next
ActiveDocument.Styles("Introduction").Delete
On Error Resume Next
ActiveDocument.Styles("Balloon Text").Delete
On Error Resume Next
ActiveDocument.Styles("Block Text").Delete
On Error Resume Next
ActiveDocument.Styles("Column Heading").Delete
On Error Resume Next

End Sub

ANSWERS TO YOUR QUESTIONS:

Why am I doing this? My assignment is to rid 900+ documents of nonstandard styles that were not intentionally created for our templates. Every time someone edits a document we get "style creep". Maintaining a standard look for our documents is difficult when you have to wade through a huge list of styles to find the right one to use.

How and where I'm I doing this? I will store this macro in the Normal.dot template and run it from Normal.dot.

QUESTION:

I am not a programmer. I have been learning VBA on my own with no help...no mentor. I've done a lot of head banging and reading and, through trial and error, have had reasonable success in creating macros to automate simple MS Word tasks. Can you recommend a reference book on VBA MS Word applications or a "VBA dictionary" that lists and describes VBA objects, methods, properties, events, etc.? Are there any tutorial books on this subject?

Thank you for your advice.
 
paperworker

If you open the Word help (without Clippy), near the bottom of the Contents is a programming section. Look at the Word reference, which has as its first or second item a list of the objects and their methods and properties.

Open the help in the VB editor to get help on the VB language itself.

One criticism of your design is that it's kind of repetitive, and only finds what it's been coded to look for. Computers are good at repetitive tasks, so lets turn it on its head
Code:
Sub StyleFascist()
    [green]'Anything not compulsory is forbidden...[/green]
    AllowedStyles = Array( _
        "Body Text Indent 2", _
        "Body Text Indent 3", _
        "Caption", _
        "Closing", _
        "TOC 9", _
        "etc")
        
    For Each s In ActiveDocument.Styles
        Dim Kill As Boolean
        Kill = True
        
        For Each a In AllowedStyles
            If s.NameLocal = a Then Kill = False
        Next
            
        If Kill Then Debug.Print s.NameLocal
        [green]'change to If Kill Then ActiveDocument.Styles(s.NameLocal).Delete[/green]
    Next
End Sub
This code looks for things that are allowed, rather than things that aren't.

The first part sets up a list of allowed styles. You need to populate this with an exhaustive list of styles you will tolerate in your documents.

The outer For Each loop looks at each of the styles in your document in turn. The inner loop looks the style up in your list of allowed styles. If it isn't found, then it gets deleted.

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Also, there is no need to repeat the On Error Resume Next. You only need it once! It is a global instruction...ON ERROR...resume next.

The only comment I would make on Steve's code is that it appears to not use Option Explicit. His variables are not declared. I would recommend you do not do this. Other than that, the logic is quite correct. You want to delete things NOT allowed.

I certainly empathize with style creep. It is a problem.

While there are methods to try and prevent users from doing manual format changes, and adding slightly modified styles, no restrictive method is foolproof.

1. Training. This is the only truly effective method to prevent style creep, and users properly using approved styles.

2. Regarding manual format changes. I do have templates that have ALL format menu possibilities removed. All the underline, bold etc etc. buttons are removed. All menu items are removed (Format Font, Paragraph) that can change format. Toolbar changes are restricted. The VBE is disabled so they can not re-code it back.

A new toolbar with the major basic styles is added. The users enter text and hit Style buttons for those major styles.

To repeat though, any decent VBA hacker can break through this. It prevents the average user from manually formatting, but that is about it.

Depending on the structure and usage of your documents, you may have a use for formfields, which when protected, disable ALL edits in the document. This is useful for data entry type documents, when you want the users to put in text, and nothing more. Formfields allow text entry and lock out everything else.

Training, that often neglected part of business, is the best route to stop style creep.

Gerry
My paintings and sculpture
 
Gerry

Apologies about the lack of Option Explicit. No excuses, I rant on enough about people not using 'strict' on the perl forum, for exactly the same reasons, so I should know better [blush]

I was wondering if there might be a better way of populating the Allowed list, maybe by referencing a standard read-only document, or some inherent collection of Styles stored in the template? It just seems a bit crude to have to paste them all in to the body of the code.

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Not meant to be personally critical re: Option Explicit. It is a good habit to use, as you seem to know. It is easy enough, though, to forget to use it here.

Yes, if the issue is with hundreds of files messed up, it would probably be worth it to reference a standard file.

Have a template file with the approved styles.
Open that file.
Build the array from the styles in that file.
Close it.
Use the array to check bad dog styles in the document.

NOTE! As there are many built-in styles that only show in the styles list (Task Pane Styles and Formatting) if you have Show all styles, you may not be aware of these. In Word 2002 there 44 Tables Styles alone. These will be included in an array of existing styles in a template where you only have 10 of your OWN styles.

Here is how to get around this.
Code:
Option Explicit

Sub ShowBadDogStyles()
Dim ApprovedStyles()
Dim oStyle As Style
Dim j As Long
Dim var
[COLOR=red]' open the template file with approved styles
' build the array of ONLY those that are not builtin
' that is, YOUR styles
' close the template file[/color red]

Documents.Open FileName:="c:\temp\approvedstyles.dot"
For Each oStyle In ActiveDocument.Styles
  If oStyle.BuiltIn = False Then
     ReDim Preserve ApprovedStyles(j)
     ApprovedStyles(j) = oStyle.NameLocal
     j = j + 1
  End If
Next
Documents("approvedstyles.dot").Close wdDoNotSaveChanges

[COLOR=red]' now loop through the active document styles
' checking again if builtin, and if not
' check against the array of approved styles
' if not matched this displays the name
' change to oStyle.Delete to actually remove[/color red]

For Each oStyle In ActiveDocument.Styles
  If oStyle.BuiltIn = False Then
     For var = 0 To UBound(ApprovedStyles)
       If oStyle.NameLocal = ApprovedStyles(var) Then
          Exit For
       Else
          MsgBox oStyle.NameLocal
          Exit For
       End If
     Next
  End If
Next
End Sub

Gerry
My paintings and sculpture
 
Useful tip about style.BuiltIn - makes the original method with the hand-made array seem more acceptable, if you only have a few non-built in styles allowed.

Not sure about
Code:
     For var = 0 To UBound(ApprovedStyles)
       If oStyle.NameLocal = ApprovedStyles(var) Then
          Exit For
       Else
          MsgBox oStyle.NameLocal
          Exit For
       End If
     Next
though, it looks like it would only work if your style was the first one on the list...

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
though, it looks like it would only work if your style was the first one on the list...
Explain please.

ApprovedStyles is the array of added styles from the source template, the one used for the approved list.

Say that has:

Myheading1
MyBodytext
MyBodyIndent_.5
MyBullet1

In the current document there some of those, AND some others. Say the user bolded MyBodyIndent_.5. This will now be MyBodyIndent_.5 + Bold.

So say in the document the styles are:

Myheading1
MyBodytext
MyBodyIndent_.5
MyBodyIndent_.5 + Bold
MyBullet1
Code:
For var = 0 To UBound(ApprovedStyles)
  If oStyle.NameLocal = ApprovedStyles(var) Then
     Exit For
  Else
     MsgBox oStyle.NameLocal
     Exit For
  End If
Next

MyHeading1 - ......CRAP! You are right. OK, hmmmm

Code:
Dim bolOKStyle As Boolean
For Each oStyle In ActiveDocument.Styles
  If oStyle.BuiltIn = False Then
     For var = 0 To UBound(ApprovedStyles)
       If oStyle.NameLocal = ApprovedStyles(var) Then
          bolOKStyle = True
          Exit For
       Else
          bolOKStyle = False
       End If
     Next
     If Not bolOKStyle Then oStyle.Delete
  End If
Next
That should do it. It will take each style and run it through the array. Eventually it will make the boolean either True, or False, and delete as appropriate.

In the example Ubound(ApprovedStyles) = 4.

MyBodyIndent_.5 + Bold

Var = 0, bolOKStyle = False
Var = 1, bolOKStyle = False
Var = 2, bolOKStyle = False
Var = 3, bolOKStyle = False
Var = 4, bolOKStyle = False

Style is deleted.

MyBodytext

Var = 0, bolOKStyle = False
Var = 1, bolOKStyle = True
Exit For

Style is not deleted - go to next style

MyBullet1

Var = 0, bolOKStyle = False
Var = 1, bolOKStyle = False
Var = 2, bolOKStyle = False
Var = 3, bolOKStyle = False
Var = 4, bolOKStyle = True

Style is not deleted.

Thanks. You were absolutely correct. That is what I get for just writing directly into here....

[blush]

Gerry
My paintings and sculpture
 
It will of course delete any NEW styles the user made have added.

This may - or may not - be acceptable. Is the idea to NEVER allow users to create new styles? I could live with that if it is a well designed corporate template. If it is the company/organization approved style and format, the users should never need to manually format.

And I believe it is the manually formatting that is likely the issue. Rather than the users actually making new styles.

Actually...it may be a good idea if I take the new code above and (gasp!) actually test it.....

Gerry
My paintings and sculpture
 
Gerry

Coding from the hip - I like it! When it works first time, it's cool, and respect is clearly due. If not, well, we've all done it... [smile]

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Thanks for your help and advice. Your solutions are interesting and clever. Now that I have something working, I'll try some of your suggestions to refine my code and make it more efficient.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top