View Full Version : Arrays
chapster21
10-17-2008, 02:16 PM
I have two lists of names. Column A and Column B.Some names are in both lists. I have to write a sub that captures the 2 lists in 2 arrays. Then create 3 arrays from that info. 1 new array is for names that are only in the previous year, one is for names only in the current year, and the 3rd for names that are in both lists. It does not run correctly. Any ideas?
 
See later post for code.
mdmackillop
10-17-2008, 03:20 PM
Hi Chapster,
Use the green VBA button to format yout code
Regards
MD
chapster21
10-17-2008, 07:48 PM
Ok. Thanks.
Can anyone help? Or should I post somewhere else? 
     :dunno
Greetings Chapster,
 
It's Friday/weekend, so you might have to exercise a  bit of patience.  In the meantime, for those of us with less-than-stellar visualization skills, you might want to attach a sample workbook.  Makes it easier to see what is happening and what might be erroring.  
 
Mark
chapster21
10-17-2008, 10:12 PM
Updated code. I figured out how to get the column "customers both years" filled. Now I just cannot get the other two taken care of. The workbook is attached. The button in the sheet is insignicant. 
By the way, thanks. My last post was just from experience of waiting endlessly on other sites.
 
 
Option Explicit
Option Base 1
Sub CustList()
Dim i1, i2, i3, i4, i5 As Integer
Dim size1, size2, size3, size4, size5 As Integer
Dim list1(), list2(), list3(), list4(), list5() As String
Dim index1, index2, index3 As Integer
Dim name1, name2, name3 As String
With Range("F3")
Range(.Offset(1, 0), .Offset(1, 0).End(xlDown)).ClearContents
End With
 
With Range("A3")
size1 = Range(.Offset(1, 0), .End(xlDown)).Rows.Count
ReDim list1(size1)
For i1 = 1 To size1
list1(i1) = .Offset(i1, 0)
Next
size2 = Range(.Offset(1, 1), .Offset(0, 1).End(xlDown)).Rows.Count
ReDim list2(size2)
For i2 = 1 To size2
list2(i2) = .Offset(i2, 1)
Next
size5 = Range(.Offset(1, 0), .Offset(1, 1).End(xlDown)).Rows.Count
ReDim list5(size5)
For i5 = 1 To size5
list5(i5) = .Offset(i5, 1)
Next
End With
 
 
 
 
 
size4 = 0
size5 = 0
index1 = 1
index2 = 1
 
name1 = list1(index1)
name2 = list2(index2)
 
 
Do While index1 <= size1 And index2 <= size2
name1 = list1(index1)
name2 = list2(index2)
size5 = size5 + 1
ReDim Preserve list5(size5)
 
If name1 < name2 Then
index1 = index1 + 1
ElseIf name1 > name2 Then
index2 = index2 + 1
ElseIf name1 = name2 Then
list5(size5) = name1
index1 = index1 + 1
index2 = index2 + 1
End If
Loop
 
With Range("F3")
For i5 = 1 To size5
.Offset(i5, 0) = list5(i5)
Next
End With
 
Range("F4:F200").Select
Selection.SpecialCells(xlCellTypeBlanks).Delete (xlShiftUp)
 
size3 = 0
 
With Range("F3")
size3 = Range(.Offset(1, 0), .End(xlDown)).Rows.Count
ReDim list3(size3)
For i3 = 1 To size3
list3(i3) = .Offset(i3, 1)
Next
End With
 
With Range("D3")
Range(.Offset(1, 0), .Offset(1, 0).End(xlDown)).ClearContents
End With
size3 = 0
index3 = 1
name3 = list3(index3)
Do While index1 <= size1 And index3 <= size3
name1 = list1(index1)
name3 = list3(index3)
size3 = size3 + 1
ReDim Preserve list3(size3)
 
If name1 = name3 Then
index1 = index1 + 1
index3 = index3 + 1
ElseIf name1 <> name3 Then
list3(size3) = name1
index1 = index1 + 1
End If
Loop
 
