Hide corresponding rows when cell value = 0 - excel

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.

Related

Color Excel rows based on text cells

I'm trying to color rows of data based on some key terms in column A.
Some rows need to be green and some rows need to be red.
I found this online but when I run it nothing happens on the sheet. I don't really know why or how to fix it. This is the version from my excel sheet, so it has all my info in it.
Public Sub ColorCHange2()
Dim mapping As Object, itm As Variant
Set mapping = CreateObject("Scripting.Dictionary")
mapping(XlRgbColor.rgbLightPink) = Array("exclude from emails","exclude from listings")
mapping(XlRgbColor.rgbLightGreen) = Array("include in billing list","include in emails")
Application.ScreenUpdating = False
Sheet1.AutoFilterMode = False
With Sheet1.UsedRange
.Interior.ColorIndex = xlColorIndexNone
For Each itm In mapping
.AutoFilter Field:=1, Criterial1:=mapping(itm), Operator:=xlFilterValues
.Offset(1).Resize(.Rows.Count - 1, .Columns.Count).Interiror.Color = itm
Next
.AutoFiler
End With
Application.ScreenUpdating = True
End Sub
Fixing your typos and the the fact your code doesn't only color visible cells post-filter...
Public Sub ColorCHange2()
Dim mapping As Object, itm As Variant, rngVis As Range
Set mapping = CreateObject("Scripting.Dictionary")
mapping(XlRgbColor.rgbLightPink) = Array("exclude from emails", "exclude from listings")
mapping(XlRgbColor.rgbLightGreen) = Array("include in billing list", "include in emails")
Application.ScreenUpdating = False
Sheet1.AutoFilterMode = False
With Sheet1.UsedRange
.Interior.ColorIndex = xlColorIndexNone
For Each itm In mapping
.AutoFilter Field:=1, Criteria1:=mapping(itm), Operator:=xlFilterValues
Set rngVis = Nothing
On Error Resume Next
Set rngVis = .Offset(1).Resize(.Rows.Count - 1, .Columns.Count).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If Not rngVis Is Nothing Then rngVis.Interior.Color = itm
Next
.AutoFilter
End With
Application.ScreenUpdating = True
End Sub

Creating DropDown by ComboBox1 and Filter the Desired Column

I have been using a sheet where i have created a manual drop down through "Data Validation" and was using this below code to filter the Column.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim lastrow As Long
lastrow = Cells(Rows.Count, "I").End(xlUp).Row
With Me
If Not Intersect(Target, .Range("I13")) Is Nothing Then
If Target.Value <> "" Then
.AutoFilterMode = False
.Range("I15:I" & lastrow).AutoFilter field:=1, Criteria1:=Target.Value
End If
End If
End With
End Sub
But now I'm trying to do an ActiveX program that loads the Unique value in ComboBox1 from given range and Filter column using the Value of the ComboBox1.
Here is the code which gets the unique values.
Problem is that i have tried to merge both codes to make it work for ComboBox1 but couldn't make it.
Dim v, e
With Sheets("Sheet1").Range("I16:I10000")
v = .Value
End With
With CreateObject("scripting.dictionary")
.comparemode = 1
For Each e In v
If Not .exists(e) Then .Add e, Nothing
Next
If .Count Then Sheets("Sheet1").ComboBox1.List = Application.Transpose(.keys)
End With
I want to merge these both codes in one to work. I have tried but failed.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim lastrow As Long
With Sheets("Sheet1").Range("I15:I" & lastrow)
v = .Value
End With
With CreateObject("scripting.dictionary")
.comparemode = 1
For Each e In v
If Not .exists(e) Then .Add e, Nothing
Next
If .Count Then Sheets("Sheet1").ComboBox1.List = Application.Transpose(.keys)
End With
lastrow = Cells(Rows.Count, "I").End(xlUp).Row
With Me
If Not Intersect(Target, .Range("I1")) Is Nothing Then
If Target.Value <> "" Then
.AutoFilterMode = False
.Range("I15:I" & lastrow).AutoFilter field:=1, Criteria1:=Target.Value
End If
End If
End With
You do not need the Worksheet_Change event anymore because you are not trapping the value from the data validation cell but from a ComboBox1. Paste this code (Untested) in the Sheet1 code area. The below code will automatically filter when you select an item from the ComboBox1. If you want you can also use a CommandButton to run this code.
Let me know if you face an issue?
Private Sub ComboBox1_Click()
If ComboBox1.ListIndex = -1 Then Exit Sub
Dim ws As Worksheet
Set ws = Sheet1
With ws
.AutoFilterMode = False
LastRow = .Range("I" & .Rows.Count).End(xlUp).Row
.Range("I15:I" & LastRow).AutoFilter Field:=1, Criteria1:=ComboBox1.Value
End With
End Sub
Also you need to load the ComboBox1. You can either do that using a CommandButton or you can use the Workbook_Open() event.

