Hiding Rows Based on Information in Two Different Columns - excel

I need to be able to hide a row if the numbers in column "c" and in column "d" are zero.
I the below code works but stops after looping through only 4 rows of data. There is nothing different between the data so I don't know why it stops. Can someone please help me? Thank you.
Sub Hide_Row_3()
' Hide_Row_3 Macro
Worksheets("Costs").Activate
Application.ScreenUpdating = False
Dim rCell As Range
For Each rCell In Range("c7:c18, d7:d18")
If rCell = 0 And rCell(xright) = 0 Then
rCell.EntireRow.Hidden = True
Else
rCell.EntireRow.Hidden = False
End If
Next rCell
Application.ScreenUpdating = True
End Sub

For Each rCell In Range("c7:c18")
is enough.
Edit>
The following loop works for me"
For Each rCell In Range("c7:c18")
If rCell = 0 And rCell.Offset(0, 1) = 0 Then
rCell.EntireRow.Hidden = True
Else
rCell.EntireRow.Hidden = False
End If
HTH!

Related

Excel VBA delete row based on cell value [duplicate]

I am running the following code on a spreadsheet:
Do While i <= 100000
If Not Cells(i, 4) = "String" Then
Cells(i, 4).EntireRow.Delete
End If
i = i + 1
Loop
There are plenty of entries with not "String" but they do not get deleted.
When I copy this piece of code to a separate sheet, I even get the error "Excel cannot complete this task with available resources. Choose less data or close other applications."
What am I doing wrong that is making this loop not work?
Note: I can't use autofilter because I need to delete rows based on not meeting a condition.
This is the worst way to delete a row. Reasons
You are deleting the rows in a Loop
Your Cells Object are not qualified
Try this.
Co-incidentally I answered a similar question in the MSDN forum as well. Please See THIS
Try this way (UNTESTED)
In the below code I have hardcoded the last row to 100000 unlike as done in the above link.
Sub Sample()
Dim ws As Worksheet
Dim i As Long
Dim delRange As Range
'~~> Set this to the relevant worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
For i = 1 To 100000
If .Cells(i, 4).Value <> "String" Then
If delRange Is Nothing Then
Set delRange = .Rows(i)
Else
Set delRange = Union(delRange, .Rows(i))
End If
End If
Next i
If Not delRange Is Nothing Then delRange.Delete
End With
End Sub
NOTE: I am assuming that a cell will have values like
String
aaa
bbb
ccc
String
If you have scenarios where the "String" can be in different cases or in between other strings for example
String
aaa
STRING
ccc
dddStringddd
then you will have to take a slightly different approach as shown in that link.
Autofilter code:
Sub QuickCull()
Dim rng1 As Range
Set rng1 = Range([d4], Cells(Rows.Count, "D").End(xlUp))
ActiveSheet.AutoFilterMode = False
With Application
.DisplayAlerts = False
.ScreenUpdating = False
End With
With rng1
.AutoFilter Field:=1, Criteria1:="<>string"
If rng1.SpecialCells(xlCellTypeVisible).Count > 1 Then _
.Offset(1, 0).Resize(rng1.Rows.Count - 1).Rows.Delete
End With
With Application
.DisplayAlerts = True
.ScreenUpdating = True
End With
ActiveSheet.AutoFilterMode = False
End Sub
When you want to delete rows its always better to delete from bottom.
Sub DeleteData()
Dim r As Long
Dim Rng As Range
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With ThisWorkbook.Sheets("sheet1")
Set Rng = .Range(.Range("D1"), .Range("D1").End(xlDown))
For r = Rng.Rows.Count To 1 Step -1
If LCase(Trim(.Cells(r, 4).Value)) <> LCase("string") Then
.Cells(r, 4).EntireRow.Delete
End If
Next
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
This is a basic algorithm mistake.
Imagine your program are on, say, row 10. You delete it. So, row 11 becomes row 10, row 12 becomes 11 and so on. Then you go to row 11, skipping row 10, previous row 11!
This would work:
Do While i <= 100000
If Not Cells(i, 4) = "String" Then
Cells(i, 4).EntireRow.Delete
Else
i = i + 1
End If
Loop

