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.
较长代码的优点是能够在其他地方使用字符串,例如将其存储在工作簿中的某个地方。
我在为一堆 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.
较长代码的优点是能够在其他地方使用字符串,例如将其存储在工作簿中的某个地方。