运行代码时未调用Excel VBA功能区getEnabled

运行代码时未调用Excel VBA功能区getEnabled,vba,excel,ribbonx,Vba,Excel,Ribbonx,我有一个Excel VBA宏,可以运行很长时间(可能会运行几天,它会执行数据采集)。它最初是为Excel2003编写的,具有自定义工具栏和菜单。 我最近更新了它,使用RibbonXML使用ribbon接口 当宏运行时,我想禁用一些接口元素(如“开始测试”),并启用其他元素(如“停止测试”按钮) 我遇到的问题是,对ribbon.invalidate的调用只有在宏代码运行到完成之后才能处理 通过一个简单的测试程序,您可以很容易地看到这种效果 Sub test() ribbon.Invalidate

我有一个Excel VBA宏,可以运行很长时间(可能会运行几天,它会执行数据采集)。它最初是为Excel2003编写的,具有自定义工具栏和菜单。 我最近更新了它,使用RibbonXML使用ribbon接口

当宏运行时,我想禁用一些接口元素(如“开始测试”),并启用其他元素(如“停止测试”按钮)

我遇到的问题是,对ribbon.invalidate的调用只有在宏代码运行到完成之后才能处理

通过一个简单的测试程序,您可以很容易地看到这种效果

Sub test()

ribbon.Invalidate
DoEvents
Sleep (5000)

End Sub
功能区“getEnabled”回调中的debug.print将被视为仅在5秒睡眠结束时执行

有没有办法强制一个ribbon.Invalidate在那里激活,然后呢

::编辑1::

我创建了一个小的演示工作簿来说明这个问题:

::编辑2::

另一个论坛的一位成员找到了一个解决方案,尽管这个方案有点难看。 我想现在可以将其标记为“已回答”,但如果有更优雅的解决方案,我们将不胜感激

Application.ScreenUpdating = False
Application.ExecuteExcel4Macro "Show.ToolBar(""Ribbon"",False)"
Application.ExecuteExcel4Macro "Show.ToolBar(""Ribbon"",True)"
Application.ScreenUpdating = True

我不知道这是否比你的丑陋,但是

'Callback for Run onAction
Sub Run_r(control As IRibbonControl)

    SetRunning "Run_r_procedure"
    DoEvents

End Sub

Sub Run_r_procedure()
    Dim T As Single

    Sheet1.Range("A10").Value = "Run pressed, button states changed, and ribbon invalidated. Waiting 5 seconds in loop"
    T = Timer
    Do While Timer - T < 5
        DoEvents
    Loop
    Sheet1.Range("A10") = ""

End Sub

因此,每个回调必须有两个过程-回调,然后是执行实际工作的SetRunning调用。代码同样难看,但用户界面看起来没有那么奇怪。

谢谢,我确实想知道是否允许代码实际停止,并对这样一个定时过程进行排队,但我担心它可能会以不可预知的方式运行。但现在我知道有人有了这个想法,我至少相信这不是完全疯狂,我可能会尝试一下。
Sub SetRunning(ByVal ProcToRun As String)

    Sheet1.Range("B1") = "Disabled"
    Sheet1.Range("B2") = "Disabled"
    Sheet1.Range("B3") = "Enabled"
    Sheet1.Range("B4") = "Enabled"
    Sheet1.Range("B5") = "Enabled"
    Sheet1.Range("B6") = "Enabled"
    Sheet1.Range("B7") = "Enabled"

    myRibbon.Invalidate
    myRibbon.InvalidateControl ("Run")

    Application.OnTime Now, ProcToRun

End Sub