Visio Guy

Visio Discussions => Programming & Code => Topic started by: jogjer on December 24, 2008, 10:05:39 PM

Poll
Question: Does anyone know how to create a VBA macro to do find and replace
Option 1: No I can't votes: 3
Option 2: No I can't votes: 4
Title: Find and Replace Shape Text in VBA
Post by: jogjer on December 24, 2008, 10:05:39 PM
I once had a macro that did 10 find and replace of shape text of flowcharts
that was written in Visio 2000 (but also worked in 2003). I lost the file
that had this macro and I can't remember how it was created.

A Microsoft technician helped me create it in 2001. I could recreate the user form with textboxes for txtFind1- txtFind10 and corresponding txtReplace1-txtReplace10 with a command button to start the macro's finding and replacing. Does anyone know how to create a macro like this?  I think it used two for next or for each loops.  One for the page and one for shapes.  I tried to recreate it but I couldn't get it to work.

Here is what I tried:


Dim vsoPages As Visio.Pages
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Dim vsoShapes As Visio.Shapes

Set vsoPages = Active.Document.Pages
Set vsoShapes = vsoPages.Shapes
Dim x As String

For Each vsoPage In vsoPages

    For Each vsoShape In vsoShapes
        startPos = FIND(txtFind1, Shape.Text)
        x = Replace(Shape.Text, startPos, Len(txtReplace1), txtFind1, txtReplace1)
        Shape.Text = x
    Next
   
Next
Title: Re: Find and Replace Shape Text in VBA
Post by: Paul Herber on December 26, 2008, 03:28:22 PM
What are you trying to do that isn't more than a couple of minutes work with Edit -> Replace?

Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on December 26, 2008, 06:37:31 PM
I am trying to recreate a macro that does 10 find and replaces at once.  When I created this macro I was reusing flowcharts for reoccuring projects that had certain information change like week numbers, various codes, project numbers, etc.  Since there were many things that changed at once it was much more convenient to change them all at once.  I don't remember exactly how it was written and I lost the copies I had of it.
Title: Re: find and replace shape text in Visio VBA
Post by: Paul Herber on December 26, 2008, 06:48:32 PM
Try putting these week numbers etc into custom properties (shape data) in the document or page ShapeSheet, then link the shapes that need them to those properties. It's then just a matter of changing the data in the custom properties.

Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on December 26, 2008, 07:55:57 PM
For one I don't know how to do that and for the other that limits you to three custom variables and you have to do that for each shape, which would be very time consuming and not something most visio users would be able to do.  I wanted something that anyone could run easily without having to set up custom variables for each shape.
Title: Re: Find and Replace Shape Text in VBA
Post by: wapperdude on December 29, 2008, 08:02:07 PM
Not exactly sure what you're after, but, this macro has the basic construct of your example.  See attached visio drawing, and text file, which constains the macro.  It will change "MyText" with "NewText" in the shape.

HTH
Wapperdude
Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on December 30, 2008, 12:11:15 AM
The change macro looks like it will change the text for one shape, but I want to change the text for all the shapes and all the pages on the document.

