+ Reply to Thread
Page 1 of 2 12 LastLast
Results 1 to 15 of 29

Thread: Using Find in a Loop

  1. #1
    Forum Contributor
    Join Date
    06-07-2008
    Posts
    111

    Using Find in a Loop

    I have a list of 50000+ items in column A with their corresponding quantities in column B. There are duplicate items in A and I want to combine the quantities of the duplicate items then remove the duplicates rows.

    Doing this in For-Next loops takes hours to complete. I am looking for a quicker method such as using the Find statement.

    Thanks

  2. #2
    Valued Forum Contributor
    Join Date
    06-17-2009
    Location
    Chennai,India
    MS-Off Ver
    Excel 2003,excel 2007
    Posts
    445

    Re: Using Find in a Loop

    can you try this experiment
    keep the original file safe somewhere.
    I presume that in sheet col A and B have column heading in row 1.
    goto sheet2

    selecst A1 in sheet2
    click data(menu bar)-filter-advance filter

    in teh advance filter window
    against list ramge type
    Sheet1!$A$1:$A$5000(row 5000 is the last row)
    leave criteria range blank
    choose "copy to another locations" at the top
    click "unique records only" at the bottom
    then in "copy to type
    $A$1 (if it is not there already.

    click Ok in the advance filter window.

    you get unique values of column A of sheet 1 in column A of sheet 2

    in cell B2 of sheet 2 type this formula

    =SUMPRODUCT((Sheet1!$A$2:$A$5000=A2)*(Sheet1!$B$2:$B$5000))

    copy this down to the last row.

    will this take less time than a macro

  3. #3
    Forum Moderator Leith Ross's Avatar
    Join Date
    01-15-2005
    Location
    San Francisco, Ca
    MS-Off Ver
    2000, 2003, & read 2007
    Posts
    15,963

    Re: Using Find in a Loop

    Hello Matrex,

    This macro is fast. It copies the cell data and the values into an array and uses the Dictionary Object to blank duplicates and sum the values. Lastly, the rows are that contain blanks are deleted. The default worksheet is "Sheet1" in the code. The default starting cell is "A2". Both of the values can be changed in the code to match what you using. They marked in red. Copy this code into a standard VBA module.
    Sub MergeUniqueData()
    
      Dim Blanks As Range
      Dim Data As Variant
      Dim DSO As Object
      Dim I As Long
      Dim Item As Variant
      Dim Key As Variant
      Dim Rng As Range
      Dim RngEnd As Range
      
        StartTime = Timer
        
        Set Rng = Worksheets("Sheet1").Range("A2")
        Set RngEnd = Rng.Parent.Cells(Rows.Count, Rng.Column).End(xlUp)
        Set Rng = IIf(RngEnd.Row < Rng.Row, Rng, Rng.Parent.Range(Rng, RngEnd))
        
          Application.ScreenUpdating = False
          
          Set DSO = CreateObject("Scripting.Dictionary")
          DSO.CompareMode = vbTextCompare
        
            Data = Rng.Resize(ColumnSize:=2).Value
            For I = 1 To UBound(Data, 1)
              Key = Trim(Data(I, 1))
              If Key <> "" Then
                 Item = Data(I, 2)
                 If Not DSO.Exists(Key) Then
                    DSO.Add Key, I
                 Else
                    Data(DSO(Key), 2) = Data(DSO(Key), 2) + Item
                    Data(I, 1) = ""
                 End If
              End If
            Next I
            Rng.Value = Data
          
          On Error Resume Next
            Set Blanks = Rng.SpecialCells(xlCellTypeBlanks)
            If Err = 0 Then Blanks.EntireRow.Delete
          Err.Clear
          On Error GoTo 0
          
          Application.ScreenUpdating = True
          
        Set DSO = Nothing
        
        EndTime = Timer
        TotalTime = EndTime - StartTime
        '332.2813
         
    End Sub
    Adding the Macro
    1. Copy the macro above pressing the keys CTRL+C
    2. Open your workbook
    3. Press the keys ALT+F11 to open the Visual Basic Editor
    4. Press the keys ALT+I to activate the Insert menu
    5. Press M to insert a Standard Module
    6. Paste the code by pressing the keys CTRL+V
    7. Make any custom changes to the macro if needed at this time.
    8. Save the Macro by pressing the keys CTRL+S
    9. Press the keys ALT+Q to exit the Editor, and return to Excel.

    To Run the Macro...
    To run the macro from Excel, open the workbook, and press ALT+F8 to display the Run Macro Dialog. Double Click the macro's name to Run it.
    Last edited by Leith Ross; 07-05-2009 at 12:59 AM.
    Sincerely,
    Leith Ross

    Remember To Do the Following....

    1. Use code tags. Place [CODE] before the first line of code and [/CODE] after the last line of code.
    2. Thank those who have helped you by clicking the Star below the post.
    3. Please mark your post [SOLVED] if it has been answered satisfactorily.


    Old Scottish Proverb...
    Luathaid gu deanamh maille! (Rushing causes delays!)

  4. #4
    Valued Forum Contributor
    Join Date
    11-11-2008
    Location
    Euro
    MS-Off Ver
    2003, 2007
    Posts
    384

    Re: Using Find in a Loop

    Try:
    expression.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)

    an good example
    Sub FindCatOtherSheet()
    
    Dim rFound As Range
    
    
    
        On Error Resume Next
    
        With Sheet1
    
            Set rFound = .Columns(1).Find(What:="Cat", After:=.Cells(1, 1), LookIn:=xlValues, LookAt:= _
    
                xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
    
                , SearchFormat:=False)
    
        On Error GoTo 0
    
            If Not rFound Is Nothing Then Application.Goto rFound, True
    
        End With
    End Sub
    Plz see more detail at the link: http://www.ozgrid.com/VBA/find-method.htm

    Ref: http://www.ozgrid.com/VBA/find-method.htm

  5. #5
    Valued Forum Contributor
    Join Date
    11-11-2008
    Location
    Euro
    MS-Off Ver
    2003, 2007
    Posts
    384

    Re: Using Find in a Loop

    OR other example with loop:
    Example
    
    This example finds all cells in the range A1:A500 on worksheet one that contain the value 2 and changes it to 5.
    
    With Worksheets(1).Range("a1:a500")
        Set c = .Find(2, lookin:=xlValues)
        If Not c Is Nothing Then
            firstAddress = c.Address
            Do
                c.Value = 5
                Set c = .FindNext(c)
            Loop While Not c Is Nothing And c.Address <> firstAddress
        End If
    End With
    ref: http://msdn.microsoft.com/en-us/libr...ffice.11).aspx

  6. #6
    Forum Guru pike's Avatar
    Join Date
    12-11-2005
    Location
    Alstonville, Australia
    MS-Off Ver
    2010
    Posts
    5,150

    Re: Using Find in a Loop

    or another way
    no loops
    Option Explicit
    Sub ptest()
        Dim lRows As Long
        Application.ScreenUpdating = False
        With Sheet1.UsedRange
            lRows = .Rows.Count
        .Columns(2).Insert
        .Columns(2).FormulaR1C1 = "= SUMIF(R2C[-1]:R" & lRows & "C[-1],RC[-1],R2C[1]:R" & lRows & "C[1])"
        .Columns(2).Value = .Columns(2).Value
        .Resize(, 2).AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=.Resize(, 2), copytorange:=Range("E1"), unique:=True
       .Columns(2).Delete
        End With
    End Sub
    will take about 2-3 minutes

  7. #7
    Forum Contributor
    Join Date
    06-07-2008
    Posts
    111

    Re: Using Find in a Loop

    venkat1926 - Copying a formula to 50,000 cells is not an effecient way to do this.

    Leith Ross - Got an avtivex error on the DSO line. Besides this is not a FIND method

    tigertiger - I already saw these codes online but none actually does the job correctly. The Find lines either miss the first match, or give unexpected results. Try them on a sample of 10 or so rows and see what I mean.

    Any other ideas?

  8. #8
    Valued Forum Contributor
    Join Date
    11-11-2008
    Location
    Euro
    MS-Off Ver
    2003, 2007
    Posts
    384

    Re: Using Find in a Loop

    Quote Originally Posted by matrex View Post
    tigertiger -....The Find lines either miss the first match, or give unexpected results. Try them on a sample of 10 or so rows and see what I mean.
    Any other ideas?
    You should combine Find and For loop
    I am trying to write the example-code for you

  9. #9
    Forum Contributor
    Join Date
    06-07-2008
    Posts
    111

    Re: Using Find in a Loop

    Pike - A great piece of code. Worked brilliantly in one workbook but gave an error on " With Sheet1.UsedRange" line on the another workbook. I'm still trying to figure out what's causing the error.

  10. #10
    Forum Guru pike's Avatar
    Join Date
    12-11-2005
    Location
    Alstonville, Australia
    MS-Off Ver
    2010
    Posts
    5,150

    Re: Using Find in a Loop

    try changing
     with Activesheet.used range
    Last edited by pike; 07-05-2009 at 12:15 AM. Reason: tags

  11. #11
    Forum Moderator Leith Ross's Avatar
    Join Date
    01-15-2005
    Location
    San Francisco, Ca
    MS-Off Ver
    2000, 2003, & read 2007
    Posts
    15,963

    Re: Using Find in a Loop

    Hello matrex,

    What system are you using? I have never heard of "avtivex" error.
    Got an avtivex error on the DSO line
    Did you mean "Acitve X" ?

    "FIND" is not required to do this task. The method I presented works much faster than the Range.Find method. If you have some fondness for this method, a macro can be supplied. Just don't expect it to be fast.
    Sincerely,
    Leith Ross

    Remember To Do the Following....

    1. Use code tags. Place [CODE] before the first line of code and [/CODE] after the last line of code.
    2. Thank those who have helped you by clicking the Star below the post.
    3. Please mark your post [SOLVED] if it has been answered satisfactorily.


    Old Scottish Proverb...
    Luathaid gu deanamh maille! (Rushing causes delays!)

  12. #12
    Valued Forum Contributor
    Join Date
    11-11-2008
    Location
    Euro
    MS-Off Ver
    2003, 2007
    Posts
    384

    Re: Using Find in a Loop

    Quote Originally Posted by Leith Ross View Post
    Hello matrex,
    Did you mean "Acitve X" ?
    that is Active X for CreateObject("Scripting.Dictionary")
    in your SUB

  13. #13
    Valued Forum Contributor
    Join Date
    11-11-2008
    Location
    Euro
    MS-Off Ver
    2003, 2007
    Posts
    384

    Re: Using Find in a Loop

    try this SUB
    Public Sub findx()
    
    Const StartRow = 2
    Dim c, firstAddress, iR As Long, eR As Long, Q, Sh0 As Worksheet
    
    Set Sh0 = Application.ActiveSheet
    
    eR = Sh0.Range("A" & Rows.Count).End(xlUp).Row
    Dim aCo() As Byte: ReDim aCo(eR) As Byte: For iR = 0 To eR: aCo(iR) = 0: Next
    
    For iR = StartRow To eR
        If Sh0.Cells(iR, "A").Value2 = "" Then
            aCo(iR) = 2
        Else
            If aCo(iR) = 0 Then
                
                firstAddress = Sh0.Cells(iR, "A").Address
                Q = Sh0.Cells(iR, "A").Offset(, 1).Value2
                
                With Sh0.Range("a" & iR & ":a" & eR)
                    Set c = .Find(Sh0.Cells(iR, "A").Value2, LookIn:=xlValues, LookAt:=xlWhole)
                    Do While Not c Is Nothing And c.Address <> firstAddress
                        aCo(c.Row) = 1
                        If Q = c.Offset(, 1).Value2 Then aCo(c.Row) = 2
                        Set c = .FindNext(c)
                    Loop
                End With
            End If
        End If
    Next iR
    For iR = eR To StartRow Step -1
       If aCo(iR) = 2 Then Sh0.Rows(iR).Delete
    Next iR
    
    End Sub

  14. #14
    Forum Contributor
    Join Date
    06-07-2008
    Posts
    111

    Re: Using Find in a Loop

    Leith Ross - Yes I meant mean "Acitve X". Sorry about the typo.

    tigertiger - tried it on this sample list but nothing seems to happen!
    AAA 2
    BBB 2
    AAA 1
    AAA 4
    FFF 3
    GGG 2
    GGG 1
    RRR 4
    AAA 3
    BBB 1

    Thanks so much everyone for all your help.

    matrex

  15. #15
    Valued Forum Contributor
    Join Date
    11-11-2008
    Location
    Euro
    MS-Off Ver
    2003, 2007
    Posts
    384

    Re: Using Find in a Loop

    Quote Originally Posted by matrex View Post
    AAA 2
    BBB 2
    AAA 1
    AAA 4
    FFF 3
    GGG 2
    GGG 1
    RRR 4
    AAA 3
    BBB 1
    hiiiiiii
    it does not match your problem that you present in your original post:

    There are duplicate items in A and I want to combine the quantities of the duplicate items then remove the duplicates rows.

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.2.0