Welcome to the Excel Forum

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed.

Please Register to Remove these Ads

Please Register to Remove these Ads



Reply
  #1  
Old 07-04-2009, 09:24 PM
matrex matrex is offline
Registered User
 
Join Date: 07 Jun 2008
Posts: 74
matrex is becoming part of the community
Using Find in a Loop

Please Register to Remove these Ads

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
Reply With Quote
  #2  
Old 07-04-2009, 10:10 PM
venkat1926 venkat1926 is offline
Registered User
 
Join Date: 17 Jun 2009
Location: Chennai,India
MS Office Version:Excel 2002
Posts: 76
venkat1926 is becoming part of the community
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
Reply With Quote
  #3  
Old 07-04-2009, 11:04 PM
Leith Ross's Avatar
Leith Ross Leith Ross is offline
Forum Moderator
 
Join Date: 15 Jan 2005
Location: San Francisco, Ca
MS Office Version:2000, 2003, & read 2007
Posts: 10,537
Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding
Send a message via AIM to Leith Ross
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.
Code:
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.
__________________
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 scales above each post.
3. Please mark your post [SOLVED] if it has been answered satisfactorily.


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

Last edited by Leith Ross; 07-05-2009 at 12:59 AM.
Reply With Quote
  #4  
Old 07-04-2009, 11:20 PM
tigertiger tigertiger is offline
Forum Contributor
 
Join Date: 11 Nov 2008
Location: The Earth
Posts: 194
tigertiger has been very helpful
Re: Using Find in a Loop

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

an good example
Code:
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
Reply With Quote
  #5  
Old 07-04-2009, 11:27 PM
tigertiger tigertiger is offline
Forum Contributor
 
Join Date: 11 Nov 2008
Location: The Earth
Posts: 194
tigertiger has been very helpful
Re: Using Find in a Loop

OR other example with loop:
Code:
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
Reply With Quote
  #6  
Old 07-04-2009, 11:43 PM
pike's Avatar
pike pike is offline
Forum Guru
 
Join Date: 11 Dec 2005
Location: Moruya, Australia
MS Office Version:2007
Posts: 1,549
pike is a becoming a god in the Excel Forum World pike is a becoming a god in the Excel Forum World pike is a becoming a god in the Excel Forum World pike is a becoming a god in the Excel Forum World pike is a becoming a god in the Excel Forum World pike is a becoming a god in the Excel Forum World
Re: Using Find in a Loop

or another way
no loops
Code:
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
__________________
.

regards pike

Always add code tags to your VBA script [code] .Range("A1:A10").RemoveDuplicates [/code]
Code:
 .Range("A1:A10").RemoveDuplicates Columns:=Array(1, 2), Header:=xlYes
Remember to change the prefix to [SOLVED]
If the solution helped and you wish to add to the contributors reputation, click the.... .... icon in top right hand corner of the thread ......... ã
Spreadsheet Toolbox
Reply With Quote
  #7  
Old 07-04-2009, 11:46 PM
matrex matrex is offline
Registered User
 
Join Date: 07 Jun 2008
Posts: 74
matrex is becoming part of the community
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?
Reply With Quote
  #8  
Old 07-04-2009, 11:51 PM
tigertiger tigertiger is offline
Forum Contributor
 
Join Date: 11 Nov 2008
Location: The Earth
Posts: 194
tigertiger has been very helpful
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
Reply With Quote
  #9  
Old 07-05-2009, 12:04 AM
matrex matrex is offline
Registered User
 
Join Date: 07 Jun 2008
Posts: 74
matrex is becoming part of the community
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.
Reply With Quote
  #10  
Old 07-05-2009, 12:15 AM
pike's Avatar
pike pike is offline
Forum Guru
 
Join Date: 11 Dec 2005
Location: Moruya, Australia
MS Office Version:2007
Posts: 1,549
pike is a becoming a god in the Excel Forum World pike is a becoming a god in the Excel Forum World pike is a becoming a god in the Excel Forum World pike is a becoming a god in the Excel Forum World pike is a becoming a god in the Excel Forum World pike is a becoming a god in the Excel Forum World
Re: Using Find in a Loop

try changing
Code:
 with Activesheet.used range
__________________
.

regards pike

Always add code tags to your VBA script [code] .Range("A1:A10").RemoveDuplicates [/code]
Code:
 .Range("A1:A10").RemoveDuplicates Columns:=Array(1, 2), Header:=xlYes
Remember to change the prefix to [SOLVED]
If the solution helped and you wish to add to the contributors reputation, click the.... .... icon in top right hand corner of the thread ......... ã
Spreadsheet Toolbox

Last edited by pike; 07-05-2009 at 12:15 AM. Reason: tags
Reply With Quote
  #11  
Old 07-05-2009, 12:52 AM
Leith Ross's Avatar
Leith Ross Leith Ross is offline
Forum Moderator
 
Join Date: 15 Jan 2005
Location: San Francisco, Ca
MS Office Version:2000, 2003, & read 2007
Posts: 10,537
Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding Leith Ross Has a higher level of understanding
Send a message via AIM to Leith Ross
Re: Using Find in a Loop

Hello matrex,

What system are you using? I have never heard of "avtivex" error.
Quote:
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 scales above each post.
3. Please mark your post [SOLVED] if it has been answered satisfactorily.


Old Scottish Proverb...
Luathaid gu deanamh maille! (Rushing causes delays!)
Reply With Quote
  #12  
Old 07-05-2009, 01:22 AM
tigertiger tigertiger is offline
Forum Contributor
 
Join Date: 11 Nov 2008
Location: The Earth
Posts: 194
tigertiger has been very helpful
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
Reply With Quote
  #13  
Old 07-05-2009, 01:39 AM
tigertiger tigertiger is offline
Forum Contributor
 
Join Date: 11 Nov 2008
Location: The Earth
Posts: 194
tigertiger has been very helpful
Re: Using Find in a Loop

try this SUB
Code:
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
Reply With Quote
  #14  
Old 07-05-2009, 10:46 AM
matrex matrex is offline
Registered User
 
Join Date: 07 Jun 2008
Posts: 74
matrex is becoming part of the community
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
Reply With Quote
  #15  
Old 07-05-2009, 11:03 AM
tigertiger tigertiger is offline
Forum Contributor
 
Join Date: 11 Nov 2008
Location: The Earth
Posts: 194
tigertiger has been very helpful
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 With Quote


Reply

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off

Forum Jump