In my sample I included only one replace because I was trying to get the one to work (which I wasn't successful at). I want to have 10 replaces in this macro with the find conditions called txtFind1 thru txtFind10 and the replace conditions called txtReplace1 thru txtReplace10.

I don't understand what the swap macro is doing.  I know the old macro had two for loops and / or for each loops (one for page and the other for shapes) and some sort of replace function but I couldn't remember how it selected the text for each shape or how the replace was constructed. 

Using characters would be difficult because you have to number each shape's character.  If you don't know how many shapes you have that would be difficult to get it to work.  Is there a way to do a replace using the shape.text instead of character.text?

I have attached the file (drawing1.vsd) that has the form I created (userform1) and the few tries I took to attempt to recreate this macro.
Title: Re: Find and Replace Shape Text in VBA
Post by: wapperdude on December 30, 2008, 01:27:49 AM
Ah.  Guess I didn't remove the extra macro.   ::)  The text file had the example in question, but it doesn't do the loops.   :(  Try the following:

Sub ChgText()
    Dim vsoPage As Visio.Page, vsoShape As Visio.shape
    Dim vsoCharacters1 As Visio.Characters, vsoStrng As String
   
    For Each vsoPage In ThisDocument.Pages
        For Each vsoShape In vsoPage.Shapes
            Set vsoCharacters1 = vsoShape.Characters
            vsoStrng = vsoCharacters1.Text [/color]                 [color=green]'This step not necessary, vsoCharacters1.Text could be placed directly in the formula on the next line.[/color]
            [color=blue]vsoCharacters1.Text = Replace(vsoStrng, "MyText", "NewText")
        Next
    Next
End Sub

The outer loop should do every page in your Visio document.  The inner loop will do every shape on the page.  You will need to set up your criteria for substitution.

I haven't looked at your drawing yet, wanted to clarify your questions first.  Shape.text just fetches the entire text.  The characters let's you do replacements.  In this case, it is an entire string.  So vsoCharacters1.text is all of the shape text.  Within that body of text, this macro replaces the string MyText with the string NewText.  You can setup as many of these fetch and replace statements as needed.

Sorry for the confusion.   :'(

I'll take a look at your drawing next, but hopefully, there's enough in the above macro to get you on your way.

Wapperdude

Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on December 30, 2008, 05:36:20 AM
I made a few substitutions to fit my form's names but I got an error message with the replace:  compiler error: wrong number of arguments or invalid property assignment.



Private Sub butSubmit_Click()
Dim vsoPage As Visio.Page, vsoShape As Visio.Shape
    Dim vsoCharacters1 As Visio.Characters, vsoStrng, vsoFind, vsoReplace As String
   
    For Each vsoPage In ThisDocument.Pages
        For Each vsoShape In vsoPage.Shapes
            Set vsoCharacters1 = vsoShape.Characters
            vsoStrng = vsoCharacters1.Text
            vsoFind = txtFind1.Text
            vsoReplace = txtReplace1.Text
            vsoCharacters1.Text = Replace(vsoStrng, vsoFind, vsoReplace)
        Next
    Next
Title: Re: Find and Replace Shape Text in VBA
Post by: wapperdude on December 30, 2008, 06:47:18 AM
txtFind1 and txtReplace1 haven't been defined, need to declare them in Dim statements.
Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on December 30, 2008, 07:12:39 AM
They are defined in the userform1 why would it need to be in dim statements?
Title: Re: Find and Replace Shape Text in VBA
Post by: wapperdude on December 30, 2008, 07:27:14 AM
Step thru the macro in debug mode (F8).  After each line is executed, you can check the values of the variables.  You can also see where the macro barfs.  I don't think the userform passes the variable types into the macro.  Left hand and right hand type thing.  Anyway, it's easy enough to try.  Afraid I have to call it a night.  I'll check back tomorrow.  Perhaps the European "early risers" will have jumped in before then.
Title: Re: Find and Replace Shape Text in VBA
Post by: wapperdude on December 30, 2008, 03:28:03 PM
When you assign your text to the find and replace variables, are they enclosed with double quotes?   ???
Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on December 30, 2008, 04:07:16 PM
It is assigned when the form is run.  So no it is not assigned in double quotes it is typed into the textboxes txtFind1 .. txtFind10, txtReplace1 .. txtReplace10.  Why won't it accept the data typed into the form in this replace statement?
Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on December 30, 2008, 04:14:01 PM
And by the way it won't let me step through the macro it only gives me the error message:
"compile error: wrong number of arguments or invalid property assignment" in the replace function call.
Title: Re: Find and Replace Shape Text in VBA
Post by: wapperdude on December 30, 2008, 04:55:17 PM
Having the target and replacement text in dbl quotes is a requirement.  I'd have to search to find out how to add them after the fact, but it is do-able. 

I suspect your date entry is causing the macro violation.  You're going to have to do some detective work, manually placing the dbl quotes around the date, etc.  Or, use the single quote to comment things out and make manual, equivalent entries in the macro.  Find what's the problem basically.
Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on December 30, 2008, 05:05:59 PM
I am not typing a date into the textbox just general text.  Sure I could type text within a string in this replace but that would defeat my purpose.  How can I get the double quotes around it?  I tried to use an ampersand to concatenate it to ' " '  but that didn't work.  Is there any way to get a string variable to work in the replace function or will only a literal double quoted string work?
Title: Re: Find and Replace Shape Text in VBA
Post by: wapperdude on December 30, 2008, 05:26:33 PM
To add the double quotes, here's an example:

vsoMyText = NewText
vsoMyText = Chr(34) & vsoMyText & Chr(34)

In this example, vsoMyText was initially set without quotes.  2nd line adds the quotes.

I was only suggesting the manual entry steps to pinpoint where the problem might be, i.e., the specific line of code, and to use the comment character to minimize the number of lines that might have violations.  Easier to fix one thing at a time.  Obviously, you want to be fully automated.
Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on December 30, 2008, 05:34:54 PM
I tried this but it didn't solve the problem.  It still gives the same error message.

Private Sub butSubmit_Click()
Dim vsoPage As Visio.Page, vsoShape As Visio.Shape
    Dim vsoCharacters1 As Visio.Characters, vsoStrng, vsoFind, vsoReplace As String
   
    For Each vsoPage In ThisDocument.Pages
        For Each vsoShape In vsoPage.Shapes
            Set vsoCharacters1 = vsoShape.Characters
            vsoStrng = vsoCharacters1.Text
            vsoFind = Chr(34) & Me.txtFind1.Text & Chr(34)
            vsoReplace = Chr(34) & Me.txtReplace1.Text & Chr(34)
            vsoCharacters1.Text = Replace(vsoStrng, vsoFind, vsoReplace)
        Next
    Next
Title: Re: Find and Replace Shape Text in VBA
Post by: wapperdude on December 30, 2008, 07:10:05 PM
I went back to your file, updated the macro, and get the same error.  I was able to pinpoint the problem to the replace function. 

It is not obvious to me why it isn't working.  The only significant difference between your methodology and what I provided is that you call the replace function as code under the UserForm.   :P  For whatever reason, VBA is taking exception to this.   :o

Well, at least neither of us is imaging things!

Perhaps someone else will jump in on this. 
Title: Re: Find and Replace Shape Text in VBA
Post by: wapperdude on December 30, 2008, 08:16:00 PM
I copied your UserForm and code to a new file and ran it.  The error went away.  Must be some corruption in your present file.
Title: Re: Find and Replace Shape Text in VBA
Post by: wapperdude on December 31, 2008, 06:43:48 AM
The attached file contains the basic solution.  The Userform only has one entry, but that can be easily expanded to your 10 entries.  The macro will search all shapes on all pages, substitutes a new string for an old string.  The Userform code closes the UserForm once all of the substitutions have been completed.

Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on December 31, 2008, 07:29:49 AM
It works but I find its code a bit confusing is the get1 and new1 referring to the textbox in userform1 or the variables set to "enter text" in the showforms module? So in order to expand this to 10 replaces I have to create the "enter text" variables and textboxes with the same name (which I will change to find1 - 10 and replace1-10) and see if it still works.  Thanks for all your help.  Let's see if I am understanding your code correctly.
Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on December 31, 2008, 08:57:37 AM
I don't understand the ChgText() module.  What exactly is that doing?  Without knowing how to modify this I can't get one replace to work (much less modify it to do 10 replaces). I get the fun error I've been getting with this whole process in the replace statement: "compile error: wrong number of arguments or invalid property assignment." 

If my understanding of this is correct you are hardcoding the text that is in the shape to "my text".  That defeats the purpose of this macro.  I want to be able to find and replace any text not look for a predefined text in code.
Title: Re: Find and Replace Shape Text in VBA
Post by: wapperdude on December 31, 2008, 04:17:07 PM
Let's start at the beginning, in case others, are interested in this:

The objective was to search thru all shapes, on all pages in a Visio document and change existing text with new text.  The only requirement of the existing text is, it exists.  The macro needs to be able to accept 10 different entries at a time.

This is accomplished with a macro that launches a UserForm into which both the old text and new text may be written.  If the User enters into the old text, something that doesn't exist, then nothing gets changed.  There is nothing hardcoded.  The entire process is launched by pressing the "Replace" button on the 1st page.

My macro deviates  :o from the above in that the UserForm only does a single entry.   :-\  Other than that, it does all of the above.   :D  I'm assuming all of the necessary elements were included with file,  ???  since you said it works, which is two pages, each has two shapes, each shape has three lines of text.  Press the replace button on the 1st page to launch the process.  Type in any part or all of one line of the existing text, type in any desired replacement, and press Submit.  All objects on all pages will now show the old text replaced with new text, and unspecified old text remains unchanged.

Part of the confusion is my fault:  the ChgText() module I used to copy/paste code into the UserForm module.  In the clean up process, I failled to remove it.  Feel free to do so.   ::)

The Details:
UserForm:  Contains TextBoxes for entering both old and new text.  I named the boxes as "Get1" for the old text entry, and "New1" for the new text entry.  You need to expand the form (and re-arrange as desired) to have 9 more boxes of each type).  Rename them as desired for convenience.

