【问题标题】:VBA not refreshing calculated cells & linksVBA 不刷新计算单元格和链接
【发布时间】:2020-01-02 01:58:43
【问题描述】:

简而言之:我的更新宏运行,但如果包含其他 SUB,则不会更新单元格。如果不包含其他 SUB,则更新单元格。

我有一系列电子表格,其中包含 5000 到 25000 个计算单元格。我的最终目标是将这些电子表格链接在一起,以迭代更新所有单元格和链接。 更新代码本身可以正常工作。但是,如果我包含计时循环或检查所有值是否已更新,则单元格值将不再更新。

有效的基本代码:

     Sub Global()
      Dim ActiveWKB As Workbook
      Application.DisplayAlerts = False
      Application.ScreenUpdating = True
      Application.Calculation = xlManual
      Set ActiveWKB = Workbooks.Open("Master.xlsx")
      Set ActiveWKB = Workbooks.Open("Sub01.xlsx")
      Sub_Update
    End Sub
    Sub Sub_Update()
      Application.ScreenUpdating = True
      Application.Calculation = xlAutomatic
      Application.CalculateFull
      ActiveWorkbook.UpdateLink Name:=ActiveWorkbook.LinkSources
    End Sub

我正在添加以下代码(代码本身运行良好),但不会更新计算的链接和单元格:

我在 Sub_Update 下的 Sub Global 中添加了以下内容:

     Sub_Pause (45)

Sub_Pause 包含以下代码:

      Dim StartTime
      Dim Delay
      StartTime = Timer
      Application.ScreenUpdating = True
          Do
          Delay = Timer - StartTime
          Application.ScreenUpdating = True
          DoEvents
      Loop Until Delay >= EndPoint
      ActiveWorkbook.RefreshAll   
      Application.Calculation = xlManual
      MsgBox(“Sub_Pause Done”)
     End Sub

此 SUB 暂停 45 秒,显示消息“Sub_Pause Done”,然后宏结束。

在没有 Sub_Pause 的情况下运行后,我的仪表板会显示还有多少单元格需要更新(最初为 10134)并倒计时至零。单元格本身会从 #N/A 缓慢更改为更新后的值。

