【发布时间】:2014-10-15 01:55:50
【问题描述】:
我有 100 多个 .xlsx 文件。每个文件有两张纸。第一张表(通常称为 sts)通常有 15-2 万行,有一列称为“代码”。第二张表(通常称为 cps)有大约 85k 行,也有相同的 Code 列。
我需要将特定代码的所有行从工作表 sts 提取到表/工作表中,并将特定代码的所有行从工作表 cps 提取到第二个表/工作表中。我需要对所有文件执行此操作。
我尝试了两种方法
1) 使用 Excel VBA 打开每个文件,使用自动过滤器将所需的代码行复制到主工作簿中进行排序。使用以下代码从预定义的起始目录中获取文件并向下钻取Public Sub SearchFiles()。
Public Sub SearchFiles()
'Macro to start the file extraction by drilling down from the mydir path specified
Dim code As String
Dim time1 As Double
Dim time2 As Double
Range("a1").Value = InputBox("Please type code to extract", code)
time1 = Timer
myFileSearch _
myDir:="C:\Data\Dashboard\2014\New Files Excel Loop", _
FileNameLike:="Reporting", _
FileTypeLike:=".xlsx", _
SearchSubFol:=True, _
myCounter:=0
time2 = Timer
MsgBox time2 - time1 & "seconds"
End Sub
Private Sub myFileSearch(myDir As String, FileNameLike As String, FileTypeLike As String, _
SearchSubFol As Boolean, myCounter As Long)
Dim fso As Object, myFolder As Object, myFile As Object
Dim Rowcount As Long
Dim rowcount2 As Long
Dim masterbook As Workbook
Set masterbook = ThisWorkbook
Set fso = CreateObject("Scripting.FileSystemObject")
Dim commodity As String
code = Range("a1").Value
Application.ScreenUpdating = False
For Each myFile In fso.GetFolder(myDir).Files
Workbooks.Open (myDir & "\" & myFile.Name)
myCounter = myCounter + 1
ReDim Preserve myList(1 To myCounter)
myList(myCounter) = myDir & "\" & myFile.Name
''loop to pull out all code rows in your directories into new file
Workbooks(Workbooks.Count).Worksheets(1).Range("d2").Activate
Rowcount = Workbooks(1).Sheets(1).Range("a1").CurrentRegion.Rows.Count + 1
Rows(1).AutoFilter
Range("A1").AutoFilter Field:=3, Criteria1:=code, Operator:=xlAnd
Range("A1").CurrentRegion.SpecialCells(xlCellTypeVisible).Copy _
Destination:=Workbooks(1).Sheets(1).Range("a" & Rowcount)
'filter out the code data
Workbooks(Workbooks.Count).Worksheets(2).Activate
Range("d2").Activate
rowcount2 = Workbooks(1).Sheets(2).Range("a1").CurrentRegion.Rows.Count + 1
Rows(1).AutoFilter
Range("A1").AutoFilter Field:=6, Criteria1:=code, Operator:=xlAnd
Range("A1").CurrentRegion.SpecialCells(xlCellTypeVisible).Copy _
Destination:=Workbooks(1).Sheets(2).Range("a" & Rowcount)
Workbooks(myFile.Name).Close savechanges:=False
Next
If SearchSubFol Then
For Each myFolder In fso.GetFolder(myDir).SubFolders
myFileSearch myDir & "\" & myFolder.Name, FileNameLike, FileTypeLike, True, myCounter
Next
End If
End Sub
打开每个工作簿需要 5-10 秒,整个过程非常缓慢(目前还存在错误)。
2) 将所有内容导入两个 Access 表,然后只清除我想要的代码行。由于行数,这比 Excel 方法慢。
Sub pulloop()
DoCmd.RunSQL "delete * from sts"
DoCmd.RunSQL "delete * from cps"
strSql = "PathMap"
Set rs = CurrentDb.OpenRecordset(strSql)
With rs
If Not .BOF And Not .EOF Then
.MoveLast
.MoveFirst
While (Not .EOF)
importfile = rs.Fields("Path")
DoCmd.TransferSpreadsheet acimport, acSpreadsheetTypeExcel12, "Sts", importfile, True, "Sts!A:G"
DoCmd.TransferSpreadsheet acimport, acSpreadsheetTypeExcel12, "CPs", importfile, True, "CPs!A:Q"
'Debug.Print rs.Fields("Path")
.MoveNext
Wend
End If
.Close
End With
End Sub
我对此进行了调整以尝试使用 AcLink,但我正在努力实现它。是否可以使用 aclink 而不是 acimport 来查询每个文件进入 Access 时所需的代码行,如果是这样,这可能是一种更快的方法吗?
【问题讨论】:
-
问题更适合Code Review
-
也许这个问题有一些信息:stackoverflow.com/questions/8178161/…
-
与 5-10 秒的文件打开开销相比,实际数据操作需要多长时间?可以进行一些改进(删除
Activates等)。也许一条新的路线,例如将xlsx文件保存为csv文件并使用 PowerShell(不太难学)来操作csv文件将对可重复的任务产生影响 -
打开文件是第一次消耗性任务,我想通过某种方式从关闭的工作簿中获取数据来解决这个问题。另一个消耗性任务是复制粘贴自动过滤数据。我已经读过将数据放入一个数组并设置接收数据的工作簿的范围等于该数组,这比复制粘贴快得多。我不介意学习如何使用 powershell,但我的文件需要保持其原始格式,因为它们位于共享驱动器上,并且每天都有新的,我无法维护它们的单独 csv 库。
-
您没有说明为什么您在使用 acLink 时遇到问题。我认为链接到电子表格,然后在此链接表上运行您的查询可能是您最好的选择。