With Range("D3")
For i3 = 1 To size3
.Offset(i3, 0) = list3(i3)
Next
End With
End Sub
Demosthine
10-17-2008, 10:45 PM
Evening Youngin'
 
I copied your explanation and came up with the following description for an example workbook.
 
1.)  Row 1 is blank.
2.)  Row 2 is blank.
3.)  Row 3 has Column Headings
      a.) Column A = "Year 2007"
      b.) Column B = "Year 2008"
      c.) Column C = <Blank>
      d.) Column D = "First Year Member"
      e.) Column E = "Second Year Member"
      f.)  Column F = "Member Both Years"
4.)  Row 4 starts list of Names.
 
 
Now, I added a list of names to the list and here is what I found...
As you are cycling through the list for the first time,
- if your Name in Column 1 is not found in Column 2, add it to Column 3.  Increment Column 1.  Good.
- if your Name in Column 1 is found in Column 2, add it to Column 5.  Increment Column 2.  Good.
- LOOP
 
As you are cycling through the list for the second time,
- if your Name in Column 2 is not found in Column 2 starting from where you left off in Column 2 during the previous loop, add it to Column 3.  Bad.
 
At the start of each Loop, you need to reset the second Column to start at the top.  That way it includes all names.  Otherwise, you will be missing all of the previous names as you continue through your code.
 
 
Once that is corrected, you'll find that as you loop through, you are comparing all of the names in Column 1 to only the first name in Column 2.  You need to have a nested loop to compare each name in Column 1 to each name in Column 2.
 
That should get you going.
Scott
malik641
10-17-2008, 11:38 PM
I like Scott has done for you, chapster21. Try to work on fixing your code so it works and then I'll post the code I wrote up that I think you'll like.
Option Explicit
Public Sub Make3Arrays()
    Application.ScreenUpdating = False
    
    Dim ws As Excel.Worksheet, wsNew As Excel.Worksheet
    Const startRow As Long = 4
    Dim rngCustomersLastYear As Excel.Range
    Dim rngCustomersThisYear As Excel.Range
    Dim arrayCustomersLastYear() As String
    Dim arrayCustomersThisYear() As String
    Dim arrayCustomersBothYears() As String
    Dim lastYearCount As Long, thisYearCount As Long
    Dim bothYearsCount As Long, i As Long
    Const lastYearColumn As Long = 1, thisYearColumn As Long = 2
    
    ReDim arrayCustomersLastYear(0)
    ReDim arrayCustomersThisYear(0)
    ReDim arrayCustomersBothYears(0)
    
    Set ws = ThisWorkbook.Worksheets("Lists")
    Set rngCustomersLastYear = _
        ws.Range(ws.Cells(startRow, lastYearColumn), _
        ws.Cells(ws.Rows.Count, lastYearColumn).End(xlUp))
    Set rngCustomersThisYear = _
        ws.Range(ws.Cells(startRow, thisYearColumn), _
        ws.Cells(ws.Rows.Count, thisYearColumn).End(xlUp))
    
    ' loop Customers Last Year
    For i = startRow To ws.Cells(ws.Rows.Count, lastYearColumn).End(xlUp).Row
        ' check if name in other list
        If (IsInList(ws.Cells(i, lastYearColumn).Value, rngCustomersThisYear)) Then
            ' put in third array
            ReDim Preserve arrayCustomersBothYears(bothYearsCount)
            arrayCustomersBothYears(bothYearsCount) = ws.Cells(i, lastYearColumn).Value
            bothYearsCount = bothYearsCount + 1
        Else
            ' put in first array
            ReDim Preserve arrayCustomersLastYear(lastYearCount)
            arrayCustomersLastYear(lastYearCount) = ws.Cells(i, lastYearColumn).Value
            lastYearCount = lastYearCount + 1
        End If
    Next i
    
    ' loop customers This Year
    For i = startRow To ws.Cells(ws.Rows.Count, thisYearColumn).End(xlUp).Row
        ' check if name in other list - this time we don't do anything
        ' if it is because we already made the third array
        If (IsInList(ws.Cells(i, thisYearColumn).Value, rngCustomersLastYear) = False) Then
            ' put in second array
            ReDim Preserve arrayCustomersThisYear(thisYearCount)
            arrayCustomersThisYear(thisYearCount) = ws.Cells(i, thisYearColumn).Value
            thisYearCount = thisYearCount + 1
        End If
    Next i
    
    ' output 3 arrays to new sheet
    Set wsNew = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Wor ksheets.Count))
    wsNew.Cells(1, 1).Value = "Customers Last Year"
    wsNew.Cells(1, 2).Value = "Customers This Year"
    wsNew.Cells(1, 3).Value = "Customers Both Years"
    
    wsNew.Range(wsNew.Cells(2, 1), wsNew.Cells(lastYearCount + 1, 1)).Value = _
        WorksheetFunction.Transpose(arrayCustomersLastYear)
    
    wsNew.Range(wsNew.Cells(2, 2), wsNew.Cells(thisYearCount + 1, 2)).Value = _
        WorksheetFunction.Transpose(arrayCustomersThisYear)
    
    wsNew.Range(wsNew.Cells(2, 3), wsNew.Cells(bothYearsCount + 1, 3)).Value = _
        WorksheetFunction.Transpose(arrayCustomersBothYears)
    
    wsNew.Columns.AutoFit
    
    Application.ScreenUpdating = True
