Using DoCmd Find & Replace

Started by christianovitch, February 02, 2021, 12:14:45 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

christianovitch

I'm in a line of work where I need to frequently do batch find-and-replace actions on Visio docs.  Since Visio doesn't seem to have an API hook to do this programatically, I think you're left with two options: a) iterate through all shapes and do a string replace operation on the text in each shape (this can be extraordinarily time consuming since many of the Figures I deal with are CAD DXF imports that can sometimes have thousands of lines--each line is its own shape) OR b) use DoCmd(1179) to launch the Find & Replace dialog and use that with SendKeys to enter your find/replace parameters.

I have (a) running, but it can take a long time to run depending on drawing complexity and number of potential substitutions (minutes).  I've noticed that the Find & Replace dialog in Visio is able to do global replace operations *much* quicker (seconds), and while using SendKeys is usually a bad idea since it is hard to control *where* those keys get sent if the focus changes, it seems like the speed improvement might make it worth exploring. 

I wrote a routine that launches the Find & Replace dialog (Application.DoCmd(1179)) and then uses SendKeys to navigate through and set the various options and then launch the Find & Replace.  It almost works--the issue is that it doesn't seem to be able to do the first find & replace operation--I think because the find & replace dialog does not have the focus when the SendKeys operation to launch it is done.  If I click "cancel" on the Find & Replace dialog after the code first causes it to be brought up (thus transferring focus back to it), then the code works perfectly after that.

I should mention that this is an Excel VBA application that grabs an open Visio document; the find/replace substitutions are listed in the Excel file.  So it's a Forms application in Excel that is controlling operation of an open Visio instance.  I tried adding AppActivate vsDoc.name both before/after the DoCmd, but it didn't seem to do anything.

    Set vs = GetObject(, "Visio.Application")
    Set vsDoc = vs.Documents(vsFile)
    For x = 2 To LastRow                'Last row of excel worksheet.
        If sht.Cells(x, 2) <> "" Then
            vs.DoCmd (1179)             'Launch Find & Replace dialog.
            SendKeys "%n"               'Go to Find text field.
            SendKeys sht.Cells(x, 2)    'Enter Find text.
            SendKeys "%i"               'Go to Replace text field.
            SendKeys sht.Cells(x, 3)    'Enter Replace text.
            SendKeys "%a"               'Select All Pages.
            SendKeys "%l"               'Find & Replace All.
            SendKeys "{ESC}"            'Clear Completion pop-up dialog.
            SendKeys "{ESC}"            'Close out Find & Replace dialog.
        End If
    Next x


Any suggestions would be much appreciated.

Cheers,
Christian

Paul Herber

If you try your search on a normal Visio shape you might well find it works. There is a difference with imported DXF shapes in that they are imported as grouped shapes, with every little piece a separate sub-shape, including every individual character of the text. Therefore that shape that seems to have the text "Hello" actually contains 5 shapes, one with an "H", one with an "e" etc.
Electronic and Electrical engineering, business and software stencils for Visio -

https://www.paulherber.co.uk/

christianovitch


My "slow" algorithm actually deliberately crawls through all groups and iterates through every shape on every page--part of why it is so slow.  It does this since there is no guarantee that the text to be replaced won't be buried multiple levels down in a set of grouped shapes.  When I import CAD data, I also convert it to Visio shapes since I need to be able to edit it.

Is there a way to inherently discern between a shape that was drawn in Visio as opposed to imported?  That might help, as the text is almost always part of shapes that are added to the CAD drawings after import.

Of course, if Microsoft would just fix the API and put the hooks in for Find & Replace (like in every other Office program!), then this would be a snap.