News:

BB code in posts seems to be working again!
I haven't turned on every single tag, so please let me know if there are any that are used/needed but not activated.

Main Menu

Custom Ribbon with VBA in Visio Stencil

Started by Thomas Winkel, March 28, 2016, 03:34:22 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Remko

thank you guys for your replies. the thing that gave me permission errors was because i didnt declare a filename + extension.

i put this in the Set XML Path window: c:\temp\ 
I should have put: c:\temp\ribbon.xml   :)

Remko

im sorry for being so VBA clueless, All i need is a example VBA so i can figure out how to bind a button to a macro.

I added these 2 buttons to the Ribbon XML

<separator id="separator" />
<button id="customMacro1" label="delete all guides" supertip="Delete all guides" size="large" imageMso="_3" onAction="Button_OnAction"/>
<button id="customMacro2" label="A3 guides" supertip="A3 guides" size="large" imageMso="_2" onAction="Button_OnAction"/>


but cant make them execute.

I have a class module containing this:

Public Sub Class_Initialize()

' Class_Initialize
'
' Abstract - This constructor is intentionally left blank.

    ' No initialization is required.
End Sub
Public Function IRibbonExtensibility_GetCustomUI(ByVal RibbonID As String) As String

' IRibbonExtensibility_GetCustomUI
'
' Abstract - This method is a callback that is called by Visio to obtain the
' custom UI definition.
'
' Parameters
' RibbonID         A string identifying the Visio UI
'
' Return Value     A string representing the XML defining the custom UI

    IRibbonExtensibility_GetCustomUI = getRibbonXML(True, True, True, True)
End Function

Public Sub OnAction(ByVal control As IRibbonControl)

' OnAction
'
' Abstract - This method is a callback specified in the custom UI XML file.
' It is called by Visio when the associated button defined in the XML is pressed.
'
' Parameters
' control     The Ribbon UI control that was activated
   
    ' To execute a VBA macro, use the Document.ExecuteLine method.
    ' For example: Document.ExecuteLine("ThisDocument.HelloWorld");
    Select Case control.ID
        Case "customMacro1"
            'Call to your code
            ThisDocument.ExecuteLine "Macro1"
            Exit Sub
        Case "customMacro2"
            ThisDocument.ExecuteLine "deleteallguides"
             Exit Sub
            'Call to your codedeleteallguides
        Case "customMacro3"
            'Call to your code
        Case "customMacro4"
            'Call to your code
        Case "customMacro5"
            'Call to your code
        Case "customContextMacro1"
            'Call to your code
    End Select
   
    MsgBox control.ID, vbInformation, "OnAction"
End Sub
Public Sub CommandOnAction(ByVal control As IRibbonControl, _
    ByVal cancelDefault As Boolean)

' CommandOnAction
'
' Abstract - This method is a callback specified in the custom UI XML file.
' It is called by Visio when the associated repurposed Ribbon control is used.
'
' Parameters
' control           The Ribbon UI control that was activated
' cancelDefault     If true, call the built-in command after the custom code
' is complete

    ' Do custom work when the Copy button is pressed, for example.
    Select Case control.ID
        Case "customMacro1"
            'Call to your code
        Case "customMacro2"
            'Call to your code
        Case "customMacro3"
            'Call to your code
    End Select
    MsgBox control.ID, vbInformation, "CommandOnAction"
    cancelDefault = False
End Sub


and a normal module with the macros:
Public Sub Macro1()

    'Enable diagram services
    Dim DiagramServices As Integer
    DiagramServices = ActiveDocument.DiagramServicesEnabled
    ActiveDocument.DiagramServicesEnabled = visServiceVersion140 + visServiceVersion150

    Application.ActiveWindow.Page.AddGuide visVert, 3.937008, 11.811024

    Application.ActiveWindow.SetViewRect -20.710301, 27.271981, 56.799539, 47.81824

    Application.ActiveWindow.SetViewRect -7.666805, 17.177788, 28.698716, 24.160797

    Application.ActiveWindow.SetViewRect -4.472441, 14.708662, 21.811024, 18.362205

    Application.ActiveWindow.SetViewRect -3.4027, 13.863892, 19.474128, 16.394825

    Application.ActiveWindow.Page.AddGuide visVert, 6.496063, 7.283464

    Application.ActiveWindow.Page.AddGuide visHorz, 5.511811, 10.03937

    Application.ActiveWindow.Page.AddGuide visHorz, 5.11811, 4.330709

    'Restore diagram services
    ActiveDocument.DiagramServicesEnabled = DiagramServices

End Sub
Public Sub deleteallguides()

    'Enable diagram services
    Dim DiagramServices As Integer
    DiagramServices = ActiveDocument.DiagramServicesEnabled
    ActiveDocument.DiagramServicesEnabled = visServiceVersion140 + visServiceVersion150

    Dim vsoSelection1 As Visio.Selection
    Set vsoSelection1 = Application.ActiveWindow.Page.CreateSelection(visSelTypeByType, visSelModeSkipSuper, visTypeSelGuide)
    Application.ActiveWindow.Selection = vsoSelection1