End Sub
Public Function IsInList(ByRef lookFor As String, ByRef inRange As Excel.Range) As Boolean
    Dim rng As Excel.Range
    Set rng = inRange.Find(What:=lookFor, MatchCase:=False)
    IsInList = Not rng Is Nothing
End Function
chapster21
10-18-2008, 05:16 AM
thanks Scott  and Joseph. I will work on that later today and repost. Actually, I had some really bad code in my first post, went back to the drawing board for 12 hours and came up with what I posted yesterday. I did post my code in the VBA box by clicking on the green VBA button. I am not sure why you do not see it formatted.
Thanks again
-Mike
chapster21
10-18-2008, 10:28 PM
'
'
Workbook is attached at bottom of post.
 
Ok. I have spent a Saturday working on this. Something must be wrong with me. Anyway. I have most of column F filled up but a few names do not show up. For some reason the D column is a copy of column A. I have not even tried column E until I can get the other figured out.
 
Option Explicit
Option Base 1
Sub CustList()
Dim i1 As Integer, i2 As Integer, i3 As Integer, i4 As Integer, i5 As Integer
Dim size1 As Integer, size2 As Integer, size3 As Integer, size4 As Integer, size5 As Integer
Dim list1() As String, list2() As String, list3() As String, list4() As String, list5() As String
Dim index1 As Integer, index2 As Integer, index3 As Integer
Dim name1 As Variant, name2 As Variant, name3 As String
 
With Range("D3:F150")
Range(.Offset(1, 0), .Offset(1, 0).End(xlDown)).ClearContents
End With
 
Application.ScreenUpdating = False
 
With Range("A3")
 
size1 = Range(.Offset(1, 0), .End(xlDown)).Rows.Count
ReDim list1(size1)
For i1 = 1 To size1
list1(i1) = .Offset(i1, 0)
Next
size2 = Range(.Offset(1, 1), .End(xlDown)).Rows.Count
ReDim list2(size2)
For i2 = 1 To size2
list2(i2) = .Offset(i2, 1)
Next
End With
 
size5 = 0
size3 = 0
index1 = 1
index2 = 1
 
Do While index1 <= size1 ' And index2 <= size2
 
name1 = list1(index1)
name2 = list2(index2)
 
 
For Each name1 In list1
index2 = 1
For Each name2 In list2
 
 
If name1 = name2 Then
size5 = size5 + 1
ReDim Preserve list5(size5)
list5(size5) = name1
index2 = index2 + 1
index1 = index1 + 1
 Exit For
 ElseIf name1 <> name2 Then
 index2 = index2 + 1
 size3 = size3 + 1
 ReDim Preserve list3(size3)
 list3(size3) = name1
End If
 
Next name2
 
 
index1 = index1 + 1
Next name1
 
Loop
 
 
With Range("D3")
For i3 = 1 To size3
.Offset(i3, 0) = list3(i3)
Next
End With
 
