【问题标题】:Exit the main sub if a called sub calls `Exit Sub`如果被调用的子调用“退出子”,则退出主子
【发布时间】:2021-06-23 00:05:40
【问题描述】:

我有一个调用另一个子的子,我通常需要退出被调用的子并停止执行调用它的其余子。

所以我有一个子 Add_Format_Button_Click 调用另一个子:

call CheckEmptyComboboxValues

大多数情况下CheckEmptyComboboxValues 会结束

Exit sub

Add_Format_Button_Click 将继续执行其余部分。这是我需要帮助的地方,因为当CheckEmptyComboboxValues 退出时,我需要Add_Format_Button_Click 也退出。

谁能帮我解决这个看似简单的问题?

编辑:CheckEmptyComboboxValues 包含数十个(如果不是数百个)遵循以下结构的 if 语句:

If Format_Layout.FilmType.Value = "" Then
    MsgBox "Specify a film type!", , ("Film Type"): Exit sub
End If

所以我想我需要将 exit sub 值转换为我可以使用 if 语句在主子中检查的东西

if CheckEmptyComboboxValues .value = "Exit sub" Then
exit sub

【问题讨论】:

  • 或者设置一个在 CheckEmptyCombo 中更新的布尔全局...然后在调用后在 Add_Format_Click 中测试其值
  • 好的,代码是什么?

标签: excel vba


【解决方案1】:

3 种解决方案,每种都适用于您的情况。我会选择第一个或最后一个解决方案。取决于项目其余部分的设计:

1。功能

Function CheckEmptyComboboxValues() As Boolean
    If AnythingOddHappens Then
        Exit Function 
    End If

    CheckEmptyComboboxValues = True
End Function

这个函数的结果只有True如果它跑到最后,只要你在它之前退出它就是False

Sub Example()
    If Not CheckEmptyComboboxValues Then Exit Sub

    'instead of 
    'Call CheckEmptyComboboxValues 
End Sub

2。取消过程

Sub CheckEmptyComboboxValues(ByRef Cancel As Boolean)
    If AnythingOddHappens Then
        Cancel = True
        Exit Sub 
    End If

End Sub 


Sub Example()
    Dim Cancel As Boolean
    Call CheckEmptyComboboxValues(Cancel)  

    If Cancel Then Exit Sub
End Sub

这可以使用,但在这里我看不到任何优势,并且更喜欢上面的功能。如果您已经有一个带有返回值的函数并且想要一个额外的取消,或者如果您为一个事件编写代码,这个方法会很有用。

3。抛出错误

Sub CheckEmptyComboboxValues()
    If AnythingOddHappens Then
        Err.Raise vbObjectError + 513, "CheckEmptyComboboxValues", "Something odd happened"
        Exit Sub
    End If
End Sub 

Sub Example()
    On Error Goto ERR_HANDLER
    Call CheckEmptyComboboxValues  

    Exit Sub
ERR_HANDLER:
    MsgBox "check failed"
End Sub

如果您有多个可能引发错误的检查过程/功能,这可能是一个优势。与需要检查每个检查过程/功能的结果的第一个或第二个解决方案相比,此解决方案只需要一个错误处理程序,因此带有苗条的代码。

这还有一个好处是检查过程现在可以返回不同类型的错误,您的调用子可以使用这些错误为用户提供进一步的帮助。虽然前 2 个解决方案更像 “它没有通过检查”,但最后一个解决方案可以提供更详细的信息,例如 “它没有通过检查,因为 A/B/ C 发生” 取决于引发的错误。

Sub CheckEmptyComboboxValues()
    If AnythingOddHappens Then
        Err.Raise vbObjectError + 513, "CheckEmptyComboboxValues", "Something odd happened"
        Exit Sub
    End If

    ' more code here …
    If AnythingDifferentOddHappens Then
        Err.Raise vbObjectError + 514, "CheckEmptyComboboxValues", "Something different odd happened"
        Exit Sub
    End If
End Sub 

现在您可以使用不同的错误编号向用户提供关于什么出了问题的更详细的信息,而不仅仅是某事出了问题。

Sub Example()
    On Error Goto ERR_HANDLER
    Call CheckEmptyComboboxValues  

    Exit Sub
ERR_HANDLER:  'possibility to give a more detailed information
    Select Case Err.Number
    Case vbObjectError + 513
        MsgBox "check A failed"
    Case vbObjectError + 514
        MsgBox "check B failed"
    Case Else
        MsgBox "Undefined fail"
    End Select
End Sub

【讨论】:

  • 我如何从那个主子调用一个函数?因为 Call CheckEmptyComboboxValues 返回一个编译错误:invalid qualifier。并且是主子 if 语句: If CheckEmptyComboboxValues.Value = False Then Exit Sub
  • @Eduards 请再次仔细阅读,这一切都在我的回答中。该函数被称为If Not CheckEmptyComboboxValues Then Exit Sub。这将运行该函数并检查其结果。如果是False,则退出。
【解决方案2】:

CheckEmptyComboboxValues 重写为返回boolean 的函数。在Add_Format_Button_Click 然后你可以写

if CheckEmptyComboboxValues then
   ' You could give a message
   Exit Sub 
else
   ' rest of the code of 
   ' Add_Format_Button_Click
end if

CheckEmptyComboboxValues 可能看起来像这样

Function CheckEmptyComboboxValues  as boolean

' code goes here
if .... then
    CheckEmptyComboboxValues   = False
    exit function
else 

   ' other code
end if

CheckEmptyComboboxValues   = True

End Function

更新基于修改

Function CheckEmptyComboboxValues() As Boolean
    
    ' ....

    If Format_Layout.FilmType.Value = "" Then
        MsgBox "Specify a film type!", , ("Film Type")
        CheckEmptyComboboxValues = True
        Exit Function
    End If
    
    ' ....
    
    CheckEmptyComboboxValues = False


End Function

【讨论】:

  • 并非如此。我真的需要我所问和描述的。没有变通办法或什么都没有,因为我还可以在每次需要的情况下复制粘贴整个检查子程序,从而导致为每个按钮单击重复不必要的数千行代码。所有检查代码都在一个子中是有原因的。如果出现问题,检查 sub 返回一条消息并退出 sub。在这种情况下,我还需要停止、退出或结束称为检查的子任务
  • 因此,您不想将CheckEmptyComboboxValues 重写为函数,也不想重写其他代码。那么帮助你将变得非常困难。为什么所有检查代码都在一个无法重写为一个非常简单的功能的子程序中。
  • 因为它有数百行。在用户继续之前,如果一切都正确,这是一个检查系统。我为用户执行的每个操作调用该子。我的意思是每个按钮单击等。我确信如果有退出当前子程序的退出子程序之类的功能,则必须有一个函数停止执行调用检查子程序的子程序,例如结束(输入子名称)或其他东西。跨度>
  • 我不知道 的函数是否存在,除非您想使用 End,否则是否存在退出当前子目录的函数,例如 exit sub。但这将完全结束代码的执行。但听起来你需要一个控件数组,因为每个按钮似乎都有类似的代码。
  • @PEH:是的,我完全同意。使用End 根本不是一个好主意。正如我所说,这将完全结束代码,这通常不是一个好主意。但如果 TO 不想按照我建议的方式重写他的代码,那可能是唯一的可能性。但如果 TO 使用End,他必须承担后果。
猜你喜欢
  • 2018-06-23
  • 1970-01-01
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 2019-05-30
  • 1970-01-01
相关资源
最近更新 更多