How to embed images in Office file for custom Ribbon - vba

I am developing a custom ribbon extension for Excel, in which a control requires different custom images. I managed to use some images located in my filesystem, but I would like to embed these images inside the .xlsm file.
Is it possible to do it and to reference them from the VBA code that updates the image of the control?
For test purposes, this is the XML that defines my custom ribbon:
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="ribbonLoaded">
<ribbon>
<tabs>
<tab idMso="TabHome" >
<group id="customGroup1" label="My Group" insertAfterMso="GroupFont">
<button id="customButton1" label="Click Me" size="large" onAction="Macro1" getImage="getButtonImage"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
And this is the macro that change the image of the customButton1 control:
Dim imgIndex As Long
Public Sub getButtonImage(ByVal control As IRibbonControl, ByRef Image)
Select Case control.ID
Case "customButton1"
Set Image = LoadPicture("img" + Trim(Str(imgIndex)) + ".bmp")
imgIndex = (imgIndex + 1) Mod 2
End Select
End Sub
I tried to add the bmp files inside the .xlsm and reference them updating the relationships file (.rels), but I don't know how to reference them from VBA and most important, when I open the file with Excel and save it, they are automatically deleted...
Any help is appreciated!

If the image is embedded in the customUI, you do not need VBA to add them to a control. Just use the same ID for the image in an image tag:
<button id="button1" label="Test" size="large" image="TestID" onAction="ButtonOnAction" />
My sample is adressing the image with ID "TestID", which must be found in the customUI XML - expand the customUI node in the Custom UI Editor to find or change the image ID (or use the editor to add a new image).

robcooper's answer from UtterAccess.com might help:
Public Sub getButtonImage(ByVal control As IRibbonControl, ByRef image)
'for use in Access 2007 Ribbon control
'requires a reference to the Micrsoft Office 12.0 Object Library
Select Case control.ID
Case "cmdMainMenu"
Set image = LoadPicture(CurrentProject.Path & "\home.bmp")
End Select
End Sub

Related

VBA - Ribbon customization - When adding an add-on

