【问题标题】:Combine CSV files with Excel VBA将 CSV 文件与 Excel VBA 合并
【发布时间】:2015-04-20 15:48:15
【问题描述】:

我在一个文件夹中有一些 csv 文件。它们都包含 3 个特定的列。总列数和顺序可能会有所不同。

我想用下划线连接所有 3 列,并将它们写在运行代码的工作表的单个列中。

这是我目前所拥有的:

 Option Explicit

Sub test()

Dim i As Long
Dim LastRow As Long
Dim Columns()

Columns = Array("Column1", "Column2", "Column3")

'Find Columns by Name
For i = 0 To 2
    Columns(i) = Rows(1).Find(What:=Columns(i), LookIn:=xlValues, LookAt:=xlWhole, _
    MatchCase:=False, SearchFormat:=False).Column
Next i

'Debug.Print Columns(0)
'Debug.Print Columns(1)
'Debug.Print Columns(2)

LastRow = Cells(Rows.Count, "A").End(xlUp).Row


For i = 2 To LastRow
    Cells(i, 1) = Cells(i, Columns(0)) & "_" & Cells(i, Columns(1)) & "_" & Cells(i, Columns(2))
Next i

End Sub

如您所见,这可以满足我的要求,但仅适用于活动工作表。 我实际上想遍历与活动工作表相同的文件夹中的所有 csv 文件,并将结果写入第一张工作表,运行代码的工作表的第一列(这显然不是 csv 本身)。 我该怎么做?

谢谢!

【问题讨论】:

  • 嗨,在您的 excel 文件中,Column1 是否在 A 列上?
  • 嗨,我只有一个 excel 文件,它正在运行代码。其他文件都是csv,我感兴趣的列可能在不同的地方。

标签: excel csv vba


【解决方案1】:

这是一个循环遍历文件夹的代码

Sub Button1_Click()
    Dim MyFile As String, Str As String, MyDir As String, Wb As Workbook

    Set Wb = ThisWorkbook
    'change the address to suite
    MyDir = "C:\WorkBookLoop\"
    MyFile = Dir(MyDir & "*.xls")    'change file extension
    ChDir MyDir
    Application.ScreenUpdating = 0
    Application.DisplayAlerts = 0

    Do While MyFile <> ""
        Workbooks.Open (MyFile)

        'do something here




        MyFile = Dir()
    Loop

End Sub

【讨论】:

  • 但是,你能解释一下ChDir MyDirMyFile = Dir() 是做什么的吗?我不明白那些。为什么它们是必要的?
  • Why ChDir? & MyFile = Dir() '获取下一个条目。`
【解决方案2】:

这取决于您如何命名从 CSV 文件创建的工作表。您可以将所有工作表添加到集合中,并使用For...Each 循环在该循环中执行整个搜索和连接过程。请注意,您必须明确定义第一个工作表名称,因为这不会通过连续循环而改变:

Option Explicit

Sub test()

Dim i As Long
Dim LastRow As Long
Dim Columns()
Dim frontSheet as Worksheet
Dim wSheets as New Collection
Dim ws as Worksheet

Set frontSheet = Sheets("name of front sheet")

'Add all your CSV sheets to wSheets using the .Add() method.
For Each ws in wSheets

    Columns = Array("Column1", "Column2", "Column3")

    'Find Columns by Name
    For i = 0 To 2
        Columns(i) = ws.Rows(1).Find(What:=Columns(i), LookIn:=xlValues, LookAt:=xlWhole, _
        MatchCase:=False, SearchFormat:=False).Column
    Next i

    'Debug.Print Columns(0)
    'Debug.Print Columns(1)
    'Debug.Print Columns(2)

    LastRow = ws.Cells(Rows.Count, "A").End(xlUp).Row


    For i = 2 To LastRow
        frontsheet.Cells(i, 1) = ws.Cells(i, Columns(0)) & "_" & ws.Cells(i, Columns(1)) & "_" & ws.Cells(i, Columns(2))
    Next i

Next ws

End Sub

在 excel 中打开 CSV 文件通常既慢又费力,但 VBA 可以使用 TextStream 将它们作为文本文件读取。此外,文件脚本对象让您可以直接使用文件和目录。如果您以后不需要将文件保存在工作表中,这样的方法可能是更好的方法:

Sub SearchFoldersForCSV()

Dim fso As Object
Dim fld As Object
Dim file As Object
Dim ts As Object
Dim strPath As String
Dim lineNumber As Integer
Dim lineArray() As String
Dim cols() As Integer
Dim i As Integer
Dim frontSheet As Worksheet
Dim frontSheetRow As Integer
Dim concatString As String

Set frontSheet = Sheets("name of front sheet")
frontSheetRow = 1

strPath = "C:\where-im-searching\"

Set fso = CreateObject("Scripting.FileSystemObject")
Set fld = fso.GetFolder(strPath)

For Each file In fld.Files

    If (Right(file.Name, 3) = "csv") Then

        Debug.Print file.Name

        Set ts = file.OpenAsTextStream()

        lineNumber = 0

        Do While Not ts.AtEndOfStream

            lineNumber = lineNumber + 1
            lineArray = Split(ts.ReadLine, ",")

            If (lineNumber = 1) Then

                'We are at the first line of the .CSV so
                'find index in lineArray of columns of interest

                'Add extra ElseIf as required

                For i = LBound(lineArray) To UBound(lineArray)
                    If lineArray(i) = "Column 1" Then
                        cols(1) = i
                    ElseIf lineArray(i) = "Column 2" Then
                        cols(2) = i
                    ElseIf lineArray(i) = "Column 3" Then
                        cols(3) = i
                    End If
                Next i

            Else

                'Read and store the column of interest from this
                'row by reading the lineArray indices found above.

                concatString = ""
                For i = LBound(cols) To UBound(cols)
                    concatString = concatString & lineArray(i) & "_"
                Next i

                concatString = Left(concatString, Len(concatString) - 1)

                frontSheet.Cells(frontSheetRow, 1).Value = concatString
                frontSheetRow = frontSheetRow + 1

            End If

        Loop

        ts.Close

    End If

Next file

End Sub

您可以在FileSystemObjectTextStream here 找到更多信息。

【讨论】:

  • 感谢您的改进建议!我去看看
猜你喜欢
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
  • 2015-05-09
  • 1970-01-01
  • 1970-01-01
  • 2016-03-19
  • 2012-11-02
  • 2014-03-12
相关资源
最近更新 更多