Automated Letter-by-Letter Index Sorting

August 21, 2002 – 12:00 pm

Last week’s newsletter explained how to sort Word’s index entries letter by letter rather than word by word:

http://www.topica.com/lists/editorium/read/message.html?mid=1706922855

But it didn’t explain how to do it in an automated way. So here’s an automated way, using wildcard Find and Replace. You can learn more about using wildcards in some of our past newsletters:

http://www.topica.com/lists/editorium/read/message.html?mid=1705963026

http://www.topica.com/lists/editorium/read/message.html?mid=1706069286

http://www.topica.com/lists/editorium/read/message.html?mid=1706069286

http://www.topica.com/lists/editorium/read/message.html?mid=1706069286

http://www.topica.com/lists/editorium/read/message.html?mid=1706365638

http://www.topica.com/lists/editorium/read/message.html?mid=1706458823

Here’s the procedure, which you can record as a macro for future use. Or, better yet, just use the prerecorded macro I’ve included at the end of this article. Work through the procedure if you want to know more about using complicated searches, or if you just want to see how my devious little mind works. (There’s probably a better way to do all this using Visual Basic for Applications, but that’s a subject for another day.)

1. Make sure your index entries are visible by showing hidden text (Tools > Options > View > Hidden text).

2. Find the index entries and replace them with themselves colored as, say, plum, so your Find and Replace won’t move across entry borders later:

Find What:

(XE “*”)

Replace With:

\1 (formatted as plum)

Use Wildcards:

Checked

3. Replace escaped colons and quotation marks with arbitrary symbols to be changed back later (”escaped” means they have a backslash in front of them, telling Word to treat them as characters, which is how you can use colons and quotation marks in your index entries!):

Find What:

\:

Replace With:

&&&

Use Wildcards:

Unchecked

Find What:

\”

Replace With:

@@@

Use Wildcards:

Unchecked

4. Put a colon after main-only (but actually, after all) entries:

Find What:

(XE “*)(”)

Replace With:

\1:\2

Use Wildcards:

Checked

5. Find plum-colored, multiple-word index entries and enter semicolon entries, going from three spaces to one space, which ought to be enough for anybody (and besides, Word can only handle up to five “Find What Expression” wildcards):

Find What:

(XE “)([! :]@) ([! :]@) ([! :]@) ([! :]@): (formatted as plum)

Replace With:

\1\2 \3 \4 \5;\2\3\4\5:

Use Wildcards:

Checked

Find What:

(XE “)([! :]@) ([! :]@) ([! :]@): (formatted as plum)

Replace With:

\1\2 \3 \4;\2\3\4:

Use Wildcards:

Checked

Find What:

(XE “)([! :]@) ([! :]@): (formatted as plum)

Replace With:

\1\2 \3;\2\3:

Use Wildcards:

Checked

6. Clean up colons at ends of entries:

Find What:

(XE “*):(”) (formatted as plum)

Replace With:

\1\2 (formatted as Automatic, which gets rid of all plum)

Use Wildcards:

Checked

7. Restore escaped colons and quotation marks, if any:

Find What:

&&&

Replace With:

\:

Use Wildcards:

Unchecked

Find What:

@@@

Replace With:

\”

Use Wildcards:

Unchecked

Now move to the bottom of your document and have Word generate your index (Insert > Index and Tables > Index). Well, look at that: The entries are sorted letter by letter. Neat!

If you want to work manually, you can insert a semicolon and alternate spelling after a main index entry to force Word to sort in any way you like. For example, let’s say you’ve got some numbers in your index, ordered like this:

8123

835

86

Ordinarily, that’s how they’d sort. But if you edit your index entries like this–

{XE “835;0835″}

{XE “86;0086″}

{XE “8123;8123″}

–you’ll make them sort like this:

86

835

8123

If you really wanted to, you could even do something weird like this–

{XE “Zebra;1″}

–and force “Zebra” to the top of your index.

Pretty handy, no? At any rate, you now have an automated way to sort Word’s index entries letter by letter. Enjoy!

