+ Reply to Thread
Results 1 to 13 of 13

Efficiency issue when looping through each cell

Hybrid View

221080 Efficiency issue when looping... 07-30-2010, 07:30 AM
royUK Re: Efficiency issue when... 07-30-2010, 08:17 AM
221080 Re: Efficiency issue when... 07-30-2010, 10:32 AM
shg Re: Efficiency issue when... 07-30-2010, 12:19 PM
221080 Re: Efficiency issue when... 07-30-2010, 12:30 PM
221080 Re: Efficiency issue when... 07-30-2010, 07:02 PM
royUK Re: Efficiency issue when... 07-30-2010, 01:21 PM
221080 Re: Efficiency issue when... 07-31-2010, 11:33 AM
shg Re: Efficiency issue when... 07-31-2010, 11:36 AM
221080 Re: Efficiency issue when... 07-31-2010, 11:40 AM
shg Re: Efficiency issue when... 07-31-2010, 11:42 AM
221080 Re: Efficiency issue when... 07-31-2010, 11:50 AM
221080 Re: Efficiency issue when... 08-01-2010, 11:50 AM
  1. #1
    Registered User
    Join Date
    07-30-2010
    Location
    CPH
    MS-Off Ver
    Excel 2003
    Posts
    9

    Efficiency issue when looping through each cell

    I have a workbook with weekly data for a whole year (100.000+ records per week) that I need to compare to another workbook with 100.000 records and look for overlapping periods.
    Each record in the weekly sheet needs to be marked as checked when the comparison has been performed and if there is an overlapping period that needs to be marked as well and the record copied to a whole other sheet.

    I have done this by looping through each week checking every new record against the 100.000 records (via find), but this is quite time consuming, so I am wondering if this can’t be done more efficiently. Maybe by using matrixes?

    Any help is greatly appreciated.


    Sub New_Records_Check()
    
    Application.Calculation = xlCalculationManual
    Application.ScreenUpdating = False
    
    
    
    Dim sht As Worksheet
    Dim yr As Integer
    Dim wk As Integer
    Dim monday As Date
    
    Dim oldrecs As Long
    Dim totalrecs As Long
    
    Dim Rx As Long
    Dim Ry As Long
        
    Dim startcell As String
    Dim endcell As String
    Dim FoundNum As Range
    Dim NewNum As Variant
    
    Dim lastrow As Long
    
        
    'Loop through all the sheets
    For Each sht In Workbooks("ARCHIVE.xlsx").Sheets
    
    sht.Activate
    
    'Date of monday in the week
    yr = Mid(sht.Name, 1, 4)
    wk = Mid(sht.Name, 5, 2)
    monday = WeekStart(wk, yr) ‘calls a function that determines the date
    
    
    With Workbooks("ARCHIVE.xlsx")
    ' number of old and new records
    oldrecs = Range(Cells(1, 20), Cells(1, 20).End(xlDown)).Rows.Count
    totalrecs = Range(Cells(1, 1), Cells(1, 1).End(xlDown)).Rows.Count
    End With
    
    If oldrecs = totalrecs Then
    'sheet is either empty or has no new records
    Else
    
    'check if there is only new records on the sheet
    With Workbooks("ARCHIVE.xlsx")
    If Cells(2, 20) = "Check" Then
    Rx = oldrecs + 1
    Else
    Rx = 2
    End If
    
    End With
    
    'Range in the control registry
    startcell = Workbooks("Cal.xlsm").Sheets("control”).Cells(1, 3).Address
    endcell = Workbooks("Cal.xlsm").Sheets("control").Cells(1, 3).End(xlDown).Address
    
    
    
    For Ry = Rx To totalrecs Step 1
    
        
        
        With Workbooks("ARKIV.xlsx")
        NewNum = Cells(Ry, 6)
        End With
    
        
        Do
        
    
        Set FoundNum = Workbooks("Cal.xlsm").Sheets("control”).Range(startcell, endcell).Find(What:= NewNum)
    
    
        If FoundNum Is Nothing Then
        Exit Do
        Else
        
        If monday >= FoundNum.Offset(0, 4) And monday <= FoundNum.Offset(0, 5) Then
        'Check to see if the Monday is between a starting and finishing date
        'ifso: mark and copy
        
        Cells(Ry, 21) = "i"
        
        lastrow = Workbooks("Cal.xlsm").Sheets("Records").UsedRange.Rows.Count
            
        Rows(Ry).Copy Destination:= Workbooks("Cal.xlsm").Sheets("Records").Rows(lastrow + 1)
            
        Exit Do
        Else
        End If
        End If
        
        startcell = FoundNum.Offset(1, 0).Address
        Loop Until FoundNum Is Nothing Or FoundNum.Address = endcell
    
    'Check the record
    Cells(Ry, 20) = "Check"
    
    Next Ry
    
    
    
    
    
    End If
    Next sht
    
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    
    
    End Sub
    Last edited by 221080; 07-31-2010 at 12:06 PM. Reason: Correct an error with a variable name in the code

  2. #2
    Forum Expert royUK's Avatar
    Join Date
    11-18-2003
    Location
    Derbyshire,UK
    MS-Off Ver
    Xp; 2007; 2010
    Posts
    26,200

    Re: Efficiency issue when looping through each cell

    Would it be possible to filter the data using AutoFilter?
    Hope that helps.

    RoyUK
    --------
    For Excel Tips & Solutions, free examples and tutorials why not check out my web site

    Free DataBaseForm example

  3. #3
    Registered User
    Join Date
    07-30-2010
    Location
    CPH
    MS-Off Ver
    Excel 2003
    Posts
    9

    Re: Efficiency issue when looping through each cell

    Quote Originally Posted by royUK View Post
    Would it be possible to filter the data using AutoFilter?
    Possibly, but I do not see an immediate gain from doing that. What are you thinking?

  4. #4
    Forum Expert shg's Avatar
    Join Date
    06-20-2007
    Location
    The Great State of Texas
    MS-Off Ver
    2010, 2019
    Posts
    40,689

    Re: Efficiency issue when looping through each cell

    I think someone would need to see a reasonable amount of (sanitized) data to make a useful suggestion.

    Throughout your code, you do this:
            With Workbooks("ARCHIVE.xlsx")
                ' number of old and new records
                oldrecs = Range(Cells(1, 20), Cells(1, 20).End(xlDown)).Rows.Count
                totalrecs = Range(Cells(1, 1), Cells(1, 1).End(xlDown)).Rows.Count
            End With
    The With statement isn't doing anything. References should be like this:
            With Workbooks("ARCHIVE.xlsx").Worksheets("sheet name")
                ' number of old and new records
                oldrecs = .Range(.Cells(1, 20), .Cells(1, 20).End(xlDown)).Rows.Count
                ...
            End With
    Entia non sunt multiplicanda sine necessitate

  5. #5
    Registered User
    Join Date
    07-30-2010
    Location
    CPH
    MS-Off Ver
    Excel 2003
    Posts
    9

    Re: Efficiency issue when looping through each cell

    Quote Originally Posted by shg View Post
    I think someone would need to see a reasonable amount of (sanitized) data to make a useful suggestion.
    I will attach sample data as soon as I can, but it is just a list of numbers on the weekly sheets, being compared to another list with numbers and a start and finish date.


    Throughout your code, you do this:
            With Workbooks("ARCHIVE.xlsx")
                ' number of old and new records
                oldrecs = Range(Cells(1, 20), Cells(1, 20).End(xlDown)).Rows.Count
                totalrecs = Range(Cells(1, 1), Cells(1, 1).End(xlDown)).Rows.Count
            End With
    The With statement isn't doing anything. References should be like this:
            With Workbooks("ARCHIVE.xlsx").Worksheets("sheet name")
                ' number of old and new records
                oldrecs = .Range(.Cells(1, 20), .Cells(1, 20).End(xlDown)).Rows.Count
                ...
            End With
    It is indeed sloppy coding.
    The sheet is activated though so the code still determines the ranges, so I do not see this having any real impact on the efficiency.

  6. #6
    Registered User
    Join Date
    07-30-2010
    Location
    CPH
    MS-Off Ver
    Excel 2003
    Posts
    9

    Re: Efficiency issue when looping through each cell

    Quote Originally Posted by shg View Post
    I think someone would need to see a reasonable amount of (sanitized) data to make a useful suggestion.
    I have a small example of how the data in the different sheets look.

    Example of the data on one of the weekly sheets
    Example of data on the control sheet that each of the records on the weekly sheet is checked against.
    Attached Files Attached Files

  7. #7
    Forum Expert royUK's Avatar
    Join Date
    11-18-2003
    Location
    Derbyshire,UK
    MS-Off Ver
    Xp; 2007; 2010
    Posts
    26,200

    Re: Efficiency issue when looping through each cell

    AutoFilter would be much faster than a Loop

  8. #8
    Registered User
    Join Date
    07-30-2010
    Location
    CPH
    MS-Off Ver
    Excel 2003
    Posts
    9

    Re: Efficiency issue when looping through each cell

    Quote Originally Posted by royUK View Post
    AutoFilter would be much faster than a Loop
    Could you elaborate a little on how that could be done in this example?

  9. #9
    Forum Expert shg's Avatar
    Join Date
    06-20-2007
    Location
    The Great State of Texas
    MS-Off Ver
    2010, 2019
    Posts
    40,689

    Re: Efficiency issue when looping through each cell

    The dates in your example don't make much sense.
          ----G----- ----H-----
      1   START DATE END DATE  
      2   6/19/2010  12/31/9999
      3   6/14/2000  7/23/2005 
      4   6/21/2010  12/31/9999
      5   3/1/2008   7/5/2009  
      6   1/1/2009   4/1/2010  
      7   1/2/2009   12/31/9999

  10. #10
    Registered User
    Join Date
    07-30-2010
    Location
    CPH
    MS-Off Ver
    Excel 2003
    Posts
    9

    Re: Efficiency issue when looping through each cell

    It is the version format. mm/dd/yyyy
    12/31/9999 indicates that there is no end date, i.e it is still running as of today.
    Last edited by shg; 07-31-2010 at 11:41 AM. Reason: deleted spurious quote

  11. #11
    Forum Expert shg's Avatar
    Join Date
    06-20-2007
    Location
    The Great State of Texas
    MS-Off Ver
    2010, 2019
    Posts
    40,689

    Re: Efficiency issue when looping through each cell

    What should be the output for the given example, and why?

  12. #12
    Registered User
    Join Date
    07-30-2010
    Location
    CPH
    MS-Off Ver
    Excel 2003
    Posts
    9

    Re: Efficiency issue when looping through each cell

    If the record is on the control sheet and the dates overlap, i.e. the start date is before the monday of the week of the weekly sheet and the end date is after that monday, the record on the weekly sheet is marked as included.

    Cells(Ry, 21) = "i"
    and the record is then copied to a third sheet.

        lastrow = Workbooks("Cal.xlsm").Sheets("Records").UsedRange.Rows.Count
            
        Rows(Ry).Copy Destination:= Workbooks("Cal.xlsm").Sheets("Records").Rows(lastrow + 1)
    To check all the records and move/mark the included ones are the purpose of this piece of code.

  13. #13
    Registered User
    Join Date
    07-30-2010
    Location
    CPH
    MS-Off Ver
    Excel 2003
    Posts
    9

    Re: Efficiency issue when looping through each cell

    It was suggested that the fastest way was to use arrays, which I have implemented below.

    I had to loop through the registry-array as I could not find a (reasonable) way to search it and return the element number.

    So I think what I have now works and it is also a lot faster. However, it is now looping through a 100,000 elements for the registry for every record every week (100,000 records a week), which might not be the most efficient...

    Sub New_Records_Check()
    
    Application.Calculation = xlCalculationManual
    Application.ScreenUpdating = False
    
    
    
    Dim sht As Worksheet
    Dim yr As Integer
    Dim wk As Integer
    Dim monday As Date
    
    Dim oldrecs As Long
    Dim totalrecs As Long
    
    Dim Rx As Long
    Dim Ry As Long
    Dim CPRx As Long
       
    Dim endcell As Long
    
    Dim lastrow As Long
    
    Dim registry() As Variant
    Dim startdate() As Variant
    Dim enddate() As Variant
    
    'Range in the registry
    endcell = Workbooks("Cal.xlsm").Sheets("Reg").UsedRange.Rows.Count
    
    'define the arrays for the registry
    With Workbooks("Cal.xlsm").Sheets("Reg")
    registry = Range(Cells(2, 3), Cells(endcell, 3))
    startdate = Range(Cells(2, 7), Cells(endcell, 7))
    enddate = Range(Cells(2, 8), Cells(endcell, 8))
    
    End With
    
    
    Dim newrecords() As Variant
    
    'Loop through all the sheets
    For Each sht In Workbooks("ARCHIVE.xlsx").Sheets
    
    sht.Activate
    
    'Date of monday in the week
    yr = Mid(sht.Name, 1, 4)
    wk = Mid(sht.Name, 5, 2)
    monday = WeekStart(wk, yr)
    
    
    
    With Workbooks("ARCHIVE.xlsx")
    ' # old and new records
    oldrecs = Range(Cells(1, 20), Cells(1, 20).End(xlDown)).Rows.Count
    totalrecs = Range(Cells(1, 1), Cells(1, 1).End(xlDown)).Rows.Count
    End With
    
    If oldrecs = totalrecs Then
    'empty or no new rec
    Else
    
    'check if only new rec
    With Workbooks("ARCHIVE.xlsx")
    If Cells(2, 20) = "Check" Then
    Rx = oldrecs + 1
    Else
    Rx = 2
    End If
    
    End With
    
    
    
    'define the arrays for the records on the weekly sheet
    newrecords = Range(Cells(Rx, 6), Cells(totalrecs, 6))
    
    For Ry = 1 To UBound(newrecords)
    
    CPRx = 1
    
    
    Do Until CPRx = UBound(registry) + 1
    
    If newrecords(Ry, 1) = registry(CPRx, 1) Then
       
       
       
        If monday >= startdate(CPRx, 1) And monday <= enddate(CPRx, 1) Then
        'included
        'mark and copy
       
        Cells((Ry + Rx - 1), 21) = "i"
       
        lastrow = Workbooks("Cal.xlsm").Sheets("Records").UsedRange.Rows.Count
           
        Rows((Ry + Rx - 1)).Copy Destination:=Workbooks("Cal.xlsm").Sheets("Records").Rows(lastrow + 1)
           
        Exit Do
        Else
        End If
        Else
        End If
       
    CPRx = CPRx + 1
       
        Loop
    
    Next Ry
    
    'Check the records on the sheet
    Range(Cells(Rx, 20), Cells(totalrecs, 20)) = "Check"
    
    Erase newrecords
    
    
    End If
    Next sht
    
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    
    
    End Sub

+ Reply to Thread

Thread Information

Users Browsing this Thread

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

Tags for this Thread

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.6.0 RC 1