I wrote a function called dot
that calculates the "inner product" using arbitrary operators. It works like this
L M
1 2
3 4
=dot(L:L,M:M, "*", "+", 1)
This would return 1 * 2 + 3 * 4 = 14
. You could replace '*'
and '+'
with '^'
and '-'
or whatever binary operators you like that work between two numbers.
The cool thing about this is that the operators can be text, in which case it performs concatenation. Like:
=dot(L:L,M:M, "*", "+", 0)
This would return the string 1 * 2 + 3 * 4
. You could also use 'foo' and 'bar' or whatever floats your boat.
For now I've limited it to contiguous vertical ranges. The vertical part is so that in text mode it makes sense. I would welcome the ability for the ranges to be non-contiguous, or any other improvements to the code. The speed is decent, but it could be faster, I'm sure. Here's what I have so far:
Public Function dot(rng1 As Range, rng2 As Range, times As String, plus As String, math As Boolean) As Variant
Dim arr1 As Variant, arr2 As Variant, i As Long, rcount As Long
Dim arrtimes() As String, result As Variant
On Error GoTo HandleError
rcount = rng1.Count
If rng1.Areas.Count > 1 Then Err.Raise 1
If rng2.Areas.Count > 1 Then Err.Raise 1
If rcount <> rng2.Count Then Err.Raise 1
If rng1.Columns.Count <> 1 Then Err.Raise 1
If rng2.Columns.Count <> 1 Then Err.Raise 1
ReDim arrtimes(1 To rcount)
arr1 = rng1.Value
arr2 = rng2.Value
If rcount = 1 Then
result = rng1.Value & times & rng2.Value
If math Then
dot = Evaluate(result)
Else
dot = result
End If
Exit Function
Else
For i = 1 To UBound(arr1, 1)
arrtimes(i) = arr1(i, 1) & times & arr2(i, 1)
If math Then
result = Evaluate(result & plus & "(" & arrtimes(i) & ")")
End If
Next i
End If
If Not math Then
dot = Join(arrtimes, plus)
Else
dot = result
End If
ExitHere:
Exit Function
HandleError:
dot = CVErr(xlErrNA)
Exit Function
End Function