Posts Tagged ‘macros’

h1

Word: Macro to set the language for ALL styles

September 21, 2018

One of the issues with setting the language for a Word document is that DOESN’T change the language set for the styles. If you’re lucky, your styles use the same language as your default language, but sometimes they don’t (especially if the document has come from authors in other countries). This can result in some strange behaviour under specific circumstances.

I have a macro for setting the language for all ‘ranges’ in a document, but I needed something to change the language settings for ALL styles in one command. After a bit of internet sleuthing, I came across an answer that looked promising and modified it to suit my purposes. It works! I tested it on a sample document, where I’d set the language for Normal to Alsatian, for Heading 1 to Afrikaans, and for Heading 2 to English (US). The only text I had in the document used Normal style, but that didn’t matter—the language settings for the styles still changed to the one I’d specified in the macro. In my case, that’s English (Australian) [in VBA code that’s wdEnglishAUS].

The only thing you need to change in this macro is the LanguageID. Here are some common ones for English:

  • wdEnglishAUS
  • wdEnglishCanadian
  • wdNewZealand
  • wdEnglishSouthAfrica
  • wdEnglishUK
  • wdEnglishUS.

Here’s the macro (copy it—some of it may go off the page, so if you type it you may miss some):

Sub ChangeLangStyles()

' Macro to change language in styles
' Adapted from Macropod (17 July 2012)
' http://www.vbaexpress.com/forum/showthread.php?42993-Solved-Macro-to-change-all-styles-to-a-specific-language

Dim oDoc As Document, oSty As Style
Set oDoc = ActiveDocument
    With oDoc
        For Each oSty In .Styles
            On Error Resume Next
            oSty.LanguageID = wdEnglishAUS
            On Error GoTo 0
        Next
    End With
End Sub

I adapted it from one shared by Macropod back in July 2012: http://www.vbaexpress.com/forum/showthread.php?42993-Solved-Macro-to-change-all-styles-to-a-specific-language, and full acknowledgement goes to him.

[Links last checked September 2018]

h1

Word: Macro to convert from one style to another

September 11, 2018

I should have hunted this out years ago. My main client has a habit of changing templates every couple of years, which means the old docs have to go onto the current template when they get revised. It’s a pain and involves quite a few steps (and up to several hours) per document. I still have to do the cover page and headers/footers manually, and all the landscape/portrait sections, but now I’ve got a way to convert styles in the older template to differently named styles in the newer template. For styles with the same name, no such conversion is necessary, but when the old style is called ‘Table Bullet 1’ and the new one is called ‘Table Bullet’ you have to either reapply the correct style everywhere it is used (ugh!), do a global find and replace for the style, or do a ‘select all’ for the style and then click the new style to apply it.

Some caveats:

  • Test first. Test on a COPY of the old document before doing it on the original copy, and any other documents in the set.
  • Make sure you’ve applied the new template to the old document so that the new styles are available in the document. (or, use the Organizer to copy styles across from the old template to the new [longer, slower method]).
  • Make a list of the old styles and the matching, but differently named, new styles—make sure you write down the style names EXACTLY (including any hyphens in the style name) otherwise this macro won’t work.
  • This macro runs a find and replace and replaces ALL. Test first.

Acknowledgements: I modified the macro written by Christina and available from here: https://stackoverflow.com/questions/29953322/changing-styles-in-word-using-vba to suit my client’s situation.

In my modified macro below, several styles used in tables had name changes, as did one for the appendix headings. You can add more for your circumstances—just make sure you add a new ‘Set’ line with a unique name, call that name in a separate ‘With’ statement, and make sure you add that name to the ‘Dim’ statement at the top of the macro.

If you want to use/modify this macro, copy/paste the code below–some of it runs off the page, so if you retype the code you may miss some critical command. Then modify the Set names (if required) and the style names in the double quotes.

Sub FNR_Styles()

' Converts old table and Appendix styles to new using find and replace
' Rhonda Bracey, 11 Sept 2018 (modified from https://stackoverflow.com/questions/29953322/changing-styles-in-word-using-vba [Christina])

