2011-10-01 51 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类型,或者如果确实真的确定列表在内部循环中循环的列表真的按字母顺序排序