Macro to hide certain rows

Column A will always have the date and time in the pictured format, in 1 minute intervals for a whole month.
My first goal is to hide any rows that have a number less than 50 in column B.
Sub HideRows()
Application.ScreenUpdating = False
Application.Calculation = xlManual
For Each c In Range("B:B")
If c.Value < 50 And c.Value <> "" Then Rows(c.Row).Hidden = True
Next
Application.Calculation = xlAutomatic
Application.ScreenUpdating = True
End Sub
That Macro works.
Then, I would also like to hide any consecutive rows that are between the first row starting with a number higher than 50, and the last row higher than 50.
Essentially, it would give me a start and stop time in column A for the flows over 50 in column B.
I don't know enough about coding to hide the times in-between the start and stop times.
Any help/suggestions are greatly appreciated!
Not the most elegant solution, but try this out
Sub StartEnd()
Dim ws As Worksheet
Dim lRow As Long
Dim rng As Range
Dim c As Range
Dim cnt As Long
Dim cntTotal As Long
Set ws = ActiveSheet 'change sheet here if you want
With ws
lRow = .Cells(.Rows.Count, "A").End(xlUp).Row 'last row
Set rng = .Range("B2:B" & lRow) 'excluding headers
cntTotal = Application.CountIf(rng, ">50") 'total occurences >50
For Each c In rng
If IsNumeric(c.value) And c.value > 50 Then
cnt = cnt + 1
Select Case cnt
Case 1, cntTotal: 'do nothing if first or last occurence
Case Else: .Rows(c.Row).Hidden = True 'else hide row
End Select
Else
.Rows(c.Row).Hidden = True 'hide row if <50
End If
Next
End With
End Sub
Here's one way, just for the main logic you're looking for:
Dim in50Block As Boolean
in50Block = False
For Each c In Range("B2:B10000")
If c.Value < 50 And c.Value <> "" Then
Rows(c.Row).Hidden = True
in50Block = False
Else
If in50Block = True And c.Offset(1, 0).Value >= 50 Then
Rows(c.Row).Hidden = True
Else
in50Block = True
End If
End If
Next

VBA Worksheet_Change how to hide rows that got certain value in it

Guys,
can you help me with my problem.
What I need to do is to make code, that will HIDE entire row, if for example value in B10 will be = 100.
Thanks in advance
Try something like this
If Range("B10").Value = 100 Then
Range("B10").EntireRow.Hidden = True
End If
I think I solved my problem.
Used this (not sure if there is anything unnecessary):
Private Sub Worksheet_Change(ByVal Target As Range)
Dim LastRow As Long, c As Range
Application.ScreenUpdating = False
Application.EnableEvents = False
LastRow = Cells(Cells.Rows.Count, "B").End(xlUp).Row
On Error Resume Next
For Each c In Range("B1:B" & LastRow)
If c.Value = 100 Then
c.EntireRow.Hidden = True
ElseIf c.Value <> 100 Then
c.EntireRow.Hidden = False
End If
Next
On Error GoTo 0
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub

Excel VBA deleting rows based on an if statement (speed up)