UserForm Code:  Requires that there are a total of 10 entries each: vsoNewText1 ... vsoNewText10 and vsoOldText1 ... vsoOldText10.  (My macro does not number the two entries shown.)  All of these should be declared in Dim statements, e.g., Dim vsoNewText1 as string, vsoOldText1 as string. 

Then, in the body of the code, copy and paste the three lines, starting with the line that begins with "Set".  You'll need 10 of these, they should all be within the For/Next loop.  Remember to change the suffix numbers.

At the end of the macro, after the last Next, I show two lines of code.  These may be deleted, or copied and placed as 9 additional pairs.  They refer to the Textboxes in the userform and preset the text to "Enter Text", to indicate to the User what to do.

Module1:  ShowForm()  This is the "liason" code between the "Replace" button and the "UserForm" code.  That's the way VBA works.  Seems dumb to me.  Again, I tried to initialize the form with the entries here.  You may delete these if you desire, except for the UserForm1.Show.  That's necessary.

This Document:  ChgText()  Delete this module, it's leftover.
Replace_Click()  This module is the the "Replace" button on the Visio drawing page.  It calls the ShowForm module.

I think that pretty much summarizes/explains everything and shows what needs to be done to expand to 10 entries.  If you cannot get this to work, and the example is satisfactory, I will fill out the form for 10 entries if necessary, but, that would defeat the learning experience.

