使用split命令填充数组时遇到了一些麻烦。
我目前拥有的字符串在
之下MyString = "Row1 Column1[~]Row1 Column2[~]Row1 Column3" & vbNewLine & _
"Row2 Column1[~]Row2 Column2[~]Row2 Column3" & vbNewLine & _
"Row3 Column1[~]Row3 Column2[~]Row3 Column3" & vbNewLine & _
"Row4 Column1[~]Row4 Column2[~]Row4 Column3"
我有一个数组,我希望它是多维的,并希望每个Row#Column#根据其数字位于数组的正确部分。
例如
MyArray(1,1) = "Row1 Column1"
MyArray(2,1) = "Row2 Column1"
MyArray(3,1) = "Row3 Column1"
MyArray(4,1) = "Row4 Column1"
MyArray(1,2) = "Row1 Column2"
MyArray(2,2) = "Row2 Column2"
MyArray(3,2) = "Row3 Column2"
MyArray(4,2) = "Row4 Column2"
MyArray(1,3) = "Row1 Column3"
MyArray(2,3) = "Row2 Column3"
MyArray(3,3) = "Row3 Column3"
MyArray(4,3) = "Row4 Column3"
现在我了解如何使用split命令填充单个维度数组
MyArray = Split(MyString, vbNewLine)
这意味着
MyArray(1) = "Row1 Column1[~]Row1 Column2[~]Row1 Column3"
MyArray(2) = "Row2 Column1[~]Row2 Column2[~]Row2 Column3"
MyArray(3) = "Row3 Column1[~]Row3 Column2[~]Row3 Column3"
MyArray(4) = "Row4 Column1[~]Row4 Column2[~]Row4 Column3"
但我不知道如何使用split命令填充第二维。
这是可能的,如果是这样的话? 如果不可能,有人可以建议如何实际填充这个吗?
答案 0 :(得分:5)
除了String或包含String的Variant之外,不能使用Split()。如果要生成二维字符串数组,则将遍历Split()返回的数组,并对每个字符串运行Split()。以下功能应该符合您的要求:
Private Function SplitTo2DArray(ByRef the_sValue As String, ByRef the_sRowSep As String, ByRef the_sColSep As String) As String()
Dim vasValue As Variant
Dim nUBoundValue As Long
Dim avasCells() As Variant
Dim nRowIndex As Long
Dim nMaxUBoundCells As Long
Dim nUBoundCells As Long
Dim asCells() As String
Dim nColumnIndex As Long
' Split up the table value by rows, get the number of rows, and dim a new array of Variants.
vasValue = Split(the_sValue, the_sRowSep)
nUBoundValue = UBound(vasValue)
ReDim avasCells(0 To nUBoundValue)
' Iterate through each row, and split it into columns. Find the maximum number of columns.
nMaxUBoundCells = 0
For nRowIndex = 0 To nUBoundValue
avasCells(nRowIndex) = Split(vasValue(nRowIndex), the_sColSep)
nUBoundCells = UBound(avasCells(nRowIndex))
If nUBoundCells > nMaxUBoundCells Then
nMaxUBoundCells = nUBoundCells
End If
Next nRowIndex
' Create a 2D string array to contain the data in <avasCells>.
ReDim asCells(0 To nUBoundValue, 0 To nMaxUBoundCells)
' Copy all the data from avasCells() to asCells().
For nRowIndex = 0 To nUBoundValue
For nColumnIndex = 0 To UBound(avasCells(nRowIndex))
asCells(nRowIndex, nColumnIndex) = avasCells(nRowIndex)(nColumnIndex)
Next nColumnIndex
Next nRowIndex
SplitTo2DArray = asCells()
End Function
示例:
Dim asCells() As String
asCells() = SplitTo2DArray(MyString, vbNewline, "~")
答案 1 :(得分:4)
这是一个更快的黑客,只是交换1D和2D数组没有循环:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Sub Form_Load()
Dim MyString As String
Dim MyFlatArray As Variant
Dim MyArray As Variant
'--- split source string by column&row separator
MyString = "Row1 Column1[~]Row1 Column2[~]Row1 Column3" & vbNewLine & _
"Row2 Column1[~]Row2 Column2[~]Row2 Column3" & vbNewLine & _
"Row3 Column1[~]Row3 Column2[~]Row3 Column3" & vbNewLine & _
"Row4 Column1[~]Row4 Column2[~]Row4 Column3"
MyFlatArray = Split(Replace(MyString, "[~]", vbCrLf), vbCrLf)
'--- convert to 2D array
ReDim MyArray(1 To 3, 1 To 4) As String
pvSwapArrays MyArray, MyFlatArray
'--- access row 2
Debug.Print MyArray(1, 2)
Debug.Print MyArray(2, 2)
Debug.Print MyArray(3, 2)
End Sub
Private Sub pvSwapArrays(vDst As Variant, vSrc As Variant)
Dim nDstType As Integer
Dim nSrcType As Integer
Dim pSrcArray As Long
Dim pDstArray As Long
Dim lTemp As Long
'--- sanity check types (VARIANT.vt)
Call CopyMemory(nDstType, vDst, 2)
Call CopyMemory(nSrcType, vSrc, 2)
Debug.Assert (nSrcType And &H2000) <> 0 '--- check if VT_ARRAY
Debug.Assert nDstType = nSrcType '--- check if dest type matches src (&H2008 = VT_ARRAY | VT_BSTR)
'--- get VARIANT.parray
Call CopyMemory(pSrcArray, ByVal VarPtr(vSrc) + 8, 4)
Call CopyMemory(pDstArray, ByVal VarPtr(vDst) + 8, 4)
'--- swap SAFEARRAY.pvData
Call CopyMemory(lTemp, ByVal pSrcArray + 12, 4)
Call CopyMemory(ByVal pSrcArray + 12, ByVal pDstArray + 12, 4)
Call CopyMemory(ByVal pDstArray + 12, lTemp, 4)
End Sub
答案 2 :(得分:0)
这是基于Variant类型包含数组的能力的另一种方法。我们有一个“数组数组”而不是2D数组。
Option Explicit
Private Function SplitSplit(ByRef Delimited As String) As Variant
Dim Rows() As String
Dim AryOfArys As Variant
Dim I As Long
Rows = Split(Delimited, vbNewLine)
ReDim AryOfArys(UBound(Rows))
For I = 0 To UBound(Rows)
AryOfArys(I) = Split(Rows(I), "[~]")
Next
SplitSplit = AryOfArys
End Function
Private Sub Form_Load()
Dim MyString As String
Dim MyAry As Variant
MyString = "Row1 Column1[~]Row1 Column2[~]Row1 Column3" & vbNewLine _
& "Row2 Column1[~]Row2 Column2[~]Row2 Column3" & vbNewLine _
& "Row3 Column1[~]Row3 Column2[~]Row3 Column3" & vbNewLine _
& "Row4 Column1[~]Row4 Column2[~]Row4 Column3"
MyAry = SplitSplit(MyString)
AutoRedraw = True
DumpAry MyAry
End Sub
Private Sub DumpAry(ByRef AryOfArys As Variant)
Dim Row As Long, Col As Long
For Row = 0 To UBound(AryOfArys)
For Col = 0 To UBound(AryOfArys(Row))
Print AryOfArys(Row)(Col),
Next
Print
Next
End Sub
这里的奖励是“乱七八糟的数组”,其中每行可以有不同数量的列。