运行 WITH Sub_Pause 后,我的仪表板显示要更新的初始单元格数 (10134),并且单元格值永远不会刷新(改为显示 #N/A)

我尝试将 Sub_Pause 中的计时器替换为以下部分代码,以简单地计算 #NA 剩余的数量:

      NAs = Application.WorksheetFunction.Countif(Range(“C2:Q1500),“#N/A”)

我在 Do Until 循环中嵌入了一个消息框来显示变量 NAs。

逐步显示变量 NAs 从初始计数 10134 开始不会改变。

关于如何在运行 Sub_Pause 时更新值有什么建议吗?

这个 sub 的目的是在我保存并关闭文件之前暂停宏足够长的时间以使所有单元格更新,然后打开下一个电子表格文件。

有什么建议吗? 谢谢

更新: 宏结束后,我不小心按了一个热键来打开自动计算(自动计算已经打开)。

所有单元格立即更新为其计算值,我的仪表板将 #NA 值的数量从 10134 更新为 0。

认为这可能是屏幕刷新问题,我将以下代码插入到我的 Sub_Pause 中:

    Dim NACount As Long
.
 .
  .
        NACount = Application.WorksheetFunction.CountIf(Range("C2:Q1100"), "#N/A")
        MsgBox (NACount)

完整的 Sub_Pause 内容如下:

    Sub Sub_Pause(EndPoint As Long)

    Dim StartTime
    Dim Delay
    StartTime = Timer
    Dim NACount As Long

    Application.ScreenUpdating = True

    Do
        Delay = Timer - StartTime
        DoEvents
        ActiveWorkbook.RefreshAll
        NACount = Application.WorksheetFunction.CountIf(Range("C2:Q1100"), "#N/A")
        MsgBox (NACount)

    Loop Until Delay >= EndPoint

    ActiveWorkbook.RefreshAll

    NACount = Application.WorksheetFunction.CountIf(Range("C2:Q1100"), "#N/A")
    MsgBox (NACount)

    End Sub

在 Do Until 循环内和 Sub_Pause 结束时,NACount 都返回为 10134,表明这不是屏幕刷新问题,但宏代码无法识别单元格已更新。 宏一完成,我就立即按下热键“开启”自动计算(它们已经开启)。

#NA 的计数立即设置为零。

如果只是屏幕刷新问题,NACount 将反映内部值为零。因为它反映了 10134 的内部计数,所以我不得不相信 VBA 代码没有识别单元格值已更新。

我也在我的笔记本电脑上(从 OneDrive)运行了这些,结果相同。

有什么见解吗?有什么建议吗?

【问题讨论】:

  • xlCalculationAutomatic 虽然我认为它与 xlAutomatic 的值相同
  • 你在哪里插入 Sub_Pause (45)Global 里面?
  • @Tim:xlCalculationAutomatic 的结果与 xlAutomatic 相同。不过还是谢谢。
  • @DecimalTurn:Sub_Pause 紧接在 Sub_Update 下方
  • @DecimalTurn:已经几个月了,但我想告诉你刷新外部数据链接的正确命令:Application.CalculateFullRebuild。此命令强制 Excel 重新构建每个公式并重新连接到外部链接,从而刷新外部数据。这与您的计时解决方案相结合,提供了我需要的灵活性。谢谢。

标签: excel vba


【解决方案1】:

很难用单元格和计算刷新来复制这些类型的问题,因为当这些问题发生时会发生很多事情,并且一些其他因素可能会干扰,从而使事情变得更加不确定。

为了有一个更可靠的方法在代码中创建暂停,我建议使用Application.OnTime 方法。它将在稍后安排一个宏,因此您可以同时将完全控制权返回给 Excel,以便让 Excel 更新计算和单元格。

例如,您可以执行以下操作:

Public RepeatCounter As Long

Sub Main()

    Dim ActiveWKB As Workbook
    Application.DisplayAlerts = False
    Application.ScreenUpdating = True
    Application.Calculation = xlManual
    Set ActiveWKB = Workbooks.Open("Master.xlsx")
    Set ActiveWKB = Workbooks.Open("Sub01.xlsx")
    Sub_Update


    RepeatCounter = 0 'Reset Counter
    Application.OnTime Now + TimeValue("00:00:10"), "PauseInOrOut" 'Start Pause
End Sub


Sub PauseInOrOut()

    'Customizable parameter
    Const RepeatLimit As Long = 3

    If RepeatCounter < RepeatLimit Then
        If Application.WorksheetFunction.CountIf(Range("C2:Q1100"), "#N/A") = 0 Then
            MsgBox "Pause completed"
            'You can call the code that needs to run after the pause here
        Else
            RepeatCounter = RepeatCounter + 1
            Application.OnTime Now + TimeValue("00:00:10"), "PauseInOrOut" 'Run this macro again
        End If
    Else
        MsgBox "Values couldn't be updated within time limit."
    End If

End Sub

在这里,我在下次运行“暂停”宏之前设置了 10 秒的等待时间。我还添加了一个限制,所以它不会永远运行。随意修改以适合您需要的方式完成暂停的条件,我在此处添加了一个示例,该示例与我从您关于 NA 的问题中得到的内容相匹配。

【讨论】:

  • 这种方法解决了更新问题。谢谢。
  • 很抱歉,我的声望点数没有达到我的投票计数的最低要求。我确实认为这是最有用的。
  • @Steve 我很高兴能帮上忙。如果这解决了您的问题,您仍然可以通过clicking the check mark beside it 接受它。这不需要声誉。
猜你喜欢
  • 1970-01-01
  • 2013-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多