With Range("F3")
For i5 = 1 To size5
.Offset(i5, 0) = list5(i5)
Next
End With
Range("D4:F200").Select
Selection.SpecialCells(xlCellTypeBlanks).Delete (xlShiftUp)
 
Range("A2").Select
End Sub
mdmackillop
10-19-2008, 04:07 AM
Hi Chapster,
Checking each item in one array against each in another is labourious and fiddly (as you have found out). Consider using the Match function instead. 
Personally, I would not use arrays here. You can compare the items using Find (similar reasoning would be used with Match)
 
Option Explicit
Sub CustList()
Dim LastY As Range, ThisY As Range, r As Range, s As Range
Dim Test As Range
With Range("D3:F150")
Range(.Offset(1, 0), .Offset(1, 0).End(xlDown)).ClearContents
End With
Application.ScreenUpdating = False
 
'Compare last year
With Range("A3")
Set LastY = Range(.Offset(1, 0), .End(xlDown))
Set ThisY = Range(.Offset(1, 1), .Offset(1, 1).End(xlDown))
End With
For Each r In LastY
Set Test = ThisY.Find(r, lookat:=xlWhole)
 
If Test Is Nothing Then
'Not in This Year
Cells(Rows.Count, 4).End(xlUp).Offset(1) = r
Else
'In This Year
Cells(Rows.Count, 6).End(xlUp).Offset(1) = r
End If
Next
'compare This Year
For Each s In ThisY
Set Test = LastY.Find(s, lookat:=xlWhole)
If Test Is Nothing Then
'Not in Last Year
Cells(Rows.Count, 5).End(xlUp).Offset(1) = s
End If
Next
 
End Sub
mdmackillop
10-19-2008, 04:10 AM
BTW this will return a wrong result
size2 = Range(.Offset(1, 1), .End(xlDown)).Rows.Count 
you need
 
size2 = Range(.Offset(1, 1), .Offset(1, 1).End(xlDown)).Rows.Count
chapster21
10-19-2008, 06:42 AM
Thanks Joseph. Unfortunately, I have to use arrays.
malik641
10-19-2008, 06:52 AM
Thanks Joseph. Unfortunately, I have to use arrays.
??? I think you meant mdmackillop.
Here was the code that I came up with a few days ago for your solution. It uses arrays. Let me know if you don't understand anything.
Option Explicit
Public Sub Make3Arrays()
    Application.ScreenUpdating = False
    
    Dim ws As Excel.Worksheet, wsNew As Excel.Worksheet
    Const startRow As Long = 4
    Dim rngCustomersLastYear As Excel.Range
    Dim rngCustomersThisYear As Excel.Range
    Dim arrayCustomersLastYear() As String
    Dim arrayCustomersThisYear() As String
    Dim arrayCustomersBothYears() As String
    Dim lastYearCount As Long, thisYearCount As Long
    Dim bothYearsCount As Long, i As Long
    Const lastYearColumn As Long = 1, thisYearColumn As Long = 2
    
    ReDim arrayCustomersLastYear(0)
    ReDim arrayCustomersThisYear(0)
    ReDim arrayCustomersBothYears(0)
    
    Set ws = ThisWorkbook.Worksheets("Lists")
    Set rngCustomersLastYear = _
        ws.Range(ws.Cells(startRow, lastYearColumn), _
        ws.Cells(ws.Rows.Count, lastYearColumn).End(xlUp))
    Set rngCustomersThisYear = _
        ws.Range(ws.Cells(startRow, thisYearColumn), _
        ws.Cells(ws.Rows.Count, thisYearColumn).End(xlUp))
    
    ' loop Customers Last Year
    For i = startRow To ws.Cells(ws.Rows.Count, lastYearColumn).End(xlUp).Row
        ' check if name in other list
        If (IsInList(ws.Cells(i, lastYearColumn).Value, rngCustomersThisYear)) Then
            ' put in third array
            ReDim Preserve arrayCustomersBothYears(bothYearsCount)
            arrayCustomersBothYears(bothYearsCount) = ws.Cells(i, lastYearColumn).Value
            bothYearsCount = bothYearsCount + 1
        Else
            ' put in first array
            ReDim Preserve arrayCustomersLastYear(lastYearCount)
            arrayCustomersLastYear(lastYearCount) = ws.Cells(i, lastYearColumn).Value
            lastYearCount = lastYearCount + 1
        End If
    Next i
    
    ' loop customers This Year
    For i = startRow To ws.Cells(ws.Rows.Count, thisYearColumn).End(xlUp).Row
        ' check if name in other list - this time we don't do anything
        ' if it is because we already made the third array
        If (IsInList(ws.Cells(i, thisYearColumn).Value, rngCustomersLastYear) = False) Then
            ' put in second array
            ReDim Preserve arrayCustomersThisYear(thisYearCount)
            arrayCustomersThisYear(thisYearCount) = ws.Cells(i, thisYearColumn).Value
            thisYearCount = thisYearCount + 1
        End If
    Next i
    
    ' output 3 arrays to new sheet
    Set wsNew = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Wor ksheets.Count))
    wsNew.Cells(1, 1).Value = "Customers Last Year"
    wsNew.Cells(1, 2).Value = "Customers This Year"
    wsNew.Cells(1, 3).Value = "Customers Both Years"
    
    wsNew.Range(wsNew.Cells(2, 1), wsNew.Cells(lastYearCount + 1, 1)).Value = _
        WorksheetFunction.Transpose(arrayCustomersLastYear)
    
    wsNew.Range(wsNew.Cells(2, 2), wsNew.Cells(thisYearCount + 1, 2)).Value = _
        WorksheetFunction.Transpose(arrayCustomersThisYear)
    
    wsNew.Range(wsNew.Cells(2, 3), wsNew.Cells(bothYearsCount + 1, 3)).Value = _
        WorksheetFunction.Transpose(arrayCustomersBothYears)
    
    wsNew.Columns.AutoFit
    
    Application.ScreenUpdating = True
