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

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

Related

Hiding rows in Sheet 2 based on Sheet 1 change

I have Sheet 1 containing information that are drawn into Sheet 2. Only Sheet 1 will be edited for future updates.
I would like to hide rows within a range in Sheet 2 that are "" or 0, based on Sheet 1 input.
This code (in Sheet 2) currently works for me:
Private Sub Worksheet_Activate()
Application.ScreenUpdating = False
Application.Calculation = xlManual
Dim c As Range
For Each c In Me.Range("P15:P22")
If c.Value = 0 Or c.Value = "" Then
c.EntireRow.Hidden = True
Else
c.EntireRow.Hidden = False
End If
Next c
Application.Calculation = xlAutomatic
Application.ScreenUpdating = True
End Sub
The only issue is that there is an obvious lag in loading the sheet.
To resolve this, I have tried moving the code to Sheet 1 instead:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
Application.Calculation = xlManual
Sheet2.Activate
Dim c As Range
For Each c In Me.Range("P15:P22")
If c.Value = 0 Or c.Value = "" Then
c.EntireRow.Hidden = True
Else
c.EntireRow.Hidden = False
End If
Next c
Sheet1.Activate
Application.Calculation = xlAutomatic
Application.ScreenUpdating = True
End Sub
This edit is not working for me. Upon a change in Sheet 1, the linked cell in Sheet is not updated and the relevant rows are not being hidden.
Could anyone kindly point out if there's an alternative approach to resolve this issue?

Dynamically hiding rows with VBA

I have a spreadsheet which hides all rows except those designated by a date and a named region like so:
'Get week no value...
wk = Range("$B$2").Value
'If value changes...
If Target.Address = "$B$2" Then
'Hide all rows/weeks...
Range("allWeeks").Select
Application.Selection.EntireRow.Hidden = True
'...but show week selected by 'wk'
Range(wk).Select
Application.Selection.EntireRow.Hidden = False
All works great. However. Within each named week I have hidden calculation rows defined by "HC" in column A of the row to be hidden. The display of Range(wk) unhides those hidden rows so I introduce a loop to close all the "HC" hidden columns
Dim x As Integer
For x = 1 To 1500
If Sheet1.Cells(x, 1).Value = "HC" Then
Sheet1.Rows(x).Hidden = True
End If
Next
End Sub
The result is that it kinda works but I have to wait several seconds for the process to complete every time I type into a cell which is making the sheet almost unworkable. Any pointers would be appreciated.
Generally you want to build up a range of rows to hide within the loop and then afterwards hide that range separately. You can build the range to hide using he Union() function like so:
Option Explicit
Sub HideRows()
Dim mainRng As Range
Set mainRng = Range("A2:A" & Range("A" & Rows.count).End(xlUp).Row)
Dim unionRng As Range
Dim i As Long
For i = mainRng.Row To mainRng.Row + mainRng.Rows.count - 1
If Cells(i, 1).Value2 = "HC" Then
If Not unionRng Is Nothing Then
Set unionRng = Union(unionRng, Cells(i, 1))
Else
Set unionRng = Cells(i, 1)
End If
End If
Next i
If Not unionRng Is Nothing Then unionRng.EntireRow.Hidden = True
End Sub
Sometimes when you want to update too many things at once, the UI becomes a bit unresponsive.
I've found that disabling UI updates while doing those changes, speeds things up by an order of magnitude:
Sub XXX()
...
On Error GoTo EH
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Application.StatusBar = "I'm working on it..."
' do lots of changes in cells, rows, sheets...
' Undo the accel changes:
CleanUp:
On Error Resume Next
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
Application.StatusBar = False
Exit Sub
EH:
' Do error handling
MsgBox "Error found: " & Err.Description
GoTo CleanUp
End Sub
See https://learn.microsoft.com/en-us/office/vba/api/excel.application.screenupdating
and Effect of Screen Updating

VBA - Speed of Hiding/Unhiding Row as a Worksheet Event