I am deleting rows based on the value in column P.
Cells in column P have an if statement: IF(K<10,0,1)
If the value in column P is 0, then the row needs to be deleted.
I am using the following macro which works but takes quite long.
I would like to beable to process about 10000 rows.
It would be much appreciated if I could have some suggestions on speeding up this code.
[I had tried using this if statement: IF(K<10,"",1)
And then deleting rows using SpecialCells(XlCellTypeBlanks) but the the cells are not interpreted as blank , due to the presence of the formula I presume. ]
Sub RemoveBlankRows()
Application.ScreenUpdating = False
'PURPOSE: Deletes any row with 0 cells located inside P
'Reference: www.TheSpreadsheetGuru.com
Dim rng As Range
Dim blankrng As Range
Dim cell As Range
'Store blank cells inside a variable
'On Error GoTo NoBlanksFound
Set rng = Range("P2:P30000") '.SpecialCells(xlCellTypeBlanks)
'On Error GoTo 0
For Each cell In rng
If cell.Value = 0 Then
cell.EntireRow.Delete
'Value = ""
End If
Next
Application.ScreenUpdating = True
End Sub
This looks for 0 and avoids blanks:
Sub RowKiller()
Dim rKill As Range, r As Range, rng As Range
Set rng = Range("P2:P30000")
Set rKill = Nothing
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
For Each r In rng
If r.Value = 0 And r.Value <> "" Then
If rKill Is Nothing Then
Set rKill = r
Else
Set rKill = Union(rKill, r)
End If
End If
Next r
If Not rKill Is Nothing Then rKill.EntireRow.Delete
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub
This is only demo code. Tailor it to meet your needs.

VBa conditional delete loop not working

I am running the following code on a spreadsheet:
Do While i <= 100000
If Not Cells(i, 4) = "String" Then
Cells(i, 4).EntireRow.Delete
End If
i = i + 1
Loop
There are plenty of entries with not "String" but they do not get deleted.
When I copy this piece of code to a separate sheet, I even get the error "Excel cannot complete this task with available resources. Choose less data or close other applications."
What am I doing wrong that is making this loop not work?
Note: I can't use autofilter because I need to delete rows based on not meeting a condition.
This is the worst way to delete a row. Reasons
You are deleting the rows in a Loop
Your Cells Object are not qualified
Try this.
Co-incidentally I answered a similar question in the MSDN forum as well. Please See THIS
Try this way (UNTESTED)
In the below code I have hardcoded the last row to 100000 unlike as done in the above link.
Sub Sample()
Dim ws As Worksheet
Dim i As Long
Dim delRange As Range
'~~> Set this to the relevant worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
For i = 1 To 100000
If .Cells(i, 4).Value <> "String" Then
If delRange Is Nothing Then
Set delRange = .Rows(i)
Else
Set delRange = Union(delRange, .Rows(i))
End If
End If
Next i
If Not delRange Is Nothing Then delRange.Delete
End With
End Sub
NOTE: I am assuming that a cell will have values like
String
aaa
bbb
ccc
String
If you have scenarios where the "String" can be in different cases or in between other strings for example
String
aaa
STRING
ccc
dddStringddd
then you will have to take a slightly different approach as shown in that link.
Autofilter code:
Sub QuickCull()
Dim rng1 As Range
Set rng1 = Range([d4], Cells(Rows.Count, "D").End(xlUp))
ActiveSheet.AutoFilterMode = False
With Application
.DisplayAlerts = False
.ScreenUpdating = False
End With
With rng1
.AutoFilter Field:=1, Criteria1:="<>string"
If rng1.SpecialCells(xlCellTypeVisible).Count > 1 Then _
.Offset(1, 0).Resize(rng1.Rows.Count - 1).Rows.Delete
End With
With Application
.DisplayAlerts = True
.ScreenUpdating = True
End With
ActiveSheet.AutoFilterMode = False
End Sub
When you want to delete rows its always better to delete from bottom.
Sub DeleteData()
Dim r As Long
Dim Rng As Range
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With ThisWorkbook.Sheets("sheet1")
Set Rng = .Range(.Range("D1"), .Range("D1").End(xlDown))
For r = Rng.Rows.Count To 1 Step -1
If LCase(Trim(.Cells(r, 4).Value)) <> LCase("string") Then
.Cells(r, 4).EntireRow.Delete
End If
Next
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
This is a basic algorithm mistake.
Imagine your program are on, say, row 10. You delete it. So, row 11 becomes row 10, row 12 becomes 11 and so on. Then you go to row 11, skipping row 10, previous row 11!
This would work:
Do While i <= 100000
If Not Cells(i, 4) = "String" Then
Cells(i, 4).EntireRow.Delete
Else
i = i + 1
End If
Loop

Resources