End Sub
Public Function IsInList(ByRef lookFor As String, ByRef inRange As Excel.Range) As Boolean
    Dim rng As Excel.Range
    Set rng = inRange.Find(What:=lookFor, MatchCase:=False)
    IsInList = Not rng Is Nothing
End Function
mdmackillop
10-19-2008, 07:02 AM
Thanks Joseph. Unfortunately, I have to use arrays.
 
Can I ask why? Is this a homework assignment?
malik641
10-19-2008, 07:52 AM
If this IS a homework assignment, I wouldn't recommend copying our solutions. Your teacher will be expecting a lot from you on the next assignment.
chapster21
10-19-2008, 09:44 AM
It is an assignment. That is why I did everything that I could to figure it out myself. I have spent over 20 hours trying to figure this problem out. 
Your code is probably a little more complex than what is expected. Thank you though. I will just turn in what I have and suffer the given grade. I am not trying to get others to do my work, but the professor does encourage getting help if needed. This is a distance course and he is not offering any in person instruction. I have two kids, full time job, and I am just having a really hard time figuring this stuff out. It is taking time away from other priorities.
Thanks guys
Demosthine
10-19-2008, 10:14 AM
Good Morning All.
 
Chapster, we are all willing to help out with homework assignments and you are more than welcome to come ask for help.  Please, though, make sure you specify that it is an assignment and when the assignment is due.  If you look through my posts, I provide a lot more of the educational posts rather than just posting code, rather than just providing code.  I find that is much more beneficial for you and very fulfilling when you figure it out.
 
Malik's example was almost identical to my second method.  The only difference was that I didn't place the .Find Function in a separate Function.
 
When is your assignment actually due?
 
Scott
mdmackillop
10-19-2008, 12:40 PM
You were actually very close to a working solution, so here's a little assistance with your own methodology.
 
For good assignment marks, you should be adding comments.  It helps with future updates/changes and  can clarify in your own mind what each step should achieve.
 
 
 
Option Explicit
Option Base 1
 
