Input, control and automation

Tuesday, 8 September 2015

VBA: Test if style exists in Word document

06:51 Posted by Roxton , , 3 comments
Frustratingly, there isn't a native function for testing whether or not a particular style exists in a Word document or template. The most direct and obvious way to work this out is to loop through all the styles in the document, thus:
Dim style As Word.Style

For Each style In ActiveDocument.Styles
    If style = "style_to_test" Then
        Debug.Print "style_to_test exists in this document"
        Exit For
    End If
Next style
While this works, it's extremely slow. I don't mean that in the special "if you run this a million times it will add twelve microseconds to your process" sense of "slow" reserved for quants and 4K gamers, either: for some reason it can take Word a good half-second or so to retrieve the information for each style in your loop, so if you have a document with a hundred styles it can take about a minute for VBA to do something that you could visually check in a couple of seconds.

If you want to speed things up, you'll have to resort to error handling. I know, I know, it's terribly bad manners, but I think it's justified here - rather like police officers wearing made-up ties. I've tried a few different approaches to style errors, and I think this is the fastest and least likely to crash:
Dim testStyle as Word.Style

On Error Resume Next
Set testStyle = ActiveDocument.Styles(style_to_test)
if testStyle is nothing then
    debug.print "style_to_test is not in the document"
else
    debug.print "style_to_test is in the document"
end if
On Error Goto 0    'Or whatever error handler you were using before

Because this is code I tend to use quite frequently, I find it easier to bundle it up into a boolean-returning function:
Function styleExists(ByVal styleToTest As String, ByVal docToTest as Word.Document) As Boolean
    Dim testStyle as Word.Style
    On Error Resume Next
    Set testStyle = docToTest.Styles(styleToTest)
    styleExists = Not testStyle Is Nothing
End Function
The other nice thing about using a function is that you don't have to worry about resetting your error handling; the On Error Resume Next setting is contained within the function. Now we have our function, we can use it whenever we need to check a style:
    ...
    If styleExists(myStyle,ActiveDocument) = True Then
        'Do some tests involving myStyle
    End If
    ...

3 comments:

  1. Thank you. Nice solution. I have not compared it yet, but you found looping the styles list of the document to slow?

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Well, I was to quick to ask. The answer is yes; looping through the styles is way slower.

    ReplyDelete