我们有一个自定义 UI,在工作空间环境中添加了两个功能区。此 CustomUI 有一个 OnLoad 事件,该事件将功能区的指针变量加载到内存中以供稍后访问。不幸的是,如果代码突然停止并丢失其状态,则没有明确的机制可以恢复此状态变量。唯一明显的方法是重新启动 Excel。如果 IRibbonUI 变量丢失,我需要一种方法将其恢复到内存中。
当我在互联网上搜索时,我看到了 Ron de Bruin 的一篇文章,不幸的是,对于 Windows Excel 编程世界,他选择从互联网上删除他的 Windows 材料。我能够挖掘互联网档案,找到他的解决方案,我发现它非常优雅,并且我立即实施了。由于此 CustomUI 与加载项绑定;我在工作表上存储信息没有问题,因为它是隐藏的且未使用,但我还遇到了另一种用于存储在 .Net 域中的变量中的选项。我会分享两个
Ron de Bruin 的解决方案基于 Excel MVP RoyA 此处。
Public Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias _
"RtlMoveMemory" (ByRef destination As Any, ByRef source As Any, ByVal length As Long)
#If VBA7 Then
Public Function GetRibbon(ByVal lRibbonPointer As LongPtr) As Object
#Else
Public Function GetRibbon(ByVal lRibbonPointer As Long) As Object
#End If
Dim objRibbon As Object
CopyMemory objRibbon, lRibbonPointer, LenB(lRibbonPointer)
Set GetRibbon = objRibbon
Set objRibbon = Nothing
End Function
Public Sub GetVisibleRibbon(control As IRibbonControl, ByRef visible)
If MyTag = "show" Then
visible = True
Else
If control.Tag Like MyTag Then
visible = True
Else
visible = False
End If
End If
End Sub
Public Function RefreshRibbon(Tag As String) As IRibbonUI
MyTag = Tag
If MyRibbonUI Is Nothing Then
Set MyRibbonUI = GetRibbon(ThisWorkbook.Sheets(1).Range("A30").Value)
MyRibbonUI.Invalidate
MsgBox "The Ribbon handle was lost, Hopefully this is sorted now by the GetRibbon Function?. You can remove this msgbox, I only use it for testing"
Else
MyRibbonUI.Invalidate
End If
Set RefreshRibbon = MyRibbonUI
End Function
Public Sub OnRibbonLoad(ribbonUI As IRibbonUI)
On Error Resume Next
Set MyRibbonUI = ribbonUI
ThisWorkbook.Sheets(1).Range("A30").Value = ObjPtr(ribbonUI)
End Sub
我修改了 Ron 的解决方案,将 RefreshRibbon 转变为函数而不是 Sub,因此,它可以在代码中使用该变量的所有位置用作变量。
然后我遇到了另一个用户提出的 Stack Overflow 问题,该用户不喜欢使用对象指针的单元存储的解决方案,所以我想我会在此处链接这篇文章
-CJ