Get value from Ribbon Control (Drop Down or Combo Box etc.) - vba

Is it possible to design a ribbon addin with either drop down list or combo box and then use the values to run a subroutine?
I created a PowerPoint Ribbon Addin with a DropDown with items showing as "Depart 1", "Depart 2" & "Depart 3" and one button to import from an Excel file.
The idea is user can select which department to prepare slides for. Then they can run the report which will copy the charts from the designated Excel file.
Below is example code to show what I am trying to do.
When I select department in the dropdown list; I get the message which department is selected from the DropDown. But when I tried to use that as a variable, my code did not recognise it.
XML code for Ribbon Addin:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon>
<tabs>
<tab id="CustomTab" label="TestLabel">
<group id="SampleGroup" label="BU Selection">
<dropDown id="DdropDown" label="Select Dept" onAction="DReportSelection" getSelectedItemIndex = "DropDown_OnGetSelectedItemIndex">
<item id="item1" label="Depart 1" />
<item id="item2" label="Depart 2" />
<item id="item3" label="Depart 3" />
</dropDown>
</group >
<group id="SampleGroup1" label="TestLabel">
<button id="Button" label="Import Excel" imageMso="MicrosoftExcel" screentip="Import Data from Excel" size="large" onAction="ExcelImport" />
</group >
</tab>
</tabs>
</ribbon>
</customUI>
VBA code in my presentation.
Sub BUReportSelection(control As IRibbonControl, ID As String, selectedindex As Variant)
Dim department As String
department = Choose(selectedindex + 1, "Depart 1", "Depart 2", "Depart 3")
MsgBox department & " is selected ", vbInformation
End Sub
Sub ExcelImport()
If department = "Depart 1" Then
Call Macro4Department 1
End If
If department = "Depart 2" Then
Call Macro4Department 2
End If
If department = "Depart 3" Then
Call Macro4Department 3
End If
End Sub
Note: code just to demonstrate.

VBA can't access the Ribbon directly. Your dropdown is triggering a callback to DReportSelection. Instead it should trigger a callback to a macro that stores the selected item (the id, not the label i.e. item1, item2, or item3) in a global variable. Then the DReportSelection macro (I assume that's what's in the second listing) can read that variable and call the relevant macro.

Related

How to color shapes when i click on button in power point?

I want to change color for a selected shape. If i click one shape and i click a button i want to change color in red, like in picture but when i press button.
How i create a button i put condition to change color shapes selected?
I tried to change color by pressing another shapes but is not what i want.
Thanks a lot
OK, so firstly, because you are trying to change the colour of a selected shape, this implies you are in the normal (editing) view and not a slide show. Secondly, ActiveX buttons or shapes with Actions to run macros can only be clicked when in slide show mode. So, the only option you have for a "button" in the normal view is to use the ribbon extensibility features of Office. You need to add the XML for a button to the customUI of your PowerPoint file and create an associated macro for it to run. For example, add this XML to your file using the CustomUI Editor:
// Fluent UI customisation to add a single button to the PowerPoint ribbon //
// Written by Jamie Garroch of YOUpresent Ltd. http://youpresent.co.uk //
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon>
<tabs>
<tab id="tabMyTab" label="My Tab">
<group id="grpMyGroup" label="My Group">
<button id="btnMyButton" label="My Button" onAction="MyMacro"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
...then close the file in the CustomUI Editor and reopen in PowerPoint. Then add your macro:
' PowerPoint macro to change the fill colour of a single selected shape
' Written by Jamie Garroch of YOUpresent Ltd. http://youpresent.co.uk
Public Sub MyMacro(control As IRibbonControl)
With ActiveWindow.Selection
If .Type = ppSelectionShapes Then
If .ShapeRange.Count = 1 Then
If .ShapeRange.Type = msoAutoShape Then
.ShapeRange.Fill.ForeColor.RGB = RGB(255, 0, 0)
End If
End If
End If
End With
End Sub
Now when you click My Button in your custom tab My Tab, if there is a single selected shape of type AutoShape on the slide in view then the fill colour will change to red.

