VBA Word Custom Ribbon does not effect Macros - vba

I've written a few subroutines in VBA to do some things in Word that I want it to do. It works as intended. However, when I created a custom ribbon for it, using the Office RibbonX Editor and generated callbacks, nothing happens when the associated button is pressed. Here is the xml schema for the ribbon:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon startFromScratch="false" >
<tabs>
<tab id="Ribbon1" label="Custom Ribbon">
<group id="Group_1" label="Common" autoScale="true">
<button id="btn1" label="DoThis" imageMso="AppointmentColor10" onAction="RibbonControl.DoThis" visible="true"/>
<button id="btn2" label="DoThis1" imageMso="BlackAndWhiteWhite" onAction="RibbonControl.DoThis1" visible="true"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
Callbacks are generated like this:
'Callback for btn1 onAction
Sub DoThis(control As IRibbonControl)
End Sub
'Callback for btn2 onAction
Sub DoThis1(control As IRibbonControl)
End Sub
I have tried different modification of the >onAction< attribute, but between getting VBA errors and buttons not working, this is the point I'm stuck in.
I'd appreciate any tips on how to solve it.

In my working Ribbon XML I am not using a module name, just calling the method directly. So your XML code should look like this:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon startFromScratch="false" >
<tabs>
<tab id="Ribbon1" label="Custom Ribbon">
<group id="Group_1" label="Common" autoScale="true">
<button id="btn1" label="DoThis" imageMso="AppointmentColor10" onAction="DoThis" visible="true"/>
<button id="btn2" label="DoThis1" imageMso="BlackAndWhiteWhite" onAction="DoThis1" visible="true"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
For these methods to be reachable from the Ribbon some things must be true:
The code must exist in a regular Module. Not a class module, form, or any other object. Make a module called "RibbonActions" or something and put them all there.
The methods must be public, your subs are implicitly public so that should work but I like to add the Public keyword just to be explicit about it.
The signature must match the event, which yours does appear to fit the pattern.

Related

Outlook 2019: Button does not show up in Home Ribbon

I am writing an Outlook 2019 add-in for which I would like to place a button on the home tab. I am using ribbon xml and I am able to get this to successfully appear on the AddIns and View tab. However, I cannot get it to appear on the Home tab. This is my XML:
<tabs>
<tab idMso="TabHome">
<group id="ContentGroup" label="Custom Content">
<button id="textButton" label="Custom Button" screentip="Text" onAction="MethodCall"/>
</group>
</tab>
</tabs>
If I change "TabHome" to "TabView" then the button shows up at the end of the ribbon perfectly. Is there a special trick to making this work? Is the idMso of "TabHome" correct for outlook 2019?
Finally, what is the idMso for the "Message" tab when you're in a separate window with an email?
The correct idMSo is "TabMail".

VSTO Addin same buttons multiple tab

Working on the VSTO Add-in for Outlook. Is there anyway to avoid duplicating the whole ribbon XML code if I just want the same buttons to appear under two different tab/view (TabCalendar and TabMail)
My ribbon code is the following:
<ribbon>
<tabs>
<tab idMso="TabMail">
<button id="ID1" label="XxX" onAction="OnTextButton" image="myImg1" size="large" getVisible="GetVisible"/>
<button id="ID2" label="XxX" onAction="OnTextButton" image="myImg2" size="large" getVisible="GetVisible"/>
...
</tab>
<tab idMso="TabCalendar">
<button id="SameThanID1" label="XxX" onAction="OnTextButton" image="myImg1" size="large" getVisible="GetVisible"/>
<button id="SameThanID2" label="XxX" onAction="OnTextButton" image="myImg2" size="large" getVisible="GetVisible"/>
...
</tab>
</tabs>
</ribon>
What I would love to to is:
<ribbon>
<tabs>
<tab idMso="TabMail" OR "TabCalendar">
<button id="ID1" label="XxX" onAction="OnTextButton" image="myImg1" size="large" getVisible="GetVisible"/>
<button id="ID2" label="XxX" onAction="OnTextButton" image="myImg2" size="large" getVisible="GetVisible"/>
...
</tab>
</tabs>
</ribon>
It is really annoying as the button needs to be unique and I therefore have to duplicate the same logic. I read this post which is not really encouraging. Is there any option?
The Fluent UI (aka Ribbon UI) doesn't allow to combine built-in tabs markup and place the ribbon XML into a single place. You need to specify (repeat) the markup for each built-in tab separately. Read more about the ribbon UI in the following series of articles:
Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)

