Hide rows based on choice - excel

I have a bunch of choices that can be made in the cells (C41:C59) using a dropdown, the value of the dropdown also is seen in the cells (E41:E59). For each choice I want different rows to show or hide. Hide if the dropdown is N/A else show the rows. The problem i can't get around is that every choice has different rows and als a different amount of rows. So I tried to make a code per choice and only change this when the cell in column E changes. This is what I have so far, but doesn't do anything.
If Not Application.Intersect(Target, Range("E41")) Is Nothing Then
If Range("E41") = "N/A" Then
[67:73].EntireRow.Hidden = True
Else
[67:73].EntireRow.Hidden = False
End If
End If

The code below is an event procedure. It runs when a cell is changed on the worksheet in whose code sheet the procedure is found. (The location of the code in that particular module is paramount.) If a single cell was changed - ignoring multiple simultaneous changes such as might be caused by copy/paste action - the code will check if the modified cell was in the ranges C41:C59 or E41:E59. If so, it will hide or show rows in the same worksheet depending upon whether or the cell's value is "N/A" after modification.
Private Sub Worksheet_Change(ByVal Target As Range)
' 010
Dim TriggerRange As Range
Dim Rng As Range
' ignore simultaneous changes of many cells
If Target.Cells.CountLarge > 1 Then Exit Sub
Set TriggerRange = Application.Union(Range("C41:C59"), Range("E41:E59"))
If Not Application.Intersect(TriggerRange, Target) Is Nothing Then
Select Case Target.Row
Case 41, 46, 59
Set Rng = Range("67:73")
Case 50 To 59
Set Rng = Range(Rows(67), Rows(73))
Case Else
Set Rng = Range(Rows(67), Rows(73))
End Select
Rng.Rows.Hidden = (Target.Value = "N/A")
End If
End Sub
In this code always the same rows are hidden or shown. The code serves to demonstrate how you could specify different row ranges depending upon which row the changed cell is in, using different syntax depending upon your preference.

Related

VBA Excel: Write timestamp to cell on change of another cell

I want to insert a timestamp (E3) when the status (B3) changes. This should happen for at least 30 more such examples in the worksheet. The code currently works only for one example (Country1). Do you have an idea how this can be implemented?
I already tried different types but it just worked for example "Country 1" not for "Country 1", "Country 2", "Country 3" etc.
When I adjust the code for the range "B3:I3" then I received an adjustment in every 3rd column, example: I add a comment in D3 then a timestamp will be created in H3. That is not what I want. :(
Is there a way to adjust the code so that as soon as a change is made in the Status column (B3;F3;J3etc.), the Timestamp column (E3;I3 etc.) will reflect the time stamp?
Code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("B3:B5"))
Is Nothing Then Exit Sub
Application.EnableEvents = False
Target.Offset(0,3).Value = Now
Application.EnableEvents = True
Please, try the next adapted event. It will calculate how many groups of four columns exists and set a range of their first column intersected with rows 3 to 5. Only for this range the event will be triggered:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim lastCol As Long, rngCols As Range
lastCol = Me.cells(2, Me.Columns.count).End(xlToLeft).column 'last column on the second row
Set rngCols = Me.Range(trigData(Me.Range("B2", Me.cells(2, lastCol)))) 'create the range of the columns for what the event to be triggered
Set rngCols = Intersect(Me.rows("3:5"), rngCols) 'create the range inside which the change to trigger the event
If Not Intersect(rngCols, Target) Is Nothing Then
Application.EnableEvents = False
Target.Offset(0, 3).Value = Now
Application.EnableEvents = True
End If
End Sub
Function trigData(rngCols As Range) As String
Dim i As Long, strCols As String
For i = 1 To rngCols.Columns.count Step 4 'iterate from four to four and create the necessary columns string address
strCols = strCols & "," & rngCols.cells(i).EntireColumn.address
Next i
trigData = Mid(strCols, 2) 'Mid eliminates the first (unnecessary) comma...
End Function
The code will be confused if you place on the second row data after the necessary groups of four columns. If necessary, one or two such columns, the code can be adapted to work for a fix number extracting the divided integer (without decimals).
The code assumes that you need to be triggered for the mentioned rows (3 to 5). If you need something different in terms of rows to be affected, you should change Me.rows("3:5") according to your need.
Please, send some feedback after testing it.
Your request is a little unclear, and your table format may not have come across correctly in your post. Your code is written to add the current time to a cell 3 columns away from the target cell. It is dynamic, so if you set
If Intersect(Target, Range("B2:I3"))
You are going to get the value in cell 3 columns offset from the changed cell. If you always want it to update column E, then you can use the target.row property...
Cells(Target.Row,5).Value = Now
...to make the row dynamic, and the column static. Clarify your question if this is not what you're looking for. If country2 is in cell F2, where do you want to write the timestamp?
You can use this simple function:
Public Function TimeStamp(Status As Range) As Double
TimeStamp = Now
End Function
So, in Cell E3 will be the formula =TimeStamp(B3). (Format cell E3 appropriately as Time Format)

