2016-07-05 3 views
0

이 매크로에서는 특정 날짜 (전날)에 영향을받은 회사의 모든 고객 계정을 은행 계좌 명세서의보고 된 모든 지불 금액과 비교합니다. 저는 VLookup을 사용하여 은행 계좌 명세서 열의 각 고객 수를 비교하고 그 반대로 고객 레코드를 은행 기록과 비교합니다.값을 요약하기 위해 배열 객체를 어떻게 비교합니까?

나는 VLookup - ErrorHandler : 및 ErrorHandler2 :)에서 오류를보고하는 것들을 취하고 고객 이름에 대해서는 GPMissing1()을, 고객 금액에는 GPMissing2()를 저장하도록 동적 배열을 수정합니다.) 결국

Sub GPWireDifference() 
    Dim GPMissing1() As String, GPMissing2() As Double, GPCount As Integer 

    GPMissingString = "" 
    Cells.EntireColumn.AutoFit 
    Range("B:E").NumberFormat = "$#,##0.00" 
    Range("D2").Activate 

    On Error GoTo ErrorHandler: 
    Do Until ActiveCell.Offset(0, -3).Value = "" 
     ActiveCell.Value = Application.WorksheetFunction. _ 
      IfError(Application.WorksheetFunction. _ 
       VLookup(ActiveCell.Offset(0, -2), Range("C:C"), 1, False), 0) 


     ActiveCell.Offset(1, 0).Activate 
     If ActiveCell.Row = 300 Then 
      Exit Sub 
     End If 

    Loop 
    ErrorHandler: 
     If Not ActiveCell.Offset(0, -3).Value = "" Then 
      GoTo ErrorHandler2: 
     End If 
    ErrorHandler2: 
     If Not ActiveCell.Offset(0, -3).Value = "" Then 
      ReDim Preserve GPMissing1(GPCount) 
      ReDim Preserve GPMissing2(GPCount) 
      GPMissing1(GPCount) = ActiveCell.Offset(0, -3).Value 
      GPMissing2(GPCount) = ActiveCell.Offset(0, -2).Value 
      GPCount = GPCount + 1 
      Resume Next 
     End If 

    For x = 0 To GPCount - 1 
     If x > 0 Then 
      GPMissingString = GPMissingString & vbCr & GPMissing1(x) & " - " & GPMissing2(x) 
     Else 
      GPMissingString = GPMissing1(x) & " - " & GPMissing2(x) 
     End If 
    Next 
    Cells.EntireColumn.AutoFit 
    If GPCount > 0 Then MsgBox GPMissingString 

End Sub 

, 그것은 영향을받은하지만 은행 문에 반영되지 않은 모든 계정의 사용자에게 경고 할 수있는 MsgBox를 표시합니다.

예 메시지 :

In Great Plains But Not In Bank Statement: 
    Rod Powers - $3,343.60   
    Tod Dindino - $13,709.15  
:이 두 개의 별도의 배열은, 아직 각 배열 위치가 내가 보여 각 메시지를 요약 할 수있을 것입니다 방법, 다른 배열의 각각의 값과 일치하기 때문에

In Great Plains But Not In Bank Statement: 
    Rod Powers - $196.40   'Array Object 0 - Array Object 0 
    Rod Powers - $394.40   'Array Object 1 - Array Object 1 
    Tod Dindino - $1,190.40  'Array Object 2 - Array Object 2 
    Rod Powers - $2,752.80   'Array Object 3 - Array Object 3 
    Tod Dindino - $12,518.75  'Array Object 4 - Array Object 4 

고객 주문을위한 은행 전선을 받았으며 고객이 여러 주문을 반영하기 위해 하나의 전신환을 보낸 경우이 합계를 사용하면 한 줄 단위가 아닌 단일 고객 이름의 합계를 위해 전신환을 더 비교할 수 있습니다. 저 할 수 있어요 분명히 누락 된 값으로 반환 그의 와이어)

가 여기에 시트가 어떻게 보일까의 예 대 그의 3 개 개별 주문에 비해, 자신의 싱글 와이어로드 힘의 합계를 비교 : enter image description here

솔루션/FIXED :

매트의 도움으로, 동적 배열의 사용을 제거하고이를 사전으로 전환했습니다. 이를 통해 모든 반복 된 이름의 총계를 만들고 은행 명세서의 모든 값과 비교할 수있었습니다.

