【问题标题】:How to disable ribbon while VBA code is running如何在 VBA 代码运行时禁用功能区
【发布时间】:2018-11-15 02:52:49
【问题描述】:

如果代码已经在运行,我需要取消自定义功能区上的按钮点击。

问题:虽然我可以禁用按钮,但点击仍然是“注册的”,即使禁用,每次按钮点击对应的代码都会运行一次。

Public Sub OnActionButton(control As IRibbonControl)

    ' The following approach fails to prevent code from running
    If Not globalEnabled Then Exit Sub

    ' The following approach fails to prevent code from running
    Dim goodToGo as Boolean
    GetEnabled control, goodToGo
    If Not goodToGo Then Exit Sub


    ' *********************************************************
    ' Code Below Here Should NOT Run If Button Was Clicked 
    ' While globalEnabled = False (i.e. code already running)
    ' *********************************************************

    ' Disable the Ribbon
    globalEnabled = False
    RibbonInvalidate

    Select Case control.id
        Case "btnID"
            ' doSomething
    End Select

    ' Re-enable the ribbon
    globalEnabled = True
    RibbonInvalidate

End Sub

编辑:不管怎样,这就是我禁用按钮的方式:

Public Sub GetEnabled(control As IRibbonControl, ByRef enabled)
' Called by RibbonInvalidate
    Select Case control.id
        Case "btnID"
            enabled = globalEnabled 
    End Select 
End Sub

我可以想象第一次点击按预期运行,第二次点击(在与第一次点击对应的代码运行时进行)被“排队”,直到第一次点击完成。那时 globalEnabled 再次为 True,因此检查无效。

我想我可以隐藏自定义功能区选项卡(或将其替换为虚拟选项卡) - 但这真的有必要吗?

有没有一种优雅的方式来取消按钮按下?


编辑:

我可以在代码中添加一堆 doEvents,但速度太慢了。

编辑2:

如果我在代码执行期间显示一个消息框,那么出于某种原因,事情似乎按预期工作......

事实上......如果我显示一个消息框,那么我什至不需要提前退出逻辑 - 太奇怪了!

【问题讨论】:

  • 这就是响应式 UI 的工作原理。如果您重新进入按钮处理程序并立即在您的重新进入标志处退出,这有什么关系?
  • @Comintern 除非我遗漏了什么......我真的不介意它进入按钮处理程序,但代码应该只运行一次......将 globalEnabled 设置为 false 不会导致随后按下按钮可在我的 PC 上提前退出。我认为这是因为当第一次点击完成时 globalEnabled 再次变为 True (必然),这就是这一切崩溃的原因......
  • 在这里,我在遵循逻辑时遇到了一些困难。您显示的代码禁用然后在同一过程中重新启用功能区。如果用户操作(键盘、鼠标)无法立即执行,Windows 界面会缓存它们,因为正在执行的其他操作会阻止它们。由于 Word/Office 是同步的(大部分情况下),因此鼠标点击被缓存了?我认为没有办法解决这个问题,除非 Windows API 中有某些东西。
  • @CindyMeister 好吧,让我们退后一步 - 假设我有一个需要 5 分钟才能运行的宏,并且它是通过单击功能区按钮触发的。它只需要单击 1 次,代码运行...用户再次单击,代码第二次运行...现在将在代码完成前 10 分钟过去...用户决定单击多次...现在代码将运行30 多分钟...如何禁用按钮以避免出现这种情况?
  • @CindyMeister 当然......如果按钮被禁用(我可以确认它们是灰色的),那么按钮处理程序甚至不应该触发......但是......在我的电脑上它确实.

标签: vba ms-word ribbonx


【解决方案1】:

这行得通,主要是在最后添加 doEvents(或消息框)。

Public Sub OnActionButton(control As IRibbonControl)

    ' Disable the Ribbon
    globalEnabled = False
    RibbonInvalidate

    Select Case control.id
        Case "btnID"
            ' doSomething
    End Select

    ' Re-enable the ribbon
    doEvents                     ' <-- Adding this fixed the issue for me
    ' msgbox "finished"          ' <-- also works, but pretty annoying ;-)
    globalEnabled = True
    RibbonInvalidate

End Sub

【讨论】:

    【解决方案2】:

    我迟到了,但您是否将 GlobalEnabled 声明为全局变量?因为根据我的理解和测试(在类似问题上),如果它没有明确声明为全局,则每次单击功能区按钮时,都会创建 GlobalEnabled 的局部变量,而不是使用之前运行宏时设置的值。

    【讨论】:

      猜你喜欢
      • 2014-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-19
      • 2022-07-22
      • 2022-09-26
      相关资源
      最近更新 更多