(Editor: I added an improvement to HarveyFrench code)
You can make it a little less nested:
Function foo(Optional a, Optional b, Optional c, Optional d) Dim passed As String If Not IsMissing(a) Then passed = "a " If Not IsMissing(b) Then passed = passed & "b " If Not IsMissing(c) Then passed = passed & "c " If Not IsMissing(d) Then passed = passed & "d " foo = IIf(Len(passed) = 0, "Nothing ", passed) & "passed" End Function Function foo_dispatcher(Optional a, Optional b, Optional c, Optional d) Dim caseNum As Long caseNum = IIf(IsNull(a) Or IsEmpty(a) Or IsMissing(a), 0, 8) caseNum = caseNum + IIf(IsNull(b) Or IsEmpty(b) Or IsMissing(b), 0, 4) caseNum = caseNum + IIf(IsNull(c) Or IsEmpty(c) Or IsMissing(c), 0, 2) caseNum = caseNum + IIf(IsNull(d) Or IsEmpty(d) Or IsMissing(d), 0, 1) Select Case caseNum Case 0: foo_dispatcher = foo() Case 1: foo_dispatcher = foo(, , , d) Case 2: foo_dispatcher = foo(, , c) Case 3: foo_dispatcher = foo(, , c, d) Case 4: foo_dispatcher = foo(, b) Case 5: foo_dispatcher = foo(, b, , d) Case 6: foo_dispatcher = foo(, b, c) Case 7: foo_dispatcher = foo(, b, c, d) Case 8: foo_dispatcher = foo(a) Case 9: foo_dispatcher = foo(a, , , d) Case 10: foo_dispatcher = foo(a, , c) Case 11: foo_dispatcher = foo(a, , c, d) Case 12: foo_dispatcher = foo(a, b) Case 13: foo_dispatcher = foo(a, b, , d) Case 14: foo_dispatcher = foo(a, b, c) Case 15: foo_dispatcher = foo(a, b, c, d) End Select End Function Sub test() Debug.Print foo_dispatcher(Null, Null, Null, Null) Debug.Print foo_dispatcher(Null, 1, Null, 2) Debug.Print foo_dispatcher(1, 2, 3, 4) Debug.Print foo_dispatcher() Debug.Print foo_dispatcher(, 1, , 2) Debug.Print foo_dispatcher(a:=1, d:=Null) End Sub
test output:
Nothing passed bd passed abcd passed Nothing passed bd passed a passed
Obviously, actions in 16 cases can be adapted to the calling convention foo (for example, you can send foo(a,d) rather than foo(a,,,d) if you need to). I have not tested all 16 cases explicitly, but it seems to work. What I did was somewhat mechanical. You can write a dispatcher generator โ a function that takes the name of a string function, an array of required parameters, an array of optional parameters and a value that plays the role of Null and returns the dispatcher as a string that can be copied from the direct window to the code module. I thought about doing it here, but it did not seem to him appropriate for the manager of the evidence-based concept.