Sub GPWireDifference() 

    Dim values As Dictionary 
    Set values = New Dictionary 

    Dim lookup As String 
    Dim amount As Currency 
    lastRow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row 
    GPMissingString = "" 

    Cells.EntireColumn.AutoFit 
    Range("B:E").NumberFormat = "$#,##0.00" 
    Range("D2").Activate 

    On Error GoTo ErrorHandler: 
    Do Until ActiveCell.Offset(0, -3).Value = "" 
     ActiveCell.Value = Application.WorksheetFunction. _ 
      IfError(Application.WorksheetFunction. _ 
       VLookup(ActiveCell.Offset(0, -2), Range("C:C"), 1, False), 0) 
     ActiveCell.Offset(1, 0).Activate 
    Loop 

    ErrorHandler: 
     If Not ActiveCell.Offset(0, -3).Value = "" Then 
      GoTo ErrorHandler2: 
     End If 

    ErrorHandler2: 
     If Not ActiveCell.Offset(0, -3).Value = "" Then 
      lookup = ActiveCell.Offset(0, -3).Value 
      amount = ActiveCell.Offset(0, -2).Value 
      If values.Exists(lookup) Then 
       values(lookup) = values(lookup) + amount 
      Else 
       values.Add lookup, amount 
      End If 
      Resume Next 
     End If 

    For x = 0 To values.Count - 1 
     If x > 0 Then 
      GPMissingString = GPMissingString & vbCr & values.Keys(x) & " - " & _ 
       Format(values.Items(x), "$#,##0.00")values.Items(x) 
     Else 
      GPMissingString = values.Keys(x) & " - " & _ 
       Format(values.Items(x), "$#,##0.00")values.Items(x) 
     End If 
    Next 
    Cells.EntireColumn.AutoFit 
    If values.Count > 0 Then MsgBox GPMissingString 

End Sub 

모두에게 감사드립니다! 나는 얼마나 오래 그리고 얼마나 빨리 당신이 몇 년 동안 나를 도울 수 있었는지 날아갔습니다! 그 다음

+0

'Collections'와'.Exists'를 찾아서 일치하는 것이 발견되면 값을 추가하십시오. –

+0

@ScottHoltzman 약 4 일 전에 연구하기 시작 했으므로 VBA에 익숙하지 않지만 Java에 대한 이전 경험으로 인해 sytax 구조를 이해하고 있습니다. 그렇다면 Collections는 본질적으로 동적 배열을 수립 할 것인가? 또는이를 설명하는 데이터 시트가 있습니까? (직장에 있기 때문에 불행히도 일부 포럼은 차단됩니다.) – Munkeeface

+0

[this] (https://msdn.microsoft.com/en-us/library/f26wd2e5(v=vs.100).aspx) 도움이 –

답변

2

배열 조회가 될 것입니다 새로운 배열 구성원을 삽입하는 대신 기존 값에 값을 추가 않을 경우

+0

사전 (대 배열/컬렉션)을 연구 후, 이것이 정확히 내가 원하는 것 같다 ... 대신 사전을 활용하기 위해 내 코드를 수정하려고합니다 내가 사용해온 어레이 중 일부는 내 결과에 대해 다시보고 할 것입니다. – Munkeeface

+0

그것은 훌륭하게 작동합니다! 그러나 MsgBox의 문자열 비트로 변환 할 때 두 번째 소수점 이하 자릿수가 0 일 때 ## (#)로 반환되는 값 (사전의 항목)이 나타납니다. 이 형식을 지정하는 방법이 있습니까? 나는'$ ###. 00'을 출력하고 .00은 소수점 이하를 보여주고 싶습니다. – Munkeeface

+1

'Format (amount, "$ #, ## 0.00")'을 시도해보십시오. 또한 문제가 해결되면 답변을 수락 한 것으로 간주하십시오. 건배! –

1

사소한 방법은 이름이 존재하는지 이름의 배열을 검색, 그리고 것 O (n) 이는 항목이 많을수록 조회가 길어질 것이라는 것을 의미합니다.

(초기 바인딩에 대한 마이크로 소프트 런타임 스크립팅 라이브러리를 참조) 대신 자신에게 Dictionary 개체를 확인 - O (1)는, 조회 시간을 의미 에 관계없이 얼마나 많은 항목을 일정하게 유지 사전 키 조회가 Collection도 키가 될 수

Dim values As Dictionary 
Set values = New Dictionary 

Dim lookup As String 
Dim amount As Currency 

For row = 2 To lastRow 
    lookup = Sheet1.Range("A" & row).Value 
    amount = Sheet1.Range("B" & row).Value 
    If values.Exists(lookup) Then 
     values(lookup) = values(lookup) + amount 
    Else 
     values.Add lookup, amount 
    End If 
Next 

하지만, 키가 검색되거나 반복, 그 구성원이 너무 빈약하다 될 수 없다 :있다 Dictionary은 훨씬 더 잘할 것입니다.

관련 문제