Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 为什么Join()需要对一维长数组进行双换位?_Arrays_Excel_Vba - Fatal编程技术网

Arrays 为什么Join()需要对一维长数组进行双换位?

Arrays 为什么Join()需要对一维长数组进行双换位?,arrays,excel,vba,Arrays,Excel,Vba,为什么Join()需要一个一维长数组的双重转置? 由于 Join()函数需要一个sourcearray作为“包含要联接的子字符串的一维数组”(顺便说一句,帮助站点对它是变体还是长型没有区别) 注:在 数组定义为具有相同内在数据类型的顺序索引元素集 通过Join()和 甚至可以连接数字,因为它们似乎在内部被解释为“将我们转换为字符串” 1-dim阵列声明为长的问题 在某些情况下,我希望将元素类型限制为Long,并避免上面提到的Variant解决方案。- 将“平面”数组(此处:Numbers())声

为什么Join()需要一个一维长数组的双重转置?

由于 Join()函数需要一个sourcearray作为“包含要联接的子字符串的一维数组”(顺便说一句,帮助站点对它是变体还是长型没有区别)

注:在 数组定义为具有相同内在数据类型的顺序索引元素集

通过
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
Sub
FillNumbers
由上述主过程调用

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