2016-07-05 4 views
0

このマクロでは、特定の日付(前日)に影響を受けた当社のすべての顧客口座を、当社の銀行口座明細書から報告されたすべての支払いと比較しています。私はVLookupを使用して、銀行報告書の列にある各顧客の金額を比較し、逆に銀行の記録を顧客口座に比較します。値を要約するために配列オブジェクトをどのように比較しますか?

VLookup - ErrorHandler:とErrorHandler2 :)でエラーが報告されたものを取り、その値を保存するように動的配列を変更します(GPMissing1()をCustomer Name、GPMissing2()をCustomer Amounts最終的には)

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 

、それが影響を受けているが、銀行取引明細書には反映されていないすべてのアカウントのユーザーに警告するメッセージボックスを表示します。

例メッセージ:

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 

これらは、2つの別個の配列で、まだ各アレイ位置がどのように表示する各メッセージを要約することができるであろう、他の配列にそのそれぞれの値と一致するので:

In Great Plains But Not In Bank Statement: 
    Rod Powers - $3,343.60   
    Tod Dindino - $13,709.15  

(私たちは顧客の注文に銀行の電線を受け取りましたが、顧客が複数の注文を反映するために1本の電線を送ってくることがあります)この合計によって、1行ごとの値ではなく1つの顧客名の合計できます/

enter image description here

SOLUTION:ここではシートがどのように見えるかの例です)明らかに欠損値として返す彼の電線対彼の3回の個々の注文に対して、彼の単線に

をロッド・パワーズの合計を比較します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構造を理解しています。それで、コレクションは本質的にダイナミックアレイを確立していますか?あるいは、これらを記述するデータシートがありますか? (私は仕事中ですので、いくつかのフォーラムは残念ながらブロックされています) – Munkeeface

+0

[this](https://msdn.microsoft.com/en-us/library/f26wd2e5(v = vs.100).aspx)が役に立ったかどうかを確認する –

答えて

2

配列検索があることを行っている挿入の既存の値に値を追加しない場合O(n)これは、存在するアイテムが多いほど、ルックアップが長くなることを意味します。

自分の代わりにDictionaryオブジェクト(早期バインディングのためののMicrosoftスクリプトランタイムライブラリを参照)してください - 辞書のキー検索は検索時間を意味O(1)が、関係なく、どのように多くの項目の一定のままされますあります。

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 

Collectionもキーすることができますが、キーは、検索または反復することができない、とそのメンバーは、あまりにも最低限です。 Dictionaryははるかに良い仕事をします。

+0

辞書(vs配列/コレクション)を研究した後、これは私が必要とするものであるようだ...私は代わりに辞書を利用するために自分のコードを修正しようとする私が使用していた配列のうち、私の所見を報告します。 – Munkeeface

+0

それは素晴らしいです!しかし、MsgBox用の文字列ビットへの変換では、小数点以下2桁目にゼロがある場合、##(#)という数値(Dictionary内の項目)が返されています。これをフォーマットする方法はありますか? '$ ###。00'を出力したいと思います。.00はその後の小数点以下を示します。 – Munkeeface

+1

「フォーマット(金額、$#、## 0.00」)を試してみてください。また、問題が解決した場合に回答を受け入れたものとみなしてください。乾杯! –

1

些細な方法は、名前が存在するかどうかを確認するには、名前の配列を検索するだろう、そしてそれは、代わりに新しいアレイのメンバー

関連する問題