Compile Error in Hidden Module: Module 1

I've an Addin for Excel-2010 in VBA. If I execute the code from the VBA editor it works fine. But when I execute the macro using the button in the Ribbon generated for the Addin it throws this error: Compile Error in Hidden Module: Module 1
My code:
Sub QE_eventhandler(control As IRibbonControl)
If MsgBox("Esta acción no se podrá deshacer. ¿Desea Continuar?", vbExclamation + vbOKCancel, "Confirmar -Quitar Espacios-") = vbOK Then
QuitaEspacios
End If
End
Sub QuitaEspacios()
Dim celda As Range
For Each celda In Selection
If TypeName(celda.Value) = "String" Then
celda.Value = Application.WorksheetFunction.Trim(celda.Value)
End If
Next
End Sub
The code generated with the Custom UI Editor:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon>
<tabs>
<tab id="customTab" label="GARSA Tools">
<group id="customGroup1" label="Reformateo Texto">
<button id="customButton3" label="Quitar Espacios" size="large" onAction="QE_eventhandler" imageMso="TextEffectTracking" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
You are missing an End Sub at the end of the callback - you just have End:
Sub QE_eventhandler(control As IRibbonControl)
If MsgBox("Esta acción no se podrá deshacer. ¿Desea Continuar?", vbExclamation + vbOKCancel, "Confirmar -Quitar Espacios-") = vbOK Then
QuitaEspacios
End If
End Sub
Check out the following links which describe a similar issue:
You receive a "Compile error in hidden module" error message when you start Word or Excel
compile error in Excel

Create a new Ribbon tab with vba that only appears selecting certain shapes

