gpt4 book ai didi

excel - 在没有模块级变量的情况下使功能区控制无效

转载 作者:行者123 更新时间:2023-12-02 23:13:17 25 4
gpt4 key购买 nike

我开发了一个包含自定义功能区的 Excel 加载项。我希望能够在某些情况下使功能区上的控件无效(启用/禁用),但我能找到的每个示例都使用模块级或全局变量在首次加载功能区时存储功能区对象。这似乎是一个好方法,但是,如 listed here ,在某些情况下变量可以为空。

所以我想知道,是否有一种不同的方法可以实现在 Excel 功能区中启用/禁用控件的结果,而不使用变量来存储功能区对象,甚至根本不使用 invalidate 方法?

最佳答案

阅读您的描述后,我假设您已经开发了一个纯 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

这样做后,您可以稍后恢复对功能区对象的引用(如有必要)。您可以通过调用以下示例中的“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

我建议在 Excel session 结束时清除辅助单元格,否则 Excel 有时会意外崩溃。

替代方案:将 VBA 外接程序重新开发为 VSTO 外接程序,以避免丢失对象引用的问题。

关于excel - 在没有模块级变量的情况下使功能区控制无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34319470/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com