Formula to hide rows based on the value of a cell - excel

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.

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)

Automatically Update a Pivot Table Based Based on Cell Reference

I have a pivot table with the following columns:
item_number, job_number, description and qty.
I would like to have VBA code take the input of a cell, A5, to automatically sort through the job_number column of my pivot table and find the entries that have the job_number found within A5.
The data set is very large, so it is not a wise idea to sort through using PivotItems.
I have a file that does exactly that. I have a cell which isn't part of the pivot table but acts like a filter field for the pivot table.
I put a script into the Worksheet_Change event to watch that cell for changes and a sub which swaps out the filter on the pivot table to match the cell value.
The Worksheet_Change event is basically like
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("A5")) Is Nothing Then Call FilterChanger
End Sub
And the FilterChanger sub is basically like
Private Sub FilterChanger()
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Dim FilterText as String
FilterText = Me.Range("A5")
With Me.PivotTables("MyPivotTable")
.ManualUpdate = True
.PivotFields(3).ClearAllFilters
.PivotFields(3).PivotFilters.Add Type:=xlCaptionContains, Value1:="zzzzzzzzzzzz"
'Filter out all results to prevent table updating when clearing filters
.PivotFields(5).ClearAllFilters
'now that there is another filter, there isnt any lag while the table tries to load all the unfiltered data
.PivotFields(5).PivotFilters.Add Type:=xlCaptionEquals, Value1:=FilterText, Value2:=FilterText
.PivotFields(5).ShowDetail = True
.PivotFields(3).ClearAllFilters
.ManualUpdate = False
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub
In this code PivotFields(3) is any pivot row field that is in the table other than the one you intend to filter. and PivotFields(5) is the field that I am targetting with my filter. You can put column names instead of a number when referring to your fields, but I just prefer numbers.
In my file, the source data for the pivot table is 20k rows and growing, so I found that whenever I did .ClearAllFilters the workbook would pause for ~10 seconds while the pivot table attempted to load all 20k rows. To fix that issue, I put in a temporary filter in another field which will prevent any rows from loading while I swap out the filter in the intended field. I chose zzzzzzzzzzzz in PivotField(3) because it will always return 0 rows.
Sub Macro1()
' in A1 there is the value for sorting
' if you want to show the whole table again run only the "select all" part (line 2):
' Field value == Column (right now column 2); Criterial == Filter Value (value of cell A1) ; change Table name to yours
ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=2, Criteria1:=Range("A1").Value
' "Select All -- to show whole table again de-comment following line
'ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=2
End Sub
Hope this is what you are looking for.

VBA - How to lock entire column based on a cell value in this column

