Run a sub-routine within another sub-routine - Compile Error: Argument not optional

Viewed 48
Sub StoreQA(ShapeClicked As Shape)
MsgBox "yeee"
End Sub

Sub ThisIsToBeRun()
StoreQA
End Sub

I get Compile Error: Argument not optional. I tried mentioning StoreQA(ShapeClicked As Shape) but that didn't help either.

1 Answers

Argument not optional

You are defining a parameter here, named ShapeClicked:

Sub StoreQA(ShapeClicked As Shape)

Because the parameter isn't Optional, an argument must be provided for this parameter by any code that means to invoke this StoreQA procedure:

' gets the first Shape in Sheet1 (assumes it exists), then passes it to StoreQA:
StoreQA Sheet1.Shapes(1) 

If the parameter isn't needed, remove it:

Sub StoreQA()

If it's needed in some places but not in others, consider making it Optional:

Sub StoreQA(Optional ByVal ShapeClicked As Shape)

Then you can invoke the procedure legally without supplying any parameters:

StoreQA '<~ compiles fine now

Optional Considerations

If the StoreQA procedure receives an Optional parameter, it needs to verify whether it received a valid object reference before using it - otherwise expect problems:

Sub StoreQA(Optional ByVal ShapeClicked As Shape)
    If ShapeClicked Is Nothing Then
        ' argument was not provided *or 'Nothing' was supplied*
        ''Debug.Print ShapeClicked.Name '<~ error 91
    Else
        ' ShapeClicked is holding a valid Shape object reference
        Debug.Print ShapeClicked.Name
    End If
End Sub

If Optional parameters are declared As Variant (explicitly or not), then you can use the IsMissing function to verify whether an optional parameter was supplied - useful when Nothing is also a valid, useful value to receive (for object references anyway - for plain value types it can remove the need to resort magic/hard-coded "invalid" values):

Sub StoreQA(Optional ByVal ShapeClicked As Variant)
    If IsMissing(ShapeClicked) Then '<~ only valid with an Optional+Variant parameter
        ' argument was not provided
        ''Debug.Print ShapeClicked.Name '<~ error 91
    ElseIf Not ShapedClicked Is Nothing Then
        ' ShapeClicked is holding a valid Shape object reference
        Debug.Print ShapeClicked.Name
    Else
        ' 'Nothing' was explicitly supplied
        '...
    End If
End Sub
Related