将2列CSV导入两个单独的阵列

时间:2015-04-12 20:29:22

标签: arrays vba excel-vba csv import

我一直致力于一个涉及导入大量数据的项目,而我一直在做的事情太慢了。我有两个列.csv文件,我一直将它们一个一个地导入到一个新工作表中,然后使用for循环将单元格复制到一个数组中。

我想直接将.csv导入数组而不在工作表单元格上运行(它们太慢了!)。

我见过一个先前的解决方案,涉及将.csv复制到二维数组中,但我只是复制并粘贴他们的代码,然后编写自己的代码将其转换为单独的数组。非常混乱,而且很难调试。

Load csv file into VBA array rather than Excel sheet

有没有人有更简单的功能?下面的格式:

     Dim myXArray(1 TO 10000) as Double
     Dim myYArray(1 TO 10000) as Double

    'myArray = ImportCSV(path, column)
     myXArray = ImportCSV("C:\Users\Desktop\file.csv", 1)
     myYArray = ImportCSV("C:\Users\Desktop\file.csv", 2)

我的感觉是有人已经这样做了,并且通过询问,我不必重新发明轮子。它似乎是一个普遍有用的功能。

感谢您的帮助!

迈克尔

1 个答案:

答案 0 :(得分:1)

关于性能,请记住EXCEL是SPREADSHEET,而不是数据库。

它允许非程序员做编程类型的事情。混合代码和excel程序本身很少有优势。

所有这些都是vbscript,但vbscript在VBA中运行,但是可以通过不使用createobject来加快速度。

这取决于您处理数据的方式。如果它是线性的那么这很容易

Set fso = CreateObject("Scripting.FileSystemObject")
Set srcfile = fso.GetFile(objArgs(0))
If err.number = 0 then Set TS = srcFile.OpenAsTextStream(1, 0)
Src()=Split(Repace(ts.readall, VBCR, ""), VBLF)
For Each Line in Src()
     Field() = Split(Line, ",")
     msgbox Field(0) & Field(1)
Next

但如果您的数据很大,则会使用内存,这一次只能读取一行。

Do Until srcfile.AtEndOfStream
    Line=srcfile.readline
     Field() = Split(Line, ",")
     msgbox Field(0) & Field(1)
Loop

比数组更强大的是字典和记录集。记录集可以在内存中创建,但由于CSV是数据库文件,因此ADO可以读取它们并返回而不是作为记录集(可以保存)。以下是MS网站上有关如何使用ADO进行查询以及如何使用ADO进行查询的示例。

  

https://msdn.microsoft.com/en-us/library/ms974559.aspx?f=255&MSPPError=-2147217396

On Error Resume Next
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H0001

Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")

strPathtoTextFile = "C:\Databases\"

objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
          "Data Source=" & strPathtoTextFile & ";" & _
          "Extended Properties=""text;HDR=YES;FMT=Delimited"""

objRecordset.Open "SELECT * FROM PhoneList.csv", _
          objConnection, adOpenStatic, adLockOptimistic, adCmdText

Do Until objRecordset.EOF
    Wscript.Echo "Name: " & objRecordset.Fields.Item("Name")
    Wscript.Echo "Department: " & _
        objRecordset.Fields.Item("Department")
    Wscript.Echo "Extension: " & objRecordset.Fields.Item("Extension")   
    objRecordset.MoveNext
Loop

制作自己的

Sub Swap
    Dim LineCount
    Set rs = CreateObject("ADODB.Recordset")
    With rs
        .Fields.Append "LineNumber", 4 
        .Fields.Append "Txt", 201, 5000 
        .Open
        LineCount = 0
        Do Until Inp.AtEndOfStream
            LineCount = LineCount + 1
            .AddNew
            .Fields("LineNumber").value = LineCount
            .Fields("Txt").value = Inp.readline
            .UpDate
        Loop
        .Sort = "LineNumber DESC"
        Do While not .EOF
            Outp.writeline .Fields("Txt").Value
            .MoveNext
        Loop
    End With
End Sub