情况:
我有一个函数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),它将失败),但它应该失败,因为它不返回任何内容。