programing

Excel VBA에서 화면 강제 업데이트

topblog 2023. 4. 28. 20:00
반응형

Excel VBA에서 화면 강제 업데이트

제 Excel 도구는 긴 작업을 수행하며, 아래와 같이 상태 표시줄이나 시트의 일부 셀에 진행 상황 보고서를 제공하여 사용자에게 친절하게 대하려고 합니다.그러나 화면이 새로 고쳐지지 않거나 어느 시점(예: 33%)에 새로 고쳐지지 않습니다.작업이 완료되지만 진행률 표시줄은 사용할 수 없습니다.

화면을 강제로 업데이트하려면 어떻게 해야 합니까?

For i=1 to imax ' imax is usually 30 or so
    fractionDone=cdbl(i)/cdbl(imax)
    Application.StatusBar = Format(fractionDone, "0%") & "done..."
    ' or, alternatively:
    ' statusRange.value = Format(fractionDone, "0%") & "done..."

    ' Some code.......

Next i

저는 엑셀 2003을 사용하고 있습니다.

루프 내에 DoEvents 기능을 추가합니다(아래 참조).

또한 사용자가 상태 표시줄을 볼 수 있는지 확인하고 코드가 완료되면 상태 표시줄을 재설정할 수도 있습니다.

Sub ProgressMeter()

Dim booStatusBarState As Boolean
Dim iMax As Integer
Dim i As Integer

iMax = 10000

    Application.ScreenUpdating = False
''//Turn off screen updating

    booStatusBarState = Application.DisplayStatusBar
''//Get the statusbar display setting

    Application.DisplayStatusBar = True
''//Make sure that the statusbar is visible

    For i = 1 To iMax ''// imax is usually 30 or so
        fractionDone = CDbl(i) / CDbl(iMax)
        Application.StatusBar = Format(fractionDone, "0%") & " done..."
        ''// or, alternatively:
        ''// statusRange.value = Format(fractionDone, "0%") & " done..."
        ''// Some code.......

        DoEvents
        ''//Yield Control

    Next i

    Application.DisplayStatusBar = booStatusBarState
''//Reset Status bar display setting

    Application.StatusBar = False
''//Return control of the Status bar to Excel

    Application.ScreenUpdating = True
''//Turn on screen updating

End Sub

워크시트의 텍스트 상자는 텍스트 또는 형식이 변경될 때 업데이트되지 않는 경우가 있으며 DoEvent 명령도 도움이 되지 않습니다.

Excel에는 사용자 양식을 새로 고칠 수 있는 방법으로 워크시트를 새로 고치는 명령이 없으므로, Excel이 화면을 업데이트하도록 강제하는 방법을 사용해야 합니다.

다음 명령은 효과가 있는 것 같습니다.

- ActiveSheet.Calculate    
- ActiveWindow.SmallScroll    
- Application.WindowState = Application.WindowState

DoEvents순환하여

이는 성능에 영향을 미치므로, 예를 들어 10번째 반복에 대해서만 호출하는 것이 좋습니다.
하지만 30개만 가지고 있다면 거의 문제가 되지 않습니다.

@휴비산들의 논평이 저에게 가장 효과적이었습니다.

ActiveWindow.SmallScroll down:=1
ActiveWindow.SmallScroll up:=1

특히, 사용자 양식을 다루는 경우 다시 방법을 사용할 수 있습니다.양식에서 이벤트 트리거를 사용하는 경우 DoEvents와 관련된 문제가 발생할 수 있습니다.예를 들어, 기능이 실행되는 동안 누른 키는 DoEvents에 의해 전송됩니다. 화면이 업데이트되기 전에 키보드 입력이 처리되므로 키보드의 화살표 키 중 하나를 눌러 스프레드시트의 셀을 변경하는 경우 기본 기능이 종료되기 전에 셀 변경 이벤트가 계속 실행됩니다.

DoEvents가 이벤트를 실행하므로 사용자 양식이 새로 고쳐지지 않는 경우도 있지만, 다시 칠하면 이전 이벤트 직후에 다른 이벤트가 발생하더라도 사용자 양식이 화면에 변경된 내용을 볼 수 있습니다.

사용자 양식 코드에서는 다음과 같이 간단합니다.

Me.Repaint

이것은 저에게 효과가 있었습니다.

ActiveWindow.SmallScroll down:=0

또는 더 간단하게:

ActiveWindow.SmallScroll 0

나는 아직 상속된 광범위한 코드에 대한 조사를 얻을 수 없었습니다.그리고 정확히 이 문제는 몇 달 동안 저를 괴롭혔습니다.DoEnvent를 사용하는 많은 접근 방식은 도움이 되지 않았습니다.위의 답변이 도움이 되었습니다.진행률 표시줄과 함께 작업한 코드에서 이 Sub를 의미 있는 위치에 배치합니다.

Sub ForceScreenUpdate()
    Application.ScreenUpdating = True
    Application.EnableEvents = True
    Application.Wait Now + #12:00:01 AM#
    Application.ScreenUpdating = False
    Application.EnableEvents = False
End Sub

