【问题标题】:Loading More than 1 CSV File at a Time一次加载多个 CSV 文件
【发布时间】:2010-09-18 17:24:36
【问题描述】:

如何通过 Excel VBA 以一组、组或多个单个文件的形式导入 CSV 文件,而不是一次导入一个?

【问题讨论】:

    标签: vba csv excel file-import


    【解决方案1】:

    我有点困惑,大多数版本的 Excel 都可以毫无问题地打开 .csv 文件。

    strPath = "C:\Docs\"
    strFile = Dir(strPath & "*.csv")
    
    Do While strFile <> ""
        Workbooks.Open Filename:=strPath & strFile
        ActiveWorkbook.SaveAs Filename:=strPath & Mid(strFile, 1, InStr(strFile, ".") - 1) _
            & "Conv.xls", FileFormat:=xlNormal
    
        strFile = Dir
    Loop
    

    【讨论】:

      【解决方案2】:

      这会将文件快速放入一维数组

      Open "myfile.csv" For Input As 1
      Dim Txt As String
      Txt = Input(LOF(1), 1)
      Close #1
      Dim V As Variant
      V = Split(Txt, ",")
      

      那么V包含单个列中的所有项目,NB第一项是V(0)

      【讨论】:

      • 我认为你最好在 vbNewLine 上拆分以将文件分成几行,然后用逗号拆分每一行。这样,您就可以将每个字段称为 V(line)(column)。行和列当然是从零开始的。
      • 另外,这假设字段不是引号分隔或包含嵌入的逗号。
      【解决方案3】:

      这是另一种避免在 Excel 中打开 csv 文件时重新计算的方法。

      向您的工作簿添加一张空白工作表,并将以下代码添加到工作表的对象

      Function getCsv(fn)
          Dim d, scrup As Boolean
          scrup = Application.ScreenUpdating
          Application.ScreenUpdating = False
          With Me.QueryTables.Add( _
                  Connection:="TEXT;" & fn, _
                  Destination:=Me.Range("A1") _
              )
              .Name = "data"
              .FieldNames = True
              .RowNumbers = False
              .FillAdjacentFormulas = False
              .PreserveFormatting = True
              .RefreshStyle = xlOverwriteCells
              .SavePassword = False
              .SaveData = True
              .AdjustColumnWidth = False
              .TextFilePromptOnRefresh = False
              .TextFilePlatform = 850
              .TextFileStartRow = 1
              .TextFileParseType = xlDelimited
              .TextFileTextQualifier = xlTextQualifierDoubleQuote
              .TextFileCommaDelimiter = True
              .Refresh BackgroundQuery:=False
          End With
      
          d = Me.Names(1).RefersToRange.Value
      
          Me.Names(1).Delete
          Me.UsedRange.Rows.Delete
      
          Application.ScreenUpdating = scrup
          getCsv = d
      End Function
      

      您可能还想隐藏工作表,以免有人意外使用它。 然后就可以这样使用了

      dim d
      d = getCsv("C:\temp\some.csv")
      

      我稍微担心的一件事是,每次使用函数时名称都会增加(例如 data_1、data_2、...),因此如果这些名称保存在某个地方可能会出现稳定性问题。

      【讨论】:

        【解决方案4】:

        您可以编写一个简单的控制台应用程序来解析一批 csv 文件并将它们保存到 excel 文件中。
        不是最简单的解决方案,但它可能是一种选择。

        【讨论】:

          【解决方案5】:

          你也可以使用workbooks.opentext

          【讨论】:

            【解决方案6】:

            我最初的想法是这样的。鉴于这些数据

            Dog Names,Dog Ages,Collar Size
            Woof,3,4
            Bowser,2,5
            Ruffy,4.5,6
            Angel,1,7
            Demon,7,8
            Dog,9,2
            

            创建三个全局数组,分别称为Dog_NamesDog_AgesCollar_Size,并用 CSV 文件中的数据填充它们。

            这部分 VBScript 完成了这项工作并显示了结果。从x 子例程中的wscript.echo 中删除注释标记以查看这一切。

            Option Explicit
            
            Dim FSO
            Set FSO = CreateObject( "Scripting.FileSystemObject" )
            
            Dim oStream
            Dim sData
            Dim aData
            
            Set oStream = fso.OpenTextFile("data.csv")
            sData       = oStream.ReadAll
            aData       = Split( sData, vbNewLine )
            
            Dim sLine
            sLine = aData(0)
            
            Dim aContent
            aContent = Split( sLine, "," )
            
            Dim aNames()
            Dim nArrayCount
            nArrayCount = UBound( aContent )
            ReDim aNames( nArrayCount )
            
            Dim i
            
            For i = 0 To nArrayCount
              aNames(i) = Replace( aContent( i ), " ", "_" )
              x "dim " & aNames(i) & "()"
            Next
            
            For j = 0 To nArrayCount
              x "redim " & aNames(j) & "( " & UBound( aData ) - 1 & " )"
            Next
            
            Dim j
            Dim actual
            actual = 0
            
            For i = 1 To UBound( aData )
              sLine = aData( i )
              If sLine <> vbnullstring Then
                actual = actual + 1
                aContent = Split( sLine, "," )
                For j = 0 To nArrayCount
                  x aNames(j) & "(" & i - 1 & ")=" & Chr(34) & aContent(j) & Chr(34)
                Next
              End If
            Next
            
            For j = 0 To nArrayCount
              x "redim preserve " & aNames(j) & "(" & actual - 1 & ")"
            Next
            
            For i = 0 To actual - 1
              For j = 0 To nArrayCount
                x "wscript.echo aNames(" & j & ")," & aNames(j) & "(" & i & ")"
              Next
            Next
            
            Sub x( s )
              'wscript.echo s
              executeglobal s
            End Sub
            

            结果是这样的

            >cscript "C:\Documents and Settings\Bruce\Desktop\datathing.vbs"
            Dog_Names Woof
            Dog_Ages 3
            Collar_Size 4
            Dog_Names Bowser
            Dog_Ages 2
            Collar_Size 5
            Dog_Names Ruffy
            Dog_Ages 4.5
            Collar_Size 6
            Dog_Names Angel
            Dog_Ages 1
            Collar_Size 7
            Dog_Names Demon
            Dog_Ages 7
            Collar_Size 8
            Dog_Names Dog
            Dog_Ages 9
            Collar_Size 2
            >Exit code: 0    Time: 0.338
            

            【讨论】:

            • boost - 据我了解,ExecuteGlobal(和 Execute)仅在 VBScript 中可用,但在 VBA 中不可用?
            猜你喜欢
            • 2011-04-15
            • 2016-10-05
            • 1970-01-01
            • 1970-01-01
            • 2022-12-24
            • 1970-01-01
            • 2021-11-29
            • 1970-01-01
            • 2018-06-28
            相关资源
            最近更新 更多