简体   繁体   English

MMULT公式不适用于VBA函数

[英]MMULT formula not working with a VBA function

I created a VBA function =cellrange(some inputs here) that yields an array (ie $AD$3:$AP$346 ) 我创建了一个VBA函数=cellrange(some inputs here) ,它产生一个数组(即$AD$3:$AP$346

In this example I am using the following formula in order to get a matrix: =MMULT(TRANSPOSE($AD$3:$AP$345),$AD$3:$AP$345) and I get the correct response. 在此示例中,我使用以下公式来获取矩阵: =MMULT(TRANSPOSE($AD$3:$AP$345),$AD$3:$AP$345)并获得正确的响应。

When I use my VBA function: =MMULT(TRANSPOSE(INDIRECT(cellrange(A3,"all",COLUMN(AD2)-1,COLUMN(AP2)-1))),INDIRECT(cellrange(A3,"all",COLUMN(AD2)-1,COLUMN(AP2)-1))) 当我使用VBA函数时: =MMULT(TRANSPOSE(INDIRECT(cellrange(A3,"all",COLUMN(AD2)-1,COLUMN(AP2)-1))),INDIRECT(cellrange(A3,"all",COLUMN(AD2)-1,COLUMN(AP2)-1)))

Question: Why do I get an error and how can this be fixed? 问题:为什么会出现错误,如何解决?

PS I have used this function sucessfully many times before, however not in a =MMULT() PS我已经多次成功使用了此功能,但是在=MMULT()没有使用过

VBA function code: [there is nothing wrong here as far as I know, but I have provided it for reference] 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

Support Photo: 支持照片: 在此处输入图片说明

Try this. 尝试这个。 Change your cellrange function with NEWCELLRANGE and remove INDIRECT functions. 使用NEWCELLRANGE更改单元格范围函数并删除INDIRECT函数。 See if it works. 看看是否可行。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM