bod*_*soc 5 excel vba excel-vba ribbonx
我有一个运行很长时间的Excel VBA宏(可能持续数天,它执行数据采集).它最初是为Excel 2003编写的,具有自定义工具栏和菜单.我最近更新了它以使用RibbonXML使用功能区界面.
当宏运行时,我想禁用一些界面元素(例如"开始测试"),并启用其他元素(例如"停止测试"按钮.)
我遇到的问题是只有在宏代码运行完成后才会调用ribbon.invalidate .
使用简单的测试程序,您可以非常轻松地看到这种效果
Sub test()
ribbon.Invalidate
DoEvents
Sleep (5000)
End Sub
Run Code Online (Sandbox Code Playgroud)
功能区"getEnabled"回调中的debug.print将被视为仅在5秒睡眠结束时执行.
有没有办法强制使用ribbon.Invalidate在那里激活然后呢?
::编辑1 ::
我创建了一个小型演示工作簿来说明问题:http: //www.bodgesoc.org/Button_Demo.xlsm
::编辑2 ::
一个不同论坛的成员找到了一个解决方案,虽然它有点难看.我想现在可以将其标记为"已回答"但更优雅的解决方案将会受到赞赏.
Application.ScreenUpdating = False
Application.ExecuteExcel4Macro "Show.ToolBar(""Ribbon"",False)"
Application.ExecuteExcel4Macro "Show.ToolBar(""Ribbon"",True)"
Application.ScreenUpdating = True
Run Code Online (Sandbox Code Playgroud)
我不知道这是否比你的丑陋一些,但是......
'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
Run Code Online (Sandbox Code Playgroud)
然后在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
Run Code Online (Sandbox Code Playgroud)
因此,每个回调必须有两个过程 - 回调,然后是执行实际工作的 SetRunning 调用。代码同样丑陋,但用户界面对于用户来说并不那么奇怪。