• spring-cleaning docs (macro for toolbox)

    Author
    Topic
    #356167

    Something for the toolbox (excuse the long code-listing!):

    I often have to clean up docs that are (supposed to be) using styles.

    Two things make that a difficult task:
    frown Formatting done “by hand” is difficult to distinguish from formatting done by using styles.
    frown Selectively returning some formatting properties (font, size, shading, space before …) to their default values is hard to do.

    If you set all paragraph styles to look like the “Normal” style (wdStyleNormal; “Standard” in german Word), and all character styles to look like the Default Paragraph Style, then all manual formatting will be obnoxiously visible frown frown clown frown frown frown (… this is also great to show authors the “errors of their ways” grin).

    The macro will produce a new document with such “empty” styles.
    Running the following macro on a document formatted with styles will make it look like a plain text file; copying the contents into an old version — or copying the styles (from the template or from an old version) to the document — will make the formatting instantly reappear.

    You can also use this macro to selectively remove manual formatting:
    – run the macro,
    – select all text,
    – set the formatting of some property (font, underline, borders, indent …) to the default value of the “Normal” style,
    – save the doc (important! … Word does some cleaning up when saving)
    – copy back the styles.

    Sub NewDocEmptyStyles()
    '  (Save the new file before copying back the styles!)
      Dim myStyle As Style
      Dim DlgSaveAs As Dialog
      Set DlgSaveAs = Dialogs(wdDialogFileSaveAs)
      OldFile = ActiveDocument.Name
      Documents.Add NewTemplate:=False, DocumentType:=0
      NewFile = ActiveDocument.Name
      For Each myStyle In Documents(OldFile).Styles
        If (myStyle.InUse = True And myStyle.BuiltIn = False) Then
          If myStyle.Type = wdStyleTypeParagraph Then
            If myStyle  Documents(OldFile).Styles(wdStyleNormal) Then
              Documents(NewFile).Styles.Add Name:=myStyle.NameLocal, Type:=wdStyleTypeParagraph
              Documents(NewFile).Styles(myStyle).BaseStyle = wdStyleNormal
            End If
          Else
            If myStyle  Documents(OldFile).Styles(wdStyleDefaultParagraphFont) Then
              Documents(NewFile).Styles.Add Name:=myStyle.NameLocal, Type:=wdStyleTypeCharacter
              Documents(NewFile).Styles(myStyle).BaseStyle = wdStyleDefaultParagraphFont
            End If
          End If
        End If
      Next myStyle
      Documents(OldFile).Select
      Selection.WholeStory
      Selection.Copy
      Documents(NewFile).Activate
      Selection.Paste
      For Each myStyle In Documents(NewFile).Styles
        If (myStyle.InUse = True And myStyle.BuiltIn = True) Then
          If myStyle.Type = wdStyleTypeParagraph Then
            If myStyle  Documents(NewFile).Styles(wdStyleNormal) Then
              RememberOutlineLevel = myStyle.ParagraphFormat.OutlineLevel
              myStyle.BaseStyle = Documents(NewFile).Styles(wdStyleNormal)
              myStyle.Font = Documents(NewFile).Styles(wdStyleNormal).Font
              myStyle.ParagraphFormat = Documents(NewFile).Styles(wdStyleNormal).ParagraphFormat
              myStyle.ParagraphFormat.OutlineLevel = RememberOutlineLevel
            End If
          End If
        End If
      Next myStyle
      Documents(NewFile).Activate
      DlgSaveAs.Show
    End Sub
    Viewing 2 reply threads
    Author
    Replies
    • #593490

      Looks good but I ran into a couple of problems.

      First, since I have my Options set for Explicit declarations, I added the following lines:
      Dim NewFile As String ‘ added by Charles Kenyon
      Dim OldFile As String ‘ added by Charles Kenyon
      Dim RememberOutlineLevel As Variant ‘ added by Charles Kenyon

      Second, I run into an error 5173 “This style name already exists or is reserved for a built-in style.” on the line:
      Documents(NewFile).Styles.Add Name:=myStyle.NameLocal, Type:=wdStyleTypeParagraph

      Might have to shift to the OrganizerCopy method? Will this work when copying styles within a template? Haven’t tried.

      Attachment is a doc with the modified macro and a toolbar with button. (Also put command on formatting menu.)

      • #593699

        Hey, that was my very first post on Woody’s Lounge!

        I have posted a revised version, and had some private exchange with Phil… Can’t remember if we improved further on the posted macro.

        Since I know you are interested in everything about styles:
        I just discovered that styles (at least in Word2000) have a hidden “.Hidden” property. If you set that to “True”, the style won’t show in the styles drop-down or any of the styles lists (“All styles”, “Styles in use”, “Customized styles”).

        blackholeYou can even hide the built-in heading styles and “Normal” style:
        ActiveDocument.Styles(wdStyleNormal).Hidden = True

        This may be very useful: You can define “base styles” in the document on which you can base your other styles, but have them not show up in the lists. Or you can hide “Normal” or the built-in Heading styles.

        cheersKlaus

        • #593708

          Hi Klaus & Charles:
          Yes, you did further improve it, Klaus. You put in error handling. Here is the version you ultimately sent me:

          Sub NewDocEmptyStyles()
          '
          'by Klaus Linke 12/14/01
          '
            Dim myStyle As Style
            Dim myStyle2 As Style
            Dim DlgSaveAs As Dialog
            Dim OldFile As String
            Dim NewFile As String
            Dim RememberOutlineLevel
            Set DlgSaveAs = Dialogs(wdDialogFileSaveAs)
            OldFile = ActiveDocument.Name
            Documents.Add NewTemplate:=False, DocumentType:=0
            NewFile = ActiveDocument.Name
            ' Clean up new file
            Documents(NewFile).Content.Style = wdStyleNormal
            Documents(NewFile).Content.Style = wdStyleDefaultParagraphFont
            ' Remove all user-defined/changed styles from new doc
            For Each myStyle2 In Documents(NewFile).Styles
              If (myStyle2.InUse = True) Then
                If myStyle2.Type = wdStyleTypeParagraph Then
                  If myStyle2  Documents(NewFile).Styles(wdStyleNormal) Then
                    On Error Resume Next
                    Documents(NewFile).Styles(myStyle2.NameLocal).Delete
                    If Err = 4198 Then
                      MsgBox myStyle2.NameLocal, vbOKOnly + vbExclamation,  _
          "Could not delete style"
                    End If
                    Err.Clear
                  End If
                End If
              End If
            Next myStyle2
            ' Create styles from old doc in new doc
            ' (Built-in styles are treated separately below,
            ' because changes to them in an empty doc "don't take")
            For Each myStyle In Documents(OldFile).Styles
               If (myStyle.InUse = True And myStyle.BuiltIn = False) Then
                If myStyle.Type = wdStyleTypeParagraph Then
                ' base paragraph styles on wdStyleNormal
                  If myStyle  Documents(OldFile).Styles(wdStyleNormal) Then
                    Debug.Print myStyle.NameLocal
                    Documents(NewFile).Styles.Add _
                      Name:=myStyle.NameLocal, Type:=wdStyleTypeParagraph
                  End If
                Else
                  If myStyle  Documents(OldFile).Styles(wdStyleDefaultParagraphFont) Then
                  ' base character styles on wdStylDefaultParagraphFont
                    Debug.Print myStyle.NameLocal
                    Documents(NewFile).Styles.Add _
                      Name:=myStyle.NameLocal, Type:=wdStyleTypeCharacter
                  End If
                End If
              End If
            Next myStyle
          
            Documents(OldFile).Content.Select
            Selection.Copy
            Documents(NewFile).Activate
            Documents(NewFile).Content.Select
            Selection.Paste
            
            ' Make built-in styles look like Normal/DefaultParagraphFont:
            For Each myStyle In Documents(NewFile).Styles
              If (myStyle.InUse = True And myStyle.BuiltIn = True) Then
                If myStyle.Type = wdStyleTypeParagraph Then
                  If myStyle  Documents(NewFile).Styles(wdStyleNormal) Then
                    RememberOutlineLevel = myStyle.ParagraphFormat.OutlineLevel
                    ' make built-in paragraph styles look just like wdStyleNormal
                    myStyle.BaseStyle = Documents(NewFile).Styles(wdStyleNormal)
                    myStyle.Font = Documents(NewFile).Styles(wdStyleNormal).Font
                    myStyle.ParagraphFormat =  _
          Documents(NewFile).Styles(wdStyleNormal).ParagraphFormat
                    ' Reset OutlineLevel, so you can still use Outline View
                    myStyle.ParagraphFormat.OutlineLevel = RememberOutlineLevel
                  End If
                Else
                  If myStyle  Documents(NewFile).Styles(wdStyleDefaultParagraphFont) Then
                  ' make built-in character styles look just like wdStyleDefaultParagraphFont
                    myStyle.BaseStyle = Documents(NewFile).Styles(wdStyleDefaultParagraphFont)
                    myStyle.Font = Documents(NewFile).Styles(wdStyleDefaultParagraphFont).Font
                  End If
                End If
              End If
            Next myStyle
            ' If you want to always make a back-up:
            If InStr(1, OldFile, ".") > 0 Then
              OldFile = Left(OldFile, InStr(1, OldFile, ".") - 1)
            End If
            DlgSaveAs.Name = OldFile & " (stripped)"
            DlgSaveAs.Show
          End Sub

          Cheers,

        • #596076

          Klaus:

          Re: Hiding built-in styles

          I tried ActiveDocument.Styles(wdStyleNormal).Hidden = True but I couldn’t get it to work for built-in styles with names like Heading 1. I tried typing it it without the space, with an underscore, with the word “one.”

          What am I doing wrong? It works for Normal, Footer, other styles with simple names.

          Thanks.

          Jerry

          • #596201

            Hi Jerry,

            It seems you cannot remove “Heading 1” to “Heading 3” from the Styles dropdown. Don’t know why those three styles make an exception; too bad… it sure would have been nice if you *could* remove them.

            ActiveDocument.Styles(wdStyleHeading1).Hidden = True
            does have the effect that the styles dropdown doesn’t display anything if you are in a “Heading 1” paragraph, though.

            The .Hidden property for styles was very new to me, too … I only discovered it last week.

            cheersKlaus

            • #596421

              On a related note: how to clean out a document of all user styles that are not actively inuse — the Style.InUse property is of no help here since InUse is TRUE if the style was EVER used.

              So, here’s a function that checks if a style is actually in the document.

              The sample routine nukes user styles that are not in the document, and hides built-in styles from the drop down list if they are not actively in use.

              Sub NukeStyleNotInDocument()
                  ' Purpose: Remove all user styles that are not ACTIVELY
                  ' in use in the current document
                  ' Remove built-in styles that are not ACTIVELY in use
                  ' from the style list
                  
                  'Adapted from a macro by Paul Cornell
                  'http://office.microsoft.com/assistance/2002/articles/pwWordStyles.aspx
              
                  
                  Dim strTitle As String
                  Dim astrStyles() As String
                  Dim objStyle As Style
                  Dim objDocument As Word.Document
                  Dim intCount As Integer
                  Dim sh ' Added 6/26
                  
                  ' Get the title of the active Word document.
                  strTitle = _
                      ActiveDocument.BuiltInDocumentProperties(wdPropertyTitle)
                  
                  
                  ' Store, in memory, each style in the active document,
                  ' including whether the style is in use.
                   'Turn on Hidden
                   sh = ActiveDocument.ActiveWindow.View.ShowHiddenText  
                    ActiveDocument.ActiveWindow.View.ShowHiddenText = True
              
                  For Each objStyle In ActiveDocument.Styles
                  
                      ReDim Preserve astrStyles(intCount)
                      'GG Mod 
                      If objStyle.BuiltIn = False Then
                          If Not StyleInDoc(objStyle) Then
                              Debug.Print "Removing " & objStyle
                              objStyle.Delete
                          Else
                              Debug.Print "In use: " & objStyle
                              astrStyles(intCount) = objStyle & " (Style in Use)"
                              intCount = intCount + 1
                          End If
                      
                      Else
                          If objStyle.InUse And Not StyleInDoc(objStyle) Then
                              objStyle.Hidden = True
                              Debug.Print "Hiding: " & objStyle
                          Else
                              Debug.Print "In Use: " & objStyle
                              astrStyles(intCount) = objStyle & " (Style in Use)"
                              intCount = intCount + 1
                          End If
                       '**********
                      End If
                  Next objStyle
              
                  'Set ShowHidden back
                  ActiveDocument.ActiveWindow.View.ShowHiddenText = sh
              
                  ' Create a new Word document to report the results.
                  Set objDocument = Word.Documents.Add
                  
                  With objDocument.Range
                      
                      ' Report the results.
                      .InsertAfter "Styles in " & strTitle & ":"
                      .InsertParagraphAfter
                      .Collapse Direction:=wdCollapseEnd
                          
                      For intCount = 1 To UBound(astrStyles)
                  
                          .InsertAfter astrStyles(intCount)
                          .InsertParagraphAfter
                          .Collapse Direction:=wdCollapseEnd
                      
                      Next intCount
                  
                  End With
                  
                  MsgBox Prompt:="Done!"
              out:
              End Sub
              
              
              Function StyleInDoc(sty)
              'gg
              'Check if a style is in active use.
              
              Dim myRange As Range
              Set myRange = ActiveDocument.Content
              
              With myRange.Find
                  .ClearFormatting
                  .Style = sty
                  .Text = ""
                  .Replacement.Text = ""
                  .Forward = True
                  .Wrap = wdFindContinue
                  .Format = True
                  .MatchCase = False
                  .MatchWholeWord = False
                  .MatchWildcards = False
                  .MatchSoundsLike = False
                  .MatchAllWordForms = False
              
              
                  StyleInDoc = .Execute(FindText:="", Forward:=True, _
                          Format:=True) = True
                  .ClearFormatting
              End With
              
              End Function
              
              
            • #596439

              Guy,

              Nice piece of code. I can see me using that.

              I have one small problem with it, I can’t see where current is defined before being used in the line .Text = current. Or does current have some specific meaning that I don’t know?

              StuartR

            • #596441

              Current is leftover from the function I cut and paste the code from (which was passing both text and style to the routine).

              It should be:

              .Text = “”

              But it seems to work with a null variable.

            • #597265

              Found an interesting anomoly in Word, uncovered using my StyleInDoc Function.

              If one of the styles you are checking to see if it exists is defined as a hidden style, StyleInDoc returns fall under two circumstands:

              if ShowAll and ShowHidden are both false (this makes sense)

              If ShowAll is True — this does not make sense.

              The accurate reflection of whether or not a hidden style exists in the current document requires that ShowHidden = True.

              And so, from the calling procedure one should add:

              Dim sh
              sh = ActiveDocument.ActiveWindow.View.ShowHiddenText
              ActiveDocument.ActiveWindow.View.ShowHiddenText = True

              at the top and

              ActiveDocument.ActiveWindow.View.ShowHiddenText = sh

              at the end.

            • #597309

              Hi Guy,

              Great macro; I don’t want to criticize it… just my 2cents

              You can delete all built-in styles except for “Normal” and the heading styles (and,of course, the “Default Paragraph Font”). This may be a cleaner solution than to give them the “Hidden” attribute (which also doesn’t work for Heading 1/2/3).

              You can get rid of Heading 4-9 by saving as RTF and deleting the style definitions in the header (though that is a rather messy way to do it).

              The only built-in style you’d really *need* the .Hidden attribute for is “Normal”.

              cheersKlaus

            • #597317

              Hi Klaus.

              The meat of the macro is to clean out unused “user” styles… (this has come up in a module I’m working on that converts a document with similar styles from one template to another — the templates use diferent style names for the same function)

              The hiding (or deleting) of internal styles is just (for my purposes) meant to clean up the drop down list.

              But I’ll fiddle with deleting instead of hiding.

            • #894358

              Hi Guy, this thread has proved interesting reading. I am creating templates that contain a number of user styles. However, until these styles have actually been used in a document based on the template, I don’t want them to appear in the drop down list. I’ve tried modifying your macro, removing the delete and replacing with hidden.
              If objStyle.BuiltIn = False Then
              If Not StyleInDoc(objStyle) Then
              Debug.Print “Removing ” & objStyle
              ‘objStyle.Delete
              objStyle.Hidden = True ‘modified 02/11/2004 to hide not delete
              Else

              However, it actually still deletes some of my styles. Do you know if it is possible to “hide” the styles until they have been used in the current document?
              I’ve tried creating a new template based on a very clean Normal.dot, then used Organiser to copy styles from a template that was used to create the styles. All my styles then get listed in the dropdown styles box.

              If I could replace the Styles Box with a simple text box that displayed the style of the selected text, I would be happy 🙂

              Thanks.

            • #894359

              Hi Guy, this thread has proved interesting reading. I am creating templates that contain a number of user styles. However, until these styles have actually been used in a document based on the template, I don’t want them to appear in the drop down list. I’ve tried modifying your macro, removing the delete and replacing with hidden.
              If objStyle.BuiltIn = False Then
              If Not StyleInDoc(objStyle) Then
              Debug.Print “Removing ” & objStyle
              ‘objStyle.Delete
              objStyle.Hidden = True ‘modified 02/11/2004 to hide not delete
              Else

              However, it actually still deletes some of my styles. Do you know if it is possible to “hide” the styles until they have been used in the current document?
              I’ve tried creating a new template based on a very clean Normal.dot, then used Organiser to copy styles from a template that was used to create the styles. All my styles then get listed in the dropdown styles box.

              If I could replace the Styles Box with a simple text box that displayed the style of the selected text, I would be happy 🙂

              Thanks.

    • #912872

      Hi,
      I’ve just tried out the Nuke Unused Styles macro. It’s something I’ve needed for a long time. I’m using Word 2000 SR-1.

      After using the macro, I am having trouble with the Style Area in Normal View. Some style names will not display (for example, List Continue). The area is blank. Also the Style name drop-down box on the formatting tool bar is empty. When I select Format-> Style form the menu, it shows the style as “Normal”. I can scroll up and select List Continue if I’ve selected “All Styles”; I can modify it and the modifications are reflected in the document, but the style name never appears anywhere.
      I suspect it may have something to do with the hidden attribute, but I don’t know how to fix it.
      Thanks,
      Judith

      • #913182

        I would say it definately has something to do with the hiding of styles.

        What happens if you rem out the lines shown below by adding a single quote to the front of each as shown
        ‘ objStyle.Hidden = True
        ‘ Debug.Print “Hiding: ” & objStyle

        This macro will prove problematic for users of Word 2002+ when table styles have been used in the document. Table styles don’t exist in Word 2000 so this shouldn’t be a problem for you though.

      • #913183

        I would say it definately has something to do with the hiding of styles.

        What happens if you rem out the lines shown below by adding a single quote to the front of each as shown
        ‘ objStyle.Hidden = True
        ‘ Debug.Print “Hiding: ” & objStyle

        This macro will prove problematic for users of Word 2002+ when table styles have been used in the document. Table styles don’t exist in Word 2000 so this shouldn’t be a problem for you though.

    • #912873

      Hi,
      I’ve just tried out the Nuke Unused Styles macro. It’s something I’ve needed for a long time. I’m using Word 2000 SR-1.

      After using the macro, I am having trouble with the Style Area in Normal View. Some style names will not display (for example, List Continue). The area is blank. Also the Style name drop-down box on the formatting tool bar is empty. When I select Format-> Style form the menu, it shows the style as “Normal”. I can scroll up and select List Continue if I’ve selected “All Styles”; I can modify it and the modifications are reflected in the document, but the style name never appears anywhere.
      I suspect it may have something to do with the hidden attribute, but I don’t know how to fix it.
      Thanks,
      Judith

    Viewing 2 reply threads
    Reply To: spring-cleaning docs (macro for toolbox)

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information: