VBA(Excel)中的Side Step Application.MsgBox

VBA(Excel)中的Side Step Application.MsgBox,excel,excel-2010,vba,Excel,Excel 2010,Vba,为了阻止“评论出来”的回复风暴,我的情况如下: 我有一个过程通常是一个迭代一个迭代地运行。用户手动点击一个按钮调用一个宏,完成后弹出一个消息框,报告宏运行的总时间长度。它对于诊断问题非常方便。此代码已锁定,无法修改 我正试图大规模地这样做。由于主电子表格和工作簿中的代码被锁定,我在同一个excel实例中打开了一个单独的工作簿,其中有一个宏操作锁定的工作簿。而不是1乘1,我有一套300我正在尝试通过。现在,我必须照看这个东西,并点击空格以通过MsgBox。有人知道有什么窍门可以阻止我监视这个东西吗

为了阻止“评论出来”的回复风暴,我的情况如下:

我有一个过程通常是一个迭代一个迭代地运行。用户手动点击一个按钮调用一个宏,完成后弹出一个消息框,报告宏运行的总时间长度。它对于诊断问题非常方便。此代码已锁定,无法修改


我正试图大规模地这样做。由于主电子表格和工作簿中的代码被锁定,我在同一个excel实例中打开了一个单独的工作簿,其中有一个宏操作锁定的工作簿。而不是1乘1,我有一套300我正在尝试通过。现在,我必须照看这个东西,并点击空格以通过MsgBox。有人知道有什么窍门可以阻止我监视这个东西吗?禁用弹出窗口或以某种方式使其成为非模态。也许是一个让鼠标点击的技巧?

您知道解决此问题的最佳方法是更正代码,这是正确的。在这种情况下,您可能会使弹出窗口切换为可启用状态

然而,我为你写了这篇文章,它可以作为一种潜在的解决方法。它利用VBScript来“排序”模拟多线程,以便您可以将密钥发送到modal
Msgbox
。假设您可以通过代码执行您想执行的操作,只需在执行将导致
Msgbox
的操作之前调用
SendDelayedKeys
。您可能需要根据您的情况修改
延迟
,因为100毫秒可能不够。要更改
延迟
,只需按如下方式调用:
SendDelayedKeys 500
500毫秒

Sub SendDelayedKeys(Optional Delay As Long = 100, Optional keys As String = """ """)
    Dim oFSO As Object
    Dim oFile As Object
    Dim sFile As String
    sFile = "C:\SendKeys.vbs" 'Make this a valid path to which you can write.
    'Check for the .vbs file.
    If Not Len(Dir$(sFile)) Then
        'Create the vbs file.
        Set oFSO = CreateObject("Scripting.FileSystemObject")
        Set oFile = oFSO.CreateTextFile(sFile)
        oFile.WriteLine "Set WshShell = WScript.CreateObject(""WScript.Shell"")"
        oFile.WriteLine "WScript.Sleep CLng(WScript.Arguments(0))"
        oFile.WriteLine "WshShell.SendKeys WScript.Arguments(1)"
        oFile.Close
    End If
    Shell "wscript C:\SendKeys.vbs " & Delay & " " & keys
End Sub
Sub ProofOfConcept()
    'Using default parameters which sends a space after 100 milliseconds
    SendDelayedKeys
    MsgBox "I disappear on my own!"
End Sub
警告:任何使用
SendKeys
的解决方案都是脆弱的解决方案,应尽可能避免使用。然而,当您的选择有限且需要避免手动过程时,有时这是您唯一的选择


因为SiddhartRout正确地指出,这可以通过API调用来解决:这里有一个与

的链接。严格来说,这里的问题并不是更多代码可以(或者确实应该)解决的问题

有很多事情要考虑,任何解决方案都比最初试图解决的问题更加复杂和不可靠。但让我们看看你的选择

  • SendKeys
    对于这种用途是不可靠的,如果在进行临时更改后,或者在进行类似批处理的过程中,您希望在等待的同时继续进行其他操作,那么会发生什么情况,哪怕只是为了给巨魔投票。如果没有其他东西,您可能无法控制此代码,那么当维护人员意识到msgbox是坏的UX并将其杀死时,会造成什么样的混乱

  • FindWindow
    API调用将允许您检查窗口中的内容,以确保它显示了您期望的内容,但随后您可能会要求一些快速脏的vbscript进入竞争状态,直到出现正确的窗口。你能保证螺纹不会锁紧吗?。平台问题呢?如果有人想在他们闪亮的新界面上运行您的代码,会发生什么?当您正在进行的32位api调用无法看到64位模态Excel对话窗口时,会发生什么情况?新版本的office不以同样的方式呈现模态对话,怎么样?这些问题都不是不可克服的,但每一个都增加了复杂性(也就是失败的机会)


  • 最好的解决方案是解决您从一开始就发现的实际问题,即原始代码抛出了不必要的模态对话。需要有人来解决这个问题——不一定是你,但如果你估计这种模式对话会浪费多少时间在生产力损失上,那么你就应该有一个可靠的商业案例来解决它。

    打开锁,并对其进行评论。+1好主意。然而,你是对的,Sendkey可能会以一种有趣的方式行事。为什么不使用API FindWindow/Sendmessage?;)@悉达多我想你是在开玩笑,但是。。。主要是因为API调用需要从VBscript中使用变通方法。另外,由于
    Msgbox
    将停止当前线程,因此不能直接从代码中调用它。而且我倾向于假设人们的处境和我过去一样。。。没有VBA和VBScript之外的开发环境。显然,您可以使用FindWindow等,但这更容易理解。不,我不是开玩笑:)想法不是使用vbscript,而是使用一个新的Excel实例,它将启动一个使用FindWindow API的现有Excel文件;)在主宏运行之前,需要打开文件,以便
    FindWindow
    代码在后台运行,在主宏启动之前,直到主宏停止运行。。。我本不打算发布答案,但我想我现在必须发布:)@SiddharthRout我想到了这一点,但只是觉得写起来太麻烦了,我很乐意让你这么做。你发布后请告诉我,这样我就可以给你投票了-PNo如果你相信这是可以做到的,而且我不是在开玩笑,那么我不会发布它;)