You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Excel VBA调用PowerQuery加载PDF表格:分步正常连续运行无数据

问题场景与故障

通过Excel VBA调用PowerQuery,将多页PDF中的表格数据转换并加载到Excel工作表。流程为:先调用DisplayListTable过程加载PDF,获取各页面的名称及类型(页面/表格),再通过其他过程提取每页表格数据并处理。

故障现象:分步执行代码(F8)或在PowerQuery执行后设置断点时,数据加载正常;但连续运行(F5)时,无数据加载,仅显示"ExternalData_1: Getting Data..."。已尝试添加等待、刷新、DoEvents,禁用/启用事件及屏幕更新,均无效。

原DisplayListTable过程代码

Sub DisplayListTable(v_TableName as string v_Filename as string)

    'delete preexisting queries
    on error resume next
    thisworkbook.queries(v_TableName).Delete
    on error goto 0
    
    DoEvents

    thisworkbook.activate
    thisworkbook.queries.add name:=v_TableName; formula:= _
    "let" & chr(13) & "" & chr(10) & "    Source = Pdf.Tables(File.Contents("""" & v_FileName & """"), [Implementation=""1.3""])" & chr(13) & "" & chr(10) & "in" & chr(13) & "" & chr(10) & "    Source"
    thisworkbook.worksheets("LIST_OF_TABLE").select
    With activesheet.ListObjects.add(SourceType:=0, Source:= _
        "OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location="""" & v_TableName & """";Extended Properties="""""" _
        , Destination:=Range("$A$1")).QueryTable
        .CommandType = xlCmdSql
        .CommandText = Array("SELECT * FROM [" & v_TableName & "]")
        .RowNumbers = false
        .FillAdjacentFormulas = false
        .PreserveFormatting = true
        .RefreshOnFileOpen = false
        '.BackgroundQuery = true
        .BackgroundQuery = false
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = true
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .PreserveColumnInfo = true
        .Listobject.Name = v_TableName
        .Refresh
    End With
    
End Sub
解决方案

1. 修正代码语法错误

原代码存在多处语法问题,是导致连续运行失败的核心原因:

  • 过程参数定义缺少逗号:v_TableName as string v_Filename as string → v_TableName As String, v_Filename As String
  • Queries.Add方法的参数分隔符错误:分号;改为逗号,
  • PowerQuery公式中变量名写错:v_FileName → v_Filename
  • OLEDB连接字符串引号冗余:Location="""" & v_TableName & """" → Location=""" & v_TableName & """

2. 强制等待刷新完成

即使设置BackgroundQuery = False,VBA仍可能提前执行后续逻辑,需添加循环等待刷新结束:
在.Refresh语句后添加:

Do While .Refreshing
    DoEvents
Loop

3. 移除不必要的激活/选择操作

激活工作表或单元格容易引发时序冲突,改为直接引用对象:
用Set ws = ThisWorkbook.Worksheets("LIST_OF_TABLE")替代Select操作,后续通过ws引用工作表。

修正后的完整代码

Sub DisplayListTable(v_TableName As String, v_Filename As String)
    ' 删除已存在的查询
    On Error Resume Next
    ThisWorkbook.Queries(v_TableName).Delete
    On Error GoTo 0
    
    ' 创建PowerQuery查询
    Dim pqFormula As String
    pqFormula = "let" & vbCrLf & _
                "    Source = Pdf.Tables(File.Contents(""""" & v_Filename & """""), [Implementation=""1.3""])" & vbCrLf & _
                "in" & vbCrLf & _
                "    Source"
    ThisWorkbook.Queries.Add Name:=v_TableName, Formula:=pqFormula
    
    ' 直接引用目标工作表,避免Select/Activate
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("LIST_OF_TABLE")
    
    ' 添加ListObject并刷新数据
    With ws.ListObjects.Add(SourceType:=0, Source:= _
        "OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=""" & v_TableName & """;Extended Properties=""""", _
        Destination:=ws.Range("$A$1")).QueryTable
        .CommandType = xlCmdSql
        .CommandText = Array("SELECT * FROM [" & v_TableName & "]")
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .BackgroundQuery = False
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .PreserveColumnInfo = True
        .ListObject.Name = v_TableName
        .Refresh
        ' 等待刷新完成
        Do While .Refreshing
            DoEvents
        Loop
    End With
End Sub

内容的提问来源于stack exchange,提问作者MisterForty7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 12:45:00