Sub CustList()
    Dim i1 As Integer, i2 As Integer, i3 As Integer, i4 As Integer, i5 As Integer
    Dim size1 As Integer, size2 As Integer, size3 As Integer, size4 As Integer, size5 As Integer
    Dim list1() As String, list2() As String, list3() As String, list4() As String, list5() As String
    Dim index1 As Integer, index2 As Integer, index3 As Integer
    Dim name1 As Variant, name2 As Variant, name3 As String
    Dim List6()
    
    
    ReDim List6(500)
    
    With Range("D3:F150")
        Range(.Offset(1, 0), .Offset(1, 0).End(xlDown)).ClearContents
    End With
    
    Application.ScreenUpdating = False
     
    With Range("A3")
               
        size1 = Range(.Offset(1, 0), .End(xlDown)).Rows.Count
        ReDim list1(size1)
        For i1 = 1 To size1
            list1(i1) = .Offset(i1, 0)
        Next
        'Fix reference
        size2 = Range(.Offset(1, 1), .Offset(1, 1).End(xlDown)).Rows.Count
        ReDim list2(size2)
        For i2 = 1 To size2
            list2(i2) = .Offset(i2, 1)
        Next
    End With
    
    size5 = 0
    size3 = 0
    index1 = 1
    index2 = 1
    
    Do While index1 <= size1 And index2 <= size2
        
        'What does this do?
        name1 = list1(index1)
        name2 = list2(index2)
            
            
            For Each name1 In list1
            index2 = 1
                For Each name2 In list2
                        'If name in both lists, add to List5
                        If name1 = name2 Then
                            size5 = size5 + 1
                            ReDim Preserve list5(size5)
                            list5(size5) = name1
                            index2 = index2 + 1
                            index1 = index1 + 1
                            'Exit For
                            'You need to avoid incrementing size3
                            GoTo skipped
                        ElseIf name1 <> name2 Then
                            index2 = index2 + 1
                        End If
                Next name2
                'If not, add to List3
                'This will increment for each item in List1
                size3 = size3 + 1
                ReDim Preserve list3(size3)
                list3(size3) = name1
            index1 = index1 + 1
skipped:
            Next name1
                    
    Loop
       
    
    With Range("D3")
        For i3 = 1 To size3
            .Offset(i3, 0) = list3(i3)
        Next
    End With
        
    With Range("F3")
        For i5 = 1 To size5
            .Offset(i5, 0) = list5(i5)
        Next
    End With
    Range("D4:F200").Select
    Selection.SpecialCells(xlCellTypeBlanks).Delete (xlShiftUp)
    
    Range("A2").Select
End Sub
p45cal
10-19-2008, 02:12 PM
Comments in the code - I leave it to you to add any further Dim statements as I haven't used Option Explicit. See attachment also.
Sub blah()
Dim LastYearOnly(), ThisYearOnly(), BothYears() 'Arrays for results
LYOIndex = 0: TYOIndex = 0: BYIndex = 0 'Pointer to last member of each array (not needed but help clarity)
LastYear = Application.Transpose(Range(Range("A4"), Range("A4").End(xlDown))) 'Create array of pre-existing list.
ThisYear = Application.Transpose(Range(Range("B4"), Range("B4").End(xlDown))) 'as above
For i = 1 To UBound(ThisYear) 'taking each name in this year's list...
    MatchFound = False
    For j = 1 To UBound(LastYear) '...compare it to each name in last year's list...
        If ThisYear(i) = LastYear(j) Then MatchFound = True: Exit For '...abandoning loop if a match is found.
    Next j
    
    If MatchFound Then 'the name must be in both lists so add it to the new Both Years list:
        BYIndex = BYIndex + 1
        ReDim Preserve BothYears(1 To BYIndex) 'extend the size of the new array
        BothYears(BYIndex) = ThisYear(i) ' insert the name
    Else ' the name was only in the original this year's list, so add it to the new This Year Only list:
        TYOIndex = TYOIndex + 1
        ReDim Preserve ThisYearOnly(1 To TYOIndex)
        ThisYearOnly(TYOIndex) = ThisYear(i)
    End If
