Automating a Style Sheet (Part 2)

As mentioned in Automating a Style Sheet, Part 1, I recently came across the StyleThat macro, which facilitates copying of terms from a manuscript to a style sheet. It seemed pretty useful but had a few weak points, so I made some adjustments to its code to try to fix things.

A useful feature that I didn’t add, but would have liked to, would alphabetize terms as they are inserted. Integrating a sorting function into the macro could be done, but would slow the process down a bit down. Instead, I created a stand-alone macro that sorts all of the terms in the style sheet at the same time. This allows one to alphabetize the content as often as desired.

This macro (shown below) works by finding content between adjacent headings, or between a heading and the end of the document, and then sorting these entries into alphabetical order. For this to work properly all headings used to organize terms need to use a custom style named Style Sheet Heading. Since it finds headings based on their style name rather than their content, this macro can be used to sort material organized using categories different from those required by the StyleThat macro (for example, it will sort content organized using the headings “people” and “places”). The Style Sheet Heading style can have any appearance you want; the macro only cares about its name.

When sorting, the macro will ignore trailing spaces or line returns, but blank lines within a set of terms will get sorted to the top of the list, so it is best to avoid including these.

Operation of the macro is simple: just make your style sheet the active Word document and run the macro. I have found it handy to run the macro fairly regularly, and recommend assigning a keyboard shortcut to it.

If you find this macro useful, if you have problems with it, or if you have suggestions for improvements, please let me know.


The Code

 

Sub SortStyleSheet()
'Recommended shortcut: ALT+1
Dim i As Paragraph
Dim sortrange As Range
flag = 0
'flag value: 0=no heading yet located; 1=heading located; 2=entries to sort located
Selection.Collapse Direction:=wdCollapseEnd
  For Each i In ActiveDocument.Paragraphs
        If i.Style.NameLocal = "Style Sheet Heading" Then
            If flag = 2 Then
            While (Asc(Selection.Characters.Last) = 13) Or (Asc(Selection.Characters.Last) = 32)
                Selection.MoveEnd Unit:=wdCharacter, Count:=-1
            Wend
                 If Len(Trim(Selection.Text)) > 1 Then Selection.Sort SortOrder:=wdSortOrderAscending
                 flag = 1
            Else
                 flag = 1
            End If
        Else
           If flag = 1 Then
              Set sortrange = i.Range
              sortrange.Select
              flag = 2
              Else
              If flag = 2 Then
                 Selection.MoveDown Unit:=wdParagraph, Count:=1, Extend:=wdExtend
              End If
           End If
        End If
    Next
    While (Asc(Selection.Characters.Last) = 13) Or (Asc(Selection.Characters.Last) = 32)
           Selection.MoveEnd Unit:=wdCharacter, Count:=-1
    Wend
    If flag = 2 Then
        If Len(Trim(Selection.Text)) > 1 Then Selection.Sort SortOrder:=wdSortOrderAscending
    End If
 End Sub

Automating a Style Sheet (Part 1)

I recently came across the StyleThat macro, which facilitates quickly copying terms from a manuscript to a style sheet. It is incredibly useful, in that it not only copies selected terms but also places them into alphabetical categories. However, after playing with it for a while I noticed that it had a few weak points. My version of the macro (appearing at the bottom of this post) tries to address the following weaknesses in the original through some judicious code tweaking.

1) When the original macro pasted content, it retained its original format.  I added code that removes all formatting, assuming that it is easier to manually reformat a few entries (such as titles of works) than it is to manually unformat a large number of entries.

2) If the selected text includes a trailing line break or space, the original macro included these characters in the pasted entry. To help keep style sheet content clean, I added code to delete any trailing hard returns and spaces.

3) The original macro only worked with style sheets that contain specific headings (described below), which are defined within the macro. I added code to place copied content at the bottom of the style sheet if one of these headings can’t be found (or if the style sheet doesn’t contain any headings). This allows use of a blank word document as a style sheet.

4) The original only works correctly if two documents are open: the manuscript and the style sheet.  While this limitation remains in my version, I added code to notify the user if the macro is run while more than or less than two documents are open.

5) The original macro places all entries that don’t start with a letter under a “Comments:” heading. I adjusted the name of this heading to “Numbers/Other” to more clearly describe its content.