Filtering Row based off checkbox

I have some VBA code that I was intending to use to filter a row instead of a column. I have some issues though that I can't seem to work out, at this point I have confused myself.
Sub FilterRow()
Dim b As Object, cs As Integer
Set b = ActiveSheet.CheckBoxes(Application.Caller)
With b.TopLeftCell
cs = .Row
End With
Dim rng As Range, cel As Range, totalRng As Range
If ActiveSheet.AutoFilterMode = True Then
ActiveSheet.AutoFilterMode = False
End If
For Each cel In totalRng
If cel.Row <> cs Then
cel.EntireColumn.Hidden = True
Else
cel.EntireColumn.Hidden = False
End If
Next cel
End Sub
The goal is to have the code check columns C:DX of that specific row for a value, if a value is NOT found then to hide that column. Ultimately eliminating any blank cells in that particular row.
So assuming FilterRow is the macro that you've assigned to the checkbox, the following will do what I think you're trying to do:
Sub FilterRow()
Dim b As Object, cs As Integer
Set b = ActiveSheet.CheckBoxes(Application.Caller)
With b.TopLeftCell
cs = .row
End With
Dim rng As Range, cel As Range, totalRng As Range
Set totalRng = Range("C" & cs & ":DX" & cs)
If b.Value = 1 Then
If ActiveSheet.AutoFilterMode = True Then
ActiveSheet.AutoFilterMode = False
End If
For Each cel In totalRng
If cel.Value = "" Then
cel.EntireColumn.Hidden = True
Else
cel.EntireColumn.Hidden = False
End If
Next cel
Else
' Set up autofilter here
totalRng.EntireColumn.Hidden = False
End If
End Sub
Since this macro gets triggered when the checkbox is either checked or unchecked, I changed the logic so that it unhides all the columns when the check box is unchecked (ie reverses what it did when checked).

Archive data from "sheet1" to next blank row of "sheet2"

