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

如何为Before/After Refresh事件添加有效错误处理程序?

问题描述

我通过参数化查询从SQL Server导入数据,该查询需要用户输入日期:

  • 当用户正确输入开始日期和结束日期时,所有流程均正常完成。
  • 但当日期输入错误时,错误处理程序不会触发,宏会继续执行直到AfterRefresh事件。

我已为所有模块添加了错误处理程序,但仍无响应。请问如何为Before/After Refresh事件添加有效的错误处理程序?

Power Query 逻辑代码

let 
    Source = Sql.Database("MyDataBase", [Query="Select Transaction_date, Customer_ID
                                                from TransactionList
                                                where Transaction_date between @StartDate and @EndDate"])
in
    Source

VBA 代码

标准模块代码

'========== [ Modules ] ========== 
Option Explicit 
Dim colQueries As New Collection

Sub Button_RefreshData() 
On Error GoTo Error_Handler

    Call InitializeQueries
    ThisWorkbook.RefreshAll
Exit Sub
Error_Handler: 
    MsgBox Err.Number & " " & Err.Source & vbNewLine & Err.Description, vbInformation 
    Exit Sub 
End Sub

Sub InitializeQueries() 
On Error GoTo Error_Handler
Dim clsQ As clsQuery 
Dim WS As Worksheet 
Dim QT As QueryTable 
Dim LO As ListObject

For Each WS In ThisWorkbook.Worksheets 
    For Each QT In WS.QueryTables 
        Set clsQ = New clsQuery 
        Set clsQ.MyQuery = QT 
        colQueries.Add clsQ 
    Next QT 
    For Each LO In WS.ListObjects 
        Set QT = LO.QueryTable 
        Set clsQ = New clsQuery 
        Set clsQ.MyQuery = QT 
        colQueries.Add clsQ 
    Next LO 
Next WS
Exit Sub
Error_Handler: 
    MsgBox Err.Number & " " & Err.Source & vbNewLine & Err.Description, vbInformation 
    Exit Sub 
End Sub

类模块(clsQuery)代码

'========== [ Class Modules named clsQuery ] ========== 
Option Explicit 
Public WithEvents MyQuery As QueryTable

Private Sub MyQuery_AfterRefresh (ByVal Success As Boolean) 
On Error GoTo Error_Handler
    If Success Then MsgBox ("The entire process is complete.") 
Exit Sub
Error_Handler: 
    MsgBox Err.Number & " " & Err.Source & vbNewLine & Err.Description, vbInformation 
    Exit Sub 
End Sub

Private Sub MyQuery_BeforeRefresh (Cancel As Boolean) 
On Error GoTo Error_Handler
    MsgBox ("The process start now.") 
Exit Sub
Error_Handler: 
    MsgBox Err.Number & " " & Err.Source & vbNewLine & Err.Description, vbInformation 
    Exit Sub 
End Sub

解决方案

问题核心在于:日期输入错误引发的异常发生在Power Query参数验证/数据库查询阶段,不会触发VBA标准模块的错误捕获,且BeforeRefresh事件仅在刷新启动前触发,无法拦截参数输入错误。以下是针对性修复方案:

1. 利用AfterRefresh的Success参数捕获错误

AfterRefresh的Success参数会在刷新失败时返回False,这是捕获此类错误的关键入口。修改类模块的AfterRefresh事件:

Private Sub MyQuery_AfterRefresh(ByVal Success As Boolean)
    If Success Then
        MsgBox "数据刷新完成。"
    Else
        MsgBox "刷新失败:日期格式错误或查询执行异常,请检查输入后重试。", vbCritical
        ' 可选:清除错误数据
        MyQuery.ResultRange.ClearContents
    End If
End Sub

2. 提前在BeforeRefresh中验证日期输入(推荐)

从源头避免错误,在刷新启动前完成日期合法性校验:

Private Sub MyQuery_BeforeRefresh(Cancel As Boolean)
    Dim startDate As Date, endDate As Date
    Dim inputStart As String, inputEnd As String
    
    ' 替换为你的实际参数输入逻辑(比如自定义弹窗)
    inputStart = InputBox("请输入开始日期(格式:YYYY-MM-DD):")
    inputEnd = InputBox("请输入结束日期(格式:YYYY-MM-DD):")
    
    ' 验证日期格式与逻辑
    On Error Resume Next
    startDate = CDate(inputStart)
    endDate = CDate(inputEnd)
    On Error GoTo 0
    
    If Not IsDate(startDate) Or Not IsDate(endDate) Then
        MsgBox "日期格式错误,请输入合法日期(例如:2024-01-01)。", vbCritical
        Cancel = True ' 取消刷新
        Exit Sub
    End If
    
    If startDate > endDate Then
        MsgBox "开始日期不能晚于结束日期。", vbCritical
        Cancel = True
        Exit Sub
    End If
    
    ' 更新QueryTable的参数值(如果使用内置参数配置)
    With MyQuery.Parameters("StartDate")
        .Value = startDate
        .RefreshOnChange = True
    End With
    With MyQuery.Parameters("EndDate")
        .Value = endDate
        .RefreshOnChange = True
    End With
    
    MsgBox "刷新即将开始。"
End Sub

3. 在Power Query中添加错误处理逻辑

如需更精准捕获数据库返回的错误,可在Power Query中加入错误捕获:

let 
    Source = try Sql.Database("MyDataBase", [Query="Select Transaction_date, Customer_ID
                                                from TransactionList
                                                where Transaction_date between @StartDate and @EndDate"])
    otherwise error "查询执行失败:" & try Text.From(Source[Error][Message]) otherwise "未知错误"
in
    Source

当Power Query报错时,VBA的AfterRefresh事件中Success会变为False,可进一步通过VBA读取查询结果中的错误信息。

关键注意事项

  • 类模块中的Error_Handler对参数输入错误无效,因为这类错误不发生在VBA代码执行阶段,而是在Power Query与数据库交互阶段。
  • ThisWorkbook.RefreshAll是异步执行的,标准模块的错误捕获无法拦截后续刷新过程中的异常,必须依赖类模块的事件处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 15:15:09