Excel Context Menu Not Showing

I am using the "Custom UI Editor For Microsoft Office". I have added an "Office 2007 Custom UI Part" which creates the "customui.xml" file for me. It currently has the following code which adds my "Zoom Cell" button to the developer tab.
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon>
<tabs>
<tab idMso="TabDeveloper" >
<group id="customGroup1" label="Zoom" insertAfterMso="GroupModify">
<button id="customButton1" label="Zoom Cell" size="large" onAction="ZoomCell" imageMso="ZoomPrintPreviewExcel" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
What I am trying to do is add the same button basically to the context menu for right-clicking on a cell; however, it is not working for me. If I modify the code even the button from the above code gets removed. Here is what I have tried. I am pretty sure that there is something weird in my xml code; I just can't find it.
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon>
<tabs>
<tab idMso="TabDeveloper" >
<group id="customGroup1" label="Zoom" insertAfterMso="GroupModify">
<button id="customButton1" label="Zoom Cell" size="large" onAction="ZoomCell" imageMso="ZoomPrintPreviewExcel" />
</group>
</tab>
</tabs>
</ribbon>
<contextMenus>
<contextMenu idMso="ContextMenuCell">
<button id="MyButton" label="Zoom Cell" onAction="ZoomCell" imageMso="ZoomPrintPreviewExcel" insertBeforeMso="Cut" />
</contextMenu>
</contextMenus>
</customUI>
When I put your code in the CustomUI Editor and try to validate it, I get an error that "contextMenus" is not supported element in the CustomUI namespace, followed by a list of expected/allowable elements:
Allowable elements are:
qat
officeMenu
contextualTabs
It seems from THIS LINK (which is for Outlook, but I believe the approach would be same/similar for Excel/etc.) that context Menus are manipulated through VBA events in Office 2007.
I think that RibbonUI manipulation of context menus was not introduced until 2010.

Add Event to UI button click

I have created a custom ribbon in Microsoft Word but I am having issues attaching events to the buttons found in a ribbon. Below is my code:
UI XML:
<mso:cmd app="Word" dt="1" />
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon startFromScratch="true" >
<tabs>
<tab id="CustomTab" label="MyTasks" >
<group id="Group1" label="Details Labels">
<menu id="Menu1" label="Details" size="large">
<menu id="Menu21" label="Dates">
<button id="my_date" onAction="foo_eventhandler" label="Some Date" />
</menu>
</menu>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
I then have the following VBA code in Modules/NewMacros VBA code:
Sub foo_eventhandler(control As IRibbonControl)
End Sub
NOTE:
I import the XML by opening Word-->going to File-->Options-->Customize Ribbon-->Import/Export. I then select my XML file and import it.
When this code is run, though, I get the error "Argument Not Optional". If I run the same code without the "control As IRibbonControl" it's fine but I need to be able to get the Sender object. Anyone have any suggestions?
jason
I think you are running into problems because you are importing the XML code via Options -> Customize Ribbon ->Import/Export. This method is really for general users who wish, for example, to never see the Page Layout tab and have it hidden. They can export their custom ribbon and import it onto new machines for the same layout.
For developers a better method is use the most excellent CustomUIEditor for Word and Excel. http://openxmldeveloper.org/blog/b/openxmldeveloper/archive/2009/08/07/7293.aspx
The steps you need to take are to create your normal macro enabled Word template (the .dotm) file and save it. Then open that file up in the CustomUIEditor and paste you XML (minus the first line). I've expanded your XML code with another button and I've added the tag to the XML so the VBA knows which button is being pressed.
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon startFromScratch="false" >
<tabs>
<tab id="CustomTab" label="MyTasks" >
<group id="Group1" label="Details Labels">
<menu id="Menu1" label="Details" size="large">
<menu id="Menu21" label="Dates">
<button id="my_date_1" onAction="foo_eventhandler" label="Some Date" tag="Date1" />
<button id="my_date_2" onAction="foo_eventhandler" label="Some Other Date" tag="Date2" />
</menu>
</menu>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
I generally put my Ribbon code in a Ribbon module. In your callback code you just need to use the .Tag property of the inputted control variable to know which button is pressed which you'll see corresponds to the tag in the XML. ie:
Sub foo_eventhandler(control As IRibbonControl)
MsgBox "Hooray! for " & control.Tag
End Sub

