Search code examples
vbaexcelsubroutine

Auto-detection of being called with an argument VS separately called for a subroutine?


I have three subroutines, sometimes run successively, sometimes separately, but will use a same argument ("TestNumber"). My original code looks like:

Sub Main1()
    Dim TestNumber As String
        TestNumber = InputBox("Please enter TestNumber")
    ' Some codes running on TestNumber
    ' Prompt users whether to continue to Main2
    Dim Continue As String
        Continue = MsgBox("Continue to Main2?", vbYesNo)
        If Continue = vbYes Then
                Call Main2
            Else
        End If
End Sub

Sub Main2() ' Similar to Main1, just that it will prompt if user wants to continue to Main3
    Dim TestNumber As String
        TestNumber = InputBox("Please enter TestNumber")
    ' Some codes running on TestNumber
    Dim Continue As String
        Continue = MsgBox("Continue to Main3?"), vbYesNo)
        If Continue = vbYes Then
                Call Main3
            Else
        End If
End Sub

Sub Main3() ' The last call of the series
    Dim TestNumber As String
        TestNumber = InputBox("Please enter TestNumber")
    'Some codes running on TestNumber
End Sub

Then, I consider it to be a bit troublesome and risky to re-enter TestNumber for each call, so I changed my code to something like:

Sub Main1()
    Dim TestNumber As String
        TestNumber = InputBox("Please enter TestNumber")
    ' Some codes running on TestNumber
    ' Prompt users whether to continue to Main2
    Dim Continue As String
        Continue = MsgBox("Continue to Main2?", vbYesNo)
        If Continue = vbYes Then
                Call Main2(TestNumber)
            Else
        End If
End Sub

Sub Main2(TestNumber As String) ' Similar to Main1, just that it will prompt if user wants to continue to Main3
    If TestNumber = "" Then
            TestNumber = InputBox("Please enter TestNumber")
        Else
    End If
    ' Some codes running on TestNumber
    Dim Continue As String
        Continue = MsgBox("Continue to Main3?"), vbYesNo)
        If Continue = vbYes Then
                Call Main3(TestNumber)
            Else
        End If
End Sub

Sub Main3(TestNumber As String) ' The last call of the series
    If TestNumber = "" Then
            TestNumber = InputBox("Please enter TestNumber")
        Else
    End If
    ' Some codes running on TestNumber
End Sub

This works just fine if I work all the way through Main3 starting from Main1. But if I start from Main2 or Main3, neither script runs. Instead, the system prompts for which subroutine to run.

Is there a way for a subroutine to auto-detect whether it is called with an argument or it is called separately?


Solution

  • You can mark the parameter as optional and supply a default value like this:

    Sub Main2(Optional TestNumber As String = "")
    

    or you can change the parameter to a variant, mark it as optional and then test if the parameter was supplied using IsMissing like this:

    Sub Main2(Optional TestNumber As Variant)
    
    If IsMissing(TestNumber) Then
        ' do stuff
    Else
        ' do other stuff