ARi*_*ich 4 excel vba ribbon ms-office excel-2013
我开发了一个包含自定义功能区的 Excel 加载项。我希望能够在某些情况下使功能区上的控件无效(启用/禁用),但是我能找到的每个示例都使用模块级或全局变量在首次加载功能区时存储功能区对象。这似乎是一个很好的方法,但是,正如这里列出的那样,有些情况下变量可以为空。
所以我想知道,是否有不同的方法来实现在 Excel 功能区中启用/禁用控件的结果,而不使用变量来存储功能区对象,甚至根本不使用 invalidate 方法?
小智 5
阅读您的描述后,我假设您已经开发了一个纯 Excel VBA 加载项(而不是例如 Excel VSTO 加载项)。因此,恐怕没有其他方法可以实现您的目标。幸运的是,有一种解决方法可以在重置后恢复对功能区对象的对象引用。
解决方法: 在“Ribbon_Load”事件处理程序中,您将在其中设置对 Excel 功能区对象的对象引用,您还应该保存功能区对象的“ObjPtr()”值(例如,在工作表单元格中)。例如像这样:
Public gobjRibbon As Office.IRibbonUI
' Callback for customUI.onLoad
Sub Ribbon_Load(ribbon As Office.IRibbonUI)
Set gobjRibbon = ribbon
SampleWorksheet.Cells(1,1).Value = ObjPtr(ribbon)
End Sub
Run Code Online (Sandbox Code Playgroud)
这样做之后,您可以稍后恢复对功能区对象的引用(如有必要)。您可以通过调用以下示例中的“RefreshRibbon”过程(也会使整个功能区无效)来实现此目的:
#If VBA7 Then
Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
#Else
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
#End If
#If VBA7 Then
Function GetRibbon(ByVal lRibbonPointer As LongPtr) As Object
#Else
Function GetRibbon(ByVal lRibbonPointer As Long) As Object
#End If
Dim objRibbon As Object
Call CopyMemory(objRibbon, lRibbonPointer, LenB(lRibbonPointer))
Set GetRibbon = objRibbon
Set objRibbon = Nothing
End Function
Public Sub RefreshRibbon()
If gobjRibbon Is Nothing Then
Set gobjRibbon = GetRibbon(SampleWorksheet.Cells(1,1).Value)
' Else: Do nothing!
End If
On Error Resume Next
gobjRibbon.Invalidate
On Error GoTo 0
End Sub
Run Code Online (Sandbox Code Playgroud)
我建议在 Excel 会话结束时清除辅助单元格,否则 Excel 有时会令人惊讶地崩溃。
替代方法: 将您的 VBA 加载项重新开发为 VSTO 加载项,以避免出现丢失对象引用的问题。
归档时间: |
|
查看次数: |
1547 次 |
最近记录: |