使用 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 文件中检索值的主要内容,如果未能解决你的问题,请参考以下文章

C#导出数据量大于100万csv

R:从多个.csv到xts中的单个时间序列

PHP导出100万数据到excel

如何使用 pandas 模块合并(即“concat”)100 多个 .csv 文件?

vbscript:如何用ado查询csv并返回csv

vbscript creazione-csv.vb