Code deletes unique entity that reports data later than 4 quarters, runs too slow

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
2
down vote

favorite












I have a worksheet which is filled with data from Column A to G. Each row is a unique entity and Column G represents how long ago (in quarters) the data was reported. The purpose of the code is to check if the value is more than 4 (that means the reported date was more than 4 quarters from today), and if so, the code would delete that particular row.



Currently my code takes about 3 minutes to run, and I was wondering if there's anything else that I could do/restructure my code for it to run faster.



I have about 5000++ rows as of now.



Sub Two_Keep3Quarters()
Dim Firstrow As Long
Dim Lastrow As Long
Dim lRow As Long
Dim Tbl As ListObject
Dim rng As Range
Dim QuarterValue As Long

With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With

With Sheets("Filtered Data")
.DisplayPageBreaks = False

'Set the first and last row to loop through
Firstrow = 3
Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row

'We loop from Lastrow to Firstrow (bottom to top)
For lRow = Lastrow To Firstrow Step -1

QuarterValue = .Range("G" & lRow).Value

'We check the values in the Column G
With .Cells(lRow, "G")

If Not IsError(QuarterValue) Then

If QuarterValue > 4 Then .EntireRow.Delete
'This will delete each row with value of more than 4 quarters

End If

End With

Next lRow

End With

Range("F1").Value = "Quarters"
Range("G1").Value = "No. of Quarters"

On Error Resume Next
Set rng = Range(Range("A1"), Range("G1").End(xlDown)).SpecialCells(xlCellTypeBlanks)
rng.Rows.Delete Shift:=xlShiftUp

For Each Tbl In Sheets("Filtered Data").ListObjects
Tbl.Unlist

Next

Set Tbl = ActiveSheet.ListObjects.Add(xlSrcRange, Range(Range("A1"), Range("G1").End(xlDown)), , xlYes)

With Tbl
.Name = "DataTable"
.TableStyle = "TableStyleLight10"
End With

Application.ScreenUpdating = True

End Sub






share|improve this question





















  • Applying Tim Williams answer to Excel VBA to delete rows — how to make this quicker? should get the job done in under 20 seconds. Transferring all the data to an array, deleting all the rows and then writing the array back to the table will do the job in under 2 seconds.
    – user109261
    Jan 18 at 8:37










  • This question is being discussed on meta
    – Mast
    Jan 19 at 11:43
















up vote
2
down vote

favorite












I have a worksheet which is filled with data from Column A to G. Each row is a unique entity and Column G represents how long ago (in quarters) the data was reported. The purpose of the code is to check if the value is more than 4 (that means the reported date was more than 4 quarters from today), and if so, the code would delete that particular row.



Currently my code takes about 3 minutes to run, and I was wondering if there's anything else that I could do/restructure my code for it to run faster.



I have about 5000++ rows as of now.



Sub Two_Keep3Quarters()
Dim Firstrow As Long
Dim Lastrow As Long
Dim lRow As Long
Dim Tbl As ListObject
Dim rng As Range
Dim QuarterValue As Long

With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With

With Sheets("Filtered Data")
.DisplayPageBreaks = False

'Set the first and last row to loop through
Firstrow = 3
Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row

'We loop from Lastrow to Firstrow (bottom to top)
For lRow = Lastrow To Firstrow Step -1

QuarterValue = .Range("G" & lRow).Value

'We check the values in the Column G
With .Cells(lRow, "G")

If Not IsError(QuarterValue) Then

If QuarterValue > 4 Then .EntireRow.Delete
'This will delete each row with value of more than 4 quarters

End If

End With

Next lRow

End With

Range("F1").Value = "Quarters"
Range("G1").Value = "No. of Quarters"

On Error Resume Next
Set rng = Range(Range("A1"), Range("G1").End(xlDown)).SpecialCells(xlCellTypeBlanks)
rng.Rows.Delete Shift:=xlShiftUp

For Each Tbl In Sheets("Filtered Data").ListObjects
Tbl.Unlist