I have code to archive data from "sheet1" to "sheet2". It overwrites existing data in the "sheet2" rows from the previous archive exercise.
How do I have it seek the next blank row vs. overwriting existing data?
I have two header rows so it should commence with row 3.
Option Explicit
Sub Archive()
Dim lr As Long, I As Long, rowsArchived As Long
Dim unionRange As Range
Sheets("sheet1").Unprotect Password:="xxxxxx"
Application.ScreenUpdating = False
With Sheets("sheet1")
lr = .Range("A" & .Rows.Count).End(xlUp).Row
For I = 3 To lr 'sheets all have headers that are 2 rows
If .Range("AB" & I) = "No" Then
If (unionRange Is Nothing) Then
Set unionRange = .Range(I & ":" & I)
Else
Set unionRange = Union(unionRange, .Range(I & ":" & I))
End If
End If
Next I
End With
rowsArchived = 0
If (Not (unionRange Is Nothing)) Then
For I = 1 To unionRange.Areas.Count
rowsArchived = rowsArchived + unionRange.Areas(I).Rows.Count
Next I
unionRange.Copy Destination:=Sheets("sheet2").Range("A3")
unionRange.EntireRow.Delete
End If
Sheets("sheet2").Protect Password:="xxxxxx"
Application.CutCopyMode = False
Application.ScreenUpdating = True
MsgBox "Operation Completed. Total Rows Archived: " & rowsArchived
End Sub
Change
unionRange.Copy Destination:=Sheets("sheet2").Range("A3")
... to,
with worksheets("sheet2")
unionRange.Copy _
Destination:=.Cells(.rows.count, 1).end(xlup).offset(1, 0)
end with
This is like starting at the bottom row of the worksheet (e.g. A1048576) and tapping [ctrl+[↑] then selecting the cell directly below it.
The With ... End With statement isn't absolutely necessary but it shortens the code line enough to see it all without scolling across. unionRange has been definied by parent worksheet and cell range so there is no ambiguity here.
I'd propose the following "refactoring"
Option Explicit
Sub Archive()
Dim sht1 As Worksheet, sht2 As Worksheet
Set sht1 = Sheets("sheet1")
Set sht2 = Sheets("sheet2")
sht1.Unprotect Password:="xxxxxx"
With sht1.Columns("AB").SpecialCells(xlCellTypeConstants).Offset(, 1) '<== change the offset as per your need to point to whatever free column you may have
.FormulaR1C1 = "=if(RC[-1]=""NO"","""",1)"
.Value = .Value
With .SpecialCells(xlCellTypeBlanks)
.EntireRow.Copy Destination:=sht2.Cells(sht2.Rows.Count, 1).End(xlUp).Offset(1, 0)
MsgBox "Operation Completed. Total Rows Archived: " & .Cells.Count
End With
.ClearContents
End With
sht2.Protect Password:="xxxxxx"
End Sub
just choose a "free" column in "Sheet1" to be used as a helper one and that'll be cleared before exiting macro. In the above code I assumed it's one column to the right of "AB"
The following approach worked for me! I'm using a button to trigger macro.
Every time it takes the last row and append it to new sheet like a history. Actually you can make a loop for every value inside your sheet.
Sub copyProcess()
Application.ScreenUpdating = False
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Dim source_last_row As Long 'last master sheet row
source_last_row = 0
source_last_row = Range("A:A").SpecialCells(xlCellTypeLastCell).Row
Set copySheet = Worksheets("master")
Set pasteSheet = Worksheets("alpha")
copySheet.Range("A" & source_last_row, "C" & source_last_row).copy
pasteSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial
xlPasteValues
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub

Excel VBA - Using shapes as toggle buttons

I'm trying to use a shape instead of a button to toggle hiding rows with blank cells (according to conditions). Is it even possible?
Sub ToggleChevron3_Click()
Dim rng As Range, cell As Range
Set rng = Range("A1:C100")
Application.ScreenUpdating = False
With rng
For Each cell In rng
If cell.Offset(0, 4).Value = "" Then ' Condition 1
If cell.Value = "" Then ' Condition 2
ActiveSheet.Shapes("Chevron 3").cell.EntireRow.Hidden _
= Not ActiveSheet.Shapes("Chevron 3").cell.EntireRow.Hidden
End If
End If
Next
End With
Application.ScreenUpdating = True
End Sub
Yes, it is possible. The code to accomplish what I think you are looking for is below. Both pieces of code below assume you want to just click a button to hide / unhide the rows, depending on the current state.
Sub ToggleChevron3_Click()
Application.ScreenUpdating = False
Dim rng As Range, cell As Range
'Set rng = Range("A1:C100") 'do you really want to loop through every cell in columns A through C
Set rng = Range("A1:A100")
For Each cell In rng
If Len(cell.Offset(, 4).Value) = 0 And Len(cell.Value) = 0 Then
Dim bToggle As Boolean
bToggle = cell.EntireRow.Hidden
cell.EntireRow.Hidden = Not bToggle
End If
Next
Application.ScreenUpdating = True
End Sub
However, there is alternative that is cleaner code and faster execution, as long as filtering is okay for you.
Sub ToggleChevron3_Click()
Application.ScreenUpdating = False
Dim bToggle As Boolean
bToggle = ActiveSheet.AutoFilterMode
If bToggle Then
ActiveSheet.AutoFilterMode = False
Else
Dim rng As Range
Set rng = Range("A1:E100") 'used E because you had an offset of 4 columns
With rng
.AutoFilter 5, "<>"
.AutoFilter 1, "<>"
End With
End If
Application.ScreenUpdating = True
End Sub

Resources