如何将逗号分隔的字符串转换为二维数组

时间:2019-04-19 12:53:17

标签: excel vba

我有一个csv文件,该文件用Lf终止符逗号分隔,我想将此文件转换为二维数组以进行进一步处理。我成功地将文件读取为字符串,并将行终止符从Lf修改为Cr,因为我了解vba无法将Lf识别为终止符。我想使用此字符串并创建一个二维数组,在该数组中我还可以确定行数和列数,因为原始csv文件可以具有任意大小。 csv文件也可以很大(> 300 MB和> 1M个元素)

即使每条数据线的字符串中有一个CR终止符,我也无法弄清楚如何确定列数。下面的代码显示了我如何创建以Cr作为终止符的逗号分隔的字符串

Open fName For Binary As #1

     Buf$ = String$(LOF(1), 0)
     Get 1, , Buf$
     Buf$ = Replace$(Buf$, vbLf, vbCr) ' Replace LF with CR

Close #1

我想创建一个二维数组并计算行数和列数的方法或函数

2 个答案:

答案 0 :(得分:1)

我会尝试通过以下方式进行

  1. 首先使用 vbNewLine 将数据分成几行。
  2. 然后循环循环您的拆分数组,并使用逗号定界符拆分每个迭代。留下锯齿状的数组(包含数组的数组)。
  3. 最后,您现在有了两个Dim数组的尺寸,即ReDim并在其上循环以添加所有数据。
  

出于抽象目的,我将该任务分为三个独立的函数。


要调用的主要功能

我将定界符设置为可选,因此它不仅限于逗号。

  

这不考虑转义字符,如果需要,您必须添加。

Private Function TextFileToArray(ByVal FilePath As String, Optional ByVal Delimiter As String = ",") As Variant

    'READ THE CONTENTS FROM TEXTFILE
    Dim FileContent As String
    FileContent = ReadTextFile(FilePath)

    'SEPERATE THE ROWS USING vbNewLine
    Dim SplitData As Variant
    SplitData = Split(FileContent, vbNewLine)

    'CREATE A JAGGED ARRAY BY SPLITTING EACH STRING
    Dim JaggedArray As Variant
    ReDim JaggedArray(LBound(SplitData, 1) To UBound(SplitData, 1))

    Dim Index As Long
    For Index = LBound(SplitData, 1) To UBound(SplitData, 1)
        JaggedArray(Index) = Split(SplitData(Index), Delimiter)
    Next Index

    'CONVERT JAGGED ARRAY INTO A TWO DIM ARRAY
    TextFileToArray = JaggedArrayToTwoDimArray(JaggedArray)

End Function

读取文本文件的内容

这可以写在main函数中,但是通常最好将代码分成较小的块。

Public Function ReadTextFile(ByVal FilePath As String) As String

    Dim Fso As Object
    Set Fso = CreateObject("Scripting.FileSystemObject")

    Dim Ts As Object
    Set Ts = Fso.OpenTextFile(FilePath, 1, False)

    ReadTextFile = Ts.ReadAll

End Function

将锯齿状数组转换为二维数组

我已将范围存储在变量中,以使其更易于调试和读取。

Private Function JaggedArrayToTwoDimArray(ByVal SourceArray As Variant) As Variant

    'CAPTURE BOUNDS
    Dim LB1 As Long
    LB1 = LBound(SourceArray, 1)

    Dim UB1 As Long
    UB1 = UBound(SourceArray, 1)

    Dim LB2 As Long
    LB2 = LBound(SourceArray(LB1), 1)

    Dim UB2
    UB2 = UBound(SourceArray(UB1), 1)

    'SET BOUNDS OF RETURN ARRAY
    Dim ReturnArray As Variant
    ReDim ReturnArray(LB1 To UB1, LB2 To UB2)

    'POPULATE TWO DIM ARRAY FROM JAGGED ARRAY
    Dim RowIndex As Long
    For RowIndex = LB1 To UB1

        Dim ColIndex As Long
        For ColIndex = LB2 To UB2
            ReturnArray(RowIndex, ColIndex) = SourceArray(RowIndex)(ColIndex)
        Next ColIndex

    Next RowIndex

    JaggedArrayToTwoDimArray = ReturnArray

End Function

请随时添加错误处理和任何可能需要的更改。

答案 1 :(得分:0)

首先要想到的是使用InStr()来显示字符在字符串中的位置。预先定义数组尺寸(数据集的最后一行);在简短的示例中,我将使用i作为循环的迭代器)

sep = InStr(Cells(i,1).Value,"BS") 'swap BS for whatever you want to separate on

然后对每个数组使用单独的(sep)

arr(i,1) = left(Cells(i,1).value,sep-1)
arr(i,2) = right(Cells(i,1).value,len(cells(i,1))-sep+2) '2 characters in sep "b" and "s" so adding that back

我建议对您的代码进行的更改是使用一些符号或字符串而不是回车符,以便将其轻松分隔。