VBA更新OLEDB连接的循环致Excel无响应关闭,求解决方案
问题描述
尝试更新三个OLEDB连接,循环等待直到全部刷新完成,每次循环间隔5秒。手动按F8单步执行代码可正常完成,但正常运行时Excel会无响应10余分钟后崩溃。已尝试增加等待时长或添加MsgBox,均无效。原代码如下:
Sub update() Dim a As Boolean, b As Boolean, c As Boolean Dim ci As WorkbookConnection, ca As WorkbookConnection, av As WorkbookConnection Set ci = ThisWorkbook.Connections("x") Set ca = ThisWorkbook.Connections("y") Set av = ThisWorkbook.Connections("z") ci.Refresh ca.Refresh av.Refresh a = ci.OLEDBConnection.Refreshing b = ca.OLEDBConnection.Refreshing c = av.OLEDBConnection.Refreshing Do Until a = False And b = False And c = False Application.Wait (Now + TimeValue("00:00:05")) a = ci.OLEDBConnection.Refreshing b = ca.OLEDBConnection.Refreshing c = av.OLEDBConnection.Refreshing Loop Calculate Worksheets("AVANCE").PivotTables("TablaDinámica2").PivotCache.Refresh End Sub
问题原因
Application.Wait是阻塞式等待,执行该语句时Excel会完全挂起,无法处理后台的OLEDB刷新任务,导致刷新状态一直无法变为False,进入无限循环,最终引发Excel无响应甚至崩溃。而单步执行时,每一步之间Excel有足够时间处理后台刷新,所以能正常完成。
解决方案
替换Application.Wait为DoEvents结合循环计时的方式,让Excel在等待期间可以处理后台任务;同时优化状态检查逻辑,直接在循环内读取连接的刷新状态,避免变量缓存可能带来的判断误差。
修正后的代码:
Sub update() Dim ci As WorkbookConnection, ca As WorkbookConnection, av As WorkbookConnection Dim waitStart As Double Set ci = ThisWorkbook.Connections("x") Set ca = ThisWorkbook.Connections("y") Set av = ThisWorkbook.Connections("z") ' 确保连接启用后台查询(默认通常已开启,显式设置更稳妥) ci.OLEDBConnection.BackgroundQuery = True ca.OLEDBConnection.BackgroundQuery = True av.OLEDBConnection.BackgroundQuery = True ' 启动三个连接的刷新 ci.Refresh ca.Refresh av.Refresh ' 循环等待所有连接刷新完成 Do Until Not ci.OLEDBConnection.Refreshing And _ Not ca.OLEDBConnection.Refreshing And _ Not av.OLEDBConnection.Refreshing ' 记录等待开始时间 waitStart = Timer ' 等待5秒,期间通过DoEvents让Excel处理后台任务 Do While Timer < waitStart + 5 DoEvents ' 释放控制权,让Excel处理刷新等后台操作 Loop Loop ' 刷新计算和数据透视表缓存 Calculate Worksheets("AVANCE").PivotTables("TablaDinámica2").PivotCache.Refresh End Sub
额外说明
DoEvents会让Excel暂时放弃控制权,处理队列中的事件(包括OLEDB刷新的完成事件),避免程序完全阻塞。- 显式设置
BackgroundQuery = True确保连接是异步刷新,这样代码可以继续执行等待逻辑,而不是卡在刷新步骤。 - 直接在循环条件中读取连接的
Refreshing属性,避免使用中间变量可能导致的状态更新不及时问题。
内容的提问来源于stack exchange,提问作者Rodrigo Antonio Jimenez
相关产品推荐
相关产品推荐

