在被调用的子程序中结束宏

Posted

技术标签:

【中文标题】在被调用的子程序中结束宏【英文标题】:Ending a macro within a called subroutine 【发布时间】:2013-09-18 12:13:43 【问题描述】:

我有一个宏 (CMOV),它调用另一个子例程 (CMOV2),它检查一个条件,如果满足,将显示一个 vbokaycancel 消息框,我将它设置为一个名为 irep 的变量,

如果有人点击取消 (irep=2) 来取消整个宏,我想要它。即不仅退出CMOV2,也退出CMOV。

目前,我有

If jackal(1) <> vbNullString Then
    irep = MsgBox("Warning: You have a selection with two swingarms" _
          & " that are on the same radius and cannot swing past one another " _
          & Chr$(13) & " Choose Okay if you still wish to proceed otherwise " _
          & " choose Cancel to revise your order" & Chr$(13) & "         " _
          & jackal(1) & Chr$(13) & "      " & jackal(2), vbOKCancel)
    **If irep = 2 Then
    Exit Sub**
    Else: End If
    Else: End If
End Sub

在子程序的末尾。问题是即使退出 CMOV2,CMOV 仍会继续运行。有没有办法结束这个子,以及调用它的那个?

【问题讨论】:

尝试在 CMOV2 中创建一个名为 plzexit 的变量,然后在 CMOV 中创建一个 if 语句,根据 plzexit 的值退出子程序,但看起来该变量在退出 CMOV2 子程序时死亡。跨度> 将 CMOV2 更改为返回布尔值的函数。如果用户在 CMOV2 中取消,则返回 False,否则返回 True。在 CMOV 中,如果从 CMOV2 中返回“False”,则可以退出。 【参考方案1】:
End

请注意,End 完全停止代码执行(在当前调用堆栈内,因此它不会影响其他项目,如 Addins 等(一件好事))但它会关闭所有打开的文件句柄(一件好事)。另一方面,静态和模块级变量(如果您使用它们)将丢失它们的值,并且类终止方法将不会运行,因此如果您有更多的“应用程序”而不是宏,则可能不需要。

对于您的目的来说,这听起来不错,并且可能是最简单的方法。

一个愚蠢的例子:

Sub foo()
    Dim i As Long
    For i = 0 To 10
        If i = 2 Then
            Debug.Print "hooray"
            End
        Else
            Debug.Print "hip"
        End If
    Next i
End Sub

【讨论】:

End 是错误的结束方式,就像您提到的那样。他们应该禁止这个词:) @SiddharthRout 在很多情况下是的,但是对于简单的“请求用户输入,做某事,然后完成”宏(不是程序或应用程序等,而是宏,如脚本中的宏),那就完全没问题了适用于大多数情况。 End 就像直接关闭电源而不正确关闭您的电脑。 :) 如果稍后用户添加更多处理对象的代码并完全忘记End 怎么办;)我并不是说您的答案不正确。我是说人们应该忘记在 VB 中有 End 可供我们使用 :) 是的,它肯定会“杀死”您项目的其余部分。每当我想像这样停止执行当前的“正在运行的宏”时,我通常使用一个函数并返回False,或者引发我在调用过程中测试并退出的错误。 @RichardPullman 如果你读到了这篇文章,那么你或许应该考虑现在多输入一点,以免将来头疼,并接受 Siddharth 的答案(并相应地接受它作为答案):)【参考方案2】:

如果用户按下取消,则在顶部声明一个布尔变量并将其设置为True。这是一个例子。

Dim ExitAll As Boolean

Sub CMOV()
    '
    '~~> Rest of the code
    '

    ExitAll = False

    CMOV2

    If ExitAll = True Then Exit Sub

    MsgBox "Hello World"

    '
    '~~> Rest of the code
    '
End Sub

Sub CMOV2()
    '
    '~~> Rest of the code
    '
    If jackal(1) <> vbNullString Then
        irep = MsgBox("Some Message", vbOKCancel)
        If irep = 2 Then
            ExitAll = True
            Exit Sub
        End If
    End If
    '
    '~~> Rest of the code
    '
End Sub

【讨论】:

我试过这个,但由于 cmov 和 cmov2 子在不同的模块中,我收到一个错误,即 exitall 变量未在 cmov2() 子中定义 @RichardPullman 您可以通过限定子来访问它以消除模块名称+ Siddharth 所说的歧义。 @SiddharthRout +1 表示“正确”的解决方法;)。尽管我认为如果他真的想完全“重新启动”他的宏,那么下次运行它就好像它是第一次运行一样,那么End 对他来说可能就足够了。 @RichardPullman:然后在模块中将 ExitAll 定义为布尔值 PUBLIC :)

以上是关于在被调用的子程序中结束宏的主要内容,如果未能解决你的问题,请参考以下文章

高分求助VC中关于不定参数宏的使用

匹配开始/结束分析调用

一个函数中 有return后有必要用exit吗

以前的笔记迁移__形參,实參,递归

C语言中如何定义全局变量

从托管在被 CORS 策略阻止的 Asp.net 核心 Web 服务器中的 Angular 应用程序调用我的休息服务