I'm struggling with the speed at which the following VBA code executes.
The goal of this code is to activate whenever "C4" changes, and then scan column "R" for the value 'Y'. If there's a 'Y', then it hides the row, and if not, it unhides the row. The code works, it's just not speedy - for 500 rows, it can take 30 or more seconds every time I change the value of "C4".
Does anyone have any suggestions to improve the speed at which this code executes? Or another method of accomplishing this?
Thanks for taking a look.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim L As Long
Dim r As Range
L = Cells(Rows.Count, "R").End(xlUp).Row
If Not Intersect(Target, Range("C4")) Is Nothing Then
For Each r In Range("R2:R" & L)
If r.Value = "Y" Then
Rows(r.Row).Hidden = True
Else
Rows(r.Row).Hidden = False
End If
Next
End If
End Sub
In attempting to apply the suggestion below - use Union() - I have come up with the below, not working, code. Any help would be greatly appreciated.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim L As Long
Dim r As Range
Dim RowsToHide As Range
Dim RowsToUnhide As Range
L = Cells(Rows.Count, "R").End(xlUp).Row
If Not Intersect(Target, Range("C4")) Is Nothing Then
For Each r In Range("R2:R" & L)
If r.Value = "Y" Then
RowsToHide = Union(RowsToHide, r.Row)
Else
RowsToUnhide = Union(RowsToUnhide, r.Row)
End If
Next
End If
RowsToHide.Hidden = True
RowsToUnhide.Hidden = False
End Sub
Adding Application.EnableEvents = False at the beginning of the code then turning back to true will help, Also using Applciation.ScreenUpdating = False should help as well.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim L As Long
Dim r As Range
Application.EnableEvents = False
Application.ScreenUpdating = False
L = Cells(Rows.Count, "R").End(xlUp).Row
If Not Intersect(Target, Range("C4")) Is Nothing Then
For Each r In Range("R2:R" & L)
If r.Value = "Y" Then
Rows(r.Row).Hidden = True
Else
Rows(r.Row).Hidden = False
End If
Next
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
There are several techniques that will help speed this up
Writing to .Hidden is much slower than reading it. So check if the row is already hidden or showing before setting Hidden
Collect the rows to Hide or Show into a range (Union) and Hide/Show tehm in one go.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
Dim rngCheck As Range
Dim rngHide As Range, rngShow As Range
Application.ScreenUpdating = False
If Not Intersect(Target, Me.Range("C1")) Is Nothing Then
Set rngCheck = Me.Range(Me.Cells(1, "R"), Me.Cells(Me.Rows.Count, "R").End(xlUp))
For Each r In rngCheck.Cells
If r.Value2 = "Y" Then
If Not r.EntireRow.Hidden Then
If rngHide Is Nothing Then
Set rngHide = r.EntireRow
Else
Set rngHide = Union(rngHide, r.EntireRow)
End If
End If
Else
If r.EntireRow.Hidden Then
If rngShow Is Nothing Then
Set rngShow = r.EntireRow
Else
Set rngShow = Union(rngShow, r.EntireRow)
End If
End If
End If
Next
End If
If Not rngHide Is Nothing Then
rngHide.EntireRow.Hidden = True
End If
If Not rngShow Is Nothing Then
rngShow.EntireRow.Hidden = False
End If
Application.ScreenUpdating = True
End Sub

Hide corresponding rows when cell value = 0

I am trying to automatically hide/unhide corresponding rows when cell value in column E equals 0 (zero). There are formulas in these cells, and these formulas returns zero when a cell in another changes. Upon that change i would like the code to perform its hide/unhide magic.
Help much appreciated.
Here is a faster method using AutoFilter. You can call this code directly or use it in Worksheet_Calculate event. I am assuming the Cell E1 has Headers.
IN A BUTTON
Option Explicit
Sub Sample()
Dim rRange As Range, RngToHide As Range
Dim lRow As Long
'~~> Remove any filters
ActiveSheet.AutoFilterMode = False
With Sheets("Sheet1")
lRow = .Range("E" & Rows.Count).End(xlUp).Row
Set rRange = .Range("E1:E" & lRow)
With rRange
.AutoFilter Field:=1, Criteria1:="0"
Set RngToHide = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
End With
'~~> Remove any filters
ActiveSheet.AutoFilterMode = False
If Not RngToHide Is Nothing Then RngToHide.Hidden = True
End Sub
WORKSHEET CALCULATE EVENT - Not Recommended
I do not recommend calling this code automatically as this will not let you unhide the rows in case you want to change something in the hidden rows. To unhide the rows, you will have to either comment out the entire code in the Worksheet_Calculate event or change the value to a non zero value in the connected cell (provided the connected cell in not in the hidden row).
This will hide the row when the value in Col E changes to 0
Option Explicit
Private Sub Worksheet_Calculate()
Dim rRange As Range, RngToHide As Range
Dim lRow As Long
On Error GoTo Whoa
Application.ScreenUpdating = False
Application.EnableEvents = False
'~~> Remove any filters
ActiveSheet.AutoFilterMode = False
With Sheets("Sheet1")
lRow = .Range("E" & Rows.Count).End(xlUp).Row
Set rRange = .Range("E1:E" & lRow)
With rRange
.AutoFilter Field:=1, Criteria1:="0"
Set RngToHide = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
End With
'~~> Remove any filters
ActiveSheet.AutoFilterMode = False
If Not RngToHide Is Nothing Then RngToHide.Hidden = True
LetsContinue:
Application.ScreenUpdating = True
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
Use this mhetod:
Sub HideRows()
Dim i As Integer
i = 1
Do While Not Cells(i, 5) = ""
If Cells(i, 5).Value = 0 Then
Rows(CStr(i) + ":" + CStr(i)).EntireRow.Hidden = True
ElseIf Cells(i, 5).Value <> 0 And Rows(CStr(i) + ":" + CStr(i)).EntireRow.Hidden = True Then
Rows(CStr(i) + ":" + CStr(i)).EntireRow.Hidden = False
End If
i = i + 1
Loop
End Sub
You can add a button and invoke this method by Button_Click event or add next method to necessary Sheet in Microsoft Excel Objects
Private Sub Worksheet_Change()
Module1.HideRows
End Sub
This method will invoke HideRow method when some cell changed.

Hiding Rows Based on Information in Two Different Columns

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!

Resources