programing

VBA + Excel + Try Catch

golfzon 2023. 4. 9. 22:36
반응형

VBA + Excel + Try Catch

VBA에서는 사용하고 있는 스프레드시트의 버전을 기록하는 간단한 스크립트를 실행하고 있습니다.

Private Sub Workbook_Open()
    version = "1.0"

    Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
    URL = "<WEB SERVICE>"

    objHTTP.Open "POST", URL, False
    objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    objHTTP.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
    objHTTP.send ("version=" + version)
End Sub     

과정은 잘 돌아가지만...

웹 호스트가 오프라인일 경우 런타임 오류를 표시하는 대신 이를 포착하여 억제하려고 합니다.

오류 메시지가 표시되지 않도록 VBA에서 캐치를 시도하는 가장 좋은 방법은 무엇입니까?

Private Sub Workbook_Open()
    on error goto Oops
    version = "1.0"

    Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
    URL = "<WEB SERVICE>"

    objHTTP.Open "POST", URL, False
    objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    objHTTP.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
    objHTTP.send ("version=" + version)
    exit sub
Oops:
    'handle error here
End Sub   

예를 들어 오류로 인해 URL을 변경하려는 경우 이 작업을 수행할 수 있습니다.

Private Sub Workbook_Open()
    on error goto Oops
    version = "1.0"

    Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
    URL = "<WEB SERVICE>"
Send:
    objHTTP.Open "POST", URL, False
    objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    objHTTP.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
    objHTTP.send ("version=" + version)
    exit sub
Oops:
    'handle error here
    URL="new URL"
    resume Send 'risk of endless loop if the new URL is also bad
End Sub   

또한, 만약 당신의 감정이 정말로 캐치하려고 한다면, 당신은 이렇게 그것을 모방할 수 있습니다.

Private Sub Workbook_Open()
    version = "1.0"

    Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
    URL = "<WEB SERVICE>"
    on error resume next 'be very careful with this, it ignores all errors
    objHTTP.Open "POST", URL, False
    objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    objHTTP.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
    objHTTP.send ("version=" + version)
   if err <> 0 then
      'not 0 means it errored, handle it here
      err.clear 'keep in mind this doesn't reset the error handler, any code after this will still ignore errors
   end if
End Sub  

그래서 이걸 정말 어렵게 확장하면...

Private Sub Workbook_Open()
    version = "1.0"
    on error resume next
    Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
    if err <> 0 then
        'unable to create object, give up
        err.clear
        exit sub
    end if
    URL = "<WEB SERVICE>"
    objHTTP.Open "POST", URL, False
    if err <> 0 then
        'unable to open request, give up
        err.clear
        exit sub
    end if
    objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    objHTTP.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
    objHTTP.send ("version=" + version)
   if err <> 0 then
      'unable to send request, give up
      err.clear
      exit sub
   end if
End Sub  

또, 이 에러에 대해서는, 이 에러에 대해서 주의해 주세요.on error goto스타일은 처리되지 않기 때문에 이렇게 하면

private sub MakeError()
   dim iTemp as integer
   on error goto Oops
   iTemp = 5 / 0 'divide by 0 error
   exit sub
Oops:
   itemp = 4 / 0 'unhandled exception, divide by 0 error
end sub

단, 처리되지 않은 예외가 발생합니다.

private sub MakeError()
   dim iTemp as integer
   on error resume next
   iTemp = 5 / 0 'divide by 0 error
   if err <> 0 then
       err.clear
       iTemp = 4 / 0 'divide by 0 error, but still ignored
       if err <> 0 then
           'another error
       end if
   end if
end sub

VBA가 모두 무시했기 때문에 예외는 발생하지 않습니다.

다음과 같은 경우:

Try
    ...
Catch (Exception e)
    ...
End Try

VBA에서는 다음과 같이 표시됩니다.

' The "Try" part
On Error Resume Next
...
On Error GoTo 0
' The "Catch" part
If Err.Number <> 0 Then
...
End If

그러나 이 양식은 베스트 프랙티스를 따르지 않을 수 있습니다.

이것은 수색을 마치고 여기로 오는 사람들을 위해 트레버가 받아들인 답변을 일반화시키기 위한 것입니다.저만의 방법도 추가했습니다.
또, 꼭 필요한 것만 캐치하는 것을 선호하기 때문에, 에러 캐치를 asp로 끝내는 것도 포함합니다.


즉시 오류를 처리하고 다음 작업을 다시 시작합니다.

(실제 Try-Catch 블록에 가장 가까운 블록이라고 생각합니다.)

Private Sub UseTryCatchEquivalent()
    DoSolidStuff()

' Try
    On Error Goto Catch
    DoErrorProneStuff1()
    DoErrorProneStuff2() ' DOES NOT get executed when 1 errors.
    On Error Goto 0
' Catch
    If False Then
Catch:
        HandleError()
'        Exit Sub ' Optionally quit sub here.
    End If
' End Try

    DoSolidStuff()
End Sub


하단에서 오류를 즉시 처리하고 하위 항목을 종료합니다.

Private Sub HandleErrorAndExit()
    DoSolidStuff()

    On Error Goto Catch
    DoErrorProneStuff1()
    DoErrorProneStuff2() ' DOES NOT get executed when 1 errors.
    On Error Goto 0

    DoSolidStuff()
    Exit Sub

Catch:
    HandleError()
End Sub

아래에서 오류를 즉시 처리하고 다음 시점에서 다시 시작합니다.

Private Sub HandleErrorAndResume()
    DoSolidStuff()

    On Error Goto Catch
    DoErrorProneStuff1()
    DoErrorProneStuff2() ' DOES NOT get executed when 1 errors.
    On Error Goto 0

Continue:
    DoSolidStuff()
    Exit Sub

Catch:
    HandleError()
    Resume Continue
End Sub

먼저 모든 오류를 무시하고 실행한 후 나중에 처리합니다.

Private Sub IgnoreErrorAndHandleLater()
    DoSolidStuff()

    ' Everything from here on out will ignore all errors.
    On Error Resume Next
    DoErrorProneStuff1()
    DoErrorProneStuff2() ' DOES get executed when 1 errors.
    ' Stop ignoring errors.
    On Error Goto 0 
    If Err.Number <> 0 Then
        HandleError()
        Err.Clear
'        Exit Sub ' Optionally quit sub here.
    End If

    DoSolidStuff()
End Sub
그것들을 개별적으로 취급하는 경우는, 다음의 순서에 따릅니다.
Private Sub IgnoreErrorAndHandleLater()
    DoSolidStuff()

    On Error Resume Next
    DoErrorProneStuff1()
    On Error Goto 0 
    If Err.Number <> 0 Then
        HandleError()
        Err.Clear
'        Exit Sub
    End If

    On Error Resume Next
    DoErrorProneStuff2()
    On Error Goto 0 
    If Err.Number <> 0 Then
        HandleError()
        Err.Clear
'        Exit Sub
    End If

    DoSolidStuff()
End Sub

언급URL : https://stackoverflow.com/questions/44638867/vba-excel-try-catch

반응형