?
Solved

Visio VBA 2013 - 20 page visio file - I need the four buttons on each page to refer to the same four macros  throughout the file.

Posted on 2014-01-24
10
Medium Priority
?
1,058 Views
Last Modified: 2014-02-14
I have four macro buttons (ActiveX) on every page of my 20 page visio file.
Each macro switches to another layer in that page.  The layers are named the same  on every page: "Level 1 layer", "Level 2 layer", Level 3 layer", "level 4 layer"

I want the four macro buttons to switch layers.    the caption on the buttons read "layer 1", "Layer 2", etc.  On each page I will have thus:

Page one:  Four buttons:
Layer one button
Layer two button
Layer three button
Layer four button

Page two:  Four buttons:
Layer one button
Layer two button
Layer three button
Layer four button

I want the layer one button on page 1, 2, 3, etc.  to always run to the layer one macro
I want the layer two button on page 1, 2, 3, etc. to always run to the layer two macro

It seems that I have to copy and paste the switch layer VBA code over and over for each button on every page!   There's gotta be a shorter path.


Currently when I paste the four buttons on a new page, it doesn't run any macro. It seems kind of wasteful that I'd have to AGAIN code event procedures for each of the four buttons on each of the 20 pages.

When I attempt to rename the newly pasted button from  CommandButton5_Click() to CommandButton1_Click()  I get the message "Ambigous name detected"  and yet,  I WANT the command button1_click() event procedure to run when I click the newly pasted button!
0
Comment
Question by:brothertruffle880
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 5
10 Comments
 
LVL 31

Expert Comment

by:Scott Helmers
ID: 39806679
I was in the process of responding to your previous question on this subject when I noticed you'd closed it and opened this one... so here you go.

Here's a solution that eliminates the need for userforms and capitalizes on the fact that Visio shape names are unique per page and not per document. Consequently, you can copy your four special shapes to every page in your document with no concern about shape names.

The code uses two events of the Window object:
WindowTurnedToPage to determine the current page and to set shape objects to your four special shapes
MouseDown to determine where the user clicked within the window

At the moment the code displays the results of mouse clicks in the Immediate window. You can modify the code by changing the four shape name constants to match your four shapes. When you run the code, the object ThisShape will be set to the button on which the user clicked or will have a value of nothing if the user clicks anywhere other than the four buttons.
Determine-which-of-four-shapes-w.vsd
0
 

Author Comment

by:brothertruffle880
ID: 39811423
HI Scott:  I uploaded a portion of my diagram.
As you can see, I first used the shape double-click behavior  (See upper right corner) to make the diagram switch to different layers.  This was too cumbersome as my managers wanted a way to click directly into a particular layer.
Then, I tried buttons (See last page upper right corner ) and that's where I ran into problems.  (re: myposting here)
Can you help me with inserting  the code you created?
test.vsdm
0
 
LVL 31

Accepted Solution

by:
Scott Helmers earned 2000 total points
ID: 39812918
I've reorganized the code slightly to make it easier to reuse. I also created a DocumentOpened event that will initialize the code automatically each time the document is opened. To use it:
paste the code into the ThisDocument module
change my dummy shape names ("AAA", "BBB"...) to match the names of your four shapes
insert your layer switching code in the "TaskActionOnClick" sub (note: the object ThisShape is the one on which the user clicked)
Option Explicit

Dim WithEvents ThisWin As Visio.Window

Dim ThisPage    As Visio.Page
Dim ThisShape   As Visio.Shape

Dim shape1      As Visio.Shape
Dim shape2      As Visio.Shape
Dim shape3      As Visio.Shape
Dim shape4      As Visio.Shape

Const name1     As String = "AAA"       ' name of button 1
Const name2     As String = "BBB"       ' name of button 2
Const name3     As String = "CCC"       ' name of button 3
Const name4     As String = "DDD"       ' name of button 4

