2011-04-28 3 views
5

Access에서 한 테이블에서 다른 테이블로 데이터를 가져 오는 VBA 함수를 작성했습니다. 가져 오는 표에 더 엄격한 데이터 제약 (유형, 크기 등)이 있으므로 많은 오류가 예상됩니다. On Error GoTo가 작동하지 않습니다. 코드 나누기

보다는 선별까지 나오는 모든 VBA 오류를 통해

, 내 레코드 루프는 전체 현재 레코드를 건너 뛰고이 오류로 실행 할 때마다 별도의 테이블에 메모를 만들고 싶어. 다른 모든 라인에 On Error GoTo RecordError을 삽입했습니다. 그러나 어떤 이유로 모든 오류를 처리하지는 않습니다. 내 코드가 깨져서 오류가 무엇인지 알 수 있습니다. "처리되지 않은 예외 중단"옵션이 이미 선택되어 있습니다.

다음은 스크린 샷입니다. Even by itself, this screenshot seems to make no sense to me.

왜 오류 처리기 바로 다음 행에서 오류가 발생합니까?

+0

표시되는 오류 메시지의 예를 제공 할 수 있습니까? –

+0

오류 메시지가 적절하지 않습니다. 오류는 내 데이터베이스 필드의 형식과 관련이 있으며'On Error GoTo ... '를 설정하지 않으면 얻을 것으로 예상되는 오류 메시지입니다. 사실 내가 설정 한 레이블로 이동하지 않고 코드가 손상되고 있습니다. – rdevitt

+1

내가 묻는 이유는 VBA를 사용하여 트래핑 할 수없는 Access에서 트리거 된 오류 메시지가 있기 때문입니다. –

답변

1

당신은 누구의 오류 당신이 처리하고자하는 코드 앞에 On Error 라인을 배치해야합니다.

하나만 On Error 라인을 가질 필요가 무엇보다. 오류 처리기는 서브 루틴이 종료되거나 또 다른 On Error 문을 실행할 때까지 활성 상태를 유지합니다.

+0

이것은 내 가정이지만 작동하지 않는 것 같습니다. 나는 첫 번째 예외를 제외하고 모든 'On Error GoTo RecordError' 명령문을 주석 처리했으며 여전히 동일한 결과를 얻고 있습니다. 'On Error GoTo ... '를 설정하자마자, 내 코드는 그 서브 루틴에서 더 이상 아래쪽으로 떨어지지 않아야합니다. 권리?? 내가 'On Error'를 다른 것으로 변경하지 않는 한. – rdevitt

3

나는 VB (A) 오류 일을 처리하는 방법을 당신이 이해하지 못하는 것 같아요. 이러한 원칙을 따르

  • 그것은 또한 오류를 잡을 것입니다 불구하고 On Error... 문은 (이 나타나는 루틴 (하위 또는 기능)에 적용되는 루틴 내에서 호출되는 루틴에서 "최대 버블"하는 당신은 그것을 사용합니다).
  • On Error은 상태를 설정합니다. 즉, On Error...을 발행하면 새로운 On Error...을 대체하지 않는 한 나머지 루틴에 적용됩니다.

    1. On Error GoTo <label> : <label>은 한 줄에 단독으로 바로 다음에 콜론 레이블 이름을 작성하여 (:), 같은 루틴을 정의해야합니다
    2. On Error...의 네 가지 형태가있다.

    3. On Error Resume : 즉시 error-throwing 문을 다시 시도합니다. 잠재적으로 무한하기 때문에 거의 사용하지 않습니다.
    4. On Error Resume Next는 : 오류 &가 계속 무시합니다. 때로는 정리를위한 루틴 끝에 유용합니다 (예를 들어, 열려 있거나 열려 있지 않은 레코드 세트를 닫으려는 경우). 당신이 어떤 잠재적 오류 던지는 라인 직후Err 객체 을 선택하면 다른 방법으로,이 양식도 사용할 수 있습니다 (Err.Number 경우 제로 (0), 문은 오류를 던지고없이 성공). 이것은 대부분의 상황에서 너무 많은 작업입니다.
    5. On Error GoTo 0 : 오류 처리를 해제합니다.

이를 감안할 때, 그것은 어떤 사람들 사이에서 자신의 Dim 문을 넣어하지만 즉시 루틴의 선언합니다 (Sub 또는 Function 문) followng On Error... 문을 배치하는 것이 일반적이다.루틴 내에서 오류 처리 방식을 일시적으로 변경하려면 적용 할 코드 앞에 "new"를 넣고 (사용되는 경우) "되돌리기"(원본 재발행)를 바로 뒤에 놓습니다 .

