使用 VBA 刷新表

Posted

技术标签:

【中文标题】使用 VBA 刷新表【英文标题】:Refreshing Tables with VBA 【发布时间】:2016-02-17 16:37:27 【问题描述】:

我有两张表,一张是城市列表(我们称之为城市列表),另一张是与这些城市对应的数据点(称之为数据表)。数据表连接到我在 MS SQL Server 中构建的 Select 查询。此 Select 查询/数据表有一个 Where 子句,我在其中替换了 SQL 条件并替换了 ?,以便在连接到 Excel 时使其成为参数。

现在我已经解决了这个问题,我将解释我要完成的工作。我想遍历城市列表,对于列表中的每个城市,更新数据表以反映城市的数据点。最终,我想循环遍历,每次刷新数据表时,它都会使用该特定表保存工作簿的副本。

我在下面发布了我当前的代码,但我的问题是表格永远不会刷新与当前通过循环选择的城市相对应的当前数据。话虽如此,如果我按下escape 键以跳出VBA 宏,那么表格将刷新为在我停止宏之前的最后一个城市。

代码:

Sub Macro1()
Dim WS As Worksheet
Dim WS2 As Worksheet
Dim CT As Variant
Dim MSG As String

Set WS = Sheets("Sheet1")
Set WS2 = Sheets("Sheet2")
CT = Range("A1").CurrentRegion
For i = 2 To UBound(CT, 1)
    MSG = ""
    For J = 1 To UBound(CT, 2)
        WS.Range("$D$2").Value = CT(i, J) //Places the city into Cell $D$2 which is where The Data Table looks to for the parameter.

    Exit For


    Next J

        ActiveWorkbook.Connections("Query from Database").Refresh

          WS2.ListObjects(1).Refresh

Next i
End Sub

就好像宏运行得太快,表格无法跟上并刷新。我尝试在代码中添加一些等待时间,希望它能给它足够的时间来让表刷新,但这没有影响。我还关闭了Background Refresh,这似乎也没有任何作用。现在它只是循环遍历城市表,并且每个城市都显示查询正在刷新,但是在查询完成刷新后,它会进入下一个城市而无需更新数据表。帮助!

【问题讨论】:

【参考方案1】:

我认为你需要做几件事——也许你已经做了。

    当您设置参数/绑定变量(您已经完成)时,将其指向特定单元格。然后,在您的 SQL Server 查询中,确保参数每次都绑定到该范围:

如果我夸大了显而易见的事实,请原谅我,但对于那些不知道的人,您可以通过右键单击表格并选择表格->参数来进入此对话框。

    从那里,当您遍历主表(其中包含城市的表)时,您可以从该表中的每一行获取值并使用绑定参数更新单元格。

这样的事情应该可以工作:

Sub RefreshAllCities()

  Dim ws1, ws2 As Worksheet
  Dim loCities, loDataTable As ListObject
  Dim lr As ListRow

  Set ws1 = ActiveWorkbook.Worksheets("Sheet1")
  Set ws2 = ActiveWorkbook.Worksheets("Sheet2")

  Set loCities = ws1.ListObjects("CityList")
  Set loDataTable = ws2.ListObjects("DataTable")

  ' get rid of those pesky warnings to overwrite files
  Application.DisplayAlerts = False

  For Each lr In loCities.ListRows
    ws2.Cells(1, 2).Value = lr.Range(1, 1).Value
    loDataTable.QueryTable.Refresh BackgroundQuery:=False

    ActiveWorkbook.SaveAs Filename:="C:\temp\" & lr.Range(1, 1).Value & ".xlsx", _
        FileFormat:= xlOpenXMLWorkbook
  Next lr

  Application.DisplayAlerts = True
End Sub

我假设您在此示例中需要 .xlsx 文件。这将破坏任何嵌入式 VBA,这实际上是一个不错的好处,因为过滤数据集的接收者不必接触它。如果你想要xlsmxlsb,这很容易改变。

【讨论】:

我看到您正在更新查询表而不是我认为是解决方案的列表对象。 感谢您的彻底回复,但不幸的是,这仍然不能解决我的问题。在测试您的代码时,似乎只是将城市名称放在数据表中,而不是根据城市实际刷新表。 我做了一些进一步的测试,我注意到如果我像这样摆脱循环并将 2 个城市硬编码到 VBA 中:ws1.Cells(3, 4).Value = "ARIZONA MESA"ws1.Cells(3, 4).Value = "CALIFORNIA CARLSBAD",等待中间,那么它只会根据最后一个城市更新数据表。第一个城市被完全忽略。 @Jcmoney1010 -- 我知道这是非常规的,但是有什么方法可以将电子表格发布到某个地方吗?我继续运行它作为一个小测试(诚然,我最初的帖子没有经过全面测试——仅针对语法),并且它有效。我不禁认为有一个简单的解决方法 @Hambone 不幸的是,我不确定我应该这样做。数据本身包含我不想共享的客户信息,我的数据库的连接字符串包括我们数据库的用户名和密码。如果我要删除所有这些信息,那么我基本上只会给你发送一个空白的 Excel 工作表。您能否分享您的工作簿测试,也许我可以对其进行逆向工程?【参考方案2】:

默认情况下,Excel 将“启用后台刷新”,这将允许 Excel 在查询刷新实际完成之前继续执行并继续执行。有些人可以通过两次调用.Refresh 来使其工作,但这几乎是随机/任意时间。

应该有一个 Excel 选项可以取消选中“数据表”属性,或者您可以通过对 VBA 的引用来更新 BackgroundQuery = False 属性

如果您禁用后台刷新,那么您的代码将等待刷新完成,然后再继续。

【讨论】:

我也读过这个,甚至看到了“两次刷新”的技巧,但不幸的是它没有奏效。正如我上面所说,我已经取消选中“启用后台刷新”选项,虽然这会减慢速度并允许刷新查询,但由于某种原因,表格不会刷新。

以上是关于使用 VBA 刷新表的主要内容,如果未能解决你的问题,请参考以下文章

通过 VBA 在 MS Access 中自动链接/刷新 ODBC 链接表

如何刷新数据透视图

如何使用 VBA 刷新 IE

访问VBA无法刷新表单

VBA 等待刷新电源查询以执行下一行代码

EXCEL VBA:循环正在工作,但在打印到 PDF 文件之前不刷新