Next

Set Tbl = ActiveSheet.ListObjects.Add(xlSrcRange, Range(Range("A1"), Range("G1").End(xlDown)), , xlYes)

With Tbl
.Name = "DataTable"
.TableStyle = "TableStyleLight10"
End With

Application.ScreenUpdating = True

End Sub






share|improve this question





















  • Applying Tim Williams answer to Excel VBA to delete rows — how to make this quicker? should get the job done in under 20 seconds. Transferring all the data to an array, deleting all the rows and then writing the array back to the table will do the job in under 2 seconds.
    – user109261
    Jan 18 at 8:37










  • This question is being discussed on meta
    – Mast
    Jan 19 at 11:43












up vote
2
down vote

favorite









up vote
2
down vote

favorite











I have a worksheet which is filled with data from Column A to G. Each row is a unique entity and Column G represents how long ago (in quarters) the data was reported. The purpose of the code is to check if the value is more than 4 (that means the reported date was more than 4 quarters from today), and if so, the code would delete that particular row.



Currently my code takes about 3 minutes to run, and I was wondering if there's anything else that I could do/restructure my code for it to run faster.



I have about 5000++ rows as of now.



Sub Two_Keep3Quarters()
Dim Firstrow As Long
Dim Lastrow As Long
Dim lRow As Long
Dim Tbl As ListObject
Dim rng As Range
Dim QuarterValue As Long

With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With

With Sheets("Filtered Data")
.DisplayPageBreaks = False

'Set the first and last row to loop through
Firstrow = 3
Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row

'We loop from Lastrow to Firstrow (bottom to top)
For lRow = Lastrow To Firstrow Step -1

QuarterValue = .Range("G" & lRow).Value

'We check the values in the Column G
With .Cells(lRow, "G")

If Not IsError(QuarterValue) Then

If QuarterValue > 4 Then .EntireRow.Delete
'This will delete each row with value of more than 4 quarters

End If

End With

Next lRow

End With

Range("F1").Value = "Quarters"
Range("G1").Value = "No. of Quarters"

On Error Resume Next
Set rng = Range(Range("A1"), Range("G1").End(xlDown)).SpecialCells(xlCellTypeBlanks)
rng.Rows.Delete Shift:=xlShiftUp

For Each Tbl In Sheets("Filtered Data").ListObjects
Tbl.Unlist

Next

Set Tbl = ActiveSheet.ListObjects.Add(xlSrcRange, Range(Range("A1"), Range("G1").End(xlDown)), , xlYes)

With Tbl
.Name = "DataTable"
.TableStyle = "TableStyleLight10"
End With

Application.ScreenUpdating = True

End Sub






share|improve this question













I have a worksheet which is filled with data from Column A to G. Each row is a unique entity and Column G represents how long ago (in quarters) the data was reported. The purpose of the code is to check if the value is more than 4 (that means the reported date was more than 4 quarters from today), and if so, the code would delete that particular row.



Currently my code takes about 3 minutes to run, and I was wondering if there's anything else that I could do/restructure my code for it to run faster.



I have about 5000++ rows as of now.



Sub Two_Keep3Quarters()
Dim Firstrow As Long
Dim Lastrow As Long
Dim lRow As Long
Dim Tbl As ListObject
Dim rng As Range
Dim QuarterValue As Long

With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With

With Sheets("Filtered Data")
.DisplayPageBreaks = False

'Set the first and last row to loop through
Firstrow = 3
Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row

'We loop from Lastrow to Firstrow (bottom to top)
For lRow = Lastrow To Firstrow Step -1

QuarterValue = .Range("G" & lRow).Value

'We check the values in the Column G
With .Cells(lRow, "G")

If Not IsError(QuarterValue) Then

If QuarterValue > 4 Then .EntireRow.Delete
'This will delete each row with value of more than 4 quarters

End If

End With

Next lRow

End With

Range("F1").Value = "Quarters"
Range("G1").Value = "No. of Quarters"