I want to make appear a new ribbon tab that only appears when I select a shape that I want. I know to make normal tabs using Custom UI Editor For Microsoft Office or also with VBA using the following example:
Dim oToolbar As CommandBar
Dim oButton As CommandBarButton
Dim MyToolbar As String
' Give the toolbar a name
MyToolbar = "Kewl Tools"
On Error Resume Next
' so that it doesn't stop on the next line if the toolbar's already there
' Create the toolbar; PowerPoint will error if it already exists
Set oToolbar = CommandBars.Add(Name:=MyToolbar, _
Position:=msoBarFloating, Temporary:=True)
If Err.Number <> 0 Then
' The toolbar's already there, so we have nothing to do
Exit Sub
End If
On Error GoTo ErrorHandler
' Now add a button to the new toolbar
Set oButton = oToolbar.Controls.Add(Type:=msoControlButton)
' And set some of the button's properties
With oButton
.DescriptionText = "This is my first button"
'Tooltip text when mouse if placed over button
.Caption = "Do Button1 Stuff"
'Text if Text in Icon is chosen
.OnAction = "Button1"
'Runs the Sub Button1() code when clicked
.Style = msoButtonIcon
' Button displays as icon, not text or both
.FaceId = 52
' chooses icon #52 from the available Office icons
End With
' Repeat the above for as many more buttons as you need to add
' Be sure to change the .OnAction property at least for each new button
' You can set the toolbar position and visibility here if you like
' By default, it'll be visible when created. Position will be ignored in PPT 2007 and later
oToolbar.top = 150
oToolbar.left = 150
oToolbar.Visible = True
NormalExit:
Exit Sub ' so it doesn't go on to run the errorhandler code
ErrorHandler:
'Just in case there is an error
MsgBox Err.Number & vbCrLf & Err.Description
Resume NormalExit:
But I want to make it appear and disappear in certain moments. For example in Powerpoint when you select a video, there appears 2 new tabs (FORMAT AND PLAYBACK) with options for videos. When you select another shape that is not video this tab just disappear and other tabs appears with the proper options for the shape that you select and when you don't select any shape those special tabs just disappear.
Is it possible to make it using VBA?
Yes this is possible. There are three main things you need to implement to make this occur.
Enable Events in the add-in to capture the selection of a shape. When the shape selection event fires, this will be called to determine if the shape is what you want to show your tab etc.
In the XML that defines the ribbon ensure you have a 'Visible' callback function.
VBA code for the callback function of 'Visible'.
For example
In a module named 'Ribbon'
Private theRibbon As IRibbonUI 'Holds a variable for the ribbon when loaded on startup
Private MyTag As String 'A variable to tell the ribbon to show or what Tag to hide
'Callback for the Ribbon loading from XML
Public Sub RibbonOnLoad(Ribbon As IRibbonUI)
Set theRibbon = Ribbon
MyTag = "show"
End Sub
'Get visible callback function.
Sub GetVisible(control As IRibbonControl, ByRef visible)
If MyTag = "show" Then
visible = True
Else
If control.Tag Like MyTag Then
visible = True
Else
visible = False
End If
End If
End Sub
'This is a custom sub that invalidates the ribbon as needed.
'When invalidated it has to redraw itself
Sub RefreshRibbon(Tag As String)
MyTag = Tag
If theRibbon Is Nothing Then
MsgBox "Error, Save/Restart your presentation"
Else
theRibbon.Invalidate
End If
End Sub
In a module named 'Events'
'Define the new events class
Dim cPPTEvent As New clsEvents
Sub Auto_Open()
'Enable the events when the aad-in is loaded
Set cPPTEvent.PPTEvent = Application
End Sub
Sub Auto_Close()
'Disable when it is closed
Set cPPTEvent.PPTEvent = Nothing
Set cPPTEvent = Nothing
End Sub
In a class module named 'clsEvents'. This will check the shapes in the range and if any are of the movie media type the tab will be shown on the ribbon, otherwise it'll be hidden.
Public WithEvents PPTEvent As Application
Private Sub PPTEvent_WindowSelectionChange(ByVal Sel As Selection)
Dim ppCurShape As PowerPoint.Shape
If Sel.Type = ppSelectionNone Then
RefreshRibbon ""
Exit Sub
End If
For Each ppCurShape In Sel.ShapeRange
If ppCurShape.Type = msoMedia Then
If ppCurShape.MediaType = ppMediaTypeMovie Then
RefreshRibbon "show"
Exit Sub
End If
End If
Next
RefreshRibbon ""
End Sub
And of course the ribbon XML code (taken from the first reference down the bottom)
<customUI onLoad="RibbonOnLoad" xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon>
<tabs>
<tab id="MyCustomTab" label="My Tab" insertAfterMso="TabHome" getVisible="GetVisible" tag="MyPersonalTab" >
<group id="customGroup1" label="Group 1">
<button id="customButton1" label="Caption 1" size="normal" onAction="Macro1" imageMso="DirectRepliesTo" />
<button id="customButton2" label="Caption 2" size="normal" onAction="Macro2" imageMso="AccountMenu" />
<button id="customButton3" label="Caption 3" size="normal" onAction="Macro3" imageMso="RegionLayoutMenu" />
</group>
<group id="customGroup2" label="Group 2">
<button id="customButton4" label="Caption 4" size="normal" onAction="Macro4" imageMso="TextAlignGallery" />
<button id="customButton5" label="Caption 5" size="normal" onAction="Macro5" imageMso="PrintPreviewClose" />
<button id="customButton6" label="Caption 6" size="normal" onAction="Macro6" imageMso="PrintPreviewShrinkOnePage" />
<separator id="MySeparator1" />
<button id="customButton7" label="Caption 7" size="large" onAction="Macro7" imageMso="ReviewPreviousComment" />
</group>
<group id="customGroup3" label="Group 3">
<menu id="MyDropdownMenu" label="My Menu" size="large" imageMso="TextAlignGallery" >
<button id="customButton8" label="Caption 8" onAction="Macro8" imageMso="TextAlignGallery" />
<button id="customButton9" label="Caption 9" onAction="Macro9" imageMso="TextAlignGallery" />
<button id="customButton10" label="Caption 10" onAction="Macro10" imageMso="TextAlignGallery" />
<button id="customButton11" label="Caption 11" onAction="Macro11" imageMso="TextAlignGallery" />
<button id="customButton12" label="Caption 12" onAction="Macro12" imageMso="TextAlignGallery" />
</menu>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
For more reading:
Hiding the tabs and controls: http://msdn.microsoft.com/en-us/library/ee390805%28v=office.11%29#odc_office2007_DisplayHideRibbonControls_ChangingVisibilityRibbonTabs
Powerpoint events (thanks Steve): http://www.pptfaq.com/FAQ00004_Make_your_VBA_code_in_PowerPoint_respond_to_events.htm
List of events you can capture: http://officeone.mvps.org/vba/events_version.html