Sub TakeActionOnClick()
' This sub is called from the MouseDown event handler if user has clicked on one of the button shapes

    ' delete or comment out this test line after inserting real code
    Debug.Print ThisPage.name, ThisShape.name

    '
    ''
    ''' do something useful here
    ''
    '

End Sub

Private Sub Document_DocumentOpened(ByVal Doc As IVDocument)
' set these objects when document is opened in order to activate event code

    Set ThisWin = ActiveWindow
    Set ThisPage = ActivePage
    Set shape1 = ThisPage.Shapes(name1)
    Set shape2 = ThisPage.Shapes(name2)
    Set shape3 = ThisPage.Shapes(name3)
    Set shape4 = ThisPage.Shapes(name4)

End Sub

Private Sub ThisWin_WindowTurnedToPage(ByVal Window As IVWindow)
' reset page and shape objects whenever user changes to a different page

    Set ThisPage = ActivePage
    ' NOTE: technically, the lines below aren't necessary because the four shape names are
    ' the same on every page, but it feels more complete to do this!
    Set shape1 = ThisPage.Shapes(name1)
    Set shape2 = ThisPage.Shapes(name2)
    Set shape3 = ThisPage.Shapes(name3)
    Set shape4 = ThisPage.Shapes(name4)

End Sub

Private Sub ThisWin_MouseDown(ByVal Button As Long, _
                              ByVal KeyButtonState As Long, _
                              ByVal x As Double, _
                              ByVal y As Double, _
                              CancelDefault As Boolean)
' use x and y values passed into sub to determine whether the user's click on the page resides within
' one of the four special shapes; if so, set global variable 'ThisShape' to the clicked shape

    Set ThisShape = Nothing

    If fbIsInShape(shape1, x, y) Then
        Set ThisShape = shape1
    ElseIf fbIsInShape(shape2, x, y) Then
        Set ThisShape = shape2
    ElseIf fbIsInShape(shape3, x, y) Then
        Set ThisShape = shape3
    ElseIf fbIsInShape(shape4, x, y) Then
        Set ThisShape = shape4
    End If

    If Not ThisShape Is Nothing Then
        Call TakeActionOnClick
    End If

End Sub

Function fbIsInShape(shp As Visio.Shape, x As Double, y As Double) As Boolean
' determines whether the x/y coordinates reside within a specific shape

    Dim px As Double, py As Double          ' PinX and PinY for shape
    Dim w As Double, h As Double            ' Width and Height for shape
    
    Dim x1 As Double, x2 As Double          ' left- and right-most X value for shape
    Dim y1 As Double, y2 As Double          ' bottom- and top-most Y value for shape
    
    px = shp.Cells("PinX")
    py = shp.Cells("PinY")
    w = shp.Cells("Width")
    h = shp.Cells("Height")

    x1 = px - w / 2                         ' left side of shape
    x2 = px + w / 2                         ' right side of shape
    y1 = py - h / 2                         ' bottom side of shape
    y2 = py + h / 2                         ' top side of shape
    
    If (x > x1) And (x < x2) And (y > y1) And (y < y2) Then
        fbIsInShape = True
    Else
        fbIsInShape = False
    End If

End Function

Open in new window

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:brothertruffle880
ID: 39818700
What does
 Debug.Print ThisPage.name, ThisShape.name
do?

I never used debug.print
0
 
LVL 31

Expert Comment

by:Scott Helmers
ID: 39818820
It's a programmer convenience -- it displays values (the page and shape name in this case) in something called the "Immediate" window in the VB Editor.

If the window is not already open below the code window in the VB editor, select View>Immediate Window to open it. Then when you run my code you'll see the results of clicking on the four shapes.
0
 

Author Comment

by:brothertruffle880
ID: 39822210
I'm getting some oddities while trying to modify the code.
I'm using the code to switch to different layers.  I integrated that code with an earlier set of procedures.
0
 

Author Comment

by:brothertruffle880
ID: 39822215
I'm getting some oddities while trying to modify the code.
I'm using the code to switch to different layers.  I integrated that code with an earlier set of procedures.
Determine-which-of-four-shapes.vsd
0
 
LVL 31

Expert Comment

by:Scott Helmers
ID: 39822795
A couple of things:
You used the first version of the code that I posted and not the second version; the second version was organized a bit better and was also set up to be launched automatically each time you (or a user) opens the document.
I assumed you already had buttons with names -- you changed the constants for the button names but the diagram still has my buttons in it. You either need to use your buttons or change the names of my buttons (and the labels on them) to match the name constants. (You change a shape name by selecting the shape and then clicking Developer>Shape Name.)

Once you've got that much set up, see the instruction with the second set of code regarding the "TaskActionOnClick" sub -- that's where you'll put the code that calls the appropriate layer activation sub. Are you familiar with using a CASE statement? It's the perfect VB construct for a situation like this where you want to do one of four things depending which shape the user clicks. (Hint: the code will make the decision about which sub to call based on ThisShape.Name.)

See whether you can get things working based on the above. If you still need more help, just ask -- that's what we're her for!
0
 
LVL 31

Expert Comment

by:Scott Helmers
ID: 39823080
One other observation about your code: VB doesn't allow public constants, which is why the four lines at the top of your code that start with "Public Const..." are red. Remove "Public" and they will be fine.
0
 

Author Closing Comment

by:brothertruffle880
ID: 39859056
Thanks Scott!
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The ability to add structure to Visio diagrams using containers, lists and callouts is one of my favorite features in Visio 2010. In this article I’ll describe a mashup of containers and lists that meet a real-world need. Prior to reading this ar…
This script will sweep a range of IP addresses (class c only, 255.255.255.0) and report to a log the version of office installed. What it does: 1.)      Creates log file in the directory the script is run from (if it doesn't already exist) 2.)      Sweep…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question