엑셀 VBA에서 DoEvents 함수는 실행 중인 매크로가 시스템에 제어권을 넘겨 다른 프로세스를 처리할 수 있도록 허용하는 함수입니다.
즉, VBA가 긴 루프나 무거운 작업을 수행하는 동안 사용자의 입력을 허용하고 Excel이 응답하지 않는 문제를 방지하는 역할을 합니다.
1. DoEvents 기본 문법
DoEvents
|
📌 VBA가 실행되는 동안 Windows가 다른 작업을 처리할 수 있도록 함
📌 매크로가 무한 루프에 빠질 경우 사용자가 Excel을 멈출 수 있도록 함
📌 CPU 점유율을 낮추고 응답성을 높일 수 있음
2. DoEvents 사용 전후 차이
✅ DoEvents 없이 긴 루프 실행 (Excel 멈춤)
Sub 긴루프_멈춤()
Dim i As Long
For i = 1 To 100000000
Cells(1, 1).Value = i ' 셀 값 변경
Next i
MsgBox "완료!"
End Sub
|
📌 실행하는 동안 Excel이 응답하지 않고 멈춘 것처럼 보임
📌 사용자는 Ctrl + Break 또는 Esc를 눌러 중지할 수 없음
✅ DoEvents 사용 (Excel이 응답 가능)
Sub 긴루프_응답()
Dim i As Long
For i = 1 To 100000000
Cells(1, 1).Value = i
DoEvents ' 사용자 입력을 받을 수 있도록 함
Next i
MsgBox "완료!"
End Sub
|
📌 Excel이 멈추지 않고 실행되는 동안 사용자가 작업 가능
📌 사용자는 Esc 키를 눌러 실행을 중지할 수도 있음
3. DoEvents 활용 예제
✅ 진행 상태를 표시하는 프로그레스 바
Sub 진행상태표시()
Dim i As Long
For i = 1 To 100
Cells(1, 1).Value = "진행률: " & i & "%"
DoEvents ' 화면 갱신
Next i
MsgBox "작업 완료!"
End Sub
|
📌 Excel이 멈추지 않고 진행 상태를 표시함
✅ 타이머 기능과 결합하여 실행 시간 표시
Sub 실행시간_표시()
Dim 시작시간 As Double
시작시간 = Timer
Dim i As Long
For i = 1 To 10000000
DoEvents ' 시스템이 다른 작업을 수행할 수 있도록 함
Next i
MsgBox "총 실행 시간: " & Round(Timer - 시작시간, 2) & " 초"
End Sub
|
📌 VBA 실행 시간을 측정하면서 Excel이 응답 가능하도록 함
✅ 사용자가 Esc 키로 루프 중지 가능하도록 설정
Sub Esc키_중지기능()
Dim i As Long
Dim 종료 As Boolean
On Error Resume Next ' 사용자 중지 시 에러 방지
For i = 1 To 1000000
If i Mod 10000 = 0 Then Cells(1, 1).Value = i ' 진행 상태 업데이트
DoEvents ' 사용자가 Esc 키로 중지 가능
' Esc 키를 눌렀는지 확인
If Err.Number <> 0 Then
MsgBox "사용자가 중지했습니다!", vbExclamation
Exit Sub
End If
Next i
MsgBox "완료!"
End Sub
|
📌 사용자가 Esc 키를 누르면 실행이 중지됨
4. DoEvents 사용 시 주의할 점
- 남용하면 성능이 저하될 수 있음
- DoEvents를 너무 자주 호출하면 성능이 저하될 수 있음.
- 예를 들어, DoEvents를 루프마다 실행하면 과도한 시스템 리소스 사용 가능.
- If i Mod 1000 = 0 Then DoEvents와 같이 특정 횟수마다 호출하는 것이 좋음.
- 매크로 실행 속도가 느려질 수 있음
- DoEvents는 프로세스를 시스템에 넘겨주므로, 실행 속도가 약간 느려질 수 있음.
- 사용자 입력이 매크로에 영향을 줄 수 있음
- DoEvents가 실행되는 동안 사용자가 Excel에서 작업을 하면 VBA가 예상치 못한 동작을 할 수도 있음.
📝 정리
기능
|
VBA 코드 (DoEvents 활용)
|
긴 루프 실행 중 응답 가능하게 함
|
For i = 1 To 100000000: DoEvents: Next i
|
진행 상태 업데이트
|
Cells(1,1).Value = "진행률: " & i & "%": DoEvents
|
실행 시간 측정
|
Timer와 DoEvents 결합
|
Esc 키로 루프 중지
|
On Error Resume Next, If Err.Number <> 0 Then Exit Sub
|
🔥 VBA의 DoEvents를 활용하면 긴 루프에서도 Excel의 응답성을 유지할 수 있습니다! 🚀