Delete Rows based on multiple conditions

hamaraghar

New Member
Joined
May 6, 2010
Messages
8
Office Version
  1. 365
Platform
  1. Windows
  2. MacOS
Hi I have a table with 3 columns - col_id, col_id2&Col_point.
I have sorted the data for col_id2 and then col_id.

col_id2 has same values for multiple lines and within the same values, col_id has unique values with value 1 common across different col_id2 values.

Problem statement.
I want to delete rows based on the value in Col_point column using listed conditions.
1. If for a given value in col_id2, the corresponding col_point for all the same col_id2 is less than 50, then it should delete everyrows having the same col_id2.
2. If for a given value in col_id2, the corresponding col_point for any same col_id2 is more than 50, then it shoud delete all the rows having the same col_id2 except for the rows where the point is more than 50 AND the row with col_id value as 1.

Example. I need to retain the rows marked with green in col_Id and Col_point.
1690957930463.png


How can I accomplish this? I can do it one col_id2 at a time but I have data worth 80K+rows and it will take me forever. Is there a way to get it automated using VBA or online script.

I have added the MiniSheet below

Test.xlsx
ABC
1col_idcol_id2col_point
210000a5a5801f9ead29
320000a5a5801f9ead31
430000a5a5801f9ead25
540000a5a5801f9ead37
650000a5a5801f9ead10
760000a5a5801f9ead19
870000a5a5801f9ead17
980000a5a5801f9ead20
1090000a5a5801f9ead11
11100000a5a5801f9ead19
1210000a5a5804e45e2237
13110000a5a5804e45e23
14120000a5a5804e45e27
15130000a5a5804e45e27
1620000a5a5804e45e236
17140000a5a5804e45e25
1830000a5a5804e45e251
19150000a5a5804e45e23
20160000a5a5804e45e265
2140000a5a5804e45e20
22170000a5a5804e45e26
23180000a5a5804e45e235
24190000a5a5804e45e278
25200000a5a5804e45e24
2650000a5a5804e45e233
27210000a5a5804e45e25
2860000a5a5804e45e227
2970000a5a5804e45e228
3080000a5a5804e45e239
3190000a5a5804e45e21
32220000a5a5804e45e24
33100000a5a5804e45e21
34230000a5a5804e45e231
35240000a5a5804e45e218
36250000a5a5804e45e28
3710000a5a580af402b44
3820000a5a580af402b42
3930000a5a580af402b38
40160000a5a580af402b22
4140000a5a580af402b1
42180000a5a580af402b36
43190000a5a580af402b97
4450000a5a580af402b6
4560000a5a580af402b1
4670000a5a580af402b7
4780000a5a580af402b4
4890000a5a580af402b9
49100000a5a580af402b0
Sheet8
 

Excel Facts

