2016-07-05 62 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 

最後,它會顯示一個MsgBox來提醒已經受到影響,但沒有反映在銀行對賬單上的所有賬戶的用戶。

實施例的消息:

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 

由於這些是兩個單獨的陣列,但每個陣列位置相匹配的其他陣列中的其相應的值,我將如何能夠總結每個消息,以顯示:

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

(我們收到客戶訂單的銀行電匯,有時客戶發送單條電匯以反映多個訂單,這個總和允許我進一步比較單個客戶名稱的總和,而不是逐行值。我可以總羅德·鮑爾斯的比較,他的單絲,與他的3個個人訂單VS他的線,這顯然返回的缺失值)

這裏的表將是什麼樣子的例子: enter image description here

解決方案/修復:

根據馬克杯的幫助,我已經消除了使用動態數組並將其切換到字典。這使我可以創建所有重複名稱的總和,並進一步與銀行對賬單上的任何值進行比較。

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我對VBA並不是很熟悉,因爲我在4天前纔開始研究它,但由於以前的Java經驗,我對sytax結構有所瞭解。有了這個說法,Collections會基本上建立一個動態數組嗎?或者你有數據表來描述這些? (我在工作,所以一些論壇不幸被阻止) – Munkeeface

+0

看看[這個](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

經過研究字典(數組/集合),它似乎這正是我所需要的...我將嘗試修改我的代碼,以利用字典我一直在使用的陣列,並將報告我的研究結果。 – Munkeeface

+0

好吧,它非常有效!但是,在我轉換爲字符串位(用於MsgBox)時,當第二個小數位中存在零時,我得到的值(字典中的項)返回爲##。#。有沒有一種方法來格式化?我希望它輸出'$ ###。00',其中.00顯示任何後面的小數。它是我報告的貨幣,畢竟 – Munkeeface

+1

嘗試'格式(金額,「$#,## 0.00」)' - 另外,如果解決了問題,請考慮將答案標記爲已接受。乾杯! –

1

瑣碎的方法是搜索的名稱數組,看看名稱存在,如果它不那麼值添加到現有的價值,而不是插入一個新的數組成員