2013-07-22 4 views
0

Excel에서 매크로와 vba를 처음 사용했습니다. 현재 저는 직장에서 인보이스 템플릿을위한 VBA 매크로 작업을하고 있습니다. 그러나 원인을 추적하는 데 문제가 있음을 알 수없는 오류가있는 부분에서 실행 중입니다.0으로 나누기 제로 또는 0으로 제수 (VBBA)

VATRMB = 0 

두 번째 부분은 :

VATRMB = VATRMB + (0.0593 * (ActiveSheet.Range("I" & i).Value/(1 + 0.0593))) 

희미한 VATRMB가 저장되어 다음과 같이

가끔, 팝업 곳
코드의 두 가지 특정 라인 ..
첫 번째 부분이 있습니다
 Dim startRow As Integer, endRow As Integer, VATRMB As Single, VATEUR As Single, VATUSD As Single, VATRMBCell As Range, VATEURCell As Range, VATUSDCell As Range 

나는이 선들이 제로 오류에 의한 구분을 던져서는 안된다는 것을 보았습니다. 첫 번째 경우에는 약수가 전혀없고 두 번째 경우에는 항상 양수입니다.
이 오류가 발생할 수있는 이유에 대해 알고 계신 분 있습니까? 하위가 동일한 VATRMB Dim을 재사용하면서 여러 번 호출된다는 사실과 관련이 있습니까? 각 하위 호출 후에 재설정해야합니다. 맞습니까? 아니면 VATRMB을 Single로 지정한다는 사실과 관련이있을 수 있습니까? 이것은 '작은'(1,000,000 이하) 부동 소수점에 적합합니까?

는 편집 :

'Debug.Print Tab(10); ("Items will be searched in rows " & startRow & " thru " & endRow) 'Serves for debugging and testing 
For i = startRow To endRow 'Loop the following code through all rows mentioned above 
    If ActiveSheet.Range("B" & i).Find("Membership") Is Nothing Then 'If nothing is returned when searching for "Membership"; i.e. if the item in this row is not a membership payment 
     If Not ActiveSheet.Range("H" & i).Find("RMB") Is Nothing Then 'If the value for this item is RMB denoted 
      'Debug.Print Tab(20); "Item on Row " & i & " is RMB denoted, VAT = " & ((ActiveSheet.Range("I" & i).Value/(1 + 0.0593)) * 0.0593) 'Serves for debugging and testing 
      VATRMB = VATRMB + (0.0593 * (ActiveSheet.Range("I" & i).Value/(1 + 0.0593))) 'Add row's VAT to VAT total 
     End If 
     If Not ActiveSheet.Range("H" & i).Find("EUR") Is Nothing Then 'If the value for this item is EUR denoted 
      'Debug.Print Tab(20); "Item on Row " & i & " is EUR denoted, VAT = " & ((ActiveSheet.Range("I" & i).Value/(1 + 0.0593)) * 0.0593) 'Serves for debugging and testing 
      'MsgBox VATEUR + 0.0593 * ActiveSheet.Range("I" & i).Value/(1 + 0.0593) 
      VATEUR = VATEUR + (0.0593 * (ActiveSheet.Range("I" & i).Value/(1 + 0.0593))) 'Add row's VAT to VAT total 
     End If 
     If Not ActiveSheet.Range("H" & i).Find("USD") Is Nothing Then 'If the value for this item is USD denoted 
      'Debug.Print Tab(20); "Item on Row " & i & " is USD denoted, VAT = " & ((ActiveSheet.Range("I" & i).Value/(1 + 0.0593)) * 0.0593) 'Serves for debugging and testing 
      VATUSD = VATUSD + (0.0593 * (ActiveSheet.Range("I" & i).Value/(1 + 0.0593))) 'Add row's VAT to VAT total 
     End If 
    Else 'Else, i.e. if the row contains a membership payment, then essentially nothing happens 
     'Debug.Print Tab(20); ("Item on Row " & i & " is a membership payment; no VAT paid.") 'Serves for debugging and testing 
    End If 
Next 
: 사용되는 코드의 전체 블록은, 어쩌면 한 두 가지를 명확히하는 데 도움이 여기에 희미한 저장

2. 호출에 사용
1. 추가 정확한 라인입니다

그래서 기본적으로 인보이스의 모든 항목 (startRow에서 endRow까지)을 반복하고 항목이 '유형'문자열 (B 열)을 구문 분석하여 멤버십 결제인지 확인합니다. 그런 다음 회원 급여 여부에 따라 VAT를 결정하고 지급되는 통화를 확인하십시오. 지불 금액은 부동 소수점으로 I 열에 저장됩니다.

+0

변수를 밝게하기 위해 사용하고있는 정확한 행을 공유 할 수 있습니까? 때때로 사람들은 그 지역에서 실수를 저 지르며 그들이 어리 석다 고 생각하는 것에 어긋나지 않습니다. –

+0

시트에 ** ** 열에 ** 포함 된 값의 예를 들려 줄 수 있습니까? Excel03 및 Excel13에서 DIV0 오류가 계산되지 않습니다! – AKDADEVIL

+0

@matzone, 안돼! –

답변

0

VATRMB = VATRMB + (0.0593 * (ActiveSheet.Range ("I"& i) .Value/(1 + 0.0593))) 부분을 부품으로 분리하고 해당 부품의 내용을보십시오.

Dim VATRMB, i, rangeValue, dividor, divisionResult 

    i = 1 
    rangeValue = ActiveSheet.Range("I" & i).Value 
    dividor = 1.0593 
    divisionResult = rangeValue/dividor 
    VATRMB = VATRMB + (0.0593 * divisionResult) 'Add row's VAT to VAT total 
+0

