Hi,
please find attached a stencil that will draw a custom Ribbon "Visio-Tools" on load.
The XML code that defines the Ribbon is stored in the stencils document ShapeSheet "User.Ribbon".
You can export, modify and import the XML code with a mouse click.
The Ribbon will refresh automatically, no restart required.
User settings (XMLPath and reloadOnImport) are stored in the Windows Registry.
There is a button to remove this Registry settings.
The code has been derived from here:
http://blog.bvisual.net/2011/03/14/how-to-run-vba-macros-from-a-ribbon-button-in-visio-2010/
But it is much more comfortable to create the XML in your favorite editor (in my case Notepad++) than with code.
Feel free to use this stencil as start-up for your own projects.
Please give feedback if there is something to improve.
Regards,
Thomas
How can I view the shapsheet of the stencil? I figured it would be the same as viewing it for a document, but the entire shape design section of the developer ribbon is greyed out when I open just the stencil. The reason I ask is because I wanted to add this code to an existing stencil I use, but kept getting xml import errors. I can get the original "Visio tools" file to accept the xml file I have edited, but my stencil hits an error at this line:
ThisDocument.DocumentSheet.Cells("User.Ribbon").FormulaU = Chr(34) & XML & Chr(34)
which is from the "importXML()" sub.
Any help you could provide would be awesome.
Hi,
the problem is, that the code tries to access an user cell "User.Ribbon" that does not exist in your stencil.
So you have to create it by hand:
* Right click on stencil: Edit Stencil
* Right click on stencil: Drawing Explorer Window
* Right click on root in Drawing Explorer Window: Show ShapeSheet
* Right click in ShapeSheet: Insert Section -> User defined cells
Here is a video:
https://youtu.be/hzWDNw9dz8k
Regards,
Thomas
Ah I see. Thank you! I'm sure I can make use of this in the future! Nice ribbon code by the way. Managed to make lots of changes and expand the ribbon to suit my needs. I appreciate your assistance!
Hi,
is it possible to call macros inside the open document from the vss ribbon button?
I like to update the ribbon by opening a vss after opening a document but I can't seem to call subs from that document.
Thanks
I have this file attached, the macros don't fire (macros are just msgbox now to see if it works)
When pressing Ctrl+Shift+C it will change the Ribbon, only my 2 buttons.
When pressing Ctrl+Shift+R it will reset the Ribbon with my 2 extra butons
Do you know why they don't work??
I basically used the code of the stencil example but put it in a .vsd file (I don't use set CustomUI close reopen)
edit, found it i thought you could choose the name 'Button_OnAction'
Hello,
I know this is post is a bit old, but this is the solution I have been looking for! Thanks very much!
I did make mine a bit simpler and chose to create a string in VBA for the XML, and got rid of all the subs that move the string in and out of the shape data. It works very well.
ribbonXML = "<customUI onLoad=""OnRibbonLoad"" xmlns=""http://schemas.microsoft.com/office/2009/07/customui"">"
ribbonXML = ribbonXML + " <ribbon>"
ribbonXML = ribbonXML + " <tabs>"
ribbonXML = ribbonXML + " <tab id=""Tab1"" label=""Tab1"">"
ribbonXML = ribbonXML + " <group id=""Group1"" label=""Group1"" >"
ribbonXML = ribbonXML + " <button id=""Button1"" label=""Button1"" supertip=""Button1"" size=""large"" imageMso=""MailMergeGoToNextRecord"" onAction=""Button_OnAction""/>"
ribbonXML = ribbonXML + " <button id=""Button2"" label=""Button2"" supertip=""Button2"" size=""large"" imageMso=""SignaturesLoading"" onAction=""Button_OnAction""/>"
ribbonXML = ribbonXML + " </group>"
ribbonXML = ribbonXML + " </tab>"
ribbonXML = ribbonXML + " </tabs>"
ribbonXML = ribbonXML + " </ribbon>"
ribbonXML = ribbonXML + "</customUI>"
However - it seems anytime I try to do something not provided in your example, my ribbon will not load. Here are the three things I tried:
1) adding getVisible=""getVisible"" to the tabs and groups.
2) adding getEnabled=""getEnabled"" to the tabs and groups.
3) adding an editBox
All the above use the standard method (add the action in the ribbon with the callback sub name, add the callback sub) as shown below:
{the gobal variable}
Public objRibbonVisible As Boolean
'
{inside the ribbon string}
ribbonXML = ribbonXML + " <group id=""Group1"" label=""Group1"" getVisible=""GetVisible"">"
{The callback sub}
Public Sub GetVisible(control As IRibbonControl, visible)
visible = objRibbonVisible
objRibbon.Invalidate
End Sub
Is there something I am missing??
I know this is an old thread, but hope I can still get an answer.
I'm new to this ribbon (been on visio 2007 until just this year) stuff but found this stencil pretty cool and modified it to suite my needs pretty easily.
the only thing I can't get it to do is use different icons for the buttons.
there are lines in the xml file like this imageMso="SomeIcon" which specify an image but if I change that to any of the other icons which are in the word document that contains them, no image shows up.
What am I doing wrong? does this xml code actually access that word document on microsoft's site each time it loads? that doesn't sound very efficient, and what if you have no internet connection?
Thanks for any help
Handle the following to load your image,
Public Function LoadImage(strImageName As String) As IPictureDisp
Quote from: AndyW on March 16, 2020, 11:01:17 AM
Handle the following to load your image,
Public Function LoadImage(strImageName As String) As IPictureDisp
I don't see any code at all like that in the current stencil but it loads images just fine.
HI, I get a permission denied trying to export the XML. or do you need to supply one first? was hoping to export one so i can look and learn from it.
Hi,
try to set the xml path to something like
c:\temp\ribbon.xml (c:\temp must exist).
c:\ribbon.xml give me the same permission denied message.
Suggested proceeding is:
- Export the xml of the existing ribbon
- Adapt xml to your needs
- Import xml
The existing buttons demonstrates:
* Ribbon xml for Buttons, menus, checkboxes, splitter
* Store settings in Windows Registry
This is only to give you a starting point.
For real projects I suggest to remove these buttons and handle the xml import / export from VBA editor.
Quote from: Remko on November 29, 2022, 04:58:35 PM
HI, I get a permission denied trying to export the XML. or do you need to supply one first? was hoping to export one so i can look and learn from it.
Yes, you need to supply one first.
There is nothing to export in "stock" Visio. You'll get an empty string as output.
I.e. everything that you provide in ribbon.xml is applied "on the top" of the Visio's built-in user interface.
By default, nothing is applied, so the ribbon you export will be empty.
Hi Nikolay,
I guess Remkos question is about the "Export XML" function of my Visio-Tools stencil from the first post.
This will export the XML that defines the Visio-Tools ribbon (see attached screenshot).
The XML string is stored in the stencils document property User.Ribbon.
BR,
Thomas
I see. Thank you for the clarification. I thought it was about exporting the built-in ribbon
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 :)
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.
Please attach your modified stencil, then I will investigate this.
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.
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.
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?
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)
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 .