On Error Resume Next
Set rng = Range(Range("A1"), Range("G1").End(xlDown)).SpecialCells(xlCellTypeBlanks)
rng.Rows.Delete Shift:=xlShiftUp

For Each Tbl In Sheets("Filtered Data").ListObjects
Tbl.Unlist

Next

Set Tbl = ActiveSheet.ListObjects.Add(xlSrcRange, Range(Range("A1"), Range("G1").End(xlDown)), , xlYes)

With Tbl
.Name = "DataTable"
.TableStyle = "TableStyleLight10"
End With

Application.ScreenUpdating = True

End Sub








share|improve this question












share|improve this question




share|improve this question








edited Jan 22 at 14:29









Snowbody

7,7371343




7,7371343









asked Jan 18 at 8:17









Ben

111




111











  • Applying Tim Williams answer to Excel VBA to delete rows — how to make this quicker? should get the job done in under 20 seconds. Transferring all the data to an array, deleting all the rows and then writing the array back to the table will do the job in under 2 seconds.
    – user109261
    Jan 18 at 8:37










  • This question is being discussed on meta
    – Mast
    Jan 19 at 11:43
















  • Applying Tim Williams answer to Excel VBA to delete rows — how to make this quicker? should get the job done in under 20 seconds. Transferring all the data to an array, deleting all the rows and then writing the array back to the table will do the job in under 2 seconds.
    – user109261
    Jan 18 at 8:37










  • This question is being discussed on meta
    – Mast
    Jan 19 at 11:43















Applying Tim Williams answer to Excel VBA to delete rows — how to make this quicker? should get the job done in under 20 seconds. Transferring all the data to an array, deleting all the rows and then writing the array back to the table will do the job in under 2 seconds.
– user109261
Jan 18 at 8:37




Applying Tim Williams answer to Excel VBA to delete rows — how to make this quicker? should get the job done in under 20 seconds. Transferring all the data to an array, deleting all the rows and then writing the array back to the table will do the job in under 2 seconds.
– user109261
Jan 18 at 8:37












This question is being discussed on meta
– Mast
Jan 19 at 11:43




This question is being discussed on meta
– Mast
Jan 19 at 11:43










1 Answer
1






active

oldest

votes

















up vote
1
down vote













This uses an AutoFilter and performs the delete operation once (it should take less than a sec)




Option Explicit

Public Sub Two_Keep3Quarters()
Const WS_NAME = "Filtered Data"

Dim ws As Worksheet, tbl As ListObject, tblUR As Range, t As Double

t = Timer
Set ws = ThisWorkbook.Worksheets(WS_NAME)
Set tbl = ws.ListObjects("DataTable")
Set tblUR = tbl.Range.Offset(2).Resize(tbl.ListRows.Count - 1)

Application.DisplayAlerts = False
With tbl.Range
tblUR.AutoFilter Field:=7, Criteria1:=">4", Operator:=xlAnd
.Rows("1:2").Hidden = True

On Error Resume Next 'For empty filter
tblUR.SpecialCells(xlCellTypeVisible).EntireRow.Delete
On Error GoTo 0

.AutoFilter
.Rows.EntireRow.Hidden = False
.Cells(1).Activate
End With
Application.DisplayAlerts = True
Debug.Print "Time: " & Format(Timer - t, "0.000") & " sec"
End Sub



Some issues with your code:



  • Missing Option Explicit

  • The Sub should be declared Public explicitly

  • Naming conventions: what's the difference between Lastrow and lRow

    • All variable names should start with a lower case letter


  • You turn Calculation to xlCalculationManual but don't change it back at the end

  • Some ranges are not fully qualified (bellow Range("F1"))

    • When you know the worksheet used you shouldn't qualify ranges with ActiveSheet


  • You're performing an extra rng.Rows.Delete which is unneeded

    • When deleting rows make sure you use EntireRow - it's faster


  • Tables (ListObjects) are dynamic so there is no need to Unlist and resize them

  • Inconsistent indentation (at the end)