How can I add or delete lines in multiple Excel sheets with VBA

I've got an Excel file, where I have to enter names in one sheet, and then the other sheets are adding or deleting rows.
For example I have the excel sheets User, NumberSheet and GradeSheet.
I am entering "John Doe", "Jane Doe" and "Phil Doe" into the User-Sheet, and in NumberSheet and GradeSheet, 3 Rows are added.
I have this code for now:
Private Sub Worksheet_Change(ByVal Target As range)
Dim KeyCells As range
' The variable KeyCells contains the cells that will
' cause an alert when they are changed.
' Start Cell is A2 because Names start there
Set KeyCells = range("A2:A100")
If Not Application.Intersect(KeyCells, range(Target.Address)) _
Is Nothing Then
' Display a message when one of the designated cells has been
' changed.
' Place your code here.
'The row in the user-Sheet, where I added or removed a user
targetRow = Target.row - 1
'In the Number Sheet, the row from where the names should get listed
targetRowInNumberSheet = targetRow
'The value from the cell where I entered the name
vlue = Target.Value
If IsEmpty(vlue) Then
'Delete row in Worksheets
Worksheets("NumberSheet").Rows(targetRowInNumberSheet).Delete
Worksheets("GradeSheet").Rows(targetRowInNumberSheet ).Delete
Else
'Add row in Worksheets
Worksheets("NumberSheet").Rows(targetRowInNumberSheet).Insert
Worksheets("GradeSheet").Rows(targetRowInNumberSheet ).Insert
End If
End If
End Sub
Now this code works if I add a name, delete one or insert a row somewhere in between.
But I can't delete multiple names, or delete a row. In both cases IsEmpty(vlue) will be false, and I don't know why
IsEmpty does not check if a cell value is empty...
It checks if a variable has been initilized.
Instead of If IsEmpty(vlue) Then, simple please use:
If vlue = "" Then
or:
if vlue = Empty Then 'this is different!
Please, check here how Microsoft describes this function...
Then, it is recommended to declare all used variables (targetRow, targetRowInNumberSheet, vlue).
If your Target have to contain only one cell, you should add a code line:
If Target.count>1 then Exit Sub
If you want allowing the multiple cells range, you should state it and deal in a different way with what you try doing. I asked about that, but you did not answer anything. If so, i can show you how to proceed.
Thats because your Input parameter of the Worksheet_Change Function is a Range called Target.
A Range is an area instead a single Value.
If you delete now multiple Rows, the Target.Row property only returns the first Row in your Target Range and so only the First entry will be deleted.
So you should further seek information about Ranges.
I would try this:
Count all Rows in your Target Range:
Target.Rows.Count
With this number you can go on from the first Row Index of the Range like in your example with a loop or something:
targetRow = Target.row - 1

Change event triggered by change of cell value

I want to hide columns with value 0 in range G4:FC4
The cell can take values 0 (in that case the columns should be hidden) or 1 (in that case they should be visible). The value 0 or 1 is formula based and depends on the drop down input value in cell D2.
When I change the value in D2 manually the macro works fine, but when I use the drop down box it doesn't. Please find below my code. Any advice?
Many thanks
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
Dim c As Range
For Each c In Sheets("P_MM6").Range("G4:FC4").Cells
c.EntireColumn.Hidden = True
If c.Value = 1 Then
c.EntireColumn.Hidden = False
End If
Next c
End Sub
Changing manually vs drop-down should not matter, except if perhaps somewhere else in your code events are being disabled and not turned back on, or maybe calculations are set to manual and thus do not create a change in the formula value, so, even though the code fires, the column values don't change.
That said, the code below will help you because it will not try to hide/unhide on every cell change, but only when D2 changes.
Private Sub Worksheet_Change(ByVal Target As Range)
If target.address = "$D$2" Then
Dim c As Range
For Each c In Sheets("P_MM6").Range("G4:FC4").Cells
c.EntireColumn.Hidden = c.Value = 0
Next c
End If
End Sub
Also make sure that calculations are set to automatic and they are not being turned off somewhere in your code and also that events are not being disabled and not turned back on somewhere else in the code.
If all that doesn't help, put a break point on the Worksheet_Change line of code and change the cell via drop-down and see what happens.

