You need to configure the tape at runtime.
Check my question (and answer) here , although my problem was in PPT VBA, I tested in Excel, and the solution to your problem should be very similar.
Instead of setting Boolean true or false for the visible property for each button, you need a different callback so that when loading this tab, the procedure checks whether the class object was created, and then sets true or false as necessary.
For example, in my PPT part of my XML:
... <tab idMso="TabView"> <group idMso="GroupMasterViews" getVisible="VisibleGroup"/> <group idMso="GroupPresentationViews" getVisible="VisibleGroup"/> </tab> ...
Therefore, instead of using the visible property for the group, I use the getVisible custom attribute, which invokes the VisibleGroup macro. There are some nuances that I encountered, for example, I could not use the same callback / macro for different types of controls, so I have two callbacks ( EnabledControl and VisibleGroup ), both of which do exactly the same . I do not know why, and this part of the development does not seem to be very well documented, unfortunately.
Check my code to see all the places where I set breakpoints during testing. I had to debug a bit to make it work. Put breakpoints in each procedure and execute your code. Itβs a pain in the ass, but if you get to that, Iβm sure you can make it work.
UPDATE
I did a quick test on my PPT add-in. This is functionally similar, so it's easier for me to test than trying to recreate everything in Excel.
My add-in has its own menu group and some custom buttons. Corresponding line of buttons:
<button id="HelpButton" label="Help" getVisible="EnableControl" onAction="HelpFile" />
Full XML for your reference:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <customUI onLoad="RibbonOnLoad" xmlns="http://schemas.microsoft.com/office/2009/07/customui"> <commands> <command idMso="ViewSlideSorterView" getEnabled="EnableControl"/> <command idMso="ViewNotesPageView" getEnabled="EnableControl"/> <command idMso="ViewSlideShowReadingView" getEnabled="EnableControl"/> <command idMso="ViewSlideMasterView" getEnabled="EnableControl"/> <command idMso="ViewHandoutMasterView" getEnabled="EnableControl"/> <command idMso="ViewNotesMasterView" getEnabled="EnableControl"/> <command idMso="WindowNew" getEnabled="EnableControl"/> </commands> <ribbon startFromScratch="false"> <tabs> <tab idMso="TabView"> <group idMso="GroupMasterViews" getVisible="VisibleGroup"/> <group idMso="GroupPresentationViews" getVisible="VisibleGroup"/> </tab> <tab id="TabTiger" label="Chart Builder" insertAfterMso="TabDeveloper"> <group id="GroupTigerMain" label="XXXX Chart Builder"> <menu id="TigerMenu" image="XXXXLogo" size="large"> <button id="LaunchButton" label="Launch Chart Builder" onAction="ShowChart_Form" /> <button id="InfoButton" label="Info" onAction="Credit_Inf" /> <button id="VersionButton" label="Version" onAction="VersionNum" /> <button id="HelpButton" label="Help" getVisible="EnableControl" onAction="HelpFile" /> </menu> </group> </tab> </tabs> </ribbon> </customUI>
The EnableControl procedure looks like this (I will intentionally uncomment the MsgBox so that I can break and enter the code, you can do this just for debugging and ensuring that the correct logical val is passed to the control):
Sub EnableControl(control As IRibbonControl, ByRef returnedVal) returnedVal = Not TrapFlag 'TrapFlag = True indicates the Application is running. MsgBox ("GetEnabled for " & control.Id) 'Debug.Print control.Id & " enabled = " & CStr(returnedVal) Call RefreshRibbon(control.Id) End Sub
You will need to change the logic that assigns returnedVal to your needs. But basically, this macro should fire every time the button is displayed, so in my case it fires every time I open the menu containing it.
As long as the returnedVal value is false until Call RefreshRibbon(control.Id) , then the procedure works and the button no longer appears in my menu bar.