Dim objDoc As Document
Dim table1 As Style, table2 As Style, table3 As Style, table4 As Style, app1 As Style

Set objDoc = ActiveDocument
' This code does *NOT* protect against the possibility that these styles don't
' appear in the document. That's probably not a concern with built-in styles,
' but be aware of that if you want to expand upon this for other uses.
' Set up as many of these as you need, giving each a unique name.
' The style name in the quote marks is the NEW style name.
' Make sure you add the name to the second Dim row at the top of the macro as well.

Set table1 = ActiveDocument.Styles("Table Text")
Set table2 = ActiveDocument.Styles("Table Bullet")
Set table3 = ActiveDocument.Styles("Table Heading White")
Set table4 = ActiveDocument.Styles("Table Text Number")
Set app1 = ActiveDocument.Styles("Appendix Heading")

' Searches the entire document (but not foot/endnotes, headers, or footers)
' for the old style and replaces it with the new style.

With objDoc.Content.Find
    .ClearFormatting
    .Style = "Table Text - Left"
    ' The style in the quote marks is the OLD style name
    With .Replacement
    .ClearFormatting
    .Style = table1
    End With
    ' Below is the Replace All command.
    ' Could change this to Replace:=wdReplaceOne to replace one only
   
    .Execute Wrap:=wdFindContinue, Format:=True, Replace:=wdReplaceAll
End With

With objDoc.Content.Find
    .ClearFormatting
    .Style = "Table Bullet 1"
    With .Replacement
    .ClearFormatting
    .Style = table2
    End With
    .Execute Wrap:=wdFindContinue, Format:=True, Replace:=wdReplaceAll
End With
With objDoc.Content.Find
    .ClearFormatting
    .Style = "Table Head - Center"
    With .Replacement
    .ClearFormatting
    .Style = table3
    End With
    .Execute Wrap:=wdFindContinue, Format:=True, Replace:=wdReplaceAll
End With
With objDoc.Content.Find
    .ClearFormatting
    .Style = "Table Text - Number"
    With .Replacement
    .ClearFormatting
    .Style = table4
    End With
    .Execute Wrap:=wdFindContinue, Format:=True, Replace:=wdReplaceAll
End With
With objDoc.Content.Find
    .ClearFormatting
    .Style = "App H1"
    With .Replacement
    .ClearFormatting
    .Style = app1
    End With
    .Execute Wrap:=wdFindContinue, Format:=True, Replace:=wdReplaceAll
 End With

End Sub

 

h1

Word: List keyboard shortcuts, autotext, and autocorrect entries

May 3, 2017

There are many things you can do to help automate the writing and editing process. Power users of Word use keyboard shortcuts extensively — either the in-built ones that come with Word (e.g. Ctrl+s to save, Ctrl+c to copy etc.), or ones they’ve created themselves. Power users also use AutoText and AutoCorrect to speed up inserting commonly used text, tables, etc. (See the links below for some of the blog posts I’ve written on all these.)

But how do you know what you’ve got available to use? Some of the more obscure in-built keyboard commands are difficult to find listed anywhere, and how do you remember which ones you’ve created for your own use? How can you get a list of these shortcuts, and a list of your AutoText and AutoCorrect entries? Of course, once you have a list you can then save it or print it out to refer to at any time.

I used Microsoft Word 2010 for Windows when writing this blog post — the same (or very similar) information should apply to later versions of Word for Windows. Mac users — you may be able to do this too, but as I don’t own a Mac, I can’t test on a Mac or write about Mac stuff.

List all in-built Microsoft Word keyboard commands

  1. Open a blank Word document.
  2. Go to the View tab and click the large Macros icon.
  3. Click the drop-down arrow for the Macros in list, then select Word commands.
  4. Select ListCommands in the top box.
  5. Click Run.

List all custom keyboard commands

  1. Open a Word document that is based on the template where you know the custom keyboard commands are stored (if stored in Normal, just open a blank Word document).
  2. Go to the File tab and select Print.
  3. Under Settings, change from the default Print All Pages to Key Assignments.
  4. Choose your printer (e.g. PDF if you want a document to save), then click Print.

