【问题标题】:How to stop VBA macro automatically?如何自动停止 VBA 宏?
【发布时间】:2014-12-09 17:21:51
【问题描述】:

我知道您可以使用 Ctrl+Break 手动停止正在运行的 VBA 宏,但是如果满足特定条件,有没有办法让代码自动停止? exit function / exit sub 不起作用,因为它们只是终止调用它们的方法。

例如,

sub a
    call b
    msgbox "a complete"
end sub

sub b
    call c
    msgbox "b complete"    'this msgbox will still show after the `exit sub` in 'c'
end sub

sub c
    msgbox "entering c"
    exit sub               'this will only `exit sub` 'c', but not 'a' or 'b'
    msgbox "exiting c"
end sub

'OUTPUT:

'entering c
'b complete
'a complete

我想我可以把这些sub's 变成function's 并利用返回码来知道方法是否成功执行,但是有没有更简单的方法来做到这一点?

【问题讨论】:

标签: vba excel error-handling


【解决方案1】:

您可以创建宏来执行以下步骤/操作,并在您的代码满足特定条件时调用以中止其他正在运行的宏:

步骤 1-- 菜单栏 -> 运行 -> 重置

第2步--菜单栏->运行->中断

【讨论】:

    【解决方案2】:

    您可以使用err.raise 引发您自己的用户定义错误。这与您的示例类似,但功能更强大一点,因为它是一个会停止代码执行的实际错误,即使它应用于嵌套调用也是如此。

    例如,

    sub a
    on error goto exitCode
        call b
        msgbox "a complete"
        exit sub       'you need this to prevent the error handling code from always running
    exitCode:
        msgbox "code is exiting..."
        'clean up code here
    end sub
    
    sub b
        call c
        msgbox "b complete"
    end sub
    
    sub c
        msgbox "entering c"
        err.raise 555, "foo", "an error occurred"
        msgbox "exiting c"
    end sub
    
    'OUTPUT:
    
    'entering c
    'code is exiting...
    

    err.raise 行会将控件发送到exitCode: 标签,即使它是在a 之外调用的。您可以使用任何条件来测试是否应该抛出此自定义错误。

    更多关于 err 对象和 VBA 错误处理-

    https://msdn.microsoft.com/en-us/library/ka13cy19(v=vs.90).aspx

    http://www.cpearson.com/excel/errorhandling.htm

    【讨论】:

      【解决方案3】:

      我相信您想要做的是在您的错误处理代码中再次引发错误。尝试这样的事情(未测试):

      Private Sub Test
          On Error Goto bad
          x = 0
          debug.print 1/x
          Exit Sub
      
          bad:
              'Clean up code
              Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
      End Sub
      

      使用On Error Goto 时,标签前需要Exit Sub。否则即使没有错误,您的代码也会进入错误处理程序。

      您的第一个错误处理不会捕获运行时可能发生的实际错误,而不是您正在测试的错误。此外,除非您在所有调用例程中添加检查,否则没有一种方便的方法可以向调用函数发出出错的信号。

      请注意,尽管仅针对流控制引发错误,但通常被认为是糟糕的设计:

      Private Sub Test
          If x = 0 Then
              Err.Raise 
          End If
      End Sub
      

      【讨论】:

      • 这是我们为 vb6 项目所做的。不过,您可能不需要它用于每个功能,只是您想要运行清理代码的功能。你想用什么完全取决于你。
      猜你喜欢
      • 2016-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      • 2021-01-25
      • 2013-08-02
      • 1970-01-01
      相关资源
      最近更新 更多