Access ribbon items execute VBA functions

I have some problems configuring my ribbon.
Only macros are working as onAction or getPressed attributes. Functions in standard modules don't work. Callbacks written in standard modules don't work either.
How can I use the value of edit box in VBA function?
This is xml of my ribbon for example:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon startFromScratch="true">
<tabs>
<tab idMso="TabHome">
<group idMso="GroupFont" visible="false" />
</tab>
<tab id="CustomTab" label="Клиенты">
<group id="PeopleGroup" label="Люди">
<toggleButton id="ToggleButton1" size="large" label="Все люди"
onAction="Pplopenmacro" imageMso="ContactPictureMenu"/>
<editBox id="PeopleEditBox"
label="Поиск по рег№"
onChange="MyEditBoxCallbackOnChange" />
<button id="Button3" label="TEST"
size="normal" onAction="=Person_choose()" />
</group>
<group id="CompaniesGroup" label="Компании">
<toggleButton id="ToggleButton2" size="large"
label="Компании"
onAction="Cmpnopenmacro" imageMso="MeetingsWorkspace" />
</group>
</tab>
<tab id="CustomTab2" label="Документы">
<group id="MyGroup" label="Документы" >
<button id="Button1" label="Счета"
size="large" onAction="Invoiceopenmacro"
imageMso="BusinessFormWizard" />
<button id="Button2" label="Хуета" size="normal" />
</group >
</tab>
</tabs>
</ribbon>
</customUI>
And these are my functions in std module:
Public Sub MyEditBoxCallbackgetText(control As IRibbonControl, ByRef strText)
' Callback EditBox
' Select Case control.Id
' Case "PeopleEditBox"
' strText = "Hello World"
' End Select
MsgBox "1"
End Sub
Public Sub MyEditBoxCallbackOnChange(control As IRibbonControl, strText As String)
' Callback Editbox: Returnvalue Editbox
' Select Case control.Id
' Case "PeopleEditBox"
' MsgBox "Value Editbox: " & _
' strText, vbInformation, "Sample EditBox"
' End Select
MsgBox "2"
End Sub
Public Sub Person_choose()
'DoCmd.openForm "People", acNormal
MsgBox "Yahoo!"
End Sub
You may need to tell XML where the procedure can be found. Example -
<group id="PeopleGroup" label="People">
<toggleButton id="ToggleButton1" size="large"
label="All People"
onAction="ThisWorkbook.Pplopenmacro" imageMso="ContactPictureMenu"/>
<editBox id="PeopleEditBox"
label="Search by Region #"
onChange="ThisWorkbook.MyEditBoxCallbackOnChange" />
<button id="Button3" label="TEST"
size="normal" onAction="ThisWorkbook.Person_choose()" />
</group>
ThisWorkbook. means that the procedures are found in the ThisWorkbook object (see your Project Explorer in the VBA editing window)
I have never put the callbacks into a standard module, but since you are doing that maybe you need to have something like onAction="MyModuleName.Pplopenmacro" in the XML?