Hope this clarifies things.  (No, I did not proof read this post.)

Title: Re: Find and Replace Shape Text in VBA
Post by: wapperdude on December 31, 2008, 05:01:44 PM
Addendum:  I thought the Module1 ShowForm() code was unnecessary, and it is.  Just copy/paste its contents into the Replace_Click() macro, delete the ShowForm reference, and delete the ShowForm() macro.  Makes more sense, eliminates the middle man.   ;D
Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on December 31, 2008, 11:06:42 PM
Yesterday I got your version to work but not mine.  Today after deleting the unnecessary subs and modules I got mine to work with one replace.  Now I'll try it with 10 replaces.  Thanks again for all your help and your detailed explanation.
Title: Re: Find and Replace Shape Text in VBA
Post by: jogjer on January 01, 2009, 12:06:00 AM
I successfully modified the macro so it does ten find and replaces.  I could have made it more efficient using arrays but I chose not to and just repeat code several times. It also has a background page that has page numbers (page of pages) in the upper right corner, the document name at top (without directory), a place where you can paste a company logo (the original macro had an acxiom logo but I no longer have a copy of that logo) and the document name on the bottom (with the directory).  The file is attached if anyone else wants to use it.  Thanks once again for all the help.
Title: Re: Find and Replace Shape Text in VBA
Post by: Peter1958 on February 28, 2020, 03:16:04 PM
Hi, I'm a translator trying to replace a vsd's German phrases with English ones, and found this old post. Despite my lack of VBA, in Word and Excel it was a doddle to record text replacement (including case-sensitivity), but Visio won't play. I'm not interested in forms and just 10 replacements, but rather in hundreds of replacements from a list. If I knew the code fragment for one replacement explicitly stated (e.g. "Übersetzer"->"translators") I could generate 100s of them in Excel from a couple of columns of translation pairs. Can anyone help please?