List all AutoText entries

  1. Open a blank Word document.
  2. Go to the File tab and select Print.
  3. Under Settings, change from the default Print All Pages to AutoText Entries.
  4. Choose your printer (e.g. PDF if you want a document to save), then click Print.

List all AutoCorrect entries

Use the macro described here: http://wordribbon.tips.net/T009084_Printing_a_List_of_AutoCorrect_Entries

See also:

[Links last checked May 2017]

h1

Word: Macro to add a value at the beginning of each row of a table

May 2, 2017

I had a strange request — someone had a really long table in Microsoft Word (some 50+ pages long…) and wanted to add an asterisk (star) in front of the first character in each row, no matter how many rows and columns there were in the table or what the original first character in each row was (some first characters were numerals, but most were upper or lower case letters). Doing this manually was going to take hours, and he had several tables across various documents that he wanted to do this to.

My first thought was a find and replace with wildcards routine, but I quickly figured out that I didn’t have enough knowledge to do that, even if it was possible. My next thought was to add a new first column, populate it with asterisks, then merge the first and second columns of each row — the problem was that merging required selecting each pair of 1st and 2nd column cells for EACH row, then merging, then removing the added paragraph mark created by the merge process. That was going to take as long or even longer than adding the asterisks manually!

So I contacted my friend Dave Gash (www.davegash.com), a US-based programmer/tech writer, to see if he could help. His forte isn’t VBA, but he does know programming logic (and he knows what to search for), and by the next morning he had a solution for me. Actually he had a solution that was TOO good — his first solution (Macro 2 below) added the asterisk to the beginning of all rows in ALL tables in the document. But that’s not what my client wanted — he wanted to add asterisks to all rows in a specific table, not every table. A bit of tweaking and Dave came back a few minutes later with the solution that suited my client (Macro 1 below). When I ran it in test mode, the changes were almost instant, but they took about 5 mins on the 50+ page table! That was still many hours less than it would’ve taken manually. I owe Dave a beer or three!

Macro 1: Add an asterisk to the beginning of all rows in a specific table

Sub AddAsteriskToTableRow()
   ' From Dave Gash www.davegash.com April 2017 '
   ' Collapse the range to start so as to not have to deal with '
   ' multi-segment ranges. Then check if cursor is within a table. '

   Selection.Collapse Direction:=wdCollapseStart
   If Not Selection.Information(wdWithInTable) Then
      MsgBox "You can only run this when your cursor is within a table."
      Exit Sub
   End If

   ' Process every row in the current table. '
   Dim row As Integer
   Dim rng As Range

   For row = 1 To Selection.Tables(1).Rows.Count
      ' Get the range for the leftmost cell. '
      Set rng = Selection.Tables(1).Rows(row).Cells(1).Range

      ' For each, insert asterisk in leftmost cell.'
      ' Change value in quote marks if you want something other than an asterisk. '
      rng.InsertBefore ("*")
   Next
End Sub

Macro 2: Add an asterisk to the beginning of all rows in ALL tables in a document

Sub AddAsterisksToAllTables()
    
' From Dave Gash www.davegash.com April 2017
' Loop through all tables
For tbl = 1 To ActiveDocument.Tables.Count
 
    'Set up row and range vars
    Dim row As Integer
    Dim rng As Range
 
    'Loop through rows in current table
    For row = 1 To ActiveDocument.Tables(tbl).Rows.Count
        ' Get the range for the leftmost (column 1) cell
        Set rng = ActiveDocument.Tables(tbl).Rows(row).Cells(1).Range
        ' Insert the asterisk before the text in leftmost cell
        ' Change value in quote marks if you want something
        ' other than an asterisk.
        rng.InsertBefore ("*") 
    Next row 
Next tbl 
End Sub

Notes

  • The examples above use an asterisk as the added character, but you can make that character anything you want — one or more letters or numbers or standard punctuation symbols (or a combination), with or without a space. Just change the value in the double-quotation marks in the macro to what you want (e.g. you might have a list of product numbers that need to have ‘MQ’ added in front of them — change “*” to “MQ” [or “MQ-” or “MQ “]). You might want to change the name of the macro too, to reflect what you’re adding (e.g. AddMQToTableRow).
  • Don’t run this twice in the same table, otherwise you’ll end up with two asterisks!
  • Dave asked me to add this acknowledgement: ‘My source was from a StackOverflow (the coder’s friend, believe me!) member (apparently also from Western Australia!). … I modified the code I found there for your purposes.’ Source: http://stackoverflow.com/questions/7226721/how-can-you-get-the-current-table-in-ms-word-vba