이것은 당신의 질문에 직접적으로 대답하는 것이 아니라 단순히 대안을 제공하는 것입니다.저는 많은 긴 엑셀 계산에서 대기 시간의 대부분이 화면에 엑셀 업데이트 값을 가지고 있다는 것을 발견했습니다.이 경우 서브 앞에 다음 코드를 삽입할 수 있습니다.

Application.ScreenUpdating = False
Application.EnableEvents = False

그리고 이것을 끝으로.

Application.ScreenUpdating = True
Application.EnableEvents = True

이렇게 하면 사용자에게 진행 상황을 알릴 필요가 없을 정도로 코드 작업 속도가 빨라지는 경우가 많습니다.이것은 여러분이 시도해 볼 수 있는 아이디어일 뿐이며, 그 효과는 여러분의 시트와 계산에 따라 상당히 다릅니다.

UserForm에서는 두 가지 작업이 가능했습니다.

  1. 저는 왼쪽에 있는 제 형태의 스크롤바를 원했습니다.그러기 위해서는 먼저 Windows 10(설정->시간 & 언어->관리 언어 변경)의 언어 설정에서 "관리 언어 변경"에 아랍어를 추가해야 했습니다.설정은 사실 제가 아랍어(알제리어)로 변경한 "유니코드가 아닌 프로그램의 언어 변경"에 대한 것입니다.그런 다음 양식의 속성에서 "오른쪽에서 왼쪽" 속성을 True로 설정합니다.처음에는 폼이 여전히 일부 고스트 오른쪽 스크롤 막대를 그렸습니다. 그래서 저는 또한 비정상적인 시간 표시 메시지 상자를 추가해야 했습니다.
    Dim AckTime As Integer, InfoBox As Object
    Set InfoBox = CreateObject("WScript.Shell")
    'Set the message box to close after 10 seconds
    AckTime = 1
    Select Case InfoBox.Popup("Please wait.", AckTime, "This is your Message Box", 0)
    Case 1, -1
    End Select
  1. 화면을 다시 그려서 원하는 오른쪽에 4픽셀이 있는 대신 부분적으로 아래에 있거나 스크롤 막대에 바로 인접한 형태로 첫 번째 텍스트 상자를 제대로 표시하도록 모든 노력을 기울였습니다.마침내 저는 매력적으로 작동하는 다른 스택 오버플로 게시물(지금은 찾을 수 없거나 신뢰할 수 있음)에서 이것을 얻었습니다.
Me.Frame1.Visible = False
Me.Frame1.Visible = True

제 경우 문제는 워크시트에서 하나의 모양을 보이고 다른 모양을 보이지 않게 만드는 데 있었습니다.

이것은 사용자가 단추를 클릭한 후 [모양]을 "비활성화"하는 저의 접근 방식입니다.두 도형은 크기가 같고 같은 위치에 있지만 "그림자" 버전은 색상이 더 어두워서 좋은 접근 방식이었지만 작동하지 않았습니다. .vmdk = FALSE를 = TRUE로 변경한 후 화면을 업데이트할 수 없었기 때문입니다.

이 스레드의 관련 트릭 중 하나도 작동하지 않았습니다.하지만 오늘 저는 Reddit의 링크에서 저에게 맞는 해결책을 찾았습니다.

기본적으로 당신은 그냥 전화합니다.DoEvents두 번 연속적으로 변경된 코드 뒤에 있습니다.이제 왜죠?말할 수는 없지만, 효과가 있었습니다.

이 문제를 해결하려고 노력해 왔습니다.Force a screen update on a Worksheet수년간 (사용자 양식이 아님)으로 제한적인 성공을 거두었습니다.doevents스크롤 등.이 CH Oldie 솔루션은 약간의 모드에서 가장 잘 작동합니다.

나는 그것을 꺼냈습니다.Wait재설정ScreenUpdating그리고.EnableEvents사실대로

사무실 엑셀 2002에서 사무실 365까지 근무합니다.

Sub Sheet1Mess(Mess1 As String)
    Sheet1.Range("A6").Value = Mess1
    ForceScreenUpdate
End Sub
Sub ForceScreenUpdate()
    Application.ScreenUpdating = True
    Application.EnableEvents = True
   ' Application.Wait Now + #12:00:01 AM#
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.ScreenUpdating = True
    Application.EnableEvents = True
End Sub

내 경우:움직이는 형상을 이용한 그래픽 시뮬레이션이 가능한 복잡한 엑셀.속도를 높이기 위해 10번째 최적화 단계마다 디스플레이를 업데이트하고 싶었습니다.따라서 10단계마다 다시 켜야 했고, 그 다음에 다시 이벤트가 발생했습니다. 위에 설명된 문제에 부딪혔습니다. - 이상한 것은, 화면 업데이트를 간단히 설명하는 것입니다=진짜 트와이스, 효과가 있어요.?!!! 이건 말도 안 돼요.

        If counteR Mod 10 = 0 Then
            'must state this twice. WHY ??
            Application.ScreenUpdating = True
            Application.ScreenUpdating = True
            DoEvents
            Application.ScreenUpdating = False
        End If

언급URL : https://stackoverflow.com/questions/3735378/force-a-screen-update-in-excel-vba

반응형