One remaining weakness of the macro that it doesn’t sort entries within each category into alphabetical order. However, in Automating your Style Sheet, Part 2 I provide a stand-alone macro that takes care of this.

Using the macro is very simple, particularly if a keyboard shortcut is assigned to it:

1) Open the manuscript and a style sheet that contains the following headings: ABCD, EFGH, IJLK, MNOP, QRST, UVWXYZ, and Numbers/Other.

2) Select a term in the manuscript and run the macro. It will switch focus from the manuscript to the style sheet and paste the term under the appropriate heading (or at the end of the document if no matching heading is found).

3) Run the macro again and it will switch focus back to the manuscript (this feature is very handy if a keyboard shortcut is assigned).

 I would like to thank Jack Lyon at The Editorium for permission to revise his original StyleThat macro. If you find either version particularly useful, please feel free to let us know.


The Code


Sub StyleThatV2()
'Macro adapted by Hilary Powers 1/30/04; updated 4/6/04
'Adapted by Jack M. Lyon for use with editorial style sheet
'Adapted by Michael Schuler 6/4/2015 to expand functions
'Recommended shortcut: ALT+`
iNumWindows = Application.Windows.Count
If iNumWindows <> 2 Then
    MsgBox ("This macro only works if two documents (the source document and the stylesheet) are open.")
    GoTo Final
End If

If Selection.Type = wdSelectionIP Then  'No selection
    GoTo HedBack
Else
    While (Asc(Selection.Characters.Last) = 13) Or (Asc(Selection.Characters.Last) = 32)
        Selection.MoveEnd Unit:=wdCharacter, Count:=-1
        If Selection.Type = wdSelectionIP Then GoTo Final
    Wend
    FirstChar = Asc(Selection.Characters.First)
    If FirstChar > 64 And FirstChar < 69 Then MySearch = "ABCD^p"
    If FirstChar > 68 And FirstChar < 73 Then MySearch = "EFGH^p"
    If FirstChar > 72 And FirstChar < 77 Then MySearch = "IJKL^p"
    If FirstChar > 76 And FirstChar < 81 Then MySearch = "MNOP^p"
    If FirstChar > 80 And FirstChar < 85 Then MySearch = "QRST^p"
    If FirstChar > 84 And FirstChar < 91 Then MySearch = "UVWXYZ^p"
    If FirstChar > 96 And FirstChar < 101 Then MySearch = "ABCD^p"
    If FirstChar > 100 And FirstChar < 105 Then MySearch = "EFGH^p"
    If FirstChar > 104 And FirstChar < 109 Then MySearch = "IJKL^p"
    If FirstChar > 108 And FirstChar < 113 Then MySearch = "MNOP^p"
    If FirstChar > 112 And FirstChar < 117 Then MySearch = "QRST^p"
    If FirstChar > 116 And FirstChar < 123 Then MySearch = "UVWXYZ^p"
    If FirstChar > 90 And FirstChar < 97 Then MySearch = "Numbers/Other^p"
    If FirstChar < 65 Or FirstChar > 122 Then MySearch = "Numbers/Other^p"
    Selection.Copy
    WordBasic.NextWindow
    WordBasic.StartOfDocument
    Selection.Find.ClearFormatting
    With Selection.Find
        .Text = MySearch
        .Forward = True
        .Wrap = wdFindStop
        .Format = False
        .MatchCase = True
        .MatchWholeWord = False
        .MatchAllWordForms = False
        .MatchSoundsLike = False
        .MatchWildcards = False
    End With
    If Selection.Find.Execute Then
        Selection.MoveRight
    Else
        Selection.EndKey Unit:=wdStory
    End If
    Selection.Paste
    Selection.TypeParagraph
    Selection.MoveLeft Count:=1
    Selection.HomeKey Unit:=wdLine
    Selection.MoveEnd Unit:=wdLine
    With Selection
        .ClearFormatting
    End With
    Selection.Collapse Direction:=wdCollapseEnd
    GoTo Final
End If
HedBack:
WordBasic.NextWindow
Selection.MoveRight Unit:=wdCharacter, Count:=1
Final:
End Sub