VBA 对于 Excel (CSV),循环遍历文件以获取行,然后将行附加到一个列表中

VBA For Excel (CSV), Looping through files to get row, then appending rows into one List

我在为一堆 CSV 文件 (10000) 编写此 VBA 宏时遇到问题。搜索后我 found/used 这是我的代码: Loop through files in a folder using VBA?。它似乎不起作用,我不确定为什么...我尝试了 While 循环,但它非常慢我不知道它是否可以完成 运行。

Sub LoopThroughFiles()
Dim MyObj As Object, MySource As Object, file As Variant
file = Dir("C:\Users\me\Desktop\test")
While (file <> "")
  If InStr(file, "test") > 0 Then
        '// my macro code is here
     Exit Sub
  End If
 file = Dir
Wend
End Sub

我还应该尝试改变什么?我哪里做错了?我也尝试过使用此代码 https://www.thespreadsheetguru.com/the-code-vault/2014/4/23/loop-through-all-excel-files-in-a-given-folder,但不确定除了目录和 'Change First Worksheet 的背景填充蓝色 之外还有什么要更改的。

也尝试了这个 http://www.ozgrid.com/VBA/loop-through.htm 这看起来很简单,但我无法让它工作...

来自 L8N 的更新

Option Explicit

Sub looper()
Dim fso As Scripting.FileSystemObject
Dim aFolder As Scripting.Folder
Dim aFile As Scripting.file
Dim aText As Scripting.TextStreame
Dim singleLine As String

Set fso = New FileSystemObject
Set aFolder = fso.GetFolder("C:\Users\ME\Desktop\test") 'set path to the folder that contains the files

For Each aFile In aFolder.Files 'loops through every file in the top level of the folder
    If InStr(1, vbBinaryCompare) > 0 Then
        Range("A2:D200210").Clear   'what i want to happen to every file
        Set aText = fso.OpenTextFile(aFile.Path, ForReading)
        Do Until aText.AtEndOfStream
            singleLine = aText.ReadLine 'read line into string, every call advances the line counter by one, this prevents skipping lines
            If InStr(1, singleLine, vbBinaryCompare) > 0 Then Debug.Print singleLine ' in line case, prints line if target value is found
        Loop
    End If
Next aFile
Debug.Print "finished"

结束子

它运行了,但它似乎没有对每个文件实现我想要的更改 (Range("A2:D200210").Clear )。此外,我的代码的字符串名称无关紧要,sheet 中的信息也无关紧要。我的原始代码是测试它是否循环。

我不知道你到底想做什么,你的代码执行以下操作:

file = Dir("C:\Users\me\Desktop\test") 将文件名写入 file 如果文件 "test" 存在,如果您使用 Dir("C:\Users\me\Desktop\test\") 该函数将 return 第一个文件的名称它找到的文件。
在随后的运行中,它将 return 文件夹中的下一个文件,请记住这是一个全局调用,因此如果您在其他地方调用该函数,它可能会干扰。除了快速检查文件是否存在之外,大多数情况下最好使用 Microsoft Scripting Engine Runtime。

If InStr(file, "test") > 0 Then 你测试 "test" 是否是文件名的一部分,到目前为止一切顺利,但请记住告诉 InStr 它应该如何比较两个字符串。 InStr 接受四个参数(都是可选的),一定要传递正确的参数。 microsoft documentation其实还蛮不错的

这是你想要的吗?我认为您可能正在寻找 .csv 文件中的内容,如果是这样,我可以扩展下面的脚本。

下面附上了一种遍历文件夹中所有文件的简单方法:

Option Explicit

Sub looper()
    Dim fso As Scripting.FileSystemObject
    Dim aFolder As Scripting.Folder
    Dim aFile As Scripting.file
    Dim aText As Scripting.TextStream
    Dim targetName As String 'string that identifies files
    Dim targetWord As String 'string that identifies line inside csv file
    Dim singleLine As String 

    Set fso = New FileSystemObject
    Set aFolder = fso.GetFolder("C:\Users\Me\Desktop\test") 'set folder that contains the files
    targetName = "someFileName"
    targetWord = "someString"

    For Each aFile In aFolder.Files 'loops through every file in the top level of the folder
        If InStr(1, aFile.Name, targetName, vbBinaryCompare) > 0 Then
            Debug.Print "Found a matching File: "; aFile.Name
            Set aText = fso.OpenTextFile(aFile.Path, ForReading)
            Do Until aText.AtEndOfStream 
                singleLine = aText.ReadLine 'read line into string, every call advances the line counter by one, this prevents skipping lines
                If InStr(1, singleLine, targetWord, vbBinaryCompare) > 0 Then Debug.Print singleLine ' in line case, prints line if targer value is found
            Loop
        End If
    Next aFile
    Debug.Print "finished"
End Sub

奖金信息: 使用显式选项确保所有变量都正确声明


编辑:

还不能给你的 post 添加评论,所以我会把回复放在这里。

If InStr(1, vbBinaryCompare) > 0 Then 此行现在已断开,因为它将始终为 return 0。如果您想遍历每个文件,只需省略 IF-Contitional 或将其设置为 If True Then

Range("A2:D200210").Clear 是所谓的隐式引用,范围对象指的是 "Global" 工作表。每次执行这段代码时,"Global" Worksheet 都会发生变化,a nice answer by Mathieu Guindon from just recently explains this.

It runs, but it does not seem to implement the changes I want (Range("A2:D200210").Clear ) to each file. Also the string name for my code does not matter, the info in the sheet does not either. My original code was to test if it looped at all.

据我所知,您尝试删除 .csv 文件中除第一行以外的所有内容。 .csv 文件不是工作表(即使您可以将其导入 excel),因此您不能使用范围 属性.
幸运的是,有一种更简单的方法可以做到这一点,只需使用 Microsoft Scripting Runtime 来编辑 .csv 文件。

Set aText = aFile.OpenAsTextStream(ForReading) ' open file in read mode
singleLine = aText.ReadLine ' read the first line and store it
Set aText = aFile.OpenAsTextStream(ForWriting) ' open file in write mode
aText.Write (singleLine) 'write the line you saved before

或更紧凑:

aFile.OpenAsTextStream(ForWriting).Write aFile.OpenAsTextStream(ForReading).ReadLine 'overwrites the file with what was written in the first line.

较长代码的优点是能够在其他地方使用字符串,例如将其存储在工作簿中的某个地方。