So I'm creating a custom Ribbon using the Office RibbonX Editor and Excel. I want to display a simple dropdown that allows the user to switch between three worksheets.
I'm not sure why it's going wrong, but I keep running into three errors that correspond to the onAction attribute for each item:
Ln 8, Col 51: The 'onAction' attribute is not declared.
Ln 9, Col 51: The 'onAction' attribute is not declared.
Ln 10, Col 51: The 'onAction' attribute is not declared.
Here is my code:
XML (customUI14.xml file):
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon>
<tabs>
<tab id="customTab" label="DropDown" insertAfterMso="TabHome">
<group id="customGroup" label="Custom Group">
<dropDown id="dropDown1" label="Dropdown Box">
<item id="dd01" label="Sheet1" imageMso = "_1" onAction="DDOnAction" />
<item id="dd02" label="Sheet2" imageMso = "_2" onAction="DDOnAction" />
<item id="dd03" label="Sheet3" imageMso = "_3" onAction="DDOnAction" />
</dropDown>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
VBA:
Sub DDOnAction(control As IRibbonControl, id As String, index As Integer)
Select Case control.id
Case "dd01"
ActiveWorkbook.Sheets("Sheet1").Activate
Case "dd02"
ActiveWorkbook.Sheets("Sheet2").Activate
Case "dd03"
ActiveWorkbook.Sheets("Sheet3").Activate
End Select
End Sub
Hi the onAction attribute should placed in the dropdown and not in the item,
So the XML is :
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon>
<tabs>
<tab id="customTab" label="DropDown" insertAfterMso="TabHome">
<group id="customGroup" label="Custom Group">
<dropDown id="dropDown1" label="Dropdown Box" onAction="DDOnAction" >
<item id="dd01" label="Sheet1" imageMso = "_1" />
<item id="dd02" label="Sheet2" imageMso = "_2" />
<item id="dd03" label="Sheet3" imageMso = "_3" />
</dropDown>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
and the code is like this
Sub DDOnAction(control As IRibbonControl, id As String, Index As Integer)
Select Case Index
Case 0
ActiveWorkbook.Sheets("Sheet1").Activate
Case 1
ActiveWorkbook.Sheets("Sheet2").Activate
Case 2
ActiveWorkbook.Sheets("Sheet3").Activate
End Select
End Sub
Related
I have developed an excel Add-Ins which contains additional buttons with different function. My initial code was based on "Ron de Bruin Excel Automation" kit which worked great. (and I thank him for that). Recently I have added another group and a button, which worked fine on my excel (365 Excel version 2009), but failed on other machines with the same Excel version. The error was, it could not find any callbacks. I eliminated all callbacks but one "onAction" which is essential, but the error is still there.
Any help.
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon>
<tabs>
<tab id="CustomTab" label="שמאות מקרקעין" insertAfterMso="TabDeveloper">
<group id="GroupA" label="מידע נדלן רשות המיסים">
<button id="aButton01" label="יבא נתונים" onAction="RunMacro" imageMso="GetExternalDataImportClassic" size="large" />
<button id="aButton02" label="מזג גיליונות" onAction="RunMacro" imageMso="ReviewCombineRevisions" size="large" />
<button id="aButton03" label="מיין ומחק עמודות" onAction="RunMacro" imageMso="CreateQueryFromWizard" size="large" />
<button id="aButton04" label="שווי מר" onAction="RunMacro" imageMso="ConditionalFormattingAboveAverage" size="large" />
<button id="aButton05" label="התאמת משקל" onAction="RunMacro" imageMso="PageScaleToFitScale" size="large" />
<button id="aButton06" label="הכנה לדוח שומה" onAction="RunMacro" imageMso="MacroDefault" size="large" />
<button id="aButton07" label="תמונת הנכס" onAction="RunMacro" imageMso="PictureReflectionGallery" size="large" />
<button id="aButton08" label="וויסות הורדה אפשרויות" onAction="RunMacro" imageMso="StartTimer" size="large" />
<button id="aButton09" label="מחיר למשתכן" onAction="RunMacro" imageMso="TentativeAcceptInvitation" size="large" />
</group>
<group id="GroupB" label="תכנה">
<button id="bButton01" label="הוראות שימוש" onAction="RunMacro" imageMso="Help" size="large" />
<button id="bButton02" label="הזמנת רישיון" onAction="RunMacro" imageMso="GroupOmsInsert" size="large" />
<button id="bButton03" label="עידכון גירסה" onAction="RunMacro" imageMso="FillUp" size="large" />
<button id="bButton04" label="נתוני משתמש" onAction="RunMacro" imageMso="ArrangeByAccount" size="large" />
</group>
<group id="GroupC" label="נסח טאבו">
<button id="cButton01" label="PDF" onAction="RunMacro" imageMso="FileEmailAsPdfEmailAttachment" size="large" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
{
Sub RunMacro(control As IRibbonControl)
'PURPOSE: Tell each button which macro subroutine to run when clicked
Select Case control.ID
Case "aButton01": Application.Run "FromRibbon"
Case "aButton02": Application.Run "MergeSheetsmacro"
Case "aButton03": Application.Run "CleanColumns"
Case "aButton04": Application.Run "AddAverage"
Case "aButton05": Application.Run "Weight"
Case "aButton06": Application.Run "PrepareReport"
Case "aButton07": Application.Run "ActivateGoogleView"
Case "aButton08": Application.Run "GrabRegul"
Case "aButton09": Application.Run "MechirLamishtaken"
Case "bButton01": Application.Run "HelpForm"
Case "bButton02": Application.Run "LicenseRequest"
Case "bButton03": Application.Run "UpgradeVersion"
Case "bButton04": Application.Run "PersonalData"
Case "cButton01": Application.Run "ConvertPDF2Excel"
End Select
End Sub
}
enter code here
After a long trial an error process I found the reason to the effect . 64 bit vs. ,32 bit Office .
I have used some dll functions which were not properly defined for 64 office. As a result it corrupted the code.
I made a custom ribbon addin following this article,
https://www.thespreadsheetguru.com/blog/step-by-step-instructions-create-first-excel-ribbon-vba-addin
It works perfectly but can I move the tab which I have made to be the second tab after the Start tab?
You can do what you wish to do but to do so will mean that you need to edit the CustomUI.Xml file which is located in the zip file that is an Office document.
If you are working in VBA then you will best be served by the CustomUI editor tool
https://github.com/OfficeDev/office-custom-ui-editor
This tool will extract the xml file from an Office document, allow you to edit and then save it back to the office document.
This is a good link to start reading up on Ribbon Xml.
https://www.rondebruin.nl/win/s2/win001.htm
The Xml below is from one of my CustomUI for Word. I think it does the same as you are asking in that I inserts the new tab to the left of the Past group on the Home Tab of the ribbon. It also replaces the Paragraph tab with a customised version.
<tab
idMso="TabHome">
<group
id = "Home.RegulatoryCMC"
label = "Regulatory CMC"
insertBeforeMso = "GroupClipboard"
visible="true">
<button
id = "Home.RegulatoryCMC.StartHere"
label = "Start Here"
onAction = "RibbonCallbacksForButtons.OnAction"
getSupertip = "RibbonCallbacksForSupertips.getSuperTip"/>
<button
id="Home.RegulatoryCMC.ShowStylePane"
label="Show Style Pane"
onAction="RibbonCallbacksForButtons.onAction"
getSupertip = "RibbonCallbacksForSupertips.getSuperTip"/>
<button
id="Home.RegulatoryCMC.ResetXML"
label="Reset XML"
onAction="RibbonCallbacksForButtons.onAction"
getSupertip = "RibbonCallbacksForSupertips.getSuperTip"/>
</group>
<group
idMso="GroupParagraph"
getVisible="RibbonCallbacksForVisibility.getVisible"/>
<box
id="Home.Paragraph.Status"
boxStyle="horizontal">
<buttonGroup
id="Home.Paragraph.Alignment">
<toggleButton idMso="AlignLeft"/>
<toggleButton idMso="AlignCenter"/>
<toggleButton idMso="AlignRight"/>
<toggleButton idMso="AlignJustify"/>
</buttonGroup>
<buttonGroup
id="Home.Paragraph.Marks"
visible="true">
<toggleButton idMso="ParagraphMarks"/>
</buttonGroup>
</box>
<box
id="ParagraphIndent"
boxStyle="horizontal">
<button idMso="IndentDecreaseWord"/>
<button idMso="IndentIncreaseWord"/>
</box>
<box
id = "ParagraphOther"
boxStyle="horizontal">
<gallery idMso="LineSpacingGallery"/>
<button idMso="SortDialogClassic"/>
</box>
<dialogBoxLauncher>
<button idMso="ParagraphDialog"/>
</dialogBoxLauncher>
</group>
</tab>
I am using the following piece of XML code to create a custom Ribbon for an Excel add-in.
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon startFromScratch="false">
<tabs>
<tab id="ComdinheiroTab" label="COMDINHEIRO">
<group id="ComdinheiroButtons" label="Comdinheiro">
<button id="Login" getLabel="getLabelLogin" image="Login" size="large" onAction="OnActionLogin"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
I am using the following VBA code to set a label for the button login:
Sub getLabelLogin(control As IRibbonControl, ByRef returnedVal)
if loggedIn = true then
returnedVal = "Logged"
else
returnedVal = "Disconected"
end if
End Sub
The label's name changes successfully according to the variable loggedIn's value when the ribbon is loaded. However I wish I could change the label's values during the execution of my program. Is it possible to call getLabel event using a VB code? Is there anyway to refresh my ribbon so this event would be called again?
Yes, it's possible to run "get" callbacks later on. In order to do so, you need to create a module- or global-level variable to hold the "ribbon UI" object. That object has two useful methods: Invalidate and InvalidateControl. The first triggers all the "get" callbacks in the Ribbon XML. The second triggers the callbacks only for the specified control.
Your ribbon ui must be assigned to this object when the Ribbon loads. In order for this to happen, you need the attribute onLoadin the customUI tag of your Ribbon XML and its callback in your VBA.
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="ribbonLoaded">
<ribbon startFromScratch="false">
<tabs>
<tab id="ComdinheiroTab" label="COMDINHEIRO">
<group id="ComdinheiroButtons" label="Comdinheiro">
<button id="Login" getLabel="getLabelLogin" image="Login" size="large" onAction="OnActionLogin"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
In the VBA sample code, below, UpdateTheLabel is called from "the execution of my program" mentioned in the question. This procedure need not be connected to the RibbonXML in any way.
UpdateTheLabels action, however, is connected to the Ribbon: by calling InvalidateControl it causes a Ribbon control ("Login", in this case) to re-evaluate all its dynamic ("get") call-backs, such as getLabelLogin (which is in the Ribbon XML).
Dim ribbonUI as IRibbonUI
Sub ribbonLoaded(ribbon as IRibbonUI)
Set ribbonUI = ribbon
End Sub
Sub UpdateTheLabel
ribbonUI.InvalidateControl("Login")
End Sub
Sub getLabelLogin(control As IRibbonControl, ByRef returnedVal)
if loggedIn = true then
returnedVal = "Logged"
else
returnedVal = "Disconected"
end if
End Sub
It doesn't matter what procedure calls InvalidateControl as long as the procedure has access to the ribbonUI object.
More on this can be found in the MSDN article https://msdn.microsoft.com/en-us/library/aa338202(v=office.12)#OfficeCustomizingRibbonUIforDevelopers_Dynamically
I have, in ExcelDNA, created a custom ribbon (extending ExcelRibbon) and overridden the GetCustomUI() method to create a menu control from a list of strings. Basically:
public override string GetCustomUI(string RibbonID)
{
string customUIXml =
#"<customUI xmlns='http://schemas.microsoft.com/office/2006/01/customui' loadImage='LoadImage' onLoad='OnRibbonLoaded' >
<ribbon>
<tabs>
<tab id='CustomTab' label='My Dynamic Tab'>
<group id='SampleGroup' label='My Sample Group'>
<menu description='description' enabled='true' id='menuItem' visible='true' size='normal' >";
foreach (string itemName in _ItemNameList)
customUIXml += $"<button id='btn_tool_{itemName}' label='{itemName}' onAction='MyMethod' />";
customUIXml +=
#"</menu>
</group >
</tab>
</tabs>
</ribbon>
</customUI>";
return customUIXml;
}
Because _ItemNameList is retrieved from a different file/system, I can't place this customUI tag directly into the .dna file (as far as I know) and hence I build it on load via the GetCustomUI().
As a proof of concept, the onAction method will add a new item to _ItemNameList when the user clicks on a menu item.
But how do I get Excel to call GetCustomUI again in order to have the XML rebuilt?
I have tried invalidating the ribbon object itself, but this does not trigger Excel to call GetCustomUI again.
The next best thing I can think of (although I'm still to test this) is to create a menu with a whole load of invisible 'placeholder' buttons (by specifying the getVisible callbacks) and when the user clicks on a button, just invalidate the button that needs to now become visible, showing the new item added to _ItemNameList. I still need to think through how to get the correct button reference though... This also feels a little dirty.
Any ideas how to have Excel rebuild the ribbon?
Also open to other ideas to allow me to add items to a menu in an ExcelRibbon.
I think you are looking for the dynamicMenu control, which will trigger an event to let you dynamically set the contents of the menu, every time you click on it.
Something like this:
<?xml version="1.0" encoding="utf-8" ?>
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="OnLoad">
<ribbon>
<tabs>
<tab id="MyAwesomeRibbon" label="My Awesome Ribbon">
<group id="MyDynamicGroup" label="Hello Dynamic!">
<dynamicMenu id="MyDynamicMenu"
label="Click for Awesome"
getContent="OnGetContent"
invalidateContentOnDrop="true"
size="large"
imageMso="HappyFace" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
Your OnGetContent method will get fired every time the user clicks on the ribbon button, so you can dynamically assemble the items.
e.g.
public string OnGetContent(IRibbonControl control)
{
var menuXml = #"
<menu xmlns='http://schemas.microsoft.com/office/2006/01/customui' itemSize='large'>
<button id='SaveButton'
label='Save'
onAction='OnSave'
imageMso='FileSave' />
<button id='AboutButton'
label='About...'
onAction='OnAbout'
imageMso='FileDocumentInspect' />
</menu>";
return menuXml;
}
Of course, you'd have to build this string dynamically from your list, etc.
I am trying to create a new ribbon with 2 buttons in Excel 2013. I was able to create it using Custom UI editor thanks to
Excel CustomUI ribbon layout and How to add a custom Ribbon tab using VBA?
When I input the code as
<button id="aa" label="CORE" onAction = "HMA_CORE"/>
it works but once I try this code
<button id="aa" label="CORE" size = "large" onAction = "HMA_CORE"/>
and then click validate in the customUI it says that "size attribute is not declared". I am not sure what to add. I saw http://www.rondebruin.nl/win/s2/win009.htm as well, but the code looks the same.
Any help will be appreciated.
Thanks
The code for the buttons looks like this
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon>
<tabs>
<tab id="toolRibbon" label="HMA-FUNCTIONS">
<group id="groupDocument" label="HMA-xml outputs">
<buttonGroup id="a">
<button id="aa" label="CORE" onAction = "HMA_CORE"/>
<button id="ab" label="PLANT" onAction = "HMA_PLANT"/>
</buttonGroup>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
Give this a try using built in icons from Office (get rid of buttonGroup)
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon>
<tabs>
<tab id="toolRibbon" label="HMA-FUNCTIONS" insertBeforeMso="TabHome">
<group id="groupDocument" label="HMA-xml outputs">
<button id="aa" label="CORE" imageMso="MacroArguments" onAction = "HMA_CORE" size="large" />
<button id="ab" label="PLANT" imageMso="PictureBrightnessGallery" onAction = "HMA_PLANT" size="large" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
Reference: Office 2007 Icons Gallery
the problem was the space between the "size" and the "larger" statement! put it all together
error >> size = "larger"
correct >> size="larger"