share|improve this answer





















    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185377%2fcode-deletes-unique-entity-that-reports-data-later-than-4-quarters-runs-too-slo%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote













    This uses an AutoFilter and performs the delete operation once (it should take less than a sec)




    Option Explicit

    Public Sub Two_Keep3Quarters()
    Const WS_NAME = "Filtered Data"

    Dim ws As Worksheet, tbl As ListObject, tblUR As Range, t As Double

    t = Timer
    Set ws = ThisWorkbook.Worksheets(WS_NAME)
    Set tbl = ws.ListObjects("DataTable")
    Set tblUR = tbl.Range.Offset(2).Resize(tbl.ListRows.Count - 1)

    Application.DisplayAlerts = False
    With tbl.Range
    tblUR.AutoFilter Field:=7, Criteria1:=">4", Operator:=xlAnd
    .Rows("1:2").Hidden = True

    On Error Resume Next 'For empty filter
    tblUR.SpecialCells(xlCellTypeVisible).EntireRow.Delete
    On Error GoTo 0

    .AutoFilter
    .Rows.EntireRow.Hidden = False
    .Cells(1).Activate
    End With
    Application.DisplayAlerts = True
    Debug.Print "Time: " & Format(Timer - t, "0.000") & " sec"
    End Sub



    Some issues with your code:



    • Missing Option Explicit

    • The Sub should be declared Public explicitly

    • Naming conventions: what's the difference between Lastrow and lRow

      • All variable names should start with a lower case letter


    • You turn Calculation to xlCalculationManual but don't change it back at the end

    • Some ranges are not fully qualified (bellow Range("F1"))

      • When you know the worksheet used you shouldn't qualify ranges with ActiveSheet


    • You're performing an extra rng.Rows.Delete which is unneeded

      • When deleting rows make sure you use EntireRow - it's faster


    • Tables (ListObjects) are dynamic so there is no need to Unlist and resize them

    • Inconsistent indentation (at the end)





    share|improve this answer

























      up vote
      1
      down vote













      This uses an AutoFilter and performs the delete operation once (it should take less than a sec)




      Option Explicit

      Public Sub Two_Keep3Quarters()
      Const WS_NAME = "Filtered Data"

      Dim ws As Worksheet, tbl As ListObject, tblUR As Range, t As Double

      t = Timer
      Set ws = ThisWorkbook.Worksheets(WS_NAME)
      Set tbl = ws.ListObjects("DataTable")
      Set tblUR = tbl.Range.Offset(2).Resize(tbl.ListRows.Count - 1)

      Application.DisplayAlerts = False
      With tbl.Range
      tblUR.AutoFilter Field:=7, Criteria1:=">4", Operator:=xlAnd
      .Rows("1:2").Hidden = True

      On Error Resume Next 'For empty filter
      tblUR.SpecialCells(xlCellTypeVisible).EntireRow.Delete
      On Error GoTo 0

      .AutoFilter
      .Rows.EntireRow.Hidden = False
      .Cells(1).Activate
      End With
      Application.DisplayAlerts = True
      Debug.Print "Time: " & Format(Timer - t, "0.000") & " sec"
      End Sub



      Some issues with your code:



      • Missing Option Explicit

      • The Sub should be declared Public explicitly

      • Naming conventions: what's the difference between Lastrow and lRow

        • All variable names should start with a lower case letter


      • You turn Calculation to xlCalculationManual but don't change it back at the end

      • Some ranges are not fully qualified (bellow Range("F1"))

        • When you know the worksheet used you shouldn't qualify ranges with ActiveSheet


      • You're performing an extra rng.Rows.Delete which is unneeded

        • When deleting rows make sure you use EntireRow - it's faster


      • Tables (ListObjects) are dynamic so there is no need to Unlist and resize them

      • Inconsistent indentation (at the end)





      share|improve this answer























        up vote
        1
        down vote










        up vote
        1
        down vote









        This uses an AutoFilter and performs the delete operation once (it should take less than a sec)




        Option Explicit

        Public Sub Two_Keep3Quarters()
        Const WS_NAME = "Filtered Data"

        Dim ws As Worksheet, tbl As ListObject, tblUR As Range, t As Double

        t = Timer
        Set ws = ThisWorkbook.Worksheets(WS_NAME)
        Set tbl = ws.ListObjects("DataTable")
        Set tblUR = tbl.Range.Offset(2).Resize(tbl.ListRows.Count - 1)

        Application.DisplayAlerts = False
        With tbl.Range
        tblUR.AutoFilter Field:=7, Criteria1:=">4", Operator:=xlAnd
        .Rows("1:2").Hidden = True

        On Error Resume Next 'For empty filter
        tblUR.SpecialCells(xlCellTypeVisible).EntireRow.Delete
        On Error GoTo 0

        .AutoFilter
        .Rows.EntireRow.Hidden = False
        .Cells(1).Activate
        End With
        Application.DisplayAlerts = True
        Debug.Print "Time: " & Format(Timer - t, "0.000") & " sec"
        End Sub



        Some issues with your code:



        • Missing Option Explicit

        • The Sub should be declared Public explicitly

        • Naming conventions: what's the difference between Lastrow and lRow

          • All variable names should start with a lower case letter


        • You turn Calculation to xlCalculationManual but don't change it back at the end

        • Some ranges are not fully qualified (bellow Range("F1"))

          • When you know the worksheet used you shouldn't qualify ranges with ActiveSheet


        • You're performing an extra rng.Rows.Delete which is unneeded

          • When deleting rows make sure you use EntireRow - it's faster


        • Tables (ListObjects) are dynamic so there is no need to Unlist and resize them

        • Inconsistent indentation (at the end)





        share|improve this answer













        This uses an AutoFilter and performs the delete operation once (it should take less than a sec)




        Option Explicit

        Public Sub Two_Keep3Quarters()
        Const WS_NAME = "Filtered Data"

        Dim ws As Worksheet, tbl As ListObject, tblUR As Range, t As Double

        t = Timer
        Set ws = ThisWorkbook.Worksheets(WS_NAME)
        Set tbl = ws.ListObjects("DataTable")
        Set tblUR = tbl.Range.Offset(2).Resize(tbl.ListRows.Count - 1)

        Application.DisplayAlerts = False
        With tbl.Range
        tblUR.AutoFilter Field:=7, Criteria1:=">4", Operator:=xlAnd
        .Rows("1:2").Hidden = True

        On Error Resume Next 'For empty filter
        tblUR.SpecialCells(xlCellTypeVisible).EntireRow.Delete
        On Error GoTo 0

        .AutoFilter
        .Rows.EntireRow.Hidden = False
        .Cells(1).Activate
        End With
        Application.DisplayAlerts = True
        Debug.Print "Time: " & Format(Timer - t, "0.000") & " sec"
        End Sub



        Some issues with your code:



        • Missing Option Explicit

        • The Sub should be declared Public explicitly

        • Naming conventions: what's the difference between Lastrow and lRow

          • All variable names should start with a lower case letter


        • You turn Calculation to xlCalculationManual but don't change it back at the end

        • Some ranges are not fully qualified (bellow Range("F1"))

          • When you know the worksheet used you shouldn't qualify ranges with ActiveSheet


        • You're performing an extra rng.Rows.Delete which is unneeded

          • When deleting rows make sure you use EntireRow - it's faster


        • Tables (ListObjects) are dynamic so there is no need to Unlist and resize them

        • Inconsistent indentation (at the end)






        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered Jan 18 at 13:20









        paul bica

        1,059613




        1,059613






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185377%2fcode-deletes-unique-entity-that-reports-data-later-than-4-quarters-runs-too-slo%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Python Lists

            Aion

            JavaScript Array Iteration Methods