How can I set a text in a Ribbon Editbox? I can't find it on internet :/
I just can find examples of click event but nothing about set a text from a Sub.
So for example, I want something like this:
Sub settingText()
editboxname = "my text"
end sub
The solution I found on this link: http://www.shulerent.com/2011/08/16/changing-the-value-of-an-editbox-office-ribbon-control-at-runtime/
Here is an example that I tested and it worked well:
'Global Variables:
Public MyRibbonUI As IRibbonUI
Public GBLtxtCurrentDate As String
Private Sub OnRibbonLoad(ribbonUI As IRibbonUI)
Set MyRibbonUI = ribbonUI
GBLtxtCurrentDate = ""
End Sub
Private Sub ocCurrentDate(control As IRibbonControl, ByRef text)
GBLtxtCurrentDate = text
MyRibbonUI.InvalidateControl (control.id)
End Sub
Private Sub onGetEbCurrentDate(control As IRibbonControl, ByRef text)
text = GBLtxtCurrentDate
End Sub
Public Sub MyTest()
'Here is an example which you are setting a text to the editbox
'When you call InvalidateControl it is going to refresh the editbox, when it happen the onGetEbCurrentDate (which is the Gettext) will be called and the text will be atributed.
GBLtxtCurrentDate = "09/09/2013"
MyRibbonUI.InvalidateControl ("ebCurrentDate")
End Sub
<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="OnRibbonLoad">
<ribbon>
<tabs>
<tab id="Objects" label="Objects">
<group id="grp" label="My Group">
<editBox id="ebCurrentDate" label="Date" onChange="ocCurrentDate" getText="onGetEbCurrentDate"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
It's a little while since this answer was posted, and there looks to be a recent-ish change to the behaviour of the ribbon, which means the original answer posted may not be a solution any more. For the record, I'm using Excel 2013 with some updates that are dated after Braulio's answer.
The heart of the difference is that Invalidate and InvalidateControl on the ribbon don't behave the same way as previously. This means that InvalidateControl does not call the getText callback on the editBox. I replaced the InvalidateControl calls with Invalidate (so forces a re-draw on the entire ribbon), and that does trigger the callback as expected.
So here's the code of my solution for a filename/browse button (note I've included extra code for caching the ribbon UI reference on a very hidden sheet so that resets during development don't make the ribbon inaccessible).
Private sobjRibbon As IRibbonUI
Private strFilename As String
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (destination As Any, source As Any, ByVal length As Long)
Private Function GetRibbon() As IRibbonUI
If sobjRibbon Is Nothing Then
Dim objRibbon As Object
CopyMemory objRibbon, ThisWorkbook.Worksheets("Ribbon_HACK").Range("A1").Value, 4
Set sobjRibbon = objRibbon
End If
Set GetRibbon = sobjRibbon
End Function
'Callback for customUI.onLoad
Sub Ribbon_Load(ribbon As IRibbonUI)
Set sobjRibbon = ribbon
Dim lngRibPtr As Long
lngRibPtr = ObjPtr(ribbon)
' Write pointer to worksheet for safe keeping
ThisWorkbook.Worksheets("Ribbon_HACK").Range("A1").Value = lngRibPtr
strFilename = ""
End Sub
'Callback for FileName onChange
Sub OnChangeFilename(control As IRibbonControl, text As String)
strFilename = text
End Sub
'Callback for FileName getText
Sub GetFileNameText(control As IRibbonControl, ByRef returnedVal)
returnedVal = strFilename
End Sub
'Callback for FilenameBrowse onAction (I'm looking for XML files here)
Sub OnClickFilenameBrowse(control As IRibbonControl)
Dim objFileDialog As Office.FileDialog
Set objFileDialog = Application.FileDialog(msoFileDialogFilePicker)
With objFileDialog
.AllowMultiSelect = False
.Title = "Please select the file."
.Filters.Clear
.Filters.Add "XML", "*.xml"
If .Show = True Then
strFilename = .SelectedItems(1)
GetRibbon().Invalidate ' Note the change here, invalidating the entire ribbon not just the individual control
End If
End With
End Sub
For the record, here's the XML for the two objects I'm dealing with here:
<editBox id="FileName" onChange="OnChangeFilename" screentip="Filename of the XML file to upload" label="XML file name" showImage="false" getText="GetFileNameText" />
<button id="FilenameBrowse" imageMso="ImportExcel" onAction="OnClickFilenameBrowse" screentip="Find the file to upload" label="Browse" />
Related
In the xml I have a button for the ribbon:
<button id="PRUEBA" label="Boton Prueba" size="normal" onAction="Macro11" imageMso="DirectRepliesTo" tag="EtiquetaG" getEnabled="Habilitado"/>
For vba:
I would like this button to appear enabled to work on the ribbon, but once pressed, do the macro for which it is defined, then the button is disabled for two seconds and is enabled again.
Thanks.
In the ribbon XML you use the getEnabled callback which returns the control's state as a boolean value:
getEnabled="Habilitado"
You need to make sure it always returns a valid result depending on which your control can be disabled and enabled dynamically at runtime.
I dont speak english, sorry. I use a translator. Well, What I intend is that when pressing the button on the ribbon, it is disabled a couple of seconds after executing the macro. The macro does nothing, it just inserts a content block of Word. Although the example I give is a test in an excel sheet, it would be for a word document. It is related to the post: Enable/Disable Ribbon Controls Independently But I would only like it to work with a button and put a timer. I do not know how to do it.
Option Explicit
Dim Rib As IRibbonUI
Public MyTag As String
'Public EnableButton1 As Boolean
Sub Habilitado(control As IRibbonControl, ByRef Enabled)
If MyTag = "Enable" Then
Enabled = True
Else
If control.Tag Like MyTag Then
Enabled = True
Else
Enabled = False
End If
End If
End Sub
Sub EnableControlsWithCertainTag3()
'Habilita solo el control con la etiqueta Tag "SoloUno"
Call RefrescarCinta(Tag:="SoloUno")
End Sub
Sub EnabledAllControls()
'Habilita todos
Call RefrescarCinta(Tag:="*")
End Sub
Sub DisableAllControls()
'Deshabilita todos
Call RefrescarCinta(Tag:="")
End Sub
Sub RefrescarCinta(Tag As String)
MyTag = Tag
If Rib Is Nothing Then
MsgBox "Cierra y vuelve a abrir" & vbNewLine & _
"Visit this page for a solution:
http://www.rondebruin.nl/ribbonstate.htm"
Else
Rib.Invalidate
End If
End Sub
Sub RibbonOnLoad(ribbon As IRibbonUI)
Set Rib = ribbon
End Sub
Lines on XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customUI onLoad="RibbonOnLoad"
xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<!-- Add two custom groups on the Home Tab with a few buttons -->
<ribbon>
<tabs>
<tab idMso="TabHome" >
<group id="MyCustomGroup1" label="Group1"
tag="MyPersonalGroup1" >
<button id="G1B1" label="Caption 1" size="normal"
onAction="Macro1" imageMso="DirectRepliesTo"
tag="SoloUno" getEnabled="Habilitado"/>
<button id="PRUEBA" label="Boton Prueba" size="normal"
onAction="Macro11" imageMso="DirectRepliesTo"
tag="EtiquetaG" getEnabled="Habilitado"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
Macros:
Sub Macro1(control As IRibbonControl)
MsgBox "This is Macro 1 in group 1"
End Sub
Sub Macro11(control As IRibbonControl)
Application.OnTime Now + TimeValue("00:00:02"), "Macro12"
End Sub
Sub Macro12()
MsgBox "El mensaje funciona; intenta incluir en el modulo macro del
mensaje, un timer, a ver que pasa"
End Sub
I have a customUI with an EditBox and want to set the default value when the User opens the Visio template file.
Here is the customUI xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="CustomRibbonOnLoad">
<ribbon>
<tabs>
<tab id="CustomTab1" label="My Tab">
<group
id="BOMGroup"
label="BOM"
autoScale="true"
>
<editBox id="BOMLink" label="BOM Link:" onChange="ThisDocument.BOMLink_onChange" getText = "ThisDocument.BOM_getText"/>
<button
id="GoToBOMLink"
label="Go To BOM Link"
screentip="Opens Browser to go to BOM Link"
size="large"
imageMso="HyperlinkOpenExcel"
onAction="ThisDocument.OpenBOM"
/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
So I expect BOMLink to have its default text updated through its getText callback function.
Here is my vba code:
Dim MyRibbon As IRibbonUI
Sub CustomRibbonOnLoad(ribbon As IRibbonUI)
Set MyRibbon = ribbon
Debug.Print "CustomRibbonOnLoad called"
MyRibbon.InvalidateControl ("BOMLink") ' Invalidates the cache of a single control
End Sub
Sub myFunction()
MyRibbon.InvalidateControl ("BOMLink") ' Invalidates the cache of a single control
End Sub
'Callback for BOMLink onChange
Sub BOMLink_onChange(control As IRibbonControl, text As String)
End Sub
'Callback for BOMLink getText
Sub BOM_getText(control As IRibbonControl, ByRef returnedVal)
Debug.Print "Callback UpdateBOMLinkText"
MyRibbon.InvalidateControl ("BOMLink") ' Invalidates the cache of a single control
returnedVal = "test default text"
End Sub
'Callback for GoToBOMLink onAction
Sub OpenBOM(control As IRibbonControl)
Debug.Print "Callback OpenBOM"
End Sub
As it stands right now, I do not get the "CustomRibbonOnLoad called" debug print, but I do get the "Callback UpdateBOMLinkText" called. However the text does not change to the default test text as expected.
When I open the document and click the Custom Tab I get this in the debug:
>invokeVBA: ThisDocument.BOM_getText
Callback UpdateBOMLinkText
<invokeVBA: 0x80020009
I am attempting to fill it with "test default text" for now, but in the future want to call upon the Shapesheet and pull data from there to fill by default.
Any help would be appreciated, thanks!
You need to remove this line because it overwrites the value you set in the line before that.
'Callback for BOMLink getText
Sub BOM_getText(control As IRibbonControl, ByRef returnedVal)
Debug.Print "Callback UpdateBOMLinkText"
' MyRibbon.InvalidateControl ("BOMLink") ' <<<< remove this line
returnedVal = "test default text"
End Sub
I need some help with Custom UI Editor code for a Ribbon in Word. The same code I've been using in Word 2010 does not work in Word 2019 any more. When I create a document based off a template the Ribbon is there and works. I save the document and close it. When I reopen the Ribbon is like "dead". It's not activated and the code no longer runs.
What has changed in Word 2019? What do I need to do to correct this issue?
Here is the Custom UI Code:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<!--This is the Expense Template-->
<ribbon>
<tabs>
<tab id="customTab3" label="Expense">
<group id="customGroup110" label="Expense/Disbursement Calculate">
<button id="customButton110" size="large" label="Expense/Disbursement Calculate" imageMso="CreateReport" onAction="ExpenseCalculate" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
Here is the code that is in the template:
Sub ExpenseCalculate(control As IRibbonControl)
' Edited Code On: 2/6/2012
' Edited Code By: Sheila Shines
' Code Change: Added code to test to see what Template a user is in before running code
Dim rowz As Integer
Dim theRow As Integer
Dim rT As Integer
Dim myTemplate As Template
Set myTemplate = ActiveDocument.AttachedTemplate
If UCase(myTemplate.Name) = "EXPENSE.DOTM" Or UCase(myTemplate.Name) = "EXPENSE.DOT" Then
'MOVES TO BEGINNING OF DOCUMENT
Selection.HomeKey unit:=wdStory, Extend:=wdMove
'LINE DOWN
Selection.MoveDown unit:=wdLine, Count:=1, Extend:=wdMove
'LINE DOWN UNTIL INTO A TABLE
While Selection.Information(wdWithInTable) = 0
Selection.MoveDown unit:=wdLine, Count:=1, Extend:=wdMove
Wend
'MOVE TO START OF ROW OF THE TABLE
Selection.StartOf unit:=wdRow, Extend:=wdMove
'SELECTING TABLE
ActiveDocument.Tables(1).Select
'NUMBER OF ROWS IN THE TABLE
rowz = Selection.Information(wdMaximumNumberOfRows)
'MOVING LEFT ONE PLACE
Selection.MoveLeft unit:=wdCharacter, Count:=1, Extend:=wdMove
'ROW CONTAINING THE BEGINNING OF THE SELECTION
theRow = Selection.Information(wdStartOfRangeRowNumber)
'MOVING DOWN ONE LINE AT A TIME THROUGH TABLE
While theRow < rowz
Selection.MoveDown unit:=wdLine, Count:=1, Extend:=wdMove
theRow = Selection.Information(wdStartOfRangeRowNumber)
Wend
'MOVING OVER TWO CELLS
Selection.Move unit:=wdCell, Count:=2
'DELETING INFORMATION OUT OF CELL IF ANY
Selection.Range.Delete
rowz = rowz - 1
rT = Right$(Str$(rowz), Len(Str$(rowz)) - 1)
'INSERTING FIELD INTO TABLE
Selection.InsertFormula Formula:="=sum(c2:c" & CInt(rT) & ")", NumberFormat:="$#,##0.00;($#,##0.00)"
'PRINTING DOCUMENT
ActiveDocument.PrintOut
Else
MsgBox "You need to be in an Expense template in order to use this macro", vbCritical, "In wrong template"
End
End If
End Sub
Here is the solution that I have tried
What happens to the Word session ribbon after closing and reopening a document with a custom ribbon?
https://stackoverflow.com/questions/57841404/what-happens-to-the-word-session-ribbon-after-closing-and-reopening-a-document-w
The solution that you tried looks to be a real kludge and is definitely not something I would recommend. But as it partially worked for you it confirms the gut feeling that I had when I first read your question, that your ribbon needs to be invalidated (refreshed).
There is an answer here that gives the code you need, though I have a few issues with it.
At this point I have to explain that I do not put ribbons, or code, in document templates (I put all my code in a global template and then use ribbon callbacks to determine which controls should be visible/enabled) so I'm not sure if this will work for you.
To make this work you need to get a pointer to the ribbon when it loads. For that you need an onLoad callback and corresponding ribbon xml:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="ribbonOnLoad">
Callback module (BTW, I took the liberty of rewriting your code):
Option Explicit
'CopyMemory for ribbon retrieval
#If Win64 Then
Declare PtrSafe Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
#Else
Public Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
#End If
Private rbnUI As IRibbonUI
Public Property Get RibbonUI() As IRibbonUI
#If Win64 Then
Dim lngRbnPtr As LongPtr
#Else
Dim lngRbnPtr As Long
#End If
Dim objRibbon As Object
If rbnUI Is Nothing Then
'the pointer is lost so retrieve it from the registry
lngRbnPtr = GetSetting("Templates", "Ribbon", "Ribbon Pointer WD")
CopyMemory objRibbon, lngRbnPtr, 4
Set rbnUI = objRibbon
' clean up invalid object
CopyMemory objRibbon, 0&, 4
Set objRibbon = Nothing
End If
Set RibbonUI = rbnUI
End Property
Public Property Set RibbonUI(ribbon As IRibbonUI)
#If Win64 Then
Dim lngRbnPtr As LongPtr
#Else
Dim lngRbnPtr As Long
#End If
Set rbnUI = ribbon
lngRbnPtr = ObjPtr(ribbon)
'save pointer to registry for safe keeping
SaveSetting "Templates", "Ribbon", "Ribbon Pointer WD", lngRbnPtr
End Property
Private Sub ribbonOnLoad(ribbon As IRibbonUI)
' Store pointer to IRibbonUI
Set RibbonUI = ribbon
End Sub
Public Sub ribbonInvalidate()
On Error GoTo ProcError
RibbonUI.Invalidate
ProcExit:
'Clean up
On Error Resume Next
Exit Sub
ProcError:
If Err.Number = 91 Then
MsgBox "Unrecoverable Ribbon Error" & vbCrLf & "" & vbCrLf & _
"Unable to refresh the ribbon. Please save and reopen " & Application.name & _
".", vbOKOnly + vbExclamation, "Ribbon Error"
Else
'add your own
End If
End Sub
Sub ExpenseCalculate(control As IRibbonControl)
Dim myTemplate As Template
Set myTemplate = ActiveDocument.AttachedTemplate
If UCase(myTemplate.name) = "EXPENSE.DOTM" Or UCase(myTemplate.name) = "EXPENSE.DOT" Then
'INSERTING FIELD INTO TABLE
With ActiveDocument.Tables(1).Rows.Last.Cells(3)
.Range.Delete
.Formula Formula:="=sum(above)", NumFormat:="$#,##0.00;($#,##0.00)"
End With
'PRINTING DOCUMENT
ActiveDocument.PrintOut
Else
MsgBox "You need to be in an Expense template in order to use this macro", vbCritical, "In wrong template"
End
End If
Set myTemplate = Nothing
End Sub
Next you need a means of invalidating the ribbon. For this I use a class module that hooks into Word's application events. This enables me to invalidate the ribbon each time ActiveDocument changes, i.e. creating or opening a document, switching between open documents.
Option Explicit
Public WithEvents appWord As Word.Application
Private Sub appWord_DocumentChange()
InvalidateRibbon
End Sub
The class module needs to be initialized when the template is loaded. This can be done using an AutoExec routine. I like to keep the actual initializing in a separate routine so that I can call it from a global error handling routine.
Public wordEvents As clsWordEvents
Public Sub AutoExec()
instantiateEventHandler
End Sub
Public Sub instantiateEventHandler()
If wordEvents Is Nothing Then
Set wordEvents = New clsWordEvents
Set wordEvents.appWord = Word.Application
End If
End Sub
By default, when you create a .dotx document from a template, the macro code is not copied to the document. Instead, the document remains linked to the template and calls the template to run the macro.
Your macro theoretically checks whether the document is attached to a particular template, but since the macro code is only in the template, it can't run if the document is attached to a different template. So nothing happens.
BTW, your heavy use of the Selection object indicates you created this with the macro recorder. That's a good initial learning step, but the code will be more reliable and run faster if you switch all statements to use the Range object instead.
I'd like to create a button that automatically opens a hyperlink from Powerpoint.
It's easy enough to create a hyperlink in Powerpoint (Insert -> Hyperlink) and then click on that hyperlink.
I want to skip this whole process and just be able to have a button that opens a hyperlink rather than having a hyperlink in my presentation that needs to be clicked.
The XML for the button would be something like:
<button id="myButton" label="Open Hyperlink"
imageMso="HyperlinkInsert"
size="large"
onAction="openHyperlink"
/>
Of course you will need to modify the file's Ribbon XML; the above is not a complete ribbon, just the node for the desired button. I have some other Q&A about modifying the ribbon here otherwise there are some great examples if you google for them. Most are for Word or Excel, but the same principles apply. If you need references, let me know and I can provide a few.
And the callback would be like:
Sub openHyperlink(control As IRibbonControl)
'your code that opens the hyperlink goes in here, something like:
Dim ie as Object
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.Navigate "http://google.com"
End Sub
To open a PDF instead of a browser, change that procedure:
Sub openHyperlink(control As IRibbonControl)
Dim acroPath As String
Dim filePath As String
acroPath = "C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe" 'Modify as needed
filePath = "c:\users\me\file.pdf" 'Modify as needed
Shell acroPath & " " & filePath, vbNormalFocus
End Sub
You can use the ShellExecute API to open any document in the default app for that document's extension. Here's a simplified hack to start with:
Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As Long, ByVal lpszOp As String, _
ByVal lpszFile As String, ByVal lpszParams As String, _
ByVal LpszDir As String, ByVal FsShowCmd As Long) _
As Long
Function ShellEx(sFile As String) As Long
ShellEx = ShellExecute(&O0, "Open", sFile, "", "C:\", 1)
End Function
Sub Test()
Debug.Print ShellEx("path to file goes here")
End Sub
More detailed version with all the options here:
http://support.microsoft.com/kb/170918
I have create an xla (excel add-in) that have a function to protect the document (so that user could protect the document without knowing the password). This xla is added in every excel file that need this functionality.
when the xla is installed or added to excel, the protect button will be added in last menu. but when i click the button, an error occur show that
"Cannot run the macro Pivot Add-In 0.2'!protectSheet'". The macro may not be available in this workbook or all macros may be disabled."
The code that event handler onclicked is protectSheet, please see the source below:
Could anyone pointed my why this problem occur?
on ThisWorkbook
'main function'
Public Sub protectSheet()
ActiveWorkbook.ActiveSheet.protect Password:="password", AllowUsingPivotTables:=True
End Sub
Public Sub ShowToolbar()
' Assumes toolbar not already loaded '
Application.CommandBars.Add Module1.TOOLBARNAME
AddButton "Proteksi Sheet", "Memproteksi Pivot", 3817, "protectSheet"
' call AddButton more times for more buttons '
With Application.CommandBars(Module1.TOOLBARNAME)
.Visible = True
.Position = msoBarTop
End With
End Sub
Public Sub AddButton(caption As String, tooltip As String, faceId As Long, methodName As String)
Dim Btn As CommandBarButton
Set Btn = Application.CommandBars(Module1.TOOLBARNAME).Controls.Add
With Btn
.Style = msoButtonIcon
.faceId = faceId ' choose from a world of possible images in Excel: see http://www.ozgrid.com/forum/showthread.php?t=39992 '
.OnAction = methodName
.TooltipText = tooltip
End With
End Sub
Public Sub DeleteCommandBar()
Application.CommandBars(TOOLBARNAME).Delete
End Sub
'called when add-in installed
Private Sub Workbook_AddinInstall()
Call ShowToolbar
End Sub
'called when add-in uninstalled
Private Sub Workbook_AddinUninstall()
Call DeleteCommandBar
End Sub
On module1
Public Const TOOLBARNAME = "PivotTools"
After moving all function to module1 , then retain caller function on ThisWorkbook the error now gone. Seem that i have to define all functionality that call/ use constant (Public Const TOOLBARNAME = "PivotTools") in the same file (in my case in module1)
on module1 file
Public Const TOOLBARNAME = "PivotTools"
'caller method'
Public Sub protectDoc()
On Error GoTo errorInfo
protectSheet
'if success, show msg box'
MsgBox ("Report berhasil diproteksi")
Exit Sub
errorInfo:
MsgBox Err.Description & vbCrLf & Err.Number
End Sub
Public Sub protectSheet()
ActiveWorkbook.ActiveSheet.protect Password:="password", AllowUsingPivotTables:=True
End Sub
Public Sub refreshDoc()
On Error GoTo errorInfo
refreshConnection
protectSheet
'if success, show msg box'
MsgBox ("Report berhasil diperbaharui")
Exit Sub
errorInfo:
MsgBox Err.Description & vbCrLf & Err.Number
End Sub
Private Sub refreshConnection()
ActiveWorkbook.ActiveSheet.Unprotect Password:="password"
ActiveWorkbook.RefreshAll
End Sub
Public Sub ShowToolbar()
' Assumes toolbar not already loaded '
Application.CommandBars.Add TOOLBARNAME
AddButton "Proteksi Sheet", "Memproteksi Pivot", 225, "protectDoc"
AddButton "Refresh Data", "Refresh Pivot", 459, "refreshDoc"
' call AddButton more times for more buttons '
With Application.CommandBars(TOOLBARNAME)
.Visible = True
.Position = msoBarTop
End With
End Sub
Public Sub AddButton(caption As String, tooltip As String, faceId As Long, methodName As String)
Dim Btn As CommandBarButton
Set Btn = Application.CommandBars(TOOLBARNAME).Controls.Add
With Btn
.Style = msoButtonIcon
.faceId = faceId
' choose from a world of possible images in Excel: see http://www.ozgrid.com/forum/showthread.php?t=39992 '
.OnAction = methodName
.TooltipText = tooltip
End With
End Sub
Public Sub DeleteCommandBar()
Application.CommandBars(TOOLBARNAME).Delete
End Sub
on ThisWorkbook
'called when add-in installed
Private Sub Workbook_AddinInstall()
Call Module1.ShowToolbar
End Sub
'called when add-in uninstalled
Private Sub Workbook_AddinUninstall()
Call Module1.DeleteCommandBar
End Sub
I had this issue, but found that I had my module named the same as my sub (e.g. module named as "InsertLineID" and the sub was "InsertLineID").
Changing the module name to "LineID" and leaving the sub as "InsertLineID" worked a treat for me!