sql - 从众多 Excel 文件中提取到一个数据表或文件

标签 sql excel vba ms-access

我有超过 100 个 .xlsx 文件。每个文件有两张纸。第一张表(始终称为 sts)通常有 15-20,000 行,其中有一列称为“Code”。第二个工作表(始终称为 cps)大约有 85k 行,也具有相同的代码列。

我需要将工作表 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,但我在实现它时遇到了困难。当每个文件进入 Access 时,是否可以使用 aclink 而不是 acimport 来查询所需的代码行?如果可以,这可能是一种更快的方法吗?

最佳答案

看起来我倾向于支持的第二个选项中的问题之一是您要从 Excel 文件导入所有行。尝试使用 Excel 对象模型在两个工作表上定义命名范围,然后在循环中使用 docmd.transferspreadsheet 。您将需要更改其他工作表的列引用。 HTH。

用于查找实际使用的行、定义命名范围并导入 Access 的代码:

Dim xlApp As Excel.Application     
Dim xlWkb As Excel.Workbook       
Dim xlWS As Excel.Worksheet 
Dim lngLastRow as Long
Dim myImportRange as Range
dim strRangeName as String
set xlApp = New Excel.Application
xlApp.Visible=False 'make it go faster
set xlWB = xlApp.Workbooks.Open("PATH")
set xlWS = xlWB.Sheets("sts")
lngLastRow=xlWS.Range("A" & xlWS.Rows.Count).End(xlUp).Row
Set myImportRange = xlWS.Range("A1:G" & lnglastrow)
strRangeName="myData_2014MMDD"  'or any name that makes sense to you
myImportRange.Name=strRangeName
xlWB.Save
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, <Dest Table>, xlWb.FullName, True, strRangeName
xlApp.DisplayAlerts=False 'suppress save changes prompts
xlWB.Close False 

关于sql - 从众多 Excel 文件中提取到一个数据表或文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25426224/

相关文章:

sql - 在 Presto 中压缩数组

excel - 使用 VBA 将多列转置为多行

Python pandas 数据框和 excel : Add cell background color

excel - 如何在vba中向outlook中的多个收件人发送邮件

vba - 带有用户数据选择的excel图表

SQL 数据库架构 - 多对多或数据透视表

mysql - 如何通过属性连接两个表

mysql - 如果为空或计算值,则将设置 col 更新为 0.00

excel - 同时输入 2 个单元

VBA 字典正在复制键