I'm sorry this question may look like antoher ones, but I am new in VBA and struggle to get a proper code...
I would like to protect some data after they were verified. For exemple, I have data in Column B (or whatever column) and I check them in comparaison to manuscrit raw data. I would like to have a cell in that column where I say "Yes" to testify this was checked. After entering "Yes", I would like that all cells in the colum become locked.
I've found a code to lock an entire row (Lock rows in Excel using VBA), but whatever i try, i'm not able to modifiy it to work for a variable entire column (only to lock specific column, I'm not able to lock the column where "Yes" is typed ...)
Could someone help me ?
Thanks !
Maybe this solution can help:
Step 1: select all cells in a sheet. Goto properties (cell format) -> security and deaktivate the checkbox for lock cells (see picture below).
Step 2: protect the sheet with a password. In my example I used "billytalent".
Step 3: copy the following code into the code-area of the sheet. Therefore open the Visual Basic Editor. On the left side you will find a list with your sheets. Double click on the sheet where you want to lock cells with entry "yes". Copy the procedure into the code-area.
Private Const PASSW As String = "billytalent"
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cell As Range
For Each cell In Target
'only do something, if input is in row 2
If cell.Row = 2 Then
'only do something, if someone write yes in a cell
If cell.Value = "yes" Then
'deaktivate the protection of the sheet
ActiveSheet.Unprotect Password:=PASSW
'lock the cells in the column
ActiveSheet.Columns(cell.Column).Locked = True
'activate the protection
ActiveSheet.Protect Password:=PASSW, userinterfaceonly:=True, AllowFiltering:=True, AllowFormattingCells:=True, AllowFormattingRows:=True, AllowFormattingColumns:=True
ActiveSheet.EnableOutlining = True
End If
End If
Next
End Sub
You can tweak the code you're looking at there a little and I think it will do what you want. Make sure before you start this that you set all the cells on the sheet to unprotected.
This is set to check row 3 of the sheet for Yes. Change the value on the second line if you need to.
Private Sub Worksheet_Change(ByVal Target As Range)
row_to_check = 3 ' Checking row 3 for "Yes"
If Intersect(Target, Me.Rows(row_to_check)) Is Nothing Then Exit Sub ' exit early if row 3 wasn't changed
Me.Unprotect ' unprotect the sheet
For Each r In Target.EntireColumn.Columns ' cycle through each row that has seen a change
r.Locked = r.Cells(row_to_check, 1).Value = "Yes" ' set it to protected if the second cell on that row is "Yes"
Next
Me.Protect ' reprotect the sheet
End Sub

Adding msgbox if my pivot table has empty cells

enter image description hereI have an Excel workbook that runs a macro and in the end displays everything in a pivot table
I am trying to add a msgbox when my pivot table has an empty cell (at the end of my macro)
I already did the conditional formatting version(color blank cells red) and it works fine, but the client wants a msgbox to alert him.
I found a IsEmpty command that should work but I cant seem to make it look only inside said pivot table.
Here is what I tried:
Sub IsEmpty()
If IsEmpty(ActiveSheet.Range("PivotTables(1)")) = True Then
'Cell A2 is not blank
MsgBox "Cell A2 is empty"
Else
End If
End Sub
I'm sure the way my If statement is written is false. Just cant seem to find the right syntax.
Thanks in advance
Picture added; I want the macro to target pivot's C column. However, you cant know which cell will be empty or how long the list will continue.
And if just make Excel check a broad spectrum(c2:c300), there will always be en empty cell after the pivot table is finished.
There might be a loop you can create but its way over my current skill set.
The pivot table's name is "PivotTable2"
Is there a to search only in the pivot table's column c for empty cells?
Please consider the capabilities of the function below. It will return True or False depending upon the count of items in columns A and C. In column A text, number or function is counted. In column C there must be a number in each cell. If both counts are the same the function returns True. Either count can be further refined if there are exceptions which the current function doesn't correction evaluate.
Function IsComplete() As Boolean
' 025
Dim Rng As Range
With ThisWorkbook.Sheets("PivotTables(1)") ' change to suit
' set a range from A3 to end of column A
Set Rng = .Range(.Cells(3, "A"), .Cells(.Rows.Count, "A").End(xlUp))
End With
With Application.WorksheetFunction
IsComplete = (.CountA(Rng) = .Count(Rng.Offset(0, 2)))
End With
End Function
You can use code to call this function and display a message box for True and another one if the function returns False. The code can be hitched to a button on your sheet, anywhere in your workbook.
Sub CommandButton1_Click()
Dim Txt As String
If IsComplete Then
Txt = "The pivot table was created without mistakes."
Else
Txt = "Some data are missing in the pivot table."
End If
MsgBox Txt, vbInformation, "Action report"
End Sub
You can also call the function as a UDF and display True or False in a cell of any sheet in your workbook. The UDF call would be like =IsComplete(). You might also embed the UDF call in an IF condition and display another text on your worksheet.
=IF(IsComplete(),"All's well","Missing Item")
In fact, you could slightly modify the function to return the difference between one count and the other and display "1 item missing". The possibilities are endless because the function is so versatile.

Excel PivotTable Conditional Formatting

I have a pivot table in an Excel worksheet that contains the result of a query made to my database. I would like to format the information automatically based on every other data set.
The information contains 4 weeks' (1 month) worth of records for each employee sorted by an employee ID number. I would like to write a module so that it will highlight every other record (employee data set) with a different color. Is this even possible to do? Thanks for the help!
If you insist with solving your problem utilizing VBA here is an example. You'll need to specify start ranges. Please not that marking whole row will use more memory (increasing file size) so I would rather use example: range("A2:E2).select ....
Sub FormatEverySecondRow()
range("A2").EntireRow.Select
Do While ActiveCell.value <> ""
Selection.Interior.ColorIndex = 15
ActiveCell.offset(2, 0).EntireRow.Select
Loop
End Sub
use a helper column (K if I count the columns in your example)
insert into K2:
=IF(ISBlank(C2),K1,MOD(K1+1,2))
then use conditional formatting to highlight the row:
Note the formula does not have a $ sign before the 2 (i.e. $K2, not $K$2)
This might be useful to you:
Sub HighlightDifferentRows()
Dim wksht As Worksheet
Dim wkb As Workbook
Dim row As Range
Dim FloatColor As Long
FloatColor = RGB(100, 100, 100)
Set wbk = ThisWorkbook
Application.ScreenUpdating = False
For Each row In Sheets(1).UsedRange.Rows
row.Interior.Color = FloatColor
If row.Cells(1, 4).Value <> row.Cells(2, 4).Value Then
FloatColor = -FloatColor
End If
Next row
Application.ScreenUpdating = True
End Sub
It alternates row colors whenever a cell value is not the same as the one below it. Right now it is set to grayish colors but you could change it to something brighter if you wanted. You could put in your own logic to get whatever colors you wanted. Good Luck.

Resources