Next i
For i = 1 To UBound(LastYear) 'taking each name in the original last year's list...
    MatchFound = False
    For j = 1 To UBound(ThisYear) '...compare it to each name in the original this year's list...
        If ThisYear(j) = LastYear(i) Then MatchFound = True: Exit For
    Next j
    If Not MatchFound Then 'add the name to the new Last Year Only array:
        LYOIndex = LYOIndex + 1
        ReDim Preserve LastYearOnly(1 To LYOIndex)
        LastYearOnly(LYOIndex) = LastYear(i)
    End If
Next i
'put the arrays on the spreadsheet (I haven't bothered clearing what was there before)
Range("D4").Resize(LYOIndex) = Application.Transpose(LastYearOnly)
Range("E4").Resize(TYOIndex) = Application.Transpose(ThisYearOnly)
Range("F4").Resize(BYIndex) = Application.Transpose(BothYears)
End Sub
mdmackillop
10-19-2008, 04:58 PM
Why use the nested loop?  20k entries in both arrays would take a while.
 
For Each name1 In list1
                On Error Resume Next
                chk = Application.Match(name1, list2, 0)
               If IsError(chk) Then
                    'add to array or whatever
                    Cells(Rows.Count, "D").End(xlUp).Offset(1) = name1
                Else
                    'add to other array or whatever
                    Cells(Rows.Count, "F").End(xlUp).Offset(1) = name1
                End If
            Next name1
chapster21
10-19-2008, 05:00 PM
You guys are great. Thank you. 
Scott, my assignment was due 1 week ago. I am behind quite a bit.
Thanks to each of you.
p45cal
10-19-2008, 07:21 PM
Why use the nested loop?  20k entries in both arrays would take a while. 
I had tried something on those lines using countif and it seemed to insist on worksheet ranges to work on, and I assumed (wrongly) that Match might be the same, so I moved to nested arrays.
Having said that, when trying Application.WorksheetFunction.Match, it failed, whereas Application.Match worked - not sure why.
As to timing, I ran the code 100 times in a loop on the OP's data, one with Match, the other with nested loops (although I kept my Exit For statements in) and the Match version took a consistent 34%  longer, which I really didn't expect!
Sub blah()
StartTime = Timer
On Error Resume Next
For z = 1 To 100
Dim LastYearOnly(), ThisYearOnly(), BothYears() 'Arrays for results
LYOIndex = 0: TYOIndex = 0: BYIndex = 0 'Pointer to last member of each array (not needed but help clarity)
LastYear = Application.Transpose(Range(Range("A4"), Range("A4").End(xlDown))) 'Create array of pre-existing list.
ThisYear = Application.Transpose(Range(Range("B4"), Range("B4").End(xlDown))) 'as above
For Each mName In ThisYear 'taking each name in this year's list...
    MatchFound = Application.Match(mName, LastYear, 0)
    If Not IsError(MatchFound) Then 'there was a match
        BYIndex = BYIndex + 1
        ReDim Preserve BothYears(1 To BYIndex) 'extend the size of the new array
        BothYears(BYIndex) = mName ' insert the name
    Else ' the name was only in the original this year's list, so add it to the new This Year Only list:
        TYOIndex = TYOIndex + 1
        ReDim Preserve ThisYearOnly(1 To TYOIndex)
        ThisYearOnly(TYOIndex) = mName
    End If
Next mName
For Each mName In LastYear 'taking each name in the original last year's list...
    MatchFound = Application.Match(mName, ThisYear, 0)
    If IsError(MatchFound) Then
        LYOIndex = LYOIndex + 1
        ReDim Preserve LastYearOnly(1 To LYOIndex)
        LastYearOnly(LYOIndex) = mName
    End If
Next mName
'put the arrays on the spreadsheet (I haven't bothered clearing what was there before)
Range("D4").Resize(LYOIndex) = Application.Transpose(LastYearOnly)
Range("E4").Resize(TYOIndex) = Application.Transpose(ThisYearOnly)
Range("F4").Resize(BYIndex) = Application.Transpose(BothYears)
Next z
On Error GoTo 0
MsgBox Timer - StartTime
End Sub
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.