excelvbaxmlcustom-ui

Dynamically Show/Hide Custom Ribbon Tab


Currently I am developing a custom ribbon tab (using the Office CustomUI Editor) that is to show/hide when the user navigates to any page with "Roster" in its name. Below is my XML:

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="RibbonOnLoad">
<ribbon>
    <tabs>
      <tab id="customRosterTab" label="Roster Tools" getEnabled="IsRosterTabEnabled">
        <group id="rosterGroup" label="Roster Actions" />
      </tab>
    </tabs>
  </ribbon>
</customUI>

I am using the VB script in the ThisWorkbook module:

Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    If Not ribbonUI Is Nothing Then
        ribbonUI.Invalidate ("customRosterTab") ' Forces the ribbon to refresh, calling IsRosterTabEnabled
    End If
End Sub

and the script below in a separate module:

Dim ribbonUI As IRibbonUI

' Initialize ribbon UI
Sub RibbonOnLoad(ribbon As IRibbonUI)
    Set ribbonUI = ribbon
    MsgBox "Ribbon has loaded successfully!"
End Sub

' Callback function to enable/disable the tab based on sheet name
Function IsRosterTabEnabled(control As IRibbonControl) As Boolean
    ' Enable tab if the active sheet's name contains "Roster"
    IsRosterTabEnabled = InStr(1, ActiveSheet.Name, "Roster", vbTextCompare) > 0
End Function

Unfortunately, every time I change to any sheet containing "Roster" in its name, I get an "Object Required" error on this line "If Not ribbonUI Is Nothing Then" (because ribbonUI is empty).

I'm not sure how to fix this. Can anybody provide any insight?


Solution

  • Turns out, using the Tag attribute is ideal. Here's what I did:

    In a standard module I put this

    Option Explicit
    
    Dim Rib As IRibbonUI
    Dim MyTag As String
    
    'Callback for customUI.onLoad
    Sub RibbonOnLoad(ribbon As IRibbonUI)
        Set Rib = ribbon
    End Sub
    
    Sub GetVisible(control As IRibbonControl, ByRef visible)
        If control.Tag Like MyTag Then
            visible = True
        Else
            visible = False
        End If
    End Sub
    
    Sub RefreshRibbon(Tag As String, Optional TabID As String)
        MyTag = Tag
        If Rib Is Nothing Then
            MsgBox "Error, restart your workbook"
        Else
            Rib.Invalidate
            If TabID <> "" Then Rib.ActivateTab TabID
        End If
    End Sub
    

    Then, in the ThisWorkbook module

    Private Sub Workbook_SheetActivate(ByVal Sh As Object)
            
            Select Case True
                Case Sh.Name Like "*Roster"
                    Call RefreshRibbon(Tag:="RosterTab", TabID:="tabRosterSheet")        
                Case Else
                    Call RefreshRibbon(Tag:="")
            End Select
    
    End Sub
    

    And in my XML

    <tab id="tabRosterSheet" label="Roster Sheet Tools" insertBeforeMso="TabInsert" tag="RosterTab" getVisible="GetVisible">
    

    Works like a charm!