나는 이것을 생각하고 있었다. , 아직 구현되지 않았습니다, 위의 그림과 같이 단순히 희미 함을 'Currency'데이터 유형으로 선언하도록 변경했습니다. 문제가 제대로 작동하는 것처럼 _ 셈합니다. 오류가 다시 나타나기 시작하면 다음 단계로 넘어갑니다. 시험. – Martin

0

확인을 위해 통합 문서 등 전체를 제공해야하므로 문제의 해결 방법인지 확실하지 않습니다. 그럼에도 불구하고, 우리는뿐만 아니라 Div0을 100 % 재현성 상황 "불가능해야한다"이런 종류의를 만들 수 있지만, 또한 라인 등으로 거의 모든 오류에 대해 : 우리의 테스트에서

VarX = 10 ' we can make this fail with Div0, Overflow or whatever 

문제 실제로 오류가보고 된 "직접"또는 "명시 적"코드가 아니라 다른 곳에서 오류가 발생하며 무한한 지혜에있는 VBA는 이상한 시간에 이상한 방식으로 오류를 "보고"합니다. 사실 그것은 어떤 오류를 전혀보고하지 않아야합니다, 아래 참조).

패키지에 외부 실행 파일, dll, addins '등이 있습니까?

그렇다면 시작할 가능성이 높습니다.

그렇지 않은 경우 실제로 액세스하는 범위에서는 직접 또는 간접적으로 오류가 발생할 수 있지만 현재 액세스 한 셀에서는 그렇지 않을 수 있습니다.

다음은 VBA에서 addin으로 액세스 한 DLL을 통해 "Div0"을 만드는 예입니다. 다른 언어로 코드를 작성한다고 가정합니다. 여기에는 Fortran이 있습니다 (모든 곳에서 암시 적으로는 사용하지 않으며 모든 것이 올바르게 선언됩니다.) :

Pure Subroutine FortDLL(x, U) 
: 
Real(DP), Intent(In) :: x 
Real(DP), Intent(Out) :: U 
: 
Real(DP)    :: QQ 
: 
: 
QQ = Log10(x) ! Notice this is not the return var and has nothing to do with anything on the VBA side (or so you would think) 
: 
U = 10.D0 ! Notice, this is the return var, and is a constant = 10.D0 
: 
End Subroutine FortDLL 

일반적인 방법으로 DLL로 컴파일하고 액세스하십시오. 의 Log10는 X < 0으로 정의되지 않기 때문에 이것은 포트란 런타임 오류가 발생합니다 X < 0 경우, DLL이 밖으로 똥 것,

Function VBAFunc(x) as Variant 
: 
Call FortDLL(x, U) 
: 
Dim VarU as Variant 
: 
VarU = U ; you can replace this with VarU = 10, or whatever, and will get same result/failure 

지금 :

은 그럼 당신은 일부 VBA이 있다고 가정 , 당신이 설정하는 방법에 따라, 당신은 그것을 Div0, 오버 플로우를 던지게 할 수 있습니다. (예를 들어 Fortran 측에서 Double에 대한 MaxExponent는 1024입니다. 반면에 VBA 측에서는 Number of 등등)

지금까지 QQ가 VBA 측과 아무 관계가 없지만 VBA 코드가 FortDLL을 실행할 때()를 반환하면 U = 10을 반환하고 실제로 해당 부분을 올바르게 처리합니다.

그러나 DLL은 Div0 (또는 사용자가 만들고자하는 것이 무엇이든) 오류를 던졌을 것이며 "오류 메시지"는 Call FortDLL()로 돌아갈 때 묻힐 수 있습니다.

당신이 DLL의 등을 사용하지 않는 경우, 비슷한 일이 반복 당신 동안 다른 곳에서 당신의 "범위"또는에서 일어나는 것이 가능하다 등

우리는 통화로 왜 희미한 "을로 명시 적으로 테스트를 수행하지 않은

수정 "작업을하지만 우리는 Currency가 매우 특수한 Type (실제 두 개 이상의 필드가있는 구조화 된 유형)이므로"오류 메시지 "가 해당"필드 "중 하나에 묻힐 수 있으며 당신이 사용하고있는 숫자의 크기와 관련이 있고 관련이 있고, "우연히"(일종의 "운 좋은 KLUDGE") 충돌을 피할 수 있습니다. Double에 비해 너무 큰 숫자를 넣어서 테스트 할 수 있습니다. 통화 유형. "운 좋은 KLUDGE"인 경우 언젠가는 주변에 있지 않고 누군가 다른 사람을 사용하고 있습니다. 코드를 입력하고 전체 통화 기계가 필요한 번호를 입력하면 추락 할 가능성이 높으며 아무도 이유를 알 수 없습니다.

: 
On Error Resume Next 
VarX = 10 
VarX = 10 
: 

을이 "작품"(즉, 오류를 미연에 방지하는 경우 ... : 여기

는 다음과 같이 수정/후 교체 VarX = 10와 같은 줄에 충돌이 있다고 가정, 대체 시험이다/crash), 문제는 위에서 설명한 줄 ("외부"또는 "내부")에 따라 발생할 가능성이 큽니다. 이 경우, 기본적으로 "Div0 문제"는 VarX가 처음으로 할당 될 때 VBA 오류로 처리됩니다. 오류 트래핑이 설정되고 "최초"가 "DLL 측 오류"를 포착하고 무시하므로 에.

... 분명히 이것은 단지 테스트 일뿐 해결책이 아닙니다.

이것은 또한 Excel/Win/Compiler (특히 GCC, 컴파일러 버전의 경우에도 꽤 이상한 점/변경 사항이 있기 때문에)에 따라 달라질 수 있습니다. 따라서 재현성과 정확한 동작이 다를 수 있습니다.