Do you hate GETPIVOTDATA?
Prevent GETPIVOTDATA. Select inside a PivotTable. In the Analyze tab of the ribbon, open the dropown next to Options and turn it off
To use this code:

  1. Open your Excel workbook.
  2. Press "Alt + F11" to open the VBA editor.
  3. Insert a new module (if you don't have one already) by clicking "Insert" from the menu and then "Module."
  4. Paste the provided VBA code into the module.
  5. Close the VBA editor and return to your worksheet.
  6. Run the macro by pressing "Alt + F8," selecting "DeleteRowsBasedOnConditions," and clicking "Run."
This VBA code will go through your data and delete rows based on the conditions you described. Please be cautious and take a backup of your data before running the macro, as it performs deletion operations.


Rich (BB code):
Sub DeleteRowsBasedOnConditions()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim colID2 As Range
    Dim uniqueColID2 As Collection
    Dim i As Long, j As Long
    Dim deleteRows As Boolean
    
    ' Update the sheet name with the actual sheet name where your data is located
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    
    ' Find the last row in column A (col_id2)
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
    ' Set the range for col_id2
    Set colID2 = ws.Range("A2:A" & lastRow)
    
    ' Create a collection to store unique col_id2 values
    Set uniqueColID2 = New Collection
    
    ' Loop through col_id2 to get unique values and apply conditions
    For i = 1 To colID2.Rows.Count
        If Not IsError(colID2.Cells(i, 1).Value) Then
            On Error Resume Next
            uniqueColID2.Add colID2.Cells(i, 1).Value, CStr(colID2.Cells(i, 1).Value)
            On Error GoTo 0
        End If
    Next i
    
    ' Loop through unique col_id2 values and apply conditions
    For j = 1 To uniqueColID2.Count
        deleteRows = True
        For i = 1 To lastRow
            If ws.Cells(i, 1).Value = uniqueColID2(j) Then
                ' Condition 1: Check if any col_point is greater than or equal to 50
                If ws.Cells(i, 3).Value >= 50 Then
                    deleteRows = False
                End If
                ' Condition 2: Check if any col_id is equal to 1 and col_point is greater than or equal to 50
                If ws.Cells(i, 1).Value = 1 And ws.Cells(i, 3).Value >= 50 Then
                    deleteRows = False
                End If
            End If
        Next i
        
        ' Delete the rows based on the conditions
        If deleteRows Then
            For i = lastRow To 1 Step -1
                If ws.Cells(i, 1).Value = uniqueColID2(j) Then
                    ws.Rows(i).Delete
                End If
            Next i
        End If
    Next j
End Sub
 
Upvote 1
To use this code:

  1. Open your Excel workbook.
  2. Press "Alt + F11" to open the VBA editor.
  3. Insert a new module (if you don't have one already) by clicking "Insert" from the menu and then "Module."
  4. Paste the provided VBA code into the module.
  5. Close the VBA editor and return to your worksheet.
  6. Run the macro by pressing "Alt + F8," selecting "DeleteRowsBasedOnConditions," and clicking "Run."
This VBA code will go through your data and delete rows based on the conditions you described. Please be cautious and take a backup of your data before running the macro, as it performs deletion operations.


Rich (BB code):
Sub DeleteRowsBasedOnConditions()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim colID2 As Range
    Dim uniqueColID2 As Collection
    Dim i As Long, j As Long
    Dim deleteRows As Boolean
   
    ' Update the sheet name with the actual sheet name where your data is located
    Set ws = ThisWorkbook.Worksheets("Sheet1")
   
    ' Find the last row in column A (col_id2)
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
   
    ' Set the range for col_id2
    Set colID2 = ws.Range("A2:A" & lastRow)
   
    ' Create a collection to store unique col_id2 values
    Set uniqueColID2 = New Collection
   
    ' Loop through col_id2 to get unique values and apply conditions
    For i = 1 To colID2.Rows.Count
        If Not IsError(colID2.Cells(i, 1).Value) Then
            On Error Resume Next
            uniqueColID2.Add colID2.Cells(i, 1).Value, CStr(colID2.Cells(i, 1).Value)
            On Error GoTo 0
        End If
    Next i
   
    ' Loop through unique col_id2 values and apply conditions
    For j = 1 To uniqueColID2.Count
        deleteRows = True
        For i = 1 To lastRow
            If ws.Cells(i, 1).Value = uniqueColID2(j) Then
                ' Condition 1: Check if any col_point is greater than or equal to 50
                If ws.Cells(i, 3).Value >= 50 Then
                    deleteRows = False
                End If
                ' Condition 2: Check if any col_id is equal to 1 and col_point is greater than or equal to 50
                If ws.Cells(i, 1).Value = 1 And ws.Cells(i, 3).Value >= 50 Then
                    deleteRows = False
                End If
            End If
        Next i
       
        ' Delete the rows based on the conditions
        If deleteRows Then
            For i = lastRow To 1 Step -1
                If ws.Cells(i, 1).Value = uniqueColID2(j) Then
                    ws.Rows(i).Delete
                End If
            Next i
        End If
    Next j
End Sub
Thanks Guna13..

The output that I got is

1690965187192.png


The output that I am looking for is
1690965241315.png


For most part the macro works..
May be I wasn't able to explain the condition properly.

For each set of unique col_id2, there are unique entries in col_id with 1 being in all the unique col_id2.

1. Except for col_id = 1, If any col_point for a given set of unique col_id2 is less than 50, then that row should be deleted.
2. Except for col_id = 1, If any col_point for a given set of unique col_id2 is more than 50, then that row should not be deleted and the row with col_id=1 for that unique col_id2 should not be deleted.
3. If all the col_point for a given unique col_id2 is less than 50, then all the rows for that unique col_id2 should be deleted.
4. If all the col_point for a given unique col_id2 is less than 50, but for col_id = 1; the col_point is more than 50, then col_id =1 row should not be deleted.

Thank you so much for your help.
 
Upvote 0
That does not seem to be the case to me. Here all the col_id2 values are the same but it is not sorted by col_id

View attachment 96431
Thank you Peter for your reponse...

May be I wasn't able to explain the condition properly.

For each set of unique col_id2, there are unique entries in col_id with 1 being in all the unique col_id2.

1. Except for col_id = 1, If any col_point for a given set of unique col_id2 is less than 50, then that row should be deleted.
2. Except for col_id = 1, If any col_point for a given set of unique col_id2 is more than 50, then that row should not be deleted and the row with col_id=1 for that unique col_id2 should not be deleted.
3. If all the col_point for a given unique col_id2 is less than 50, then all the rows for that unique col_id2 should be deleted.
4. If all the col_point for a given unique col_id2 is less than 50, but for col_id = 1; the col_point is more than 50, then col_id =1 row should not be deleted.

Thank you so much for your help.
 
Upvote 0
Thanks Guna13..

The output that I got is

View attachment 96436

The output that I am looking for is
View attachment 96437

For most part the macro works..
May be I wasn't able to explain the condition properly.

For each set of unique col_id2, there are unique entries in col_id with 1 being in all the unique col_id2.

1. Except for col_id = 1, If any col_point for a given set of unique col_id2 is less than 50, then that row should be deleted.
2. Except for col_id = 1, If any col_point for a given set of unique col_id2 is more than 50, then that row should not be deleted and the row with col_id=1 for that unique col_id2 should not be deleted.
3. If all the col_point for a given unique col_id2 is less than 50, then all the rows for that unique col_id2 should be deleted.
4. If all the col_point for a given unique col_id2 is less than 50, but for col_id = 1; the col_point is more than 50, then col_id =1 row should not be deleted.

Thank you so much for your help.
if you ok, please accept and like comments - Thanks .
 
Upvote 0
if you ok, please accept and like comments - Thanks .
Thanks. I have liked the solution but my requirements are still not met.

Thanks for your response and if possible, can you modify the code as per my requirement.

Thanks,
 
Upvote 0
Give this a try with a copy of your workbook. I have assumed column D is empty.

BTW, I suggest that you update your Account details (click your user name at the top right of the forum) so helpers always know what Excel version(s) & platform(s) you are using as the best solution often varies by version. (Don’t forget to scroll down & ‘Save’)

VBA Code:
Sub Del_rws()
  Dim a As Variant, b As Variant
  Dim nc As Long, i As Long, j As Long, k As Long, fr As Long, r As Long
 
  a = Range("A1", Range("C" & Rows.Count).End(xlUp).Offset(1)).Value
  ReDim b(1 To UBound(a), 1 To 1)
  nc = 4
  i = 2
  
  Do
    If a(i, 2) <> a(i - 1, 2) Then
      j = 0
      r = 0
    End If
    If a(i, 1) = 1 Then fr = i
    Do
      If a(i + j, 1) <> 1 And a(i + j, 3) < 50 Then
        b(i + j, 1) = 1
        k = k + 1
        r = r + 1
      End If
      j = j + 1
    Loop Until a(i + j, 2) <> a(i, 2) Or i + j >= UBound(a)
    If r = j - 1 Then
      b(fr, 1) = 1
      k = k + 1
    End If
      i = i + j
      j = 0
  Loop Until i >= UBound(a)
    
  If k > 0 Then
    Application.ScreenUpdating = False
    With Range("A1").Resize(UBound(a), nc)
      .Columns(nc).Value = b
      .Sort Key1:=.Columns(nc), Order1:=xlAscending, Header:=xlYes
      .Offset(1).Resize(k).EntireRow.Delete
    End With
    Application.ScreenUpdating = True
  End If
End Sub
 
Upvote 1
Give this a try with a copy of your workbook. I have assumed column D is empty.

BTW, I suggest that you update your Account details (click your user name at the top right of the forum) so helpers always know what Excel version(s) & platform(s) you are using as the best solution often varies by version. (Don’t forget to scroll down & ‘Save’)

VBA Code:
Sub Del_rws()
  Dim a As Variant, b As Variant
  Dim nc As Long, i As Long, j As Long, k As Long, fr As Long, r As Long
 
  a = Range("A1", Range("C" & Rows.Count).End(xlUp).Offset(1)).Value
  ReDim b(1 To UBound(a), 1 To 1)
  nc = 4
  i = 2
 
  Do
    If a(i, 2) <> a(i - 1, 2) Then
      j = 0
      r = 0
    End If
    If a(i, 1) = 1 Then fr = i
    Do
      If a(i + j, 1) <> 1 And a(i + j, 3) < 50 Then
        b(i + j, 1) = 1
        k = k + 1
        r = r + 1
      End If
      j = j + 1
    Loop Until a(i + j, 2) <> a(i, 2) Or i + j >= UBound(a)
    If r = j - 1 Then
      b(fr, 1) = 1
      k = k + 1
    End If
      i = i + j
      j = 0
  Loop Until i >= UBound(a)
   
  If k > 0 Then
    Application.ScreenUpdating = False
    With Range("A1").Resize(UBound(a), nc)
      .Columns(nc).Value = b
      .Sort Key1:=.Columns(nc), Order1:=xlAscending, Header:=xlYes
      .Offset(1).Resize(k).EntireRow.Delete
    End With
    Application.ScreenUpdating = True
  End If
End Sub
Thanks Peter.
When I run macro with your code, I'm getting an error @ .Sort Key1:=.Columns(nc), Order1:=xlAscending, Header:=xlYes
The error is Run time error '1004'. Sort method of range class failed. When I click on End on the popup. The error box dissappears and i get the 1s and blanks in the 4th column which are correct.
IS there a way to get rid of the error so that I dont have to click on the End or Debug
 
Upvote 0
Thanks Peter.
When I run macro with your code, I'm getting an error @ .Sort Key1:=.Columns(nc), Order1:=xlAscending, Header:=xlYes
The error is Run time error '1004'. Sort method of range class failed. When I click on End on the popup. The error box dissappears and i get the 1s and blanks in the 4th column which are correct.
IS there a way to get rid of the error so that I dont have to click on the End or Debug
When I add some unique values in column 2 which are not repeatative, I am not getting the blanks for values more than 50 in column 4. Until the colored data set the code works with the error that I mentioned above but with the new data which I added below that with, I'm gettting 1s for everything. if there is a single entry in column2, then if column 3 is less than 50, it should be marked for deletion irrespective of what is in column 1. My apologies as I missed this one more condition as I was manully deleting rows for this condition.

Thanks once again Peter

1691004905032.png
 
Upvote 0

Forum statistics

Threads
1,223,885
Messages
6,175,180
Members
452,615
Latest member
bogeys2birdies

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top