[Links last checked May 2017]

h1

Word: Find and highlight multiple words at once

November 6, 2015

This is a variation on the multiple find/replace macro covered here: https://cybertext.wordpress.com/2015/03/03/word-macro-to-run-multiple-wildcard-find-and-replace-routines/. I suggest you read that post first (and test it) before attempting this one. This post assumes you can already do what’s in that earlier post.

Scenario

The scenario for this one is a little different — the author wanted to find various words in a document and highlight them for probable change. As there were MANY documents she had to process, she needed an easy way to find these words and highlight them. She didn’t want to change them at this stage. The words related to project names, company names, facility names, document number prefixes, etc. One project’s documents were to be the basis of a set of documents for another project in the same company, so one of the tasks was to ‘personalize’ the copies of the original project’s documents with the names used by the new project.

Solution

Although there may be several ways you can do this, I decided to stick with what I already knew. I figured that using a variation of the ReplaceTableWithList macro (as discussed here: https://cybertext.wordpress.com/2015/03/03/word-macro-to-run-multiple-wildcard-find-and-replace-routines/) and a new table called by that macro variation should solve it. And it did.

Step 1: Create your find/replace table

  1. Start a new Word document, and create a two-column table in it.
  2. In the left column, type in the words/phrases you want to find, each on a different row.
  3. In the right column, type \1. (This means that the wildcard find/replace will replace what was found with itself — remember, you’re only trying to identify the words that *may* need changing at this point, not changing them.)
  4. Save the document to this folder, noting the name of the file as you’ll need that later:
    C:\Users\<your_username>\AppData\Roaming\Microsoft\Word\STARTUP.

Step 2: Set up the macro to work with the table

Add the macro below to an existing document, or better, an existing template, or even better, a central macros template that loads whenever you open Word.

Once you’ve added it, change the line that starts with sFname and has the file path — that path points to MY file on MY computer. You need to change it to YOUR file name and YOUR file path.

NOTE: Copy all the code below to the clipboard — it goes off the page, so don’t type it out as you’ll miss some of it or could make a typo.

Sub ReplaceFromTableListName()
' from Doug Robbins, Word MVP, Microsoft forums, Feb 2015, based on another macro written by Graham Mayor, Aug 2010
Dim oChanges As Document, oDoc As Document
Dim oTable As Table
Dim oRng As Range
Dim rFindText As Range, rReplacement As Range
Dim i As Long
Dim sFname As String
'Change the path in the line below to reflect the name and path of the table document
sFname = "C:\Users\rhonda\AppData\Roaming\Microsoft\Word\STARTUP\find_and_replace_routines_names_macro.docx"
Set oDoc = ActiveDocument
Set oChanges = Documents.Open(FileName:=sFname, Visible:=False)
Set oTable = oChanges.Tables(1)

' Make sure highlight is set to the colour you want, e.g. wdYellow, wdBrightGreen, wdPink, wdTurquoise
Options.DefaultHighlightColorIndex = wdTurquoise

For i = 1 To oTable.Rows.Count
 Set oRng = oDoc.Range
 Set rFindText = oTable.Cell(i, 1).Range
 rFindText.End = rFindText.End - 1
 Set rReplacement = oTable.Cell(i, 2).Range
 rReplacement.End = rReplacement.End - 1
 Selection.HomeKey wdStory
 With oRng.Find
 .ClearFormatting
 .Replacement.ClearFormatting
 .MatchWildcards = True
 .Text = rFindText.Text
 .Replacement.Text = rReplacement.Text
 .Replacement.Highlight = True
 .Forward = True
 .Wrap = wdFindContinue
 .Execute Replace:=wdReplaceAll
 End With
Next i
oChanges.Close wdDoNotSaveChanges
End Sub

Step 3: Test that it works

After setting up the ReplaceFromTableListName macro (above), run it on a test document — copy an existing document and test on the copy to make sure you don’t mess up anything.

NOTES:

  • If you get an error message, check that you have the correct file name and path in the macro, AND check that your Word document containing the table that’s called by the macro has no empty rows.
  • If none of the words in your table get highlighted in your document on the first pass, select a highlight colour from the Home tab as though you were going to highlight manually, then run the macro again.
  • If some words are missed, check the table containing them — if a word has an initial capital in the table, but not in the document you are searching (e.g. in a URL), then the macro won’t highlight it. For words that could be capitalized in various ways, either add new lines for each variation, OR search for the part of the word you know won’t be capitalized (e.g. if you were searching for ‘Amazon’, then change the search term in the first column to ‘mazon’ to pick up the word whether it has an initial cap or not).
  • Some areas of your document won’t get highlighted, even if they contain the words you’re looking for — e.g. headers and footers, text boxes. You’ll have to check for these manually.

My author was VERY happy — she had something that only took a few seconds to run and highlighted all the various words she needed to look for.

[Links last checked November 2015]

h1

Word: Macro to run multiple wildcard find and replace routines

March 3, 2015

After some digging around, I’ve found a way to save myself hours of running separate find and replace routines using wildcards in Microsoft Word.

The routines I commonly use already save me time, but now I’ve got one macro that runs them all at once — currently 110 of them that are just for replacing an ordinary space with a non-breaking space!

I didn’t write the macro — that honor goes to Microsoft Word MVPs Graham Mayor who wrote the initial macro, and Doug Robbins who helped me tweak it to do what I wanted it to do. Details are here: http://answers.microsoft.com/en-us/office/forum/office_2003-word/macro-for-performing-more-than-one-find-and/bd931bf7-5ebe-4650-924c-d15c9512129c?page=1

NOTE: EditTools software (http://wordsnsync.com/edittools.php) has a neat interface for setting up your wildcard find and replace routines, along with a facility to set up a script to run them all, and I use that on my own PC. However, I’m not allowed to install that software on my work PC (long story…), so I wanted to figure out a way to emulate what an EditTools script does by creating a macro to achieve the same end.

UPDATE: PerfectIt software (v3 onwards; http://intelligentediting.com) can be customized to include wildcard find/replace routines too, without you having to know anything about macros.

Before doing these steps, you need to be familiar with:

  • accessing the VBA area of Word
  • using wildcards to find and replace in Word.

I won’t cover either of those things in this post.

Step 1: Create a table of your wildcard find/replace routines

The first stage in getting this to work is to create a 2-column table in Word, listing what you want to find in the left column and what you want to replace it with in the right column. Use one row for each find/replace routine. Use the same syntax as you would for a wildcard find/replace.

This table will take a while to set up. You should test each wildcard find/replace routine on a document BEFORE you add it to the list, just to make sure it works correctly and doesn’t mess up anything else. These find/replace routines will all be done as ‘replace all’, so you will NOT have the opportunity to accept some and reject others. Testing is crucial to make sure you don’t replace something you shouldn’t.

In the example below, I’ve set up routines for replacing a standard space between a number and a month of the year with a non-breaking space (^s) between those two elements, as well as replacing a standard space between a number and a unit of measure (e.g. lux, nm) or a word that often follows a number in the documents I work on (e.g. fish, indiv [for ‘individual’ or ‘individuals’). As I said, I have some 110 of these…

widlcard_fr_macro01

Once you’ve created your table, save it to a location that your macro can pick it up from easily — I suggest somewhere on your local drive, not a network location (unless you intend sharing it with others). I put mine in my Word > STARTUP folder, which is where I keep my macros.dotm file.

Step 2: Set up the macro to work with the table

Add the macro below to an existing document, or better, an existing template, or even better, a central macros template that loads whenever you open Word.

Once you’ve added it, change the line that starts with sFname and has the file path — that path points to MY file on MY computer. You need to change it to YOUR file name and YOUR file path.

NOTE: Copy all the code below to the clipboard — it goes off the page, so don’t type it out as you’ll miss some of it or could make a typo.

Sub ReplaceFromTableList()
' from Doug Robbins, Word MVP, Microsoft forums, Feb 2015, based on another macro written by Graham Mayor, Aug 2010
 Dim oChanges As Document, oDoc As Document
 Dim oTable As Table
 Dim oRng As Range
 Dim rFindText As Range, rReplacement As Range
 Dim i As Long
 Dim sFname As String
 'Change the path in the line below to reflect the name and path of the table document
 sFname = "C:\Users\rhonda\AppData\Roaming\Microsoft\Word\STARTUP\find_and_replace_routines_macro.docx"
 Set oDoc = ActiveDocument
 Set oChanges = Documents.Open(FileName:=sFname, Visible:=False)
 Set oTable = oChanges.Tables(1)
 For i = 1 To oTable.Rows.Count
     Set oRng = oDoc.Range
     Set rFindText = oTable.Cell(i, 1).Range
     rFindText.End = rFindText.End - 1
     Set rReplacement = oTable.Cell(i, 2).Range
     rReplacement.End = rReplacement.End - 1
     Selection.HomeKey wdStory
     With oRng.Find
             .ClearFormatting
             .Replacement.ClearFormatting
             .MatchWildcards = True
             .Text = rFindText.Text
             .Replacement.Text = rReplacement.Text
             .Forward = True
             .Wrap = wdFindContinue
             .Execute Replace:=wdReplaceAll
       End With
 Next i
 oChanges.Close wdDoNotSaveChanges
End Sub

Step 3: Test that it works

After setting up the macro, run it on a test document — copy an existing document and test on the copy to make sure you don’t mess up anything.

As my file had 110 find/replace routines for changing some normal spaces to non-breaking spaces, I needed to test it on a document that had many normal spaces for the elements I wanted to change to non-breaking spaces. I opened a copy of an existing 400p Word document, used Word’s normal find/replace to replace all existing non-breaking spaces with a normal space (some 3000 of them in that document I tested it on!). Then I ran the ReplaceFromTableList macro to see if it worked.

It did. Beautifully. And it took about 3 minutes to run ALL those routines on that 400p document. The end result was a document that had more than 5000 non-breaking spaces added to it (I checked the number by taking them all out again and replacing them with normal spaces!).

One 400p Word document, 110 separate find/replace routines. In 3 minutes. In one macro.

That’s gotta be a win for automating tedious, routine tasks! Now, to think about what other find/replace routines I can add to the table…

[Links last checked March 2015]

h1

Word: Macro to replace some hyphens with en dashes

May 16, 2014

I run several find/replace routines on most of the documents I edit. One is to replace <space><hyphen><space> with <space><en dash><space>, and another is to find any number range separated by a hyphen not an en dash (e.g. 2013-2014 or p35-47), and replace the hyphen with an en dash (e.g. 2013–2014, p35–47).

So I decided to automate this process by recording a macro for each find/replace routine, then I combined those macros into one. I could assign a keystroke combination to it, but as I only run it once on each document, there’s probably not a lot of value in doing that. The whole process takes just a few seconds, even on a long document.

CAUTION: If you have numbers legitimately separated by hyphens (e.g. document numbers like 1234-567-890) this macro will replace the hyphens in those numbers with en dashes too, which may not be what you want. A workaround if you only have a few numbers of this type is to run this macro, and then manually change those few it replaced incorrectly.

Here’s the macro:

Sub ReplaceHyphenWithEnDash()
'
' ReplaceHyphenWithEnDash Macro
'
' The first part of this macro replaces space hyphen space
' with space en dash space
    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
' The second part of this macro finds a number range separated 
' by a hyphen and replaces the hyphen with an en dash
    Selection.Find.ClearFormatting
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = "([0-9])(-)([0-9])"
        .Replacement.Text = "\1^=\3"
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchAllWordForms = False
        .MatchSoundsLike = False
        .MatchWildcards = True
    End With
    Selection.Find.Execute Replace:=wdReplaceAll
End Sub

There may be a simpler way to write this macro, but as I’m not a VBA developer and as this worked for me, I’ll leave it as it is!