情况:

我有一个函数RemoveEmptyArrRowCol,它接受两个参数,其中一个是数组(tempArr)。

当第二个参数是时,一切都很好。当我将第二个参数更改为字符串(以及相关的调用变量)时,我得到了:



因此,在下面的代码示例中:

  • Test1运行良好
  • Test2失败

  • 问题:

    1)为什么两者之间的行为不同?

    2)如何修复第二个版本,使其表现与第一个相同?

    3)当我将字典值(数组)作为第一个参数而不是直接从工作表中读取时,该如何证明呢?

    我尝试了什么:

    这似乎是关于SO的常见问题,我已经研究了其中许多问题。我将其中一些作为该问题底部的引用。但是,我仍然没有解决为什么这两个子程序中的第一个起作用,但是第二个却不起作用?

    我玩过以下几种不同的组合:
  • 添加额外的括号
  • 明确声明tempArr的类型:Dim tempArr() As Variant
  • 更改函数签名的一部分:ByRef tempArr() As Variant

  • 在查看@Fionnuala对这个问题的答案MS Access/VBA type mismatch when passing arrays to function/subroutine之后,我决定尝试使用Call:
    Call RemoveEmptyArrRowCol2(ws.Range("C4:I129").Value, tempStr)
    

    经过编译,但是这意味着我需要更改代码的其他部分,以确保正确填充tempArr。如果以这种方式进行操作,则最好将函数转换为过程。

    照原样,流程是我在测试示例中填充tempArr,直接从工作表中填充,然后移交给另一个子项,即
    tempArr = RemoveEmptyArrRowCol(ws.Range("C4:I129").Value, tempStr)
    ArrayToSheet wb.Worksheets("Test").Range("A1"), tempArr
    

    请注意:问题3:

    在最终版本中,我将传递从字典中提取的数组作为第一个参数,即
    tempArr = RemoveEmptyArrRowCol( ArrayDict(tempStr), tempStr)
    

    工作版本:
    Option Explicit
    
    Public Sub Test1()
    
        Dim tempArr() 'variant
    
        Init
    
        Dim tempStr As String: tempStr = "Response Times"
    
        tempArr = RemoveEmptyArrRowCol(ws.Range("C4:I129").Value, categoryDict(tempStr & "Cols"))
    
    End Sub
    
    Private Function RemoveEmptyArrRowCol(ByRef tempArr As Variant, ByVal nCols As Long) As Variant
    
    End Function
    

    失败版本:
    Public Sub Test2()
    
        Dim tempArr()
    
        Init
    
        Dim tempStr As String: tempStr = "Response Times"
    
        tempArr = RemoveEmptyArrRowCol2(ws.Range("C4:I129").Value, tempStr)
    
    End Sub
    
    Private Function RemoveEmptyArrRowCol2(ByRef tempArr As Variant, ByVal tempStr As String) As Variant
    
    End Function
    

    当前完整功能的示例:
    Private Function RemoveEmptyArrRowCol(ByRef tempArr As Variant, ByVal tempStr As String) As Variant
    
        Dim i As Long
        Dim j As Long
        Dim counter As Long
        counter = 0
    
        Dim tempArr2()
    
        Dim totCol As Long
        Dim adjColTotal As Long
    
        totCol = categoryDict(tempStr & "Cols")
        adjColTotal = categoryDict(tempStr & "ColsAdj")
    
        Select Case tempStr
    
            Case "ResponseTimes", "NoCCPR"
    
                ReDim tempArr2(1 To 1000, 1 To adjColTotal)
    
                For i = 1 To UBound(tempArr, 1)
    
                    If tempArr(i, 2) <> vbNullString Then   'process row
    
                        counter = counter + 1                'load row to temp array (counter becomes row count)
    
                        For j = 1 To totCol
    
                            Select Case j
                                Case Is < 4
                                    tempArr2(counter, j) = tempArr(i, j)
                                Case Is > 4
                                    tempArr2(counter, j - 1) = tempArr(i, j)
                            End Select
    
                        Next j
    
                    End If
    
                Next i
    
                RemoveEmptyArrRowCol = RedimArrDimOne(tempArr2, adjColTotal, counter)
    
           Case "Incidents"
    
        End Select
    
    End Function
    

    其他引用:

    1)Passing arrays to functions in vba

    2)Passing array to function returns compile error

    3)Type mismatch error when passing arrays to a function in excel vba

    4)Should I use Call keyword in VBA

    最佳答案

    这实际上取决于您的输入和输出,例如RemoveEmptyArrRowCol2函数中的内容。这是一个选项,其中tempStr as String没有失败:

    Public Sub Test2()
        Dim tempArr()
        Dim tempStr As String: tempStr = "Response Times"
        tempArr = RemoveEmptyArrRowCol2(Range("C4:I129").Value, tempStr)
    End Sub
    
    Private Function RemoveEmptyArrRowCol2(ByRef tempArr As Variant, _
                                           ByVal tempStr As String) As Variant
        RemoveEmptyArrRowCol2 = Array(1, 2)
    End Function
    

    例如,如果删除返回值(Array(1,2),它将失败),但它应该失败,因为它不返回任何内容。

    10-06 06:27