I did a program that I wished to distribute to my co-workers, they are not VBA oriented. So I wish to distribute it easily.
I created an Add-in, when install the add-in needs to create a custom Ribbon. I tried my best, but I cannot find easy to understand documentation.
My code is as follow :
Private Sub Workbook_AddinInstall()
On Error Resume Next 'Just in case
Application.CommandBars("Worksheet Menu Bar").Controls("Super Code").Delete
Set cControl = Application.CommandBars("Worksheet Menu Bar").Controls.Add
With cControl
.Caption = "Open SCF workbook"
.Style = msoButtonIconAndCaptionBelow
.OnAction = "OpenTheCorrectFile"
.FaceId = 7720
.DescriptionText = "Open the SCF workbook"
End With
Set cControl = Application.CommandBars("Worksheet Menu Bar").Controls.Add
With cControl
.Caption = "Are they onboard"
.Style = msoButtonIconAndCaptionBelow
.FaceId = 5817
.OnAction = "Check_Suppliers_Already_On_Board"
.DescriptionText = "Check if suppliers have already been on boarded"
End With
End Sub
Now if you use my code you will notice that:
Buttons are small
Icons are small
No description when hoovering them
No special name for the new ribbon, it is call Add-ins
No special name for this group, it is call "Menu Commands"
Does anyone know how to solve this.
Whenever I am looking for those answer people are using special application to create the ribbons, I do not wish to do it. I am also a beginner in VBA, so everything that is easily digestible is welcome.
Thank you very much.
Here's an example of how you can do it without using any external application, just a text editor. But you will have to be careful to write XML code properly, or the excel file may not open correctly (make a backup copy).
You will create a folder named "customUI" and, inside that folder, a file named "customUI.xml"
You will write all your Ribbon details inside "customUI.xml". I wrote this example, covering the issues you listed: Big buttons and icons (Images list in https://bert-toolkit.com/imagemso-list.html) / Tooltip description (screentip and supertip) / Ribbon name (tab label) / Group names (group labels)
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon>
<tabs>
<tab id="CustomTab" label="Add-ins">
<group id="Group1" label="Menu Commands">
<button id="Button1" label="Happy" size="large" screentip="Test1" supertip="Test1 description" imageMso="HappyFace" onAction="Macro1" />
<button id="Button2" label="Save" size="large" imageMso="FileSave" onAction="Macro2" />
<button id="Button3" label="{a}" size="large" imageMso="FieldCodes" onAction="Macro3" />
</group >
<group id="Group2" label="Other Commands">
<button id="Button4" label="Reply" size="large" imageMso="Reply" onAction="Macro4" />
</group >
</tab>
</tabs>
</ribbon>
</customUI>
Rename your .XLSM file to .ZIP, then you will be able to edit/add files. Add the customUI folder to the zip file.
From the ZIP file, extract the .rels file that is inside _rels folder, you will add this line between the last Relationship tag and the Relationships closing tag, and then put it back inside the ZIP file overwriting the .rels file there
<Relationship Id="someID" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml" />
Rename the file back to .XLSM and open it, if everything is right, the new Ribbon will be there. It's important that the macros that will be called by the buttons have a control parameter, like this:
Sub Macro3(ByVal control As IRibbonControl)
That's it, everything about the UI is in the customUI.xml file, there is no more adding buttons in VBA. If you have to change something in the UI, you will have to rename it to ZIP again, overwrite the customUI.xml file and rename to XLSM again. Here's the Ribbon I got in this example:

Add standard command button "New Slide" to custom ribbon in office add-in

I have created my customized ribbon in an addIn. Now I would like to add the New Slide command that exist in home screen (see screenshot below).
You can add built-in controls to your custom tab by soecifying their IdMso values. See Office 2013 Help Files: Office Fluent User Interface Control Identifiers .
You can read more about the Ribbon UI in the following series of articles in MSDN:
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)
I think after a lot of searching I finally figured it out!
This is all the code you need, delete everything else
This will create a new slide button just like the one that comes default in PowerPoint
<group id="add_slide" label="Add Slide">
<control idMso="SlideNewGallery" size="large" />
</group>
credit
i currently have new slide button in my addin like the image below which gives me a new slide
however I want the option like the already existing new slide in home ribbon where I can choose templates.Is there any way to invoke this button in my customized ribbon so below is my newslide that is what i want to get in my addin
private void New_slide_Click(object sender, RibbonControlEventArgs e)
{
PowerPoint.Application ppApp = Globals.ThisAddIn.Application;
ppApp.CommandBars.ExecuteMso("SlideNewGallery");
}
I created a new ribbon based on xml Template in VS. Afterwards I added a group and a control based on an idMso-Value. When using this xml file
<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Ribbon_Load">
<ribbon>
<tabs>
<tab id="tab0" label="AddIn">
<group id="grpCustom">
<button idMso="SlideNew" size="large" label="YOUR CUSTOM TEXT"></button>
</group>
<group idMso="GroupSlides"></group>
</tab>
</tabs>
</ribbon>
</customUI>
This results in that custom ribbon. Eugene Astafiev pointed it out, you can find idMso-Values in MSDN.
As explained by Franz the solution is to use the idMso.
For the New Slide command you are looking for, if you look at MSN in the idMso Table for "New Slide" you will find two entries.
The one you are looking for is a Gallery with idMso=SlideNewGallery.
(not a button).
You can add it in the XML. I like to use the Ribbon Editor.
With the Ribbon Editor it looks like this:
And in the Add-In it looks then like this:
The CustomUI XML relevant part looks like this
<group id="TD_GrpMisc" label="Misc">
<gallery
idMso="SlideNewGallery"
size="large"/>
<button
idMso="SlideNew"
size="large"/>
</group >

MS Word and RibbonX error (Wrong number of arguments ...)

I am trying to add an extra tab to the Word ribbon and have a couple buttons to invoke my own macros. I did the same thing with Excel and it worked fine. For some reason I can't get it to work in Word. I am using the Custom UI Editor. Here's the ribbon code.
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon startFromScratch="false">
<tabs>
<tab id="customTab" label="Pavel">
<group id="customGroup" label="Formatting">
<button id="customButton" label="Custom Button" imageMso="HappyFace" size="large" onAction="Callback" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
Just a very simple tab, with one button that calls the macro Callback().
I added a module to the Word file with the following code.
Sub Callback()
MsgBox ("Test")
End Sub
The macro runs fine on its one (hitting the play button in the editor) but when invoked via the button on the tab I get the following error:
Edit: It seems to do something with 1) public access to the module and 2) apparently the macro should be taking some argument similar to "control as ribboncontrol" or something like that. If you know where to find the documentation for this, please let me know.
A Ribbon button expects a Sub which takes a parameter:
Sub Callback(button As IRibbonControl)
MsgBox ("Test")
End Sub
http://msdn.microsoft.com/en-us/magazine/cc163469.aspx

VBA error 'Wrong number of arguments or invalid property assignments' when running macro via custom button

I have a macro that I call via a tab/group/button added by the Custom UI Editor -
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon startFromScratch="false">
<tabs>
<tab id="tabCustomActions" label="Custom ActionsXXX" insertAfterMso="TabDeveloper">
<group id="GroupTLA" label="TLA Actions">
<button id="buttonFormatTLA" label="Format as TLA" image="TLALogo" size="large" onAction="start_tla" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
The button shows up just fine, with my custom logo, but when ever I click the button I get the follow error -
VBA is not opened following this error, as it usually is, and no code within VBA is indicated as the problem if I open the developer console and then try and click the button.
Strangely though, if I try and run the macro manually, it works fine with no errors. Does anybody have any ideas how to solve this?
Here is my full code in a Pastebin, should you wish to view it. Thanks.
You have the wrong call signature for the start_tla callback in your VBA code.
If you open up your file in Custom UI Editor, there is a button called Generate Callbacks to the right in the menu. If you press it, it will give you the correct callbacks for your VBA code to match the ribbon xml in your file:
'Callback for buttonFormatTLA onAction
Sub start_tla(control As IRibbonControl)
'Your code goes here
End Sub
According to the Pastebin link, your sub looks like this, without the control As IRibbonControl parameter:
Public Sub start_tla()
It is old thread, but maybe it will help someone.
If you make 'control' argument optional, you can run either from Ribbon button or directly from VBA or Form button.
Sub start_tla(Optional control As IRibbonControl)
'Your code goes here
End Sub

Open XML SDK - Adding a macro programatically to a Word 2007 document

I am trying to dynamically add a new custom ribbon in a Word 2007 document following teh manual method described in this article :- http://msdn.microsoft.com/en-us/library/aa338202(v=office.12).aspx.
The article specifies the following :-
a) Create a XML file named customUI.xml which will contain the elements you want to display
in the tab and put the same in a folder named customUI.
b) Rename your Word 2007 document to .zip. Add the above "customUI" folder to the zip file.
c) Add the following relationship to the "_rels/rels" file in the .zip file :-
<Relationship Type="http://schemas.microsoft.com/office/2006/
relationships/ui/extensibility" Target="/customUI/customUI.xml"
Id="customUIRelID" />
Do we have some code sample to achieve the same using OpenXML SDK? For example, how to add the "RibbonExtensibilityPart" (which contains the ribbon XML) to the document?
EDIT :-
This is how I did the above mentioned steps:-
string documentFileName = <path of the docx file>;
string ribbonXml = <path of the ribbon XML file>;
using (WordprocessingDocument myDoc = WordprocessingDocument.Open(documentFileName, true))
{
MainDocumentPart mainPart = myDoc.MainDocumentPart;
if (myDoc.GetPartsCountOfType<RibbonExtensibilityPart>() > 0)
myDoc.DeletePart(myDoc.GetPartsOfType<RibbonExtensibilityPart>().First());
RibbonExtensibilityPart ribbonExtensibilityPart = myDoc.AddNewPart<RibbonExtensibilityPart>();
ribbonExtensibilityPart.CustomUI = new DocumentFormat.OpenXml.Office.CustomUI.CustomUI(File.ReadAllText(ribbonXML));
myDoc.CreateRelationshipToPart(ribbonExtensibilityPart);
}
and I am able to see the new ribbon with the elements in it.
However, I have buttons in the ribbon and I want to add handle actions on those buttons. Following is what my Ribbon XML looks like :-
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon>
<tabs>
<tab id="CustomTab" label="My Tab">
<group id="MyGroup" label="My Group" >
<button id="Button1" label="My Large Button"
size="large"/>
<button id="Button2" label="My Normal Button"
size="normal" *onAction="ThisDocument.MyOtherButtonMacro"* />
</group >
</tab>
</tabs>
</ribbon>
</customUI>
have a look at the "onAction="ThisDocument.MyOtherButtonMacro". I know I can write Macro function in the document. However, as the custom ribbon will be added dynamically on the server-side, I am not sure how I can add the macro dynamically. Could anyone help?