【问题标题】:Importing a 2-column CSV into two separate arrays将 2 列 CSV 导入两个单独的数组
【发布时间】:2023-03-09 05:13:01
【问题描述】:

我一直在做一个涉及导入大量数据的项目,我做事的方式太慢了。我有两列 .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)

我的感觉是有人已经这样做了,通过询问,我不必重新发明轮子。看起来它会是一个如此普遍有用的功能。

感谢您的帮助!

迈克尔

【问题讨论】:

  • 转换为单维数组有什么麻烦?我不认为从 CSV 读取单个列的方法会更干净。它还需要您读取文件两次。如果你不喜欢这一步,也许你可以分享你用来获取一维数组的代码。

标签: arrays vba excel csv import


【解决方案1】:

关于性能,记住 EXCEL 是电子表格,而不是数据库。

它允许非程序员做编程类型的事情。混合代码和 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来查询和获取我自己的一个又一个。

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

【讨论】:

  • 虽然我很痛苦地意识到 Excel VBA 的局限性,但我必须在我当前的应用程序中使用它。今天下午我实施了第二个解决方案,效果很好。我一直在 C# 中使用类似的 StreamReader 类型代码,并且很高兴意识到它在 VBA 中同样简单。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-02-28
  • 2016-01-06
  • 1970-01-01
  • 2012-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多