Here’s the prerecorded macro to make index entries sort letter by letter. If you don’t know how to use such macros, you can find out here:

http://www.topica.com/lists/editorium/read/message.html?mid=1706922855

‘MACRO STARTS HERE

Sub IndexEntriesLetterByLetter()


‘ IndexEntriesLetterByLetter Macro

‘ Macro recorded 8/21/2002 by Jack M. Lyon


Selection.HomeKey Unit:=wdStory

Selection.Find.ClearFormatting

Selection.Find.Replacement.ClearFormatting

Selection.Find.Replacement.Font.Color = wdColorPlum

With Selection.Find

.Text = “(XE “”)([! :]@) ([! :]@):”

.Replacement.Text = “\1\2 \3;\2\3:”

.Forward = True

.Wrap = wdFindContinue

.Format = True

.MatchCase = False

.MatchWholeWord = False

.MatchAllWordForms = False

.MatchSoundsLike = False

.MatchWildcards = True

End With

Selection.Find.ClearFormatting

Selection.Find.Replacement.ClearFormatting

Selection.Find.Replacement.Font.Color = wdColorPlum

With Selection.Find

.Text = “(XE “”*”")”

.Replacement.Text = “\1″

.Forward = True

.Wrap = wdFindContinue

.Format = True

.MatchCase = False

.MatchWholeWord = False

.MatchAllWordForms = False

.MatchSoundsLike = False

.MatchWildcards = True

End With

Selection.Find.Execute Replace:=wdReplaceAll

Selection.Find.ClearFormatting

Selection.Find.Replacement.ClearFormatting

With Selection.Find

.Text = “\:”

.Replacement.Text = “&&&”

.Forward = True

.Wrap = wdFindContinue

.Format = False

.MatchCase = False

.MatchWholeWord = False

.MatchWildcards = False

.MatchSoundsLike = False

.MatchAllWordForms = False

End With

Selection.Find.Execute Replace:=wdReplaceAll

With Selection.Find

.Text = “\”"”

.Replacement.Text = “@@@”

.Forward = True

.Wrap = wdFindContinue

.Format = False

.MatchCase = False

.MatchWholeWord = False

.MatchWildcards = False

.MatchSoundsLike = False

.MatchAllWordForms = False

End With

Selection.Find.Execute Replace:=wdReplaceAll

Selection.Find.ClearFormatting

Selection.Find.Replacement.ClearFormatting

With Selection.Find

.Text = “(XE “”*)(”")”

.Replacement.Text = “\1:\2″

.Forward = True

.Wrap = wdFindContinue

.Format = False

.MatchCase = False

.MatchWholeWord = False

.MatchAllWordForms = False

.MatchSoundsLike = False

.MatchWildcards = True

End With

Selection.Find.Execute Replace:=wdReplaceAll

Selection.Find.ClearFormatting

Selection.Find.Font.Color = wdColorPlum

Selection.Find.Replacement.ClearFormatting

With Selection.Find

.Text = “(XE “”)([! :]@) ([! :]@) ([! :]@) ([! :]@):”

.Replacement.Text = “\1\2 \3 \4 \5;\2\3\4\5:”

.Forward = True

.Wrap = wdFindContinue

.Format = True

.MatchCase = False

.MatchWholeWord = False

.MatchAllWordForms = False

.MatchSoundsLike = False

.MatchWildcards = True

End With

Selection.Find.Execute Replace:=wdReplaceAll

Selection.Find.ClearFormatting

Selection.Find.Font.Color = wdColorPlum

Selection.Find.Replacement.ClearFormatting

With Selection.Find

.Text = “(XE “”)([! :]@) ([! :]@) ([! :]@):”

.Replacement.Text = “\1\2 \3 \4;\2\3\4:”

.Forward = True

.Wrap = wdFindContinue

.Format = True

.MatchCase = False

.MatchWholeWord = False

.MatchAllWordForms = False

.MatchSoundsLike = False

.MatchWildcards = True

End With

Selection.Find.Execute Replace:=wdReplaceAll

Selection.Find.ClearFormatting

Selection.Find.Font.Color = wdColorPlum

Selection.Find.Replacement.ClearFormatting

With Selection.Find

.Text = “(XE “”)([! :]@) ([! :]@):”

.Replacement.Text = “\1\2 \3;\2\3:”

.Forward = True

.Wrap = wdFindContinue

.Format = True

.MatchCase = False

.MatchWholeWord = False

.MatchAllWordForms = False

.MatchSoundsLike = False

.MatchWildcards = True

End With

Selection.Find.Execute Replace:=wdReplaceAll

Selection.Find.ClearFormatting

Selection.Find.Font.Color = wdColorPlum

Selection.Find.Replacement.ClearFormatting

Selection.Find.Replacement.Font.Color = wdColorAutomatic

With Selection.Find

.Text = “(XE “”*):(”")”

.Replacement.Text = “\1\2″

.Forward = True

.Wrap = wdFindContinue

.Format = True

.MatchCase = False

.MatchWholeWord = False

.MatchAllWordForms = False

.MatchSoundsLike = False

.MatchWildcards = True

End With

Selection.Find.Execute Replace:=wdReplaceAll

Selection.Find.ClearFormatting

Selection.Find.Replacement.ClearFormatting

With Selection.Find

.Text = “(XE “”*):(”")”

.Replacement.Text = “\1\2″

.Forward = True

.Wrap = wdFindContinue

.Format = False

.MatchCase = False

.MatchWholeWord = False

.MatchWildcards = False

.MatchSoundsLike = False

.MatchAllWordForms = False

End With

Selection.Find.ClearFormatting

Selection.Find.Replacement.ClearFormatting

With Selection.Find

.Text = “&&&”

.Replacement.Text = “\:”

.Forward = True

.Wrap = wdFindContinue

.Format = False

.MatchCase = False

.MatchWholeWord = False

.MatchWildcards = False

.MatchSoundsLike = False

.MatchAllWordForms = False

End With

Selection.Find.Execute Replace:=wdReplaceAll

With Selection.Find

.Text = “@@@”

.Replacement.Text = “\”"”

.Forward = True

.Wrap = wdFindContinue

.Format = False

.MatchCase = False

.MatchWholeWord = False

.MatchWildcards = False

.MatchSoundsLike = False

.MatchAllWordForms = False

End With

Selection.Find.Execute Replace:=wdReplaceAll

End Sub

‘MACRO ENDS HERE

_________________________________________

READERS WRITE

The newsletter for July 31 explained how to make punctuation easier to see by formatting it as big, bold, and red; the following newsletter offered some reader tips on doing so; and last week’s newsletter included a terrific macro by Phil Rabichow to automate the process.

This week, Steve Hudson provides a similar macro as an exercise in Visual Basic programming (and of course, it’s useful, too!). It’s a toggle, so you’ll probably want to put the subroutine named SomeToolbarNameToggleBigPunctuation() on a toolbar button for easy access. You can learn how to do this here:

http://www.topica.com/lists/editorium/read/message.html?mid=1707286867

As you look through the macro, pay particular attention to Steve’s comments, which explain what’s going on. The macro is an excellent example of VBA, including find loops, wildcard matching, range objects, optional parameters, design analysis, and much more. Actually, the whole macro has many left-of-center concepts–for example, a Find that can return nothing yet still not have finished (it picks up the Chr$(7) that marks a table start, which can’t be included in the wildcard entry). The macro also nicely changes the cursor and screen updating, and it backs out formatting changes. Steve is a master at this kind of stuff, so get ready to learn something. And why not contact Steve to take care of your custom programming needs?

By the way, you’ll note Steve’s humor throughout. Here is Steve’s commentary, edited slightly by me to fit the context of this newsletter:

The past newsletters found and formatted punctuation by inclusion, which rules out Unicode and the like. So I figured a macro would be better with punctuation by exclusion in order to show up all sorts of strange dweebs.

The second problem was your suggestion to create a temporary style that mucks my document up with no subsequent hint of destruction.

The third was “How do I reverse this?” If I have a formula in character styling and another elsewhere in terminal screen, I can’t find this style and kill it dead with a known something else. So I have to transpose my edits to have a safe working practice. Ack.

The fourth problem was not acknowledging No Proofing on styles.

So the first one is easy enough, we simply start the square brackets formula for the find with a ! and then what we are not interested in. Thus the string for a trivial solution is [!A-Za-z0-9^160]. Note the ^160 for the nonbreaking space; Word honours the ole caret at a higher priority than anything else. Basically, this finds anything *except* a letter, a number, or a nonbreaking space, but I’ve added additional characters in the macro itself.

The second is also easy. We all use STYLES like good little folk, so let’s keep those in place and add–oooo–MANUAL FORMATTING. We can hunt it down and undo it easy enough later by resetting that range to its underlying style again, so it’s a temporary aberration for our temporary aberration. That’s the third taken care of as well.

Now, the fourth and last–is there any way we can tell the Find to do only those styles with proofing set? Err, no. So we have to check this ourselves manually. :-( Word’s find falls down spectacularly with stuff like this. Easy enough, and should be faster as we are doing less styling work, which is expensive.

Now some little style notes–I prefer to use ranges and let the users have their selection object. It may be faster running selection.finds, dunno, duncare :-) It makes the resulting code smaller and easier to read and allows me sick puns–the last being the most important reason of course. What’s the use of knowing all this junk if you can’t have fun with it, I say. I know that some folks hate nonstandard variable naming, but I like code that is human readable.

Next, always reset stuff back to the way it was. If users do a find, do they want your settings?

‘MACRO STARTS HERE

Public Sub SomeToolbarNameToggleBigPunctuation()

‘Attach this to a button on a toolbar

‘we use the toolbar name to start the sub so we know where

‘this sub is called from

Static Toggle As Boolean

Toggle = Not Toggle

ProofReadBigPunctuation Toggle

End Sub

Public Sub ProofReadBigPunctuation(MakeBig As Boolean, Optional Scope As Range)

‘$——–
Author: heretic [at symbol] tdfa.com

‘$Short: If makebig is true, it makes punctuation marks BIG

‘to aid proofreading as discussed by Editmeister Jack.

‘If makebig is false, it removes this formatting

‘$Known issues: Destroys original doc highlighting IF

‘highlighting is used in the formatting process.

Dim HomeOnThe As Range ‘Our findermatic

Dim Finished As Boolean

Dim Progress As Double ‘enough space for calcs in big dox

‘Be nice, don’t assume system settings

Dim Cursor_pholder As WdCursorType

Dim ScreenUpdating_pholder As Boolean

‘frilly bits: change the cursor whilst we work!

Cursor_pholder = System.Cursor

System.Cursor = wdCursorWait

‘freeze the screen to speed things up

ScreenUpdating_pholder = Application.ScreenUpdating

Application.ScreenUpdating = False

‘This basic technique can be used in as many ways as Bill

‘has bux.

‘________________________________

‘Give our range a document range to hang off.

‘The first .dupe is strictly speaking unnecc but a good habit

‘to get into with range objects–the second one prevents us

‘changing the passed scope without realising it!

‘We avoid the other parts of the document by setting our

‘ranges parent to be the range that is the content only.

‘I regularly use Activedocument.Content too.

‘Also note how we deal with no explicit scope being passed

‘from that Optional parameter

If Scope Is Nothing Then Set Scope = _

ActiveDocument.StoryRanges(wdMainTextStory).Duplicate

Set HomeOnThe = Scope.Duplicate

‘Collapse our range to a point at the start of the doc

‘main body content, just like a cursor in a virgin document.

HomeOnThe.Collapse

‘We don’t have to clearformatting or anything as it’s

‘a whole new range. Just set up the find

‘$Customize: the ! means NOT anything in the following list

With HomeOnThe.Find

‘note we don’t use If MakeBig = True then

If MakeBig Then ‘errant chars

.Text = “[! 0-9A-Za-z^9^12^13^160]” ‘$Customize

.MatchWildcards = True

Else ‘$Customize: formatting

With .Font

.Color = wdColorRed

.Bold = True

End With

.Highlight = True

End If

End With

‘Get started on a standard manual processing find loop.

While Not Finished

‘let the poor user know where we are at

Progress = Int(HomeOnThe.End * 100 / Scope.End)

Application.StatusBar = “Restyling ” & Format(Progress) & “%”

‘ensure the statusbar change gets through

DoEvents

‘the find!

With HomeOnThe.Find

.Execute Replace:=wdReplaceNone

Finished = Not .Found

End With

‘Our range is now either null, meaning nothing found

‘or it contains a range for us to examine

If Not Finished Then ‘we caught one!

If MakeBig Then ’style if proofing on

If Not ActiveDocument.Styles(HomeOnThe.Style).NoProofing Then _

FormatFontGruesome HomeOnThe

Else ‘unstyle

HomeOnThe.Font.Reset

HomeOnThe.HighlightColorIndex = wdNoHighlight

End If

End If

HomeOnThe.Collapse wdCollapseEnd ’so we keep moving along

Wend ‘finished

‘destroy our objects

Set HomeOnThe = Nothing

‘reset our changes

Application.ScreenUpdating = ScreenUpdating_pholder

System.Cursor = Cursor_pholder

Application.StatusBar = “Finished”

End Sub

Private Sub FormatFontGruesome(Scope As Range)

‘$Short: to make shtuff shtand out shorty, you

‘gotta problem wid dat?

‘$Customize: don’t forget to keep this matched with the

‘find requirements for the undo

‘I don’t like the thought of changing font name

‘as that could change the displayed character

‘Lets just make it BIG, BOLD and RED on a YELLOW background

With Scope.Font

.Color = wdColorRed

.Bold = True

.Grow

.Grow

.Grow

End With

Scope.HighlightColorIndex = wdYellow

End Sub

Sub TestProofReadBigPunctuationOn()

Dim i As Long

Application.ScreenUpdating = False

Documents.Add

DoEvents

For i = 27 To 1200

Selection.InsertAfter ChrW(i)

Next i

ProofReadBigPunctuation True

Application.ScreenUpdating = True

End Sub

Sub TestProofReadBigPunctuationOnSimple()

‘run this on any trial doc to be sure

ProofReadBigPunctuation True

End Sub

Sub TestProofReadBigPunctuationOff()

ProofReadBigPunctuation False

End Sub

‘MACRO ENDS HERE

Many thanks to Steve for the macro and for the tutorial.

_________________________________________

RESOURCES

If you’re looking for indexing resources, don’t miss those supplied by the School of Library, Archival and Information Studies at the University of British Columbia:

http://www.slais.ubc.ca/resources/indexing/index.htm

_____________________________________________________

THE FINE PRINT

Editorium Update (ISSN 1534-1283) is published by:

The EDITORIUM, LLC

Microsoft Word Add-Ins for Publishing Professionals

http://www.editorium.com

Copyright © 2008 by the Editorium. All rights reserved. Editorium Update and Editorium are trademarks of the Editorium.

You may forward copies of Editorium Update to yourself and others (but not charge for it) and print or store it for your own use. Any other broadcast, publication, retransmission, copying, or storage, without written permission from the Editorium, is prohibited. Send reprint requests to reprints [at symbol] editorium.com

Editorium Update is provided for informational purposes only and without a warranty of any kind, either express or implied, including but not limited to implied warranties of merchantability, fitness for a particular purpose, and freedom from infringement. The user assumes the entire risk as to the accuracy and use of this document.

The Editorium is not affiliated with Microsoft Corporation.

_____________________________________________________

HOW TO SUBSCRIBE OR UNSUBSCRIBE

To subscribe, send a blank email message to editorium-subscribe [at symbol] topica.com.

To unsubscribe, send a blank email message to editorium-unsubscribe [at symbol] topica.com.

We do not sell, rent, or give our subscriber list to anyone.

____________________________________________________

You must be logged in to post a comment.