Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba Excel 2013的通用解决方案&;2016屏幕更新导致屏幕闪烁=错误不工作_Vba_Excel - Fatal编程技术网

Vba Excel 2013的通用解决方案&;2016屏幕更新导致屏幕闪烁=错误不工作

Vba Excel 2013的通用解决方案&;2016屏幕更新导致屏幕闪烁=错误不工作,vba,excel,Vba,Excel,Excel 2013和2016中出现了几十个关于屏幕闪烁的问题,因为Application.ScreenUpdate=False不像以前那样工作 一个部分解决方案涉及禁用工作表计算,但在某些模型中可能需要禁用工作表计算。另一个局部解决方案是使工作簿不可见,这可能会让用户感到困惑(如果所有工作簿都消失了),或者仍然会看到屏幕闪烁(如果您使除一个工作簿之外的所有工作簿都消失了) 理想情况下,我正在寻找一种解决方案,该解决方案允许运行DoEvents(这样看起来就不会像Excel被挂起),允许状

Excel 2013和2016中出现了几十个关于屏幕闪烁的问题,因为
Application.ScreenUpdate=False
不像以前那样工作



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

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

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
为什么微软不能解决这个问题:(

下面是一些示例代码,它需要两个空白工作簿(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

闪烁最有可能来自于使用
。选择
。激活

正在更新的是环境屏幕,以反映各个工作簿的激活情况。
应用程序。屏幕更新
仅适用于应用程序实例,它不会禁用整个监视器,因为各个工作簿窗口从
激活
方法获得/失去焦点。正如您所观察到的e屏幕闪烁,直到程序完成后,您才看到单元格颜色的变化。这表明
应用程序。屏幕更新
正按照预期工作,要解决此问题,您应该阅读并应用

使用
.Activate
仅在极少数情况下才需要选择
,因此尽可能避免使用

我还要注意,如果严格要求依赖
选择
活动单元格
作为用户输入,则不可能完全消除窗口闪烁,因为
选择
活动单元格
仅存在于
活动工作簿
中的
活动工作表
的范围内

我建议在
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显示了一种更短/更快的方法来实现此目的。

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

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

现在还不清楚这是如何回答这个问题的,因为问题不是“如何优化我的代码”,而且虽然这减少了闪烁,但并没有消除闪烁:)@DavidZemens,我展示了一种方法来减少由于不必要的工作簿/工作表跳转和单元格对单元格的操作而导致的闪烁。此外,只要除了
ActiveCell
,您没有任何其他
Range
引用,您就必须
激活它的
工作簿才能引用它。最后,在我的测试中,我的代码一点也没有闪烁。在Excel 2016中,我确实看到了windows切换焦点,我编辑了另一个答案,并解释了这一点(第2-4段),以及为什么我怀疑这不是由应用程序实例的
屏幕更新
属性控制的。当然,如果您依赖的是
ActiveCell
,那么您必须
Activate
。一个好的答案应该包括一些解释,除了“这里的代码是有效的”。干杯()@DavidZemens,西服yourself@DavidZemens,顺便说一句,来自帮助中心:“我什么时候应该投反对票?当你遇到一个答案明显而且可能是危险的错误时,请使用你的反对票。”我认为你的问题在于你依赖的是
选择
激活
,这两个选项。我怀疑,如果你重构代码以避免这些方法,你将不会看到任何闪烁。添加一些细节作为第2段:)干杯。