first_page

Automating Find Operations in Word 2003

My .NET ‘disclaimer’: as long as the word Interop is relevant to Office System Word 2003 then the following discussion featuring VBA code is relevant.

The official overview of Find operation automation distinguishes between using Selection.Find() and Range.Find(). The former resembles what goes on when this operation is run manually in the user interface. Including the latter, WordForums.com summarizes from the Google cache:

Note for those already familiar with VBA: whereas if you use Selection.Find, you have to specify all of the Find and Replace parameters, such as .Forward = True, because the settings are otherwise taken from the Find and Replace dialog’s current settings, which are “sticky”, this is not necessary if using Range.Find—where the parameters use their default values if you don’t specify their values in your code…

The Execute() method of Selection.Find behaves just like what happens when the Find Again button is pressed in the Find/Change dialog. The same does not appear to the case for the Execute() method of Range.Find. So far when I set .Wrap = wdFindContinue I am getting an endless loop in this design:

Sub test() Dim objColl As VBA.Collection Dim objFind As Word.Find Dim objRange As Word.Range Set objFind = ActiveDocument.Content.Find With objFind .Forward = True .Wrap = wdFindContinue .Text = "avatar" End With Set objColl = New VBA.Collection Do While objFind.Execute = True Set objRange = objFind.Parent Call objColl.Add(objRange) Loop End SubNot only will this loop endlessly but it will also not ‘move’ to the next Range when the Execute() method is called. This means only the Range of the first match is loaded—over and over again—into the Collection of Range objects. Barring any glaring lack of information in my mind, it appears that the Execute() method of Range.Find should only be involved in replace operations and should never be used in a loop. (Also: in the example above note the strange use of the Parent property—Set objRange = objFind.Parent—this remains a mystery to me.) Anyway, this not-fun, not-challenging, black-box, problem is sucking my life away wasting vast amounts of time (which explains I appear so angry around Microsoft people) so this appears to be the way to go:

Sub test() Dim objColl As VBA.Collection Dim objFind As Word.Find Dim objRange As Word.Range Set objFind = Application.Selection.Find With objFind .Forward = True .Wrap = wdFindContinue .Text = "avatar" End With Set objColl = New VBA.Collection Do While objFind.Execute = True Set objRange = Selection.Range Call objColl.Add(objRange) Loop End SubThe drawback to this design is that the user will ‘see’ this code running when selections start flying all over the place. Also, note we set objRange with Selection.Range. Using the same line of code from the previous sample throws a ‘type mismatch’ error. I will assume that only a select few people a Microsoft and some serious Word nerds know why this shit happens.

rasx()