Looping through cells within multiple tables and changing value if font color =

I have a spreadsheet that has 3-6 tables in it. I need to use a macro that will change a value from say "30" to "'30" if any of the cells within the row are red. This is because red rows are cancelled reservations; we still need the value and I don't want my other formulas to count that number as a valid number (since it's not an actual reservation.) I've perused many articles with options but usually these articles have a range that is set with a specific table name. Since there are multiple tables, the tables change and I don't know how to make it dynamic. Furthermore, I don't want to have to update the macro each time. If I can circumvent naming the particular tables, my code could work on each sheet (sheets change monthly). One of the issues with my code is that the value I need to change is always in column J. My current code, I imagine, would see the whole row as needing to be changed. I currently get a Run-time error 6: Overflow.
Option Explicit
Sub LoopThroughAllTablesInWorksheet()
Dim tbl As ListObject
Dim Cell As Range
Dim OldValue As Integer
For Each tbl In ActiveSheet.ListObjects
For Each Cell In tbl.DataBodyRange
If Cell.Font.Color = RGB(255, 0, 0) Then
OldValue = Cell.Value
Cell.Value = "'" & OldValue
End If
Next Cell
Next tbl
End Sub
I used the following to help me get where I am: http://www.TheSpreadsheetGuru.com/the-code-vault
https://www.thespreadsheetguru.com/blog/2014/6/20/the-vba-guide-to-listobject-excel-tables
I was able to make this work by changing the line "For Each Cell In tbl.DataBodyRange" to "For Each Cell In tbl.ListColumns(10).Range".

Formula to hide rows based on the value of a cell

I have a worksheet that contains the names of all managers and their employees, ideally the way this sheet needs to work is that there is a drop down in the top left and when a manager selects their name, all rows that don't have their name against, are hidden, so only their team is shown.
I know auto filtering and having them choose their name would be the easiest way and is a good option to fall back on, but I'm hoping there is a way to do this with VBA or a formula to just hide rows when its not their team when they select their name in the drop down. As i'm trying to create something that's quite slick and looks nice
I did try to do something around having a helper cell to display true and false if the names matched, but came a bit stuck at this point. Tried using the code below, but it doesn't seem to actually be doing anything. Column with TRUE/FALSE is in Col A
Sub TEST()
Dim cell As Range
Application.ScreenUpdating = False
Application.EnableEvents = False
For Each cell In Range("A4:A34")
If cell.Value = "FALSE" Then
cell.EntireRow.Hidden = True
Else
cell.EntireRow.Hidden = False
End If
Next
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Any ideas on how to do this without just using autofilter would be great
Given the following assumptions:
Drop down with Manager name is in cell A1
Column listing manager name for each row is in column A
Data set starts in row 5
Column A is contiguous with no blank spaces
Place the following code into the Worksheet module of the data sheet and change assumptions to fit your data set.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" and Target.Cells.Count = 1 Then
Application.ScreenUpdating = False
Range("A5:A1000").EntireRow.Hidden = False
Dim mgrList as Range
Set mgrList = Range(Range("A5"),Range("A5").End(xlDown))
Dim mgrCheck as Range
For each mgrCheck in mgrList
mgrCheck.EntireRow.Hidden = mgrCheck <> Target
Next
End If
End Sub
Use an if then else statement with a call that shows/hides the rows that you'd like to show.
If Range("A1").Value = "John Snow" Then
Call Show_John_Snow
Else
If Range("A1").Value = "Daenerys Targaryen" Then
Call Show_Daenerys
Else....
'subroutine
Show_John_Snow
Rows("17:20").EntireRow.Hidden = True 'hide others
Rows("21:53").EntireRow.Hidden = False 'show John Snow
Rows("54:75").EntireRow.Hidden = True 'hide others
I have this data, in which I have Headers at A3:D3, data starting from row 4 to 99.
I tried applying Autofilter, check if this one works for you.
Sub test()
Range("A3:D3").Select
Selection.AutoFilter
ActiveSheet.Range("A3:D99").AutoFilter Field:=2, Criteria1:="0"
ActiveSheet.Range("A3:D99").AutoFilter Field:=2, Criteria1:="1"
End Sub
Here, I selected option named "0" from drop-down filter from Field-2, that is Range A4, and as you told, other cells automatically gets hidden, and the cells corresponding to that criteria only gets visible.
Also I tried with other option "1".
This seems a very difficult or involved way to do this, I have to show students their results without them seeing other students results.
So, one sheet has all the data and on a "front" sheet I call the relevant data for the particular student using index() and match(). Each student has an ID number which is entered, then for confirmation the name is returned then the relevant grades.

Resources