使用 VBScript 从 100 万多个 csv 文件中检索值
Posted
技术标签:
【中文标题】使用 VBScript 从 100 万多个 csv 文件中检索值【英文标题】:Retrieve values from 1 million plus csv files using VBScript 【发布时间】:2016-03-17 07:05:30 【问题描述】:我需要从多个文件(比如一百万个 csv 文件)复制值并将其粘贴到 Master 中。
附上代码sn-p:-
Public Sub GetDataFromClosedBook()
Dim Filename As String
Dim wkb As Workbook
Application.EnableEvents = False
Application.ScreenUpdating = False
Sheets("Meter-1").Visible = True
Sheets("Meter-1").Select
mydata = "G:\BIS Dashboard(Finalised-13012016)\Files_Oct-21\"
Filename = Dir(mydata & "\AC PANEL-2_22_**************.csv", vbNormal)
Do Until Filename = ""
Workbooks.Open Filename:=mydata & Filename, ReadOnly:=True
For Each Sheet In ActiveWorkbook.Sheets
Sheets(1).Range("C8, E8").Copy ThisWorkbook.Sheets("Meter- 1").Range("A1048576").End(xlUp).Offset(1, 0)
Next Sheet
Workbooks(Filename).Close
Filename = Dir()
Loop
Sheets("Meter-1").Select
Sheets("Meter-1").Visible = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
如果 csv 文件较少(比如 1000 个 csv 文件),上面的代码可以完美运行并检索值,但我想如何从所有文件中检索值。
代码运行了一段时间,没有响应,最终excel在一个小时左右后崩溃。
任何帮助将不胜感激!!!
【问题讨论】:
试图通过自动化来做到这一点是自找麻烦,而且开销太大。 它循环所有工作表,但只使用工作表 1,是否只有 1 个工作表,不需要循环,如果有多个工作表,你只使用工作表(1),没有用床单。您也可以查看 ADO,使用 connectionstrings.com/textfile 和 java2s.com/Code/VBA-Excel-Access-Word/Excel/… 并不是说这肯定会解决,但值得一试...... 每个 *.cvs 需要复制多少行?究竟有多少个 *.cvs 文件? 每个csv文件只有一张。我只想从包含一个工作表的每个工作簿中复制两个单元格值。@ Susilo 感谢您的建议。是的,csv 文件中只有一张表,我会根据您的建议进行更改。@Nathan_Sav 【参考方案1】:首先,这是没有意义的:
For Each Sheet In ActiveWorkbook.Sheets
Sheets(1).Range("C8, E8").Copy ThisWorkbook.Sheets("Meter- 1").Range("A1048576").End(xlUp).Offset(1, 0)
Next Sheet
您的目标似乎在当前书籍的所有工作表上循环,但是说Sheets(1).
它总是占用第一张工作表,因此您最终会得到重复的值。请改用Sheet.
。
那么,如果你真的有 100 万个文件要处理,你应该彻底改变你的方法来限制一直使用的内存。
一些提示:
不要在 Excel 中托管您的脚本。看来您现在是从 Excel VBA 执行此操作的。在独立的 VBscript 中移动它。您必须稍微重写代码才能使用 Excel 对象而不是 Application.
,例如 Set objExcel = CreateObject("Excel.Application")
甚至不要尝试将您的结果写入 Excel 文件,否则您会在某个时候耗尽内存。而是将其写入一个简单的文本文件,使用 File System Object aka FSO。 之后,您将从文本文件中将结果导入 Excel。
-
在您的循环中,您应该确保始终清理内存垃圾。您应该实例化一个工作簿对象并在您的副本完成后将其终止。第一个循环步骤应该类似于
Set objWorkbook = objExcel.Workbooks.Open(mydata & Filename)
,当您的复制内容完成后,在循环到下一个之前,执行Set objWorkbook = Nothing
所有这些都不能保证你会实现你想要的,但会增加很多你的机会
我在用手机在火车上,很抱歉,我不能提供更多细节和更好的格式。
祝你好运
【讨论】:
对不起,代码中有一个小修改,我再次重新发布代码。@Thomas G 感谢您的建议,我会努力的,我会尽快发布结果@Thomas G【参考方案2】:Do Until Filename = ""
On Error Resume Next
Set wkb = Workbooks.Open(mydata & Filename)
wkb.Sheets.Range("C8, E8").Copy ThisWorkbook.Sheets("Meter-1").Range("A1048576").End(xlUp).Offset(1, 0)
wkb.Close False
Filename = Dir()
Loop
【讨论】:
【参考方案3】:1,000,000?碉堡了!我不确定 Excel 或 VBA 或任何类似性质的东西会处理这项任务。您可以使用 SQL Server 来完成这项工作吗?文件名中必须有一个模式...我当然希望如此...试试 SQL server express,您可以使用下面的链接免费获得它。
https://www.microsoft.com/en-us/download/details.aspx?id=42299
然后,使用您可以使用的任何模式循环浏览 CSV 文件。在下面的脚本中,我正在更改日期,一次一天。这只是一个例子。我确定您没有 1,000,000 个日期,除非您正在测量恐龙四处走动时的某些东西。只需更改脚本以满足您的需要。
DECLARE @intFlag INT
SET @intFlag = 1
WHILE (@intFlag <=10000)
BEGIN
PRINT @intFlag
declare @fullpath1 varchar(1000)
select @fullpath1 = '''\\FTP\your_path' + convert(varchar, getdate()- @intFlag , 112) + '_your_file.txt'''
declare @cmd1 nvarchar(1000)
select @cmd1 = 'bulk insert [dbo].[your_table] from ' + @fullpath1 + ' with (FIELDTERMINATOR = ''\t'', FIRSTROW = 2, ROWTERMINATOR=''0x0a'')'
exec (@cmd1)
SET @intFlag = @intFlag + 1
END
GO
【讨论】:
以上是关于使用 VBScript 从 100 万多个 csv 文件中检索值的主要内容,如果未能解决你的问题,请参考以下文章