MMULT公式不适用于VBA功能

时间:2015-08-04 19:21:11

标签: excel vba excel-vba

我创建了一个VBA函数=cellrange(some inputs here),它产生一个数组(即$AD$3:$AP$346

在这个例子中,我使用以下公式来获得矩阵:=MMULT(TRANSPOSE($AD$3:$AP$345),$AD$3:$AP$345)并得到正确的答案。

当我使用我的VBA功能时: =MMULT(TRANSPOSE(INDIRECT(cellrange(A3,"all",COLUMN(AD2)-1,COLUMN(AP2)-1))),INDIRECT(cellrange(A3,"all",COLUMN(AD2)-1,COLUMN(AP2)-1)))

问题:为什么我会收到错误,如何修复?

P.S。我之前已多次成功使用此功能,但不在=MMULT()

VBA功能代码: [据我所知,此处没有任何错误,但我提供了参考资料]

Option Explicit

Public Function cellrange(rDates As Range, vFilter As Variant, Optional colOffsetA As Variant, Optional colOffsetB As Variant) As String
'DESCRIPTION:
    'This function takes any cell value in a row and a input: YTD, ALL, or any year (i.e. 2014, 2015) and it finds the range in which the date is situated

    Dim i As Long, ndx1 As Long, ndx2 As Long, r As Range, vA As Variant, bErr As Boolean, bAll As Boolean
    bErr = True
    If IsDate(rDates) Then
        With rDates.EntireColumn
            i = rDates.Parent.Evaluate("count(" & .Address & ")")
            Set r = .Cells(1 - i + rDates.Parent.Evaluate("index(" & .Address & ",match(9.9E+307," & .Address & "))").Row).Resize(i, 1)
        End With
        vA = r.Value
        If IsMissing(colOffsetA) And IsMissing(colOffsetB) Then
            colOffsetA = 0: colOffsetB = 0
        End If
        If IsMissing(colOffsetB) = True Then colOffsetB = colOffsetA
        Select Case LCase(vFilter)
            Case "all"
                bErr = 0: bAll = 1
                Set r = r.Range(r.Parent.Cells(1, 1 + colOffsetA), r.Parent.Cells(r.Count, 1 + colOffsetB))
            Case "ytd"
                For i = 1 To UBound(vA)
                    If ndx1 = 0 And Year(vA(i, 1)) = Year(Date) Then ndx1 = i
                    If vA(i, 1) <= Date Then ndx2 = i
                Next
            Case Else 'year
                vFilter = Val(vFilter)
                If vFilter Then
                    For i = 1 To UBound(vA)
                        If ndx1 = 0 And Year(vA(i, 1)) = vFilter Then ndx1 = i
                        If ndx1 And Year(vA(i, 1)) = vFilter Then ndx2 = i
                    Next
                End If
        End Select
        If Not bAll Then If ndx1 > 0 And ndx2 > 0 Then Set r = r.Range(r.Parent.Cells(ndx1, 1 + colOffsetA), r.Parent.Cells(ndx2, 1 + colOffsetB)): bErr = False
        If Not bErr Then cellrange = r.Address Else cellrange = CVErr(xlErrValue)
    Else
        cellrange = CVErr(xlErrValue) 'check if this is the correct error handling
    End If
End Function

支持照片 SQL Fiddle Demo

1 个答案:

答案 0 :(得分:0)

试试这个。使用NEWCELLRANGE更改cellrange函数并删除INDIRECT函数。看看它是否有效。

Public Function NEWCELLRANGE(rDates As Range, vFilter As Variant, Optional colOffsetA As Variant, Optional colOffsetB As Variant) As String
'DESCRIPTION:
'This function takes any cell value in a row and a input: YTD, ALL, or any year (i.e. 2014, 2015) and it finds the range in which the date is situated

Dim i As Long, ndx1 As Long, ndx2 As Long, r As Range, vA As Variant, bErr As Boolean, bAll As Boolean
bErr = True
If IsDate(rDates) Then
    With rDates.EntireColumn
        i = rDates.Parent.Evaluate("count(" & .Address & ")")
        Set r = .Cells(1 - i + rDates.Parent.Evaluate("index(" & .Address & ",match(9.9E+307," & .Address & "))").Row).Resize(i, 1)
    End With
    vA = r.Value
    If IsMissing(colOffsetA) And IsMissing(colOffsetB) Then
        colOffsetA = 0: colOffsetB = 0
    End If
    If IsMissing(colOffsetB) = True Then colOffsetB = colOffsetA
    Select Case LCase(vFilter)
        Case "all"
            bErr = 0: bAll = 1
            Set r = r.Range(r.Parent.Cells(1, 1 + colOffsetA), r.Parent.Cells(r.Count, 1 + colOffsetB))
        Case "ytd"
            For i = 1 To UBound(vA)
                If ndx1 = 0 And Year(vA(i, 1)) = Year(Date) Then ndx1 = i
                If vA(i, 1) <= Date Then ndx2 = i
            Next
        Case Else 'year
            vFilter = Val(vFilter)
            If vFilter Then
                For i = 1 To UBound(vA)
                    If ndx1 = 0 And Year(vA(i, 1)) = vFilter Then ndx1 = i
                    If ndx1 And Year(vA(i, 1)) = vFilter Then ndx2 = i
                Next
            End If
    End Select
    If Not bAll Then If ndx1 > 0 And ndx2 > 0 Then Set r = r.Range(r.Parent.Cells(ndx1, 1 + colOffsetA), r.Parent.Cells(ndx2, 1 + colOffsetB)): bErr = False
    If Not bErr Then NEWCELLRANGE = evaluate(r) Else NEWCELLRANGE = CVErr(xlErrValue)
Else
    NEWCELLRANGE = CVErr(xlErrValue) 'check if this is the correct error handling
End If
End Function