VBA:使用“Application.Ontime”强制执行代码

VBA:使用“Application.Ontime”强制执行代码,vba,Vba,这是一个后续的这个 我试图通过使用Application.Ontime启动第二个过程(带有输入变量的过程),强制执行第一个过程(没有输入变量的过程)的代码。由于Application.Ontime只能“调用”不允许输入变量的宏/过程,因此我必须使用全局变量将输入参数传递给Application.Ontime调用的第二个宏/过程(参见第一个工作示例)。它可以工作,但我不使用全局变量 我认为我很聪明,我使用了一个“介于两者之间的伪宏”,它的存在只是为了在第二个过程开始之前强制执行第一个过程中的代码。

这是一个后续的这个

我试图通过使用Application.Ontime启动第二个过程(带有输入变量的过程),强制执行第一个过程(没有输入变量的过程)的代码。由于Application.Ontime只能“调用”不允许输入变量的宏/过程,因此我必须使用全局变量将输入参数传递给Application.Ontime调用的第二个宏/过程(参见第一个工作示例)。它可以工作,但我不使用全局变量

我认为我很聪明,我使用了一个“介于两者之间的伪宏”,它的存在只是为了在第二个过程开始之前强制执行第一个过程中的代码。但它不起作用:代码执行在第二个过程开始时还没有完成。问题是我使用了一个空的伪宏?我在伪宏中尝试了不同的命令,但没有任何区别。有什么想法吗?(参见第二个非工作示例)

第一个示例有效(代码在宏之前执行):

第二个示例不起作用(第一个过程中的代码在第二个过程开始之前没有完全执行):

正如在您的应用程序中所讨论的,
应用程序.OnTime
用于计划将来运行的过程,因此我们可以利用它让操作系统或Excel更新VBA运行时无法更新的内容

请注意,我们的第二个过程是在OS/Excel重新获得控制后运行的,这确保了这一点。您可以在下图中直观地看到,当VBA未运行时,红色部分为:

在您的示例中,从第一个宏调用
procedurewithinputparameters
(您的第二个过程),这意味着在第二个宏运行之前不会中断VBA。这意味着即使您运行了
Application.OnTime
命令,操作系统也无法更新

*图像不可缩放

这是因为重要的不是您运行了
Application.OnTime
,重要的是VBA在第二个过程运行之前会停止运行一小段时间。在第二种情况下,使用
PseudoMacro
不会发生这种情况

另一种解决办法 如果您需要将参数传递给使用
Application.OnTime
调用的过程,它似乎有您想要的答案

正如Holger Leichsenring的回答所建议的,可以通过在传递的值的开头和结尾添加撇号来传递字符串作为函数的参数;在程序名称后留有空格;并用引号(Chr$(34))包围字符串参数

例如


似乎您需要在PseudoMacro中调用ProcedureWithinPutParameters。我知道您无法通过这种方式传递局部变量,但VBA需要停止运行一小段时间,以便让操作系统或Excel应用程序完成您希望它完成的操作。在您给出的示例中,VBA在运行
过程rewithinputParameters
之前不会停止,这就是它不起作用的原因。感谢您的解释,我也这么认为。在这两个示例中,第一个过程在第二个过程之后结束。因此,在第一个示例中,必须强制执行代码(或者用您的话说,控制权返回给停止运行的OS/VBA)。你知道为什么会出现这种情况吗?“内部”到底发生了什么?我想知道的是,在第二个示例中,在第一个过程的Application.OnTime之后和
end
-命令之前是否有额外的代码。测试它应该足够简单。我不确定内部或引擎盖下到底发生了什么,但我猜测,VBA代码正在访问剪贴板这一事实可能会阻止其他应用程序或进程访问它,直到执行完整的VBA堆栈,以避免冲突。
Public gloInputVariable as Variant

Sub procedureWithoutInputparameters

    'Do something in this procedure
     inputVariable = "something"

    'force code execution
        'workaround with global variable instead of inputparameter (macros don't have input parameters)
        gloInputVariable = "something"
        'start the next procedure as a macro (basicaly a procedure without input paramters)
        Application.OnTime Now + TimeSerial(0, 0, 1), "WorkaroundMacroInsteadOfProcedureWithInputParameters"

    End Sub

Sub WorkaroundMacroInsteadOfProcedureWithInputParameters()
    'get the input parameter through a global variable
    variable1 = gloInputVariable
    'do something
    End Sub
Sub procedureWithoutInputparameters

    'Do something in this procedure
     inputVariable = "something"

    'force code execution through pseudomacro (this doesn't work)
        'force execution through macro
        Application.Ontime Now + TimeSerial(0, 0, 1), "Pseudomacro"
        'run next second procedure procedure
        procedureWithInputparamters (inputVariable)

    End Sub

Sub PseudoMacro()
    'do nothing, pseudo-macro is only here to force code execution before starting the second procedure with input parameters
    End Sub

Sub procedureWithInputparamters(strSomeInputString as String)
    'get the input parameter "directly"
    variable1 = strSomeInputString 
    'do something        
    End Sub
Application.OnTime Now + TimeSerial(0, 0, 1), "'procedureWithInputparamters " & Chr$(34) & inputVariable & Chr$(34) & "'"