2011-10-01 54 views
0

我有一個去年(列A)的客戶列表,我有一個今年(B列)的客戶列表。我已經把數據從陣列中這兩列(使用下面的代碼 - 這被設置爲選項基本1):在VBA中組合數組

'Define our variables and array types' 
    Sub CustomerArray() 
     Dim LastArray() As String 
     Dim CurrentArray() As String 
     Dim BothArray() As String 
     Dim LR As Long 
     Dim i As Integer 

    'Define LastArray which is customers last year' 
    LR = Cells(Rows.Count, 1).End(xlUp).Row 
    ReDim LastArray(LR - 3) 
    With Range("A1") 
     For i = 1 To LR - 3 
     LastArray(i) = .Offset(i, 0) 
     Next i 
    End With 

    'Define CurrentArray which is customers this year' 
    ReDim CurrentArray(LR - 3) 
    With Range("B1") 
     For i = 1 To LR - 3 
     CurrentArray(i) = .Offset(i, 0) 
     Next i 
    End With 


    End Sub 

現在我要比較/合併的陣列,顯示的客戶名單誰出現在我剛剛定義的兩個陣列(去年和今年)中。我想創建第三個陣列與兩年出現的客戶(我想把它放在我的Excel表格的D列中)。我對如何編寫將比較這兩個數組的代碼(當前年和去年)感到困惑。我會使用條件If>語句嗎?每個陣列都有按字母順序列出的客戶。

我提供任何幫助,你可能會給我。

謝謝!

+0

您是否需要「最後」和「當前」數組來處理其他任何事情,還是僅僅爲了生成「兩個」數組? –

+1

您可以在Excel中使用ADO。這將很容易與查詢:http://support.microsoft.com/kb/257819 – Fionnuala

+0

根據您的要求,Remou的建議也是一個很好的建議。 – XIVSolutions

回答

2

