배움터  
  HOME > 배움터 > Daily Tip
Daily Tip

제품:   Excel 버전:   공통
검색어:   ScreenUpdating
제목:   ScreenUpdating 흉내내기
     
 

STEP

  STEP> ScreenUpdating 속성

오늘은 ScreenUpdating 속성에 대해 이야기 해볼까 합니다.

ScreenUpdating 속성은 엑셀 VBA의 Application의 속성중 하나입니다. 화면의 갱신여부를 지정하는 것입니다. 대개의 모든 윈도우 프로그램이 그렇듯이 엑셀 역시 워크시트의 내용이 변경될
때 마다 화면을 다시 만들어 뿌려줍니다.

하지만 대량의 데이터를 워크시트에 입력하는 경우, 이러한 화면작업 때문에 프로그램의 실행시간이 매우 더뎌지게 마련이죠. 그래서 작업전에 ScreenUpdating 속성을 False로 두어 화면갱신을 잠시 막고 작업이 끝나면 ScreenUpdating 속성을 다시 True로 주어 화면을 갱신하도록 합니다.

그러나 이렇게 편리한 ScreenUpdating 속성이 다른 애플리케이션의 VBA에서는 지원되지 않는 경우가 있습니다. 같은 VBA라도 이러한 차이가 있죠.

파워포인트에서도 ScreenUpdating 속성은 없습니다. 그래서 이러한 작업을 대신할 API함수를 소개하고자 합니다. 미리 양해를 구하지만 소개하는 내용은 제가 직접 만게 아닙니다. 다만 원래의 소스를 약간 바꾸었습니다. (논리적으로 이상한 점이 발견되어) 전 여러분이 소화하기 좋도록 설명만 드리겠습니다.

ScreenUpdating 속성을 만들려면 다음과 같은 재료를 준비합니다.

l         Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As Long) As Long

l         Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long

l         Declare Function UpdateWindow Lib "user32" (ByVal hwnd As Long) As Long

Findwindow()함수는 윈도우의 핸들을 돌려주는 함수입니다. 화면의 갱신작업을 하려면 어느 윈도우를 다루어야 할지를 정해야 합니다. 우리의 눈에 보이는 윈도우는 내부적으로는 윈도우의 고유ID에 해당하는 핸들을 가지고 있습니다. 따라서 윈도우에 대한 작업을 하는 경우 윈도우를 대신하여 핸들값을 가지고 작업을 하게 됩니다.

LockWindowUpdate() 함수는 말 그대로 윈도우의 업데이트(화면갱신)를 하지 못하도록 잠궈두는 역할을 합니다. 이때 Findwindow()함수가 돌려준 핸들을 받아 해당 윈도우를 잠궈둘 것입니다.

UpdateWindow()함수 역시 문자 그대로 윈도우를 업데이트합니다. 이것 역시 Findwindow()함수가 돌려준 핸들을 받아 해당 윈도우를 업데이트 하게 됩니다.

Screenupdating 클래스

'// PowerPoint VBA Equivalent of Application.ScreenUpdating
'// -------------------------------------------------------------------------
'// Excel & Word have the ScreenUpdating method thru which a developer can lock
'// the main window from unnecessarily redrawing itself whilst the macro is being executed.
'// This method is however not present in PowerPoint.
'// If left alone, redrawing is not only ugly on the eyes it also takes more time for
'// the macro to reach completion.
'// Hence I created this generic wrapper to lock the window updates.
'// -------------------------------------------------------------------------
' --------------------------------------------------------------------------
' Copyright ⓒ1999-2002, Shyam Pillai, All Rights Reserved.
' --------------------------------------------------------------------------
' You are free to use this code within your own applications, add-ins,
' documents etc but you are expressly forbidden from selling or
' otherwise distributing this source code without prior consent.
' This includes both posting free demo projects made from this
' code as well as reproducing the code in text or html format.
' --------------------------------------------------------------------------

 '// UserDefined Error codes
Const ERR_NO_WINDOW_HANDLE As Long = 1000
Const ERR_WINDOW_LOCK_FAIL As Long = 1001
Const ERR_VERSION_NOT_SUPPORTED As Long = 1002

 '// API declarations for FindWindow() & LockWindowUpdate()
'// Use FindWindow API to locate the PowerPoint handle.

Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As Long) As Long

'// Use LockWindowUpdate to prevent/enable window refresh
Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long

'// Use UpdateWindow to force a refresh of the PowerPoint window
Declare Function UpdateWindow Lib "user32" (ByVal hwnd As Long) As Long

 Property Let ScreenUpdating(State As Boolean)
    Static hwnd       As Long
    Dim VersionNo     As String

'// Get Version Number
'// Get handle to the main application window using ClassName
'// 파워포인트의 버전에 따라 클래스 값을 달리하여 파워포인트 윈도우의 핸들을 구합니다.

    VersionNo = Left(Application.Version, InStr(1, Application.Version, ".") - 1)
    Select Case VersionNo
    Case "8"
      ' For PPT97:
      hwnd = FindWindow("PP97FrameClass", 0&)
   Case "9"
      ' For PPT2K:
      hwnd = FindWindow("PP9FrameClass", 0&)
   Case "10" ' For XP:
      hwnd = FindWindow("PP10FrameClass", 0&)
   Case Else
      Err.Raise Number:=vbObjectError + ERR_VERSION_NOT_SUPPORTED, _
      Description:="Supported for PowerPoint 97/2000/2002 only."
      Exit Property
    End Select

'// 핸들값을 얻지 못하면 빠져 나옵니다.
    If hwnd = 0 Then
        Err.Raise Number:=vbObjectError + ERR_NO_WINDOW_HANDLE, _
            Description:="Unable to get the PowerPoint Window handle"
        Exit Property
    End If

    If State = False Then
        '// 얻어 온 핸들값을 가지고 화면을 잠궈 버립니다.
        If LockWindowUpdate(hwnd) = 0 Then
            Err.Raise Number:=vbObjectError + ERR_WINDOW_LOCK_FAIL, _
                Description:="Unable to set a PowerPoint window lock"
            Exit Property
        End If
    Else
        '// Unlock the Window to refresh
        '// 얻어 온 핸들값을 가지고 화면을 갱신합니다.
        LockWindowUpdate (0&)
        UpdateWindow (hwnd)
        hwnd = 0
    End If
End Property

 

사용 예

'// Sample Usage:
'// 위의 클래스에 대한 개체변수가 선언되어 있다고 가정하였습니다.
Sub LongProcessingSub()
    '// Lock screen redraw
    ScreenUpdating = False 

    '// --- Long time consuming code
    '// --- 시간이 오래 걸리는 작업을 여기에 둡니다. 

    '// Redraw screen again
    ScreenUpdating = True

    '// Also see below article for another example of usage of the code
End Sub
 

  참고> 핸들이란
핸들이란 중복되지 않는 32비트 정수형 값 입니다. Windows는 여러 가지 개체에 대해 핸들을 부여하고 이 값을 가지고 작업을 합니다. 메뉴를 다룰 때도 핸들을 사용하고 메모리를 다룰 때에도 핸들을 사용합니다. 윈도우를 만들 때마다 윈도우 핸들번호를 붙여 윈도우를 관리합니다. 이렇게 숫자 값인 핸들을 사용하는 이유는 문자 값을 사용하는 것보다 빠르게 처리할 수 있기 때문입니다.