【问题标题】:Excel - Screen flicker on screen updateExcel - 屏幕更新时屏幕闪烁
【发布时间】:2013-03-25 13:19:01
【问题描述】:

我还有另一个问题来自“停止 excel 屏幕闪烁”的长系列,但我认为这个问题有点棘手。

我有一位客户在执行宏时需要在其电子表格上显示“进度”栏。 我所做的是,我有一个饼图链接到 2 个单元格,我会根据进度进行调整。为了性能,我禁用了eventsScreenUpdating 并更改了calculation to manual

然后,我偶尔会快速切换ScreenUpdating on and off 以实际更新进度表。每次我使用它时,它就像一个魅力(现在超过 30 个项目)。

最近,客户带着一个“大”问题来找我。每当我进行快速切换以刷新进度表时,整个 Excel 屏幕(包括上面的所有项目)都会闪烁,这让这家伙发疯了。

有没有人知道如何使用此方法来保持图表更新,同时保持首页不断显示(宏在页面之间跳转)而不会出现屏幕闪烁?像双缓冲之类的东西......

解决方案

信不信由你,但我刚刚找到了解决方案。这太容易了。在 VBA 中,可以仅刷新特定对象,而其余屏幕保持“锁定”状态。例如:

ThisWorkbook.Worksheets("Welcome").ChartObjects(1).Chart.Refresh

感谢大家的意见。

【问题讨论】:

  • 可能是一个带有进度条的用户表单? (或类似进度条的东西)这样您就不需要切换screenupdating?
  • 理想情况下,我想避免使用表单来实现这一点。它们太丑了,但我会保留它们作为最后的手段......

标签: excel vba


【解决方案1】:

您可以重写宏,使其不会“在页面之间跳转”(因为通常不需要 activate 工作表来操作其数据。否则,用户表单或应用程序的 @ 987654322@ 可用于显示进度条:

Sub StatusBar()
Dim pct As Double
Dim msg as String
Application.ScreenUpdating = False
For i = 10000 To 1 Step -1
    pct = (10000 - i) / 10000
    msg = Format(pct, "0.0%")  & " complete"
    Application.StatusBar = msg

Next
Application.StatusBar = False
Application.ScreenUpdating = True
End Sub

这是一个修改后的用户窗体示例。请注意,您需要添加 UserForm 模块和至少一个 Label 以显示信息:

Sub StatusBar()
Dim pct As Variant
DoEvents
UserForm1.Show vbModeless

Application.ScreenUpdating = False
For i = 10000 To 1 Step -1
    pct = (10000 - i) / 10000
    If Int((i / 10000) * 100) = (i / 10000) * 100 Then
        msg = Format(pct, "0%")
        UserForm1.Label1 = msg & " complete"
    End If
Next
UserForm1.Label1 = "Finished!"
Application.ScreenUpdating = True
End Sub

问题可能是,根据宏的执行速度,进度指示器可能会从 0 跳到 100%。您也可以制作图形进度条,但其背后的基本思想是相同的,只是不是更新标签值,而是更改具有不同背景颜色的文本框的大小等。

按 OP cmets 修订

这是您无需“复制/粘贴”即可将范围从一张纸“复制”到另一张纸的方法:

Set rng1 = Sheets(1).Rows(12)
Set rng2 = Sheets(2).Rows(1)

rng2.Value = rng1.Value

因此,您可以只定义您的范围,并将第二个范围分配给 = 第一个范围。

【讨论】:

  • 感谢您的建议。如果没有必要,我一般不会跳。可悲的是,在这种情况下,我在页面之间复制单元格并且复制/粘贴仅适用于活动页面,所以这不是。我还使用 thae 状态栏来显示进度的详细信息。但你知道它是怎么回事——人们喜欢事物发光和移动......
  • 您可以直接在 VBA 中写入单元格值(和格式),而不是复制/粘贴。 Sheets(2).Cells(1,1).Value = Sheets(1).Cells(1,1).Value 等...但是如果您无法使用状态栏,那么弹出用户表单可能效果最好。
  • 工作表不需要处于活动状态即可从或复制/粘贴到。
  • 根据@NickSlash,您完全可以在不激活 VBA 中的工作表的情况下复制/粘贴。 Sheets(1).UsedRange.Copy 然后Sheets(2).Paste
  • 那也是,不过我在想Range.Copy <destination>。例如Sheets("Sheet1").Range("A1:I23").Copy Sheets("Sheet2").Range("A1")
猜你喜欢
  • 2015-11-05
  • 2011-01-06
  • 2015-10-19
  • 2011-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-17
相关资源
最近更新 更多