VB Personal Workbook Error where Macro runs every time I open Excel

I have a macro that I found on the net and have been using to allow me to export all chart objects within the active workbook. It seems to work just fine when I have it in its own normal workbook.
However, I want this to be a generic function that can be used on any given workbook so I have placed this code inside of my personal excel workbook. After doing this I notice that the code now runs every time I open my excel application and I basically get a ton of windows opening that are empty ".png" files.
How can I prevent this code from running every time the application opens? Is it an excel setting or something inherently wrong with the macro code?
I have other Macros in my personal workbook that appear to be working normally (only running when selected through the Tools > VB > Macro menu) so I feel like there is something going wrong with the code. Any help would be greatly appreciated.
'the main problematic function'
Sub ExportAllPossibleCharts()
Dim i As Integer, exportCount As Integer
Dim fileNum As String, fileBase As String
Dim sheetObj As Worksheet
Dim chartObj As Chart
fileBase = ActiveWorkbook.FullName
fileBase = Replace(fileBase, ".xlsx", "")
exportCount = 0
'First, export all charts that are in their own sheets'
For Each chartObj In ActiveWorkbook.Charts
fileNum = NiceFileNumber(exportCount)
exportCount = exportCount + 1
'Do the export'
chartObj.Export fileBase & "_chart" & fileNum & ".png"
Next
'Then, export all charts that are embedded inside normal sheets'
For Each sheetObj In ActiveWorkbook.Worksheets
For i = 1 To sheetObj.ChartObjects.Count
fileNum = NiceFileNumber(exportCount)
exportCount = exportCount + 1
'Do the export'
sheetObj.ChartObjects(i).Activate
ActiveChart.Export fileBase & "_chart" & fileNum & ".png"
Next i
Next
End Sub
'small nicety to ensure two-digits for better file sorting'
Function NiceFileNumber(num As Integer) As String
If num < 10 Then
NiceFileNumber = "0" & num
Else
NiceFileNumber = num
End If
End Function
I would not place this macro in a "run everytime you open excel" location. That's just not your intend. Instead, I would save this macro in a addin and add a simple button into the Office-Ribbon.
This way, your macro should show up, but don't do anything until you are clicking the button.
Building a Button for a macro is not so complicated, it consists of the following steps:
1. Store your macro as addin (*.xlam). You will redirected to a folder in %Appdata% and thats ok. Excel stores all addins there.
1a: Beware: Don't throw away your normal xlsm file - it is difficult to edit a addin, so I usually edit the macro and simply save again.
1b: Beware: Make sure ysou delete uneccessary sheets from the macro before saving it as addin. If you forget this, your addin will become big and slowdown excel startup considerably.
2: Close all Excel instances and fire up a xml editor for office like "Custom UI Editor For Microsoft Office"
3: Insert a Office 2007 custom ui part into the file
4: Insert the following xml to the file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon>
<tabs>
<tab id="Best" label="Best Tools">
<group id="MyGroup" visible="true" label="GroupLabel">
<button id="MyMacroID" imageMso="TableIndexes" size="large"
label="Export"
onAction="DoMacro" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
This will call you macro, provided you have a "Public Sub DoMacro (obj as variant)" in your addin.
5. activate your addin in the excel-options (this is a little different four excel-versions, so you have to look up it yourself.
Additional Information:
More general Information about Ribbon-Xml can be found here:
http://gregmaxey.mvps.org/word_tip_pages/customize_ribbon_main.html
The image for the button (imageMso="TableIndexes" in xml) can be customized to a large number of buttons, download the file from microsoft to see which are available: http://www.microsoft.com/en-us/download/details.aspx?id=11675

Getting the selected item from the dropdown in a ribbon in Word 2007 using macro

I see the following question which explains how to get the selected item from the dropdown:-
http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/d1cf7b3e-68cf-4b82-b806-a3431acde3b6/
The above thread advises to have a hashtable of the items upfront, cache the selected id in the onAction() of the dropdown and use that selected id to find the item from the hashtable in the onAction() of the button.
BUT, in my case, I populate the ribbon XML from the database. This ribbon XML obviously has the XML for dropdown and I am useing macros to interact with the dropdown and other controls in the ribbon. I am not sure how to have a collection upfront which can be used by the macro similar to approach described in the above thread.
I wanted to put the solution just in case someone has the same problem:-
This is how my ribbon dropdown looks like :-
<dropDown id="ddlItem"
getItemLabel="SetTheSelectedItemInDropDown"
onAction="GetTheSelectedItemInDropDown" label="Items">
<item id="Item1" label="Item1"/>
<item id="Item1" label="Item1"/>
<item id="Item1" label="Item1"/>
<item id="Item1" label="Item1"/>
<item id="Item1" label="Item1"/>
<item id="Item1" label="Item1"/>
<item id="Item1" label="Item1"/>
</dropDown>
Note the callbacks for getItemLabel and onAction. Interestingly, getItemLabel is meant for setting the item on the dropdown (get by the dropdown). It is kinda confusing but thats the way it is and thats why I named my method as "SetTheSelectedItemInDropDown".
Function "GetTheSelectedItemInDropDown" for the onAction is to get the selected item.
Now following is the macro code:-
' Declare a global variable to hold the selected item
Dim itemName As String
' Definition of GetTheSelectedItemInDropDown which gets the selected item of the dropdown
Sub GetTheSelectedItemInDropDown(control As IRibbonControl
, id As String, index As Integer)
If control.id = "ddlItems" Then
itemName= id
End If
End Sub
'Definition for SetTheSelectedItemInDropDown which sets the value in the dropdown from the global variable
Sub SetTheSelectedItemInDropDown(control As IRibbonControl,
index As Integer, ByRef returnedVal)
If control.id = "ddlItems" Then
returnedVal = itemName
End If
End Sub
And thats it, you should be able to set and get the dropdown now.
Next function script is for Excel...
after 2 hour testing and google searching, i´ve found a way how to change and get value.
1.) You must have list of items (sequence), witch are in dropdowns.
2.) use .onaaction and application.caller features: (sorry for czech language in next script):
Sub test1()
Dim zabka As Byte
zabka = ActiveSheet.DropDowns((Application.Caller)).Value
'MsgBox zabka
Select Case zabka
Case 1
ActiveSheet.DropDowns((Application.Caller)).Text = "předání signální paré"
Case 2
ActiveSheet.DropDowns((Application.Caller)).Text = "předání čistopis"
Case 3
ActiveSheet.DropDowns((Application.Caller)).Text = "předání dokumentace SP"
End Select
End Sub
Sub aha()
With ActiveSheet.DropDowns.Add(Left:=Range("B" & 11 - 1).Left + 27, Top:=Range("B" & 11 - 1).Top, Width:=113, Height:=14)
.Caption = ""
.Name = "251"
.Text = "hoho"
.AddItem "předání signální paré"
.AddItem "předání čistopis"
.AddItem "předání dokumentace SP"
.OnAction = "test1"
'"'test1 " & xy & " '" <-way to call a sub and give a variable
End With
End Sub