'    ActiveWindow.DeselectAll
'    ActiveWindow.Select Application.ActiveWindow.Page.Shapes.ItemFromID(148), visSelect
'    ActiveWindow.Select Application.ActiveWindow.Page.Shapes.ItemFromID(150), visSelect
'    ActiveWindow.Select Application.ActiveWindow.Page.Shapes.ItemFromID(151), visSelect
'    ActiveWindow.Select Application.ActiveWindow.Page.Shapes.ItemFromID(152), visSelect
    Application.ActiveWindow.Selection.DeleteEx (visDeleteNormal)

    'Restore diagram services
    ActiveDocument.DiagramServicesEnabled = DiagramServices

End Sub


thank you for your time.

Thomas Winkel

Please attach your modified stencil, then I will investigate this.

Remko

I created marcos in the file. not the stencil, and its a mess :) thats why i prefer a "simple" example VBA snip. I attached the file..  thank you for your time.

Thomas Winkel

I recommend to keep all code only in the stencil, not in documents.
It's easier to maintain code in a global stencil than hundreds of documents.

See attached stencil.

Remko

Hi Thoman, many thanks for this. I will hopefully have some time tomorrow to play around with this, but is does give me some better insight.

Q: Does adding this stencil to your visio drawing mean you are actually running macros in a non macro enabled visio file?

Q2: after editing VBA in the stencil, I cant save because its read only, is this normal stencil behavior?

Thomas Winkel

Q1:
The macros are running from the stencil.
No need to enable macros for the document.
With the Visio Object model you can directly access everything within the current application:

  • Application returns the current application.
  • ThisDocument returns the document where the code is running.
  • ActiveDocument returns the active document.
  • ActivePage returns the active page.
  • ActiveWindow returns the active window.

This example prints the same result to Immediate window, regardless if running from document or stencil:

Option Explicit 'Always use "Option Exlicit"

Sub IterateThroughAllShapesWithinCurrentVisioApplication()
    Dim doc As Visio.Document
    Dim pge As Visio.Page
    Dim shp As Visio.Shape
   
    'Never use this (except you really know what you are doing):
    'On Error Resume Next
   
    For Each doc In Application.Documents
        Debug.Print "* " & doc.Name
        For Each pge In doc.Pages
            Debug.Print "....* " & pge.Name
            For Each shp In pge.Shapes
                Debug.Print "........* " & shp.Name
            Next shp
        Next pge
    Next doc
End Sub


Btw. Visio Documents, Stencils & Templates are the exactly same object types: Visio.Document
Only the filename extension differs and tells Visio how to handle it.

Q2:
Before you edit a stencil you should set it to "Edit" mode via context menu (see attached screenshot).
Before adding master shapes this is mandatory, but before editing code it's easy to forget.

Extra tip:
In the VBA editor, goto Tools -> Options...
Uncheck "Auto Syntax Check"
Check "Require Variable Declaration"
(See second screenshot)

bossi

#22
happy new one folks.
So i dropped the "VisioTools" into "MyShapes" and activated it in the "Shapes" Section, but there is no further happening.
Is there supposed to appear an additional Tab entry or sth ?

Edit:
ok , security Setting was on , had to either enable macros or better apply own certificate to it .

Surrogate

#23
Quote from: bossi on January 02, 2023, 12:46:18 AMok , security Setting was on , had to either enable macros or better apply own certificate to it .
Make sure that this option is checked!

You can find it File -> Options -> Advanced -> General.

PS @Thomas Winkel, thank you for VisioTools.vss!
Quote from: Thomas Winkel on December 14, 2022, 02:37:32 PMI recommend to keep all code only in the stencil, not in documents.
It's easier to maintain code in a global stencil than hundreds of documents.
Absolutely

Thomas Winkel

Good point. This is one of the most common reasons for us when the ribbon doesn't load.

Application.EventsEnabled is often used for performance tuning.
And if the script crashes, this property can remain FALSE.

Here error handling helps:

Sub ErrorHandlerDemo()
    Const SubName = "ErrorHandlerDemo"
    Dim scopeId As Long
    On Error GoTo ErrorHandler
   
    Application.ScreenUpdating = False
    Application.EventsEnabled = False
    Application.DeferRecalc = True
    scopeId = Application.BeginUndoScope(SubName)
   
   
    ' ---- Begin of your code
    Dim shp As Visio.Shape
   
    For Each shp In ActiveWindow.Selection
        shp.CellsU("Width").ResultIU = 1
        shp.CellsU("Height").ResultIU = 1
    Next shp
   
    'shp.CellsU("NotExistingField").ResultIU = 1 ' Simulate Error
    ' ---- End of your code
   
   
    Application.EndUndoScope scopeId, True
    Application.EventsEnabled = True
    Application.ScreenUpdating = True
    Exit Sub
   
ErrorHandler:
    Application.EndUndoScope scopeId, False
    Application.EventsEnabled = True
    Application.ScreenUpdating = True
    MsgBox Err.Description, vbInformation, SubName
End Sub

Browser ID: smf (possibly_robot)
Templates: 4: index (default), Display (default), GenericControls (default), GenericControls (default).
Sub templates: 6: init, html_above, body_above, main, body_below, html_below.
Language files: 4: index+Modifications.english (default), Post.english (default), Editor.english (default), Drafts.english (default).
Style sheets: 4: index.css, attachments.css, jquery.sceditor.css, responsive.css.
Hooks called: 364 (show)
Files included: 34 - 1306KB. (show)
Memory used: 1217KB.
Tokens: post-login.
Cache hits: 14: 0.00141s for 26,729 bytes (show)
Cache misses: 4: (show)
Queries used: 17.

[Show Queries]