好的。我有點得意忘形這裏,但這樣做你是問(您可能需要調整它以滿足您的特定需求。若要使用此代碼,只需調用子「滿足客戶」。

你的原代碼建議使用三個數組,Excel VBA提供了一些機制來完成你所尋求的任務,這些機制既易於使用又可能更高效。好像更多的代碼,你會發現每個peice可能會更有意義,並且更易於維護。如果需要,您現在也可以重新使用其他操作的單個函數。

我也拉將範圍和列索引編輯到本地定義的常量中。這樣,如果需要更改各種行或列引用,則只需在一個位置更改值。

這不一定是最有效的方法,但最可能比使用最初提議的數組複雜。

我沒有詳盡地測試過這個,但它在最基本的意義上起作用。如果您有任何問題,請告訴我。

希望有所幫助。 。 。

Option Explicit 

'Set your Column indexes as constants, and use the constants in your code. 
'This will be much more maintainable in the long run: 
Private Const LY_CUSTOMER_COLUMN As Integer = 1 
Private Const CY_CUSTOMER_COLUMN As Integer = 2 
Private Const MATCHED_CUSTOMER_COLUMN As Integer = 4 
Private Const OUTPUT_TARGET As String = "D1" 
Private Const LAST_ROW_OFFSET As Integer = -3 


'A Function which returns the list of customers from last year 
'as a Range object: 
Function CustomersLastYear() As Range 
    Dim LastCell As Range 

    'Find the last cell in the column: 
    Set LastCell = Cells(Rows.Count, LY_CUSTOMER_COLUMN).End(xlUp) 

    'Return the range of cells containing last year's customers: 
    Set CustomersLastYear = Range(Cells(1, LY_CUSTOMER_COLUMN), LastCell) 

End Function 


'A Function which returns the list of customers from this year 
'as a Range object: 
Function CustomersThisYear() As Range 
    Dim LastCell As Range 

    'Find the last cell in the column: 
    Set LastCell = Cells(Rows.Count, CY_CUSTOMER_COLUMN).End(xlUp) 

    'Return the range of cells containing this year's customers: 
    Set CustomersThisYear = Range(Cells(1, CY_CUSTOMER_COLUMN), LastCell) 

End Function 


'A function which returns a range object representing the 
'current list of matched customers (Mostly so you can clear it 
'before re-populating it with a new set of matches): 
Function CurrentMatchedCustomersRange() As Range 
    Dim LastCell As Range 

    'Find the last cell in the column: 
    Set LastCell = Cells(Rows.Count, MATCHED_CUSTOMER_COLUMN).End(xlUp) 

    'Return the range of cells containing currently matched customers: 
    Set CurrentMatchedCustomersRange = Range(Cells(1, MATCHED_CUSTOMER_COLUMN), LastCell) 

End Function 


'A Function which performs a comparison between two ranges 
'and returns a Collection containing the matching cells: 
Function MatchedCustomers(ByVal LastYearCustomers As Range, ByVal ThisYearCustomers As Range) As Collection 
    Dim output As Collection 

    'A variable to iterate over a collection of cell ranges: 
    Dim CustomerCell As Range 

    'Initialize the collection object: 
    Set output = New Collection 

    'Iterate over the collection of cells containing last year's customers: 
    For Each CustomerCell In LastYearCustomers.Cells 
     Dim MatchedCustomer As Range 

     'Set the variable to reference the current cell object: 
     Set MatchedCustomer = ThisYearCustomers.Find(CustomerCell.Text) 

     'Test for a Match: 
     If Not MatchedCustomer Is Nothing Then 

      'If found, add to the output collection: 
      output.Add MatchedCustomer 
     End If 

     'Kill the iterator variable for the next iteration: 
     Set MatchedCustomer = Nothing 
    Next 

    'Return a collection of the matches found: 
    Set MatchedCustomers = output 

End Function 


Sub MatchCustomers() 
    Dim LastYearCustomers As Range 
    Dim ThisYearCustomers As Range 
    Dim MatchedCustomers As Collection 
    Dim MatchedCustomer As Range 

    'Clear out the destination column using the local function: 
    Set MatchedCustomer = Me.CurrentMatchedCustomersRange 
    MatchedCustomer.Clear 
    Set MatchedCustomer = Nothing 

    'Use local functions to retrieve ranges: 
    Set LastYearCustomers = Me.CustomersLastYear 
    Set ThisYearCustomers = Me.CustomersThisYear 

    'Use local function to preform the matching operation and return a collection 
    'of cell ranges representing matched customers. Pass the ranges of last year and this year 
    'customers in as Arguments: 
    Set MatchedCustomers = Me.MatchedCustomers(LastYearCustomers, ThisYearCustomers) 


    Dim Destination As Range 

    'Use the local constant to set the initial output target cell: 
    Set Destination = Range(OUTPUT_TARGET) 

    'Itereate over the collection and paste the matches into the output cell: 
    For Each MatchedCustomer In MatchedCustomers 
     MatchedCustomer.Copy Destination 

     'Increment the output row index after each paste operation: 
     Set Destination = Destination.Offset(1) 
    Next 

End Sub 
+1

......你教這些如何釣魚,而不是給他們在銀盤上煮熟的低音。但無論如何+1。 – jpinto3912

+1

@ jpinto - 同意,但有時,當人們嘗試通過樣本工作時,他們會學到很多關於「釣魚」的知識。另外,當我學習VBA時,弄清楚其他人是如何做到的。感謝+1! – XIVSolutions

+1

另外值得注意的是,VBA + Excel爲笨重的代碼提供了各種機會。再加上大多數VBA/Excel實現的用例邀請倉促編寫的代碼,這些代碼稍後會變得有問題。不一定是OP在做什麼,但是一些重構的例子不會受到傷害。 – XIVSolutions

3

您不需要使用數組或循環一塌糊塗可言,保持它的簡單,嘗試這樣的事情:

Sub HTH() 

    With Range("A1", Cells(Rows.Count, "A").End(xlUp)).Offset(, 3) 
     .Formula = "=IF(COUNTIF(B:B,A1)>0,A1,"""")" 
     .Value = .Value 
     .SpecialCells(xlCellTypeBlanks).Delete 
    End With 

End Sub 
+0

做得很好! +1 – XIVSolutions

+0

@XIV,謝謝。 :) – Reafidy

0

如果你想使用循環兩個數組來比較,也許是因爲例如,您已將所有數據提取到數組中,以加快計算速度,而不是與電子表格範圍對象進行交互,或者您需要比較兩個數組中的多個事項,以檢查條目是否匹配,從而無法使用a。找說法,那麼這就是你所需要的:

- 兩個循環,嵌套在其他

- 三櫃檯內的一個,每一個陣列

-One「退出循環」,「退出對於」 「轉到foundmatch」 或退出內環

-A 「REDIM保留」 的結果陣列

-An的 「if」 語句的類似方式

- 最後,您可以將兩個數組中出現的名稱分配到結果數組中的一行代碼

這就是將它簡單地編寫爲循環所需的所有內容 - 但不會提供最快或最好的方式來執行此操作( Redim Preserve不是最好的..)。然而,從這個列表構造它應該很容易:if語句應該是用於一般用法的x = y類型,或者如果確實真的確定列表在內部循環中循環的列表真的按字母順序排序