심지어 모든 것을 주어진다면, "처리되지 않은 오류로 나누기"가 선택되었을 때 오류가 발생하는 줄에서 왜 깨지는 지 전혀 모르겠다. 능동적 인 오류가 없다고 생각하면 혼란스럽지 않을 것이다. 처리 (그리고 나는 그것이 컴파일 된 경우에 놀랄 것이다).

1

오류 VBA로 처리 데이비드 헤퍼는 그의 대답에 당신이의 필수적인 부분을 주었고, 그것은 나의 전에 여기에 있었다

참고 .... 진짜 피타입니다. 나는 당신에게 this answer to the 'MS-Access, VBA and error handling' question을보고 자신의 상황에 적응 시키라고 제안 할 것입니다. 모든 오류 메시지를 테이블에 저장하여 사실상 오류보고 시스템을 구축 할 수있는 코드를 쉽게 작성할 수 있습니다.

0

아무도 정말로 귀하의 질문에 답변하지 않았습니다. 당신이 무시하고자하는 오류를 결정하기 위해 오류 처리기에서 SELECT CASE를 사용,이 코드에서

Public Sub MySub() 
On Error GoTo errHandler 
    Dim rs As DAO.Recordset 

    Set rs = CurrentDB.OpenRecords([SQL SELECT]) 
    If rs.RecordCount >0 Then 
    rs.MoveFirst 
    Do Until rs.EOF 
     [do whatever that produces the error] 
errSkipToNext: 
     rs.MoveNext 
    Loop 
    End If 

exitRoutine: 
    If Not (rs Is Nothing) Then 
    rs.Close 
    Set rs = Nothing 
    Exit Sub 

errHandler: 
    Select Case Err.Number 
    Case X, Y, Z ' where these are error numbers you want to ignore 
     Err.Clear 
     ' do whatever it is you need to do in order to record the offending row 
     Call RecordError(rs!PK, Err.Number) ' PK is a field that identifies the bad record 
     GoTo errSkipToNext 
    Case Else 
     MsgBox Err.Number & ": " & Err.Description, vbExclamation, _ 
     "Error!" 
     Resume exitRoutine 
    End Select 
End Sub 

:

은 당신의 코드는 다음과 같은 (골격 프레임 워크)를 말한다. 위의 코드 프레임 워크에서 오류 번호를 X, Y, Z으로 나열했지만 대신 무시할 실제 오류 번호로 바꾸십시오.

모든 단일 오류를 무시하고 싶지 않을 수 있습니다. 중요한 오류는 서브 루틴의 다른 위치에서 무시할 수 있기 때문입니다. 제한된 오류 수를 파악하고 싶지 않으면 무시할 오류를 생성하는 코드 블록의 시작 부분에 플래그를 설정 한 다음 `If ​​bolErrorInCodeBlockToIgnore 그런 다음 모든 오류를 무시하는지 여부를 결정하십시오. 이런 식으로 뭔가 : 나는이 알려진 오류 발생하지 오래된 오류를 무시에 확고한 신자 해요로

Public Sub MySub() 
On Error GoTo errHandler 
    Dim rs As DAO.Recordset 
    Dim bolErrorInCodeBlockToIgnore As Boolean 

    Set rs = CurrentDB.OpenRecords([SQL SELECT]) 
    If rs.RecordCount >0 Then 
    rs.MoveFirst 
    Do Until rs.EOF 
     bolErrorInCodeBlockToIgnore = True 
     [do whatever that produces the error] 
errSkipToNext: 
     rs.MoveNext 
    Loop 
    End If 

exitRoutine: 
    If Not (rs Is Nothing) Then 
    rs.Close 
    Set rs = Nothing 
    Exit Sub 

errHandler: 
    If bolErrorInCodeBlockToIgnore Then 
    Err.Clear 
    ' do whatever it is you need to do in order to record the offending row 
    Call RecordError(rs!PK, Err.Number) ' PK is a field that identifies the bad record 
    bolErrorInCodeBlockToIgnore = False 
    GoTo errSkipToNext 
    Else 
    MsgBox Err.Number & ": " & Err.Description, vbExclamation, _ 
     "Error!" 
    Resume exitRoutine 
    End If 
End Sub 

나는 훨씬 첫번째를 선호하는 것입니다. 그러나 무시하고 싶은 모든 오류를 생성하는 테스트를 찾는 것은 매우 어려울 수 있습니다.

2

오류 처리기에서 On Error Goto ...를 사용할 수 없기 때문에 작동하지 않는 이유가 있습니다.

http://www.cpearson.com/excel/errorhandling.htm

당신이 (당신의 예제에서 당신은 아마 멀리 하나의 오류로 얻을 수있는 다음 원하는 다음 라인으로의 재개 오류 처리기로 이동해야하는 대신 오류에 몇 줄을 건너 뛸 오류에 사용할 수 없습니다

핸들러는 다음 필드로 다시 돌아갈 다음 재개를 포함합니다). 이 질문에 팀 윌리엄스

감사 : The second of 2 'On Error goto ' statements gets ignored

및 BTW으로 parseInt 우편에 0으로 시작하는 우편 번호를 파괴가 된 우편 번호는 아마 텍스트로 처리해야합니다.

+0

이것이 답입니다. 제 경우에는 적어도 "For Error GoTo _label_"을 사용하여 'For'사이클의 일부 코드 줄을 건너 뜁니다. 감사! –

0

오류 처리도 실패했습니다. 한 가지 예가 있습니다.

Public Function Have(ByVal item As Variant) As Boolean 
'Have = Have data. Simplifies handling nulls and empty strings in validation code 

    On Error GoTo Procerr 

    If IsNull(item) Then 
     Have = False 
    **ElseIf Len(Trim(item)) = 0 Then 'Faster than Item <> ""** 
     Have = False 
    ElseIf item = 0 Then 
     Have = False 
    Else 
     Have = True 
    End If 

exitproc: 
    Exit Function 

Procerr: 
    'Errors sometimes occur if an unbound control is referenced 
    Have = False 

End Function 

**으로 표시된 행에서 코드가 실패하는 경우가 있습니다. 다음은 오류 메시지입니다.오류 핸들러가 실패했음을

error dialog

참고. 이 경우 반환 된 코드를 호출 한 폼은 해당 레코드 소스를 빈 레코드 세트로 즉석에서 설정 했으므로 화면의 필드는 표시되지 않습니다. 양식은 연속 양식이므로 양식에 빈 레코드 세트가로드 될 때 레코드와 필드가 표시되지 않습니다. have() 함수는 내 코드에 의해 직접 호출되지 않지만, 어떻게 든 me.requery 메소드에 의해 트리거되는 것처럼 보입니다. have()는 내 코드에서 수억 번 호출되었지만 오류가 발생하는 유일한 인스턴스이며 오류 핸들러는 별개가 아닙니다.

랜스 로버트에게 원래 질문. UTF-8 유니 코드는 때로는 데이터가 명령 코드 (내 추측)에 혼동을 야기 할 수 있으므로 ms 액세스로 혼란을 일으킬 수 있습니다. utf-8은 데이터가 원래 텍스트 파일에서로드 된 경우 데이터에 들어갈 수 있습니다. 바이트 순서 표시 (BoM)가있는 utf-8은 특히 불쾌합니다. 데이터와 함께 작동하는 일부 절차를 실행하면 이상한 오류가 발생할 수 있으며 파일이 손상된 것처럼 보일 수 있습니다. 다른 경우 텍스트 처리 함수가 잘못된 답변을 제공합니다. Mid()에 BOM이 표시되고 시작점을 지정하면 BOM에서 시작되지만 Len()은 BOM을 무시합니다. 나는이 문제가 있다면 ms 액세스가 오류를 올바르게 처리하지 않을 수도 있다고 추측하고 있습니다. 데이터를 가져오고 utf-8을 가져 오는 것과 비슷한 문제가 발생했습니다. ANSI가 원인이었습니다. utf-8과 ANSI는 평범한 영어 데이터에 대해 대부분 동일하므로 오류가 모든 행에 없을 수도 있습니다. 내 실수는 대부분 시간대 필드와 관련이 있습니다. 데이터를 먼저 내보내고 ANSI가되도록 강제 실행하고 BoM을 제거한 다음 다시 가져옵니다. 오류 처리기가 제대로 작성되었습니다 심지어 오류를 발생시키는 줄에서 프로그램 실행 정지를 만들 것입니다 '모든 오류에 휴식'을 디버그 모드 설정

+0

감사합니다 Andoriyu, 내 시스템이 모든 오류를 해결하도록 설정되었으며 이것이 문제였습니다. – AndrewM

1

. 오류 처리가 작동하지 않는 것으로 보아 혼동 될 수 있습니다.

관련 문제