目前我正在开发一个自定义功能区选项卡(使用 Office CustomUI 编辑器),当用户导航到名称中包含“Roster”的任何页面时显示/隐藏该选项卡。下面是我的 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>
我在 ThisWorkbook 模块中使用 VB 脚本:
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
以及下面的脚本位于单独的模块中:
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
不幸的是,每次我更改为名称中包含“Roster”的任何工作表时,我都会在“If NotribbonUIIsNothingThen”这一行上收到“ObjectRequired”错误(因为ribbonUI为空)。
我不知道如何解决这个问题。有人可以提供任何见解吗?
有两个原因可以解释您收到的错误:
ThisWorkbook
代码模块访问它。因此,它必须声明为: Public ribbonUI As IRibbonUI
Option Explicit
'This goes in the standard module top part, in the declarations area:
'To memorize the Ribbon object pointer! _____________________________________
#If VBA7 Then
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal length As LongPtr)
#Else
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
#End If
'______________________________________________________________________
Public ribbonUI As IRibbonUI
Const strRib As String = "\MyRibb"
' Modify the initialization of ribbon UI in the next way:
Sub RibbonOnLoad(ribbon As IRibbonUI)
Dim Path As String: Path = Environ("temp") & strRib
Dim File As Integer: File = FreeFile
Open Path For Output As #File
Print #File, ObjPtr(ribbon) 'memorize IRibbonUI pointer
Close #File
Set ribbonUI = ribbon
Debug.Print "Ribbon has loaded successfully!"
End Sub
Sub getRibbon() 'reSet ribbonUI if it was lost (it's Nothing):
Dim Path As String: Path = Environ("temp") & strRib
Dim File As Integer: File = FreeFile
Dim ribValue As String
If ribbonUI Is Nothing Then
Open Path For Input As #File
Input #File, ribValue
Close #File
#If VBA7 Then
CopyMemory ribbonUI, CLngPtr(ribValue), 8 'place in memory IRibbonUI object from its memorized pointer '64 bit
#Else
CopyMemory ribbonUI, CLng(ribValue), 4 'place in memory IRibbonUI object from its memorized pointer
#End If
Debug.Print "Ribbon object recuperated..."
End If
End Sub
在上述模块中保留所有必要的功能,您已经使用的子功能。
现在,按以下方式修改您的事件代码:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If ribbonUI Is Nothing Then getRibbon 'ribbon object is recuperated if lost
ribbonUI.Invalidate ("customRosterTab") ' Forces the ribbon to refresh, calling IsRosterTabEnabled
End Sub