tags:

views:

81

answers:

0

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