由于ScreenUpdating导致Excel 2013和2016屏幕闪烁的通用解决方案=无效

时间:2018-08-15 07:25:31

标签: excel vba excel-vba

由于Application.ScreenUpdating = False不能像以前那样起作用,因此在Excel 2013和2016中存在许多关于屏幕闪烁的问题。

Screen Flickering VBA Excel
Excel ScreenUpdating False and still flickering screen
ScreenUpdating = False fails in Excel 2013 and 2016

一个局部解决方案涉及禁用工作表计算,但是在某些模型中可能是必需的。另一个部分解决方案是使工作簿不可见,这可能使用户感到困惑(如果所有工作簿都消失了),或者仍然看到屏幕闪烁(如果您使除一个之外的所有工作簿都消失了)。

理想情况下,我正在寻找一种解决方案,该解决方案允许运行DoEvents(这样就不会看起来好像挂起了Excel),允许StatusBar可见(用于报告进度)并阻止所有其他屏幕闪烁。

Microsoft为什么不能解决这个问题呢?(

这是一些示例代码,它们需要两个空白工作簿(Book1和Book2),并引起可怕的屏幕闪烁。

Sub Macro1()
    ' this worked fine in Excel 2010
    Application.ScreenUpdating = False

    ' this clears all flicker, but the whole of excel disappears
    ' Application.Visible = False
    ' this changes the flicker between Book1 and blank white screen
    ' Application.Workbooks("Book2").Windows(1).Visible = False

    ' some flickery code
    For i = 1 To 10
        Windows("Book2").Activate
        Call Jiggle("Red")
        Windows("Book1").Activate
        Call Jiggle("Yel")
    Next i

    ' restore normality
    Application.ScreenUpdating = True
    Application.Visible = True
End Sub


Sub Jiggle(c As Variant)
    For i = 1 To 100
        ActiveCell.Offset(1, 0).Select
        If (c = "Yel") Then Selection.Interior.Color = 255
        If (c = "Red") Then Selection.Interior.Color = 65535
    Next i
End Sub

2 个答案:

答案 0 :(得分:1)

闪烁最可能来自使用.Select.Activate

正在更新环境屏幕以反映相应工作簿的激活Application.ScreenUpdating仅适用于应用程序 instance ,它不会禁止整个监视器刷新,因为各个Workbook窗口都从Activate方法获得/失去了焦点。正如您将看到的那样,在屏幕闪烁的同时,您不会看到单元格颜色发生变化,直到过程完成为止。这表明Application.ScreenUpdating的工作完全符合预期的目的,要解决此问题,您应该阅读并应用How to avoid using Select in Excel VBA

仅在极少数情况下才需要使用.Activate.Select,因此请尽可能避免使用它。

我还要注意,如果严格要求依靠SelectionActiveCell作为用户输入,则不可能完全消除窗口闪烁,因为{{ 1}}或Selection仅存在于ActiveCellActiveSheet的范围内。

我建议在ActiveWorkbook中将工作表作为参数,然后绝对地处理单元格。这样可以使您的代码更可靠,并且可以在后台运行,而无需选择和激活任何内容。

Jiggle

请注意,此示例说明了如何不使用Option Explicit Public Sub Macro1() Application.ScreenUpdating = False ' some flickery code Dim i As Long For i = 1 To 10 Call Jiggle("Red", Workbooks("Book2").Worksheets(1)) Call Jiggle("Yel", Workbooks("Book1").Worksheets(1)) Next i ' restore normality Application.ScreenUpdating = True End Sub Public Sub Jiggle(c As Variant, ws As Worksheet) Dim i As Long For i = 1 To 100 With ws.Cells(i, 1) 'address your cells absolutely Select Case c Case "Yel": .Interior.Color = 255 Case "Red": .Interior.Color = 65535 End Select End With Next i End Sub ,而@DisplayName显示了一种实现相同目的的更短/更快的方法。

答案 1 :(得分:1)

在我看来,您的整个代码可以归结为:

Public Sub Macro1()
    Application.ScreenUpdating = False 
    Workbooks("Cartel2").Activate
    ActiveCell.Offset(1).Resize(1000).Interior.Color = 65535
    Workbooks("Cartel3").Activate
    ActiveCell.Offset(1).Resize(1000).Interior.Color = 255
    Application.ScreenUpdating = True
End Sub