使用 SQL 查询循环遍历文件夹

Posted

技术标签:

【中文标题】使用 SQL 查询循环遍历文件夹【英文标题】:Looping through folder with SQL query 【发布时间】:2016-10-20 14:04:21 【问题描述】:
strQuery = _
     "SELECT * FROM [Sheet1$A15:E999] " & _
     "IN '" & ThisWorkbook.Path & "\Source1.xlsx' " & _
     "[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;ExtendedProperties='HDR=YES;'] " & _
     "UNION " & _
     "SELECT * FROM [Sheet1$A15:E999] " & _
     "IN '" & ThisWorkbook.Path & "\Source2.xlsx' " & _
     "[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=YES;'] " & _
     "UNION " & _
     "SELECT * FROM [Sheet1$A15:E999] " & _
     "IN '" & ThisWorkbook.Path & "\Source3.xlsx' " & _
     "[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=YES;'] " & _
     "ORDER BY A;"

早上好,

我有最后一个钉子可以继续我的编码,非常感谢任何帮助。我正在从一个文件夹中收集大量文件,并且文件名不同(尽管数据顺序和数据相同)。

问题是:

是否可以通过“strQuery”获取所有文件而不减慢代码速度?我该如何继续这样做? (例如:我认为可能是循环,但它可能会变慢?- 见下文) 是否可以一次读取(比如说)100 个 excel 文件数据? (虽然我不知道它的名字?)

我可以修改 strQuery(通过为其分配一个文本字符串)并输入一个循环来遍历每个文件,但我认为这需要我为每个文件创建一个连接,而不是一次创建一个连接?

感谢任何帮助!

提前致谢。

--

下面的完整代码(我不知道在哪里可以看到)

Sub SqlUnionTest()

Dim strConnection As String
Dim strQuery As String
Dim objConnection As Object
Dim objRecordSet As Object, qText As String

strConnection = _
    "Provider=Microsoft.ACE.OLEDB.12.0;" & _
    "User ID=Admin;" & _
    "Data Source='" & ThisWorkbook.FullName & "';" & _
    "Mode=Read;" & _
    "Extended Properties=""Excel 12.0 Macro;"";"


Dim sFile As String

sFile = Dir(ThisWorkbook.Path & "\*.xlsx")

Do While sFile <> ""

    strQuery = _
     "SELECT * FROM [Sheet1$A15:E999] " & _
     "IN '" & ThisWorkbook.Path & "\" & sFile & _
     "[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;ExtendedProperties='HDR=YES;'] " & _
     "UNION "

    sFile = Dir()

Loop

strQuery = Left(strQuery, Len(strQuery) - 7) 'to remove last UNION which is not necessary

Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open strConnection
Set objRecordSet = objConnection.Execute(strQuery)
RecordSetToWorksheet Sheets(1), objRecordSet
objConnection.Close

End Sub

Sub RecordSetToWorksheet(objSheet As Worksheet, objRecordSet As Object)

Dim i As Long

With objSheet
    .Cells.Delete
    For i = 1 To objRecordSet.Fields.Count
        .Cells(1, i).Value = objRecordSet.Fields(i - 1).Name
    Next
    .Cells(2, 1).CopyFromRecordset objRecordSet
    .Cells.Columns.AutoFit
End With

End Sub

【问题讨论】:

【参考方案1】:

您可以使用DIR() 函数循环遍历文件夹中的所有.xlsx 文件,而无需知道具体的文件名。如果您需要清除任何文件,您可以在循环中放置条件测试。

代码未经测试

Dim sFile As String, strQuery As String

sFile = Dir(ThisWorkbook.Path & "\*.xlsx")

Do While sFile <> ""

    strQuery = strQuery & _
     "SELECT * FROM [Sheet1$A15:E999] " & _
     "IN '" & ThisWorkbook.Path & "\" & sFile & _
     "[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;ExtendedProperties='HDR=YES;'] " & _
     "UNION;"

    sFile = Dir()

Loop

strQuery = Left(strQuery, Len(strQuery) - 7) 'to remove last UNION which is not necessary

【讨论】:

嗨,谢谢,这是我的想法,但无法将其放入编码中!再次感谢。它给我一个错误运行时错误'-2122..“filepath\source3.xlsx[excel 12.0;provider=Microsoft.ace.oledb....不是有效名称。确保它不包含无效字符或标点符号,它不会太长。”我仍在尝试使用 3 个文件运行它,这些文件在原始问题中使用我的代码。如果我删除第三个文件,它会在第二个文件上显示错误。错误出现在行codeSet objRecordSet = objConnection.Execute(strQuery) 感谢您的输入! 我已经在原始问题中输入了我正在使用的代码(完整代码) @Dingo - 在 strQuery 构建后执行 debug.print 并查找语法关闭并调整的位置。从概念上讲,我的代码可以工作,但您需要进行调试以找出问题 斯科特,谢谢!我添加了以下内容和撇号,它起作用了! strQuery = strQuery & _ @dingo - 啊,是的。对于那个很抱歉。我编辑了我的答案。

以上是关于使用 SQL 查询循环遍历文件夹的主要内容,如果未能解决你的问题,请参考以下文章

sql查询出来的内容存入map,然后把他们遍历出来

循环遍历列表以从 SQL 查询创建多个数据帧

动态 SQL Server 查询循环遍历架构查找主键重复

SQL查询遍历数据方法一 [ 临时表 + While循环]

sql 声明两个临时表,在运行更新查询时循环遍历两个数据集。

使用SQL While循环遍历列表