Arrays 为什么Join()需要对一维长数组进行双换位?
为什么Join()需要一个一维长数组的双重转置? 由于 Join()函数需要一个sourcearray作为“包含要联接的子字符串的一维数组”(顺便说一句,帮助站点对它是变体还是长型没有区别) 注:在 数组定义为具有相同内在数据类型的顺序索引元素集 通过Arrays 为什么Join()需要对一维长数组进行双换位?,arrays,excel,vba,Arrays,Excel,Vba,为什么Join()需要一个一维长数组的双重转置? 由于 Join()函数需要一个sourcearray作为“包含要联接的子字符串的一维数组”(顺便说一句,帮助站点对它是变体还是长型没有区别) 注:在 数组定义为具有相同内在数据类型的顺序索引元素集 通过Join()和 甚至可以连接数字,因为它们似乎在内部被解释为“将我们转换为字符串” 1-dim阵列声明为长的问题 在某些情况下,我希望将元素类型限制为Long,并避免上面提到的Variant解决方案。- 将“平面”数组(此处:Numbers())声
Join()
和
甚至可以连接数字,因为它们似乎在内部被解释为“将我们转换为字符串”
1-dim阵列声明为长的问题
在某些情况下,我希望将元素类型限制为Long
,并避免上面提到的Variant
解决方案。-
将“平面”数组(此处:Numbers()
)声明为Long,但会引发错误5“过程调用或参数无效”,
如果您试图通过一个简单的
'[2] Failing
Join(Numbers, "|") .
我发现了一个有趣的故事► 通过基本冗余的双转置解决(c.f.[1]
),
当它“转换”平面一维阵列时,最终会返回到相同的维度
'[1] work around
Join(Application.Transpose(Application.Transpose(Numbers)), "|")
问题
VBA处理这两种情况的内部区别是什么?为什么Join()
需要对一维长数组进行双重换位
加入声明为Long的“平面”数组的调用示例 要显示变通代码行
[1]
以及引发错误的代码行[2]
,请执行以下操作:,
我还集成了一个基本的错误处理,显示用户定义的错误行(ERL
)
VB编辑器的即时窗口显示ERL 200中的错误5:
示例呼叫
Sub JoinArr()
Dim Numbers() As Long ' provide for long array Numbers()
FillNumbers 3, Numbers ' call sub procedure to assign 3 numbers to array Nums
' Numbers is now an array of 3 numbers
On Error GoTo oops
'[1] work around - why does Join() need a double transposition in a 1-dim array?
100 Debug.Print " OK: [1] " & UBound(Numbers) & " elems:" & _
" ~> " & Join(Application.Transpose(Application.Transpose(Numbers)), "|")
'[2] join an already existing "flat" array raises Error 5 "Invalid procedure call or argument"
200 Debug.Print " OK [2] " & UBound(Numbers) & " elems:" & _
" ~> " & Join(Numbers, "|")
Exit Sub
oops: Debug.Print "ERL: " & Erl & " Error No " & Err.Number & " " & Err.Description
End Sub
SubFillNumbers
由上述主过程调用
Sub FillNumbers(ByVal n As Long, arr)
ReDim arr(1 To n)
arr(1) = 100
arr(2) = 200
arr(3) = 300
End Sub
尝试Join()
一个Long
s数组将失败:
Sub JoinTestFails()
Dim Numbers(0 To 2) As Long, msg As String
Numbers(0) = 0
Numbers(1) = 1
Numbers(2) = 2
With Application.WorksheetFunction
msg = Join(Numbers, "|")
End With
MsgBox msg
End Sub
双重使用TRANSPOSE()
Sub JoinTest()
Dim Numbers(0 To 2) As Long, msg As String
Numbers(0) = 0
Numbers(1) = 1
Numbers(2) = 2
With Application.WorksheetFunction
Arr = .Transpose(.Transpose(Numbers))
msg = LBound(Arr) & "**" & UBound(Arr) & vbCrLf
msg = msg & Join(.Transpose(.Transpose(Numbers)), "|") & vbCrLf & TypeName(Arr)
End With
MsgBox msg
End Sub
对我来说,转置的这种用法是不直观的。我宁愿使用以下内容制作变体
数组:
Public Function MkVar(arr() As Long) As Variant
' make a variant array from a long array
Dim temp() As Variant, i As Long
ReDim temp(LBound(arr) To UBound(arr))
For i = LBound(arr) To UBound(arr)
temp(i) = arr(i)
Next i
MkVar = temp
End Function
然后:
Sub JoinTest2()
Dim Numbers(0 To 2) As Long, msg As String
Numbers(0) = 0
Numbers(1) = 1
Numbers(2) = 2
arr = MkVar(Numbers)
msg = LBound(arr) & "**" & UBound(arr) & vbCrLf
msg = msg & Join(MkVar(Numbers), "|") & vbCrLf & TypeName(arr)
MsgBox msg
End Sub
Split()创建索引为0的第一个元素的1d变量数组。Join()是Split()的必然结果,它的设计目的是完全颠倒过程,因此需要一个变量数组。^^^^^为了清楚起见,Application.Transpose(Application.Transpose(Numbers))
返回一个变量数组。Excel工作表函数Transpose()将1d数组视为一行值。当您转置它时,它会将其转换为二维数组,并将值转置到第一列。转置再次将其转换为2d数组,值位于第一行。还要了解该应用程序。转置有局限性和缺点。如果您打算在某个时刻将数组写入工作表,通常从一开始就可以更好地使用二维数组进行尺寸标注和处理,而不是希望使用应用程序。转置可以在写入时为您解围。请参阅上面的提示。在我看来,Join()实际上需要一个变体(尽管在MS Help中不明显),而双转置提供可以连接的元素。同时,我发现VBA语言规范的第6.1.2.11.1.16章将函数声明缩小为:“函数连接(SourceArray()作为变量,可选分隔符作为变量)作为字符串”。对我来说,这种转置的使用是不直观的——这就是为什么我出于系统性原因要求理解内部功能。当然,我同意Variant数组提供了一种简单的方法(请参阅OP中的简介:“通过Join()连接一维Variant数组没有问题”)。这与我希望完全理解的不完全一样,但被认为是有帮助的分析:+)
Sub JoinTest2()
Dim Numbers(0 To 2) As Long, msg As String
Numbers(0) = 0
Numbers(1) = 1
Numbers(2) = 2
arr = MkVar(Numbers)
msg = LBound(arr) & "**" & UBound(arr) & vbCrLf
msg = msg & Join(MkVar(Numbers), "|") & vbCrLf & TypeName(arr)
MsgBox msg
End Sub