I have a very rudimentary question about functions in VBA. Basically, I would like to create a function that would return 2 outputs, a scalar and a matrix. A user should be able to both store these results into separate variables in VBA and display them in Excel spreadsheet.
I could obviously use 2 different functions but this is not elegant and involves redundant computation
I created a class that has 2 properties and then defined my function as an instance of that class, storing my scalar and matrix as those properties. The problem is that in this case I don’t know how to display my results easily in Excel.
- I could however create 2 additional functions that would just read the respective (scalar or a matrix) output of the first function but this would again result in redundant computations.
I am afraid I am missing something really basic here and hope you can offer me some guidelines… Thanks a lot for your help 🙂
You can create a class with these two properties and return a new instance of this class as return value. Then your calling code would have to read both properties.
You could use
ByRef. Probably not the best plan though.
Sub Example(ByRef A As String, ByRef B As String) A = A & "Hello" B = B & "World!" End Sub Sub test() Dim A As String Dim B As String A = "Test" B = "Test" Example A, B Debug.Print A & " " & B End Sub
If your trying to make a UDF available on the worksheet then you can disregard me completely.
If you’re calling this (whatever your solution is) from the worksheet I think you will always have multiple (2) calls to the function. You might be able to cache the results of your function assuming it wont change frequently.
It wont stop the call, but it will stop some excess calculations.
Private Cache As Object Public Function MonsterFunction(ByVal A As Integer, ByVal B As Integer, Optional ByVal Add As Boolean = False) As Variant Dim Key As String Dim Result As Integer Key = CStr(A) & IIf(Add, "+", "-") & CStr(B) If Cache Is Nothing Then Set Cache = CreateObject("Scripting.Dictionary") End If If Cache.Exists(Key) Then MonsterFunction = Cache(Key) Else If Add Then Result = A + B Else Result = A - B End If Cache.Add Key, Result MonsterFunction = Result End If End Function
The easiest way? Probably:
Function TwoOutputs() As Variant() Dim matrix(1 To 2, 1 To 3) As Variant matrix(1, 1) = "Did" matrix(1, 2) = "it" matrix(1, 3) = "work?" matrix(2, 1) = "Yes" matrix(2, 2) = "it" matrix(2, 3) = "did!" TwoOutputs = Array("scalar", matrix) End Function
Then to access whichever attribute you want, you can:
Within VBA (0 will return the scalar, 2 will return the matrix):
Sub tst() Dim FunctionResult() As Variant Dim i As Long Dim j As Long FunctionResult = TwoOutputs MsgBox "Scalar: " & FunctionResult(0) For i = LBound(FunctionResult(1), 1) To UBound(FunctionResult(1), 1) For j = LBound(FunctionResult(1), 2) To UBound(FunctionResult(1), 2) MsgBox "Matrix loc(" & i & ", " & j & "): " & FunctionResult(1)(i, j) Next j Next i End Sub