How to hide cell rows in Excel - vba

Thanks in advance for your help. I have been working on this for a few days now and have tried a few different options. What I need done is to hide specific rows of an excel sheet based on the contents of an active X dropdown. I have indexed the dropdown to a cell and every time the user changes the dropdown selection, the indexed cell contains their selection as either text or number (whichever makes it easiest to code - I've been trying both). I want to keep the code as close to how it is at the moment if possible. I'm sure there are shorter/ more convenient methods, but I just want this over. I think the issue is that when the user selects a new option from the dropdown, the macro isnt refreshing and showing ALL rows again before it begins to hide the new rows. As a result, I just end up with a whole bunch of hidden rows based on what was originally selected. I hope that makes sense.
See the code below for what I've already tried. I also tried this one too, but had the same issue (that the macro wasnt refreshing and showing ALL rows before applying another Hide function)
Private Sub Worksheet_Change(ByVal Target As Range)
ActiveSheet.Activate
If Not Application.Intersect(Range("U13"), Range(Target.Address)) Is Nothing Then
Select Case Target.Value
Case Is = "Brand Health": Rows("19:39").EntireRow.Hidden = True
Rows("40:60").EntireRow.Hidden = False
Case Is = "Brand Imagery": Rows("38:60").EntireRow.Hidden = True
Rows("61:81").EntireRow.Hidden = False
Case Is = "NPS": Rows("30:82").EntireRow.Hidden = True
Rows("83:102").EntireRow.Hidden = False
Case Is = "Talent": Rows("35:103").EntireRow.Hidden = True
Rows("104:126").EntireRow.Hidden = False
Case Is = "Shows": Rows("37:127").EntireRow.Hidden = True
Rows("128:148").EntireRow.Hidden = False
End Select
End If
End Sub
Private Sub Worksheet_Change(ByVal Target`enter code here` As Range)
Sheets("Brand Tracking Dashboard").Rows("1:1000").EntireRow.Hidden = False ' Move this to the top
If Target.Address = ("$U$13") And Target.Value = 1 Then
Sheets("Brand Tracking Dashboard").Rows("19:39").EntireRow.Hidden = True
Sheets("Brand Tracking Dashboard").Rows("59:1000").EntireRow.Hidden = True
ElseIf Target.Address = ("$u$13") And Target.Value = 2 Then
Sheets("Brand Tracking Dashboard").Rows("43:63").EntireRow.Hidden = True
Sheets("Brand Tracking Dashboard").Rows("80:1000").EntireRow.Hidden = True
ElseIf Target.Address = ("$u$13") And Target.Value = 3 Then
Sheets("Brand Tracking Dashboard").Rows("32:84").EntireRow.Hidden = True
Sheets("Brand Tracking Dashboard").Rows("101:1000").EntireRow.Hidden = True
ElseIf Target.Address = ("$u$13") And Target.Value = 4 Then
Sheets("Brand Tracking Dashboard").Rows("37:106").EntireRow.Hidden = True
Sheets("Brand Tracking Dashboard").Rows("121:1000").EntireRow.Hidden = True
ElseIf Target.Address = ("$u$13") And Target.Value = 5 Then
Sheets("Brand Tracking Dashboard").Rows("37:129").EntireRow.Hidden = True
Sheets("Brand Tracking Dashboard").Rows("145:1000").EntireRow.Hidden = True
End If
End Sub
What should happen is that after the user makes a selection, I guess the logic should be that the sheet is told to show ALL rows before applying the hide line command.

You are almost there - your guess was right. You just need to unhide all the rows before you hide the right ones based on the selection.
The first sub you posted is trying to do some unhiding, but it's only unhiding a few rows - and as you can't control what order the user selects the values in, it's probably trying to unhide the wrong ones. (Work through what happens if a user selects "Brand Health" followed by "Shows").
Try this:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ws As Worksheet
On Error GoTo errHandler
Application.ScreenUpdating = False
Set ws = Target.Worksheet
If Not Application.Intersect(ws.Range("U13"), Range(Target.Address)) Is Nothing Then
ws.Rows("19:148").Hidden = False 'edit this to include all the rows that could be hidden
Select Case Range("U13").Value
Case Is = "Brand Health"
ws.Rows("19:39").Hidden = True
Case Is = "Brand Imagery"
ws.Rows("38:60").Hidden = True
Case Is = "NPS"
ws.Rows("30:82").Hidden = True
Case Is = "Talent"
ws.Rows("35:103").Hidden = True
Case Is = "Shows"
ws.Rows("37:127").Hidden = True
End Select
End If
Application.ScreenUpdating = True
Exit Sub
errHandler:
Application.ScreenUpdating = True
End Sub
I've made a few other improvements:
ActiveSheet.Activate wasn't doing anything
You shouldn't rely on a particular sheet being the active one - what if the user changes it halfway through your macro? So I get the right worksheet at the start and use that throughout (make sure we are always working on the correct sheet)
Target could be a range of cells; you are only interested in the value of U13 so make that the condition for the Select Case
it's neater and faster to turn off screen updating - making sure it always gets turned on afterwards (even if there's an error).
Rows("xx:yy") returns whole rows so there's no need for EntireRow

Related

Trigger macro with change in different worksheet

Apologies any incorrect terms, this is the first time I am trying to code a macro. I currently have the following code running:
Private Sub Worksheet_Deactivate()
'Alpha Show / Hide
If Sheets("Project_selection").Range("D4") = Range("C2") Then
Sheet3.EnableCalculation = True
ElseIf Sheets("Project_selection").Range("D4") = "All" Then
Sheet3.EnableCalculation = True
Else
Sheet3.EnableCalculation = False
End If
End Sub
which has been cobbled together from other codes and google. It works, but only when I move out of the sheet, which I think is being driven by the first line.
I would actually like it to activate when the Cell D4 in the 'Project_selection' sheet (a separate sheet to the one the code is on) gets changed - does anyone know how I would do that? I have seen references to worksheet_change, but I do not understand how one defines the target/range to get the appropriate reference.
Hope that makes sense and thanks in advance!
If you were to place the following code under the sheet (Project_selection), it would fire that event every time a change has happened in Cell D4:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ws As Worksheet: Set ws = Sheets("Project_selection")
If Target.Address = "$D$4" Then
If ws.Range("D4") = ws.Range("C2") Then
Sheet3.EnableCalculation = True
ElseIf ws.Range("D4") = "All" Then
Sheet3.EnableCalculation = True
Else
Sheet3.EnableCalculation = False
End If
End If
End Sub

Excel VBA Hide different columns depending on different cell values in another sheet, in real time

I've got a workbook with 5 sheets: Sheet1, Sheet2, Sheet3, Sheet4, Sheet5. The first sheet: "Sheet" has a cell: "C3" with a drop down menu with 4 different options: Opt1, Opt2, Opt3, Opt4.
Depending on what is selected in this drop down menu, I'd like different columns to be hidden in the various sheets - in real time. And if nothing is entered, I'd like no columns hidden.
I've entered the below code which partly works but I think there's an issue because I've selected overlapping columns to hide - not completely sure.
Additionally, I'd like to work in hiding particular rows as well as the column below, depending on what different option you select in the drop down menu.
Also, I'll replicate hiding the same columns across all Sheets1-5.
Private Sub Worksheet_Change(ByVal Target As Range)
If Range("C3").Value = "Opt1" Then
Sheets("Sheet1").Columns("G:L").EntireColumn.Hidden = True
Sheets("Sheet1").Columns("N:T").EntireColumn.Hidden = True
Else
Sheets("Sheet1").Columns("G:L").EntireColumn.Hidden = False
Sheets("Sheet1").Columns("N:T").EntireColumn.Hidden = False
End If
If Range("C3").Value = "Opt2" Then
Sheets("Sheet1").Columns("B:F").EntireColumn.Hidden = True
Sheets("Sheet1").Columns("N:T").EntireColumn.Hidden = True
Else
Sheets("Sheet1").Columns("B:F").EntireColumn.Hidden = False
Sheets("Sheet1").Columns("N:T").EntireColumn.Hidden = False
End If
If Range("C3").Value = "Opt3" Then
Sheets("Sheet1").Columns("B:M").EntireColumn.Hidden = True
Else
Sheets("Sheet1").Columns("B:M").EntireColumn.Hidden = False
End If
If Range("C3").Value = "Opt4" Then
Sheets("Sheet1").Columns("B:AB").EntireColumn.Hidden = True
Else
Sheets("Sheet1").Columns("B:AB").EntireColumn.Hidden = False
End If
End Sub
Following on from my comment. You can define the entire range of columns as a variable e.g. entireRange and set this to unhidden at the start of each worksheet change.
Add fully qualified references to the ranges i.e. ThisWorkbook.Sheets("Sheet1") or ws (as a variable shown below).
As everything is unhidden at start Else is not needed for each If statement. This is probably where confusion arises.
Change to a Select case statement as you are testing the value of a single cell against different expected values.
Combine your separate line column ranges that you are hiding into one line statements e.g.
Sheets("Sheet1").Columns("G:L").EntireColumn.Hidden = True
Sheets("Sheet1").Columns("N:T").EntireColumn.Hidden = True
Becomes:
ws.Range("G:L,N:T").EntireColumn.Hidden = True
You code would then look like the following:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim wb As Workbook
Dim ws As Worksheet
Dim entireRange As Range
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1")
Set entireRange = ws.Columns("B:AB")
entireRange.EntireColumn.Hidden = False
Select Case ws.Range("C3") 'Test the value of C3
Case "Opt1"
ws.Range("G:L,N:T").EntireColumn.Hidden = True
Case "Opt2"
ws.Range("B:F,N:T").EntireColumn.Hidden = True
Case "Opt3"
ws.Range("B:M").EntireColumn.Hidden = True
Case "Opt4"
entireRange.Hidden = True
End Select
End Sub
This will be easier to debug in terms of where things are being hidden or unhidden.
I have rewritten your code to make it easy to read and edit. My goal was to make the code as short as possible. I changed your if statement into a Select Case. It's more elegant and I think it's faster, but don't take my word for it.
The problem that had to be tackled was that if I select Opt1 and then select Opt2, the columns from Opt1 would still be hidden. So before the code hides anything, it automatically unhides all the columns in the range B:AB.
I added the Case Else to unhide all columns if you entered anything but Opt1, Opt2, Opt3 or Opt4. This could easily be changed into a MsgBox that warns the user that the entered value is incorrect. You can remove this line if you have limited the choice for the users already.
The Code:
Private Sub Worksheet_Change(ByVal Target As Range)
' Unhide Columns
Worksheets("Sheet1").Range("B:AB").EntireColumn.Hidden = False
Select Case Worksheets("Sheet1").Range("C3").Value
Case "Opt1"
Worksheets("Sheet1").Range("G:L,N:T").EntireColumn.Hidden = True
Case "Opt2"
Worksheets("Sheet1").Range("B:F,N:T").EntireColumn.Hidden = True
Case "Opt3"
Worksheets("Sheet1").Range("B:M").EntireColumn.Hidden = True
Case "Opt4"
Worksheets("Sheet1").Range("B:AB").EntireColumn.Hidden = True
' If anything else is entered, the columns will be unhidden.
Case Else
Worksheets("Sheet1").Range("B:AB").EntireColumn.Hidden = False
End Select
End Sub

Excel VBA combobox doesn't allow to select specific items from list

I have a combobox in my worksheet with a dynamic search, the dynamic search is done by searching the typed letters in a list that is on another worksheet. The search is done by excel formulas. The list is a defined range and then the combobox listfillrange is set to the named range.
When I type the dropdown list opens, for certain items the combobox allows me to select from the list and for others the selection disappear as I select. I tried figure why do these items disappear. The list is long (10,000 items) so it kind of works slow, but I am not sure if this is the problem.
How can I fix such a problem? Is there a way to define a variable for the mouseclick selection from dropdown list?
Thanks in advance,
Tali
This is my code:
Private Sub ComboBox1_Change()
Sheets("PS").EnableCalculation = True
ComboBox1.ListFillRange = "DropDownList"
ComboBox1.DropDown
End Sub
Private Sub CommandButton21_Click()
Dim PS As Worksheet
Application.ScreenUpdating = False
Application.ErrorCheckingOptions.BackgroundChecking = False
Sheets("PharmaSoft").Select
Set PS = Sheets("PS")
SelectionA = PS.Range("J2").Value
If ComboBox1.Value = SelectionA Then
Range("J19") = "Pharmacy purchase price"
Range("N19") = PS.Range("K2")
Range("O19") = "ILS"
Range("J21") = "Pharmacy selling price Incl.VAT"
Range("N21") = PS.Range("L2")
Range("O21") = "ILS"
Range("J23") = "Package size"
Range("N23") = PS.Range("M2")
Range("J19:O23").Select
With Selection.Font
.ThemeColor = xlThemeColorDark1
.TintAndShade = 0
End With
Selection.Font.Bold = True
Application.ScreenUpdating = True
Range("N19").Errors.Item(1).Ignore = True
Range("N21").Errors.Item(1).Ignore = True
Range("N23").Errors.Item(1).Ignore = True
Else
MsgBox "Please select a product", vbCritical, "Error"
End If
Sheets("PS").EnableCalculation = False
End Sub
Private Sub CommandButton22_Click()
Application.ScreenUpdating = False
Sheets("PharmaSoft").Select
ComboBox1.Value = Null
Range("J19:O23").Value = Null
Application.ScreenUpdating = True
End Sub
Also the code for the workbook:
Private Sub Workbook_Open()
Sheets("PharmaSoft").Select
Application.ScreenUpdating = False
Sheets("PharmaSoft").ComboBox1.Value = Null
Range("J19:O23").Value = Null
Application.ScreenUpdating = True
End Sub
Although I can't comment on what you're doing given that your search is done as you mention with excel formulas. I do know that using data validation via a combo box can be pretty quick. The method I use is as per this page and is extremely fast. It's pretty much instantaneous on a validation range that is about 15k rows long. The best part about it is that it provides auto completion. So when you type in the combo box and that value isn't in the list, the entry that matched one character ago disappears. It's a good visual cue whether you're selection is valid or not. And of course, you can still use the drop down box in the usual way. The only down side is that, as coded at the link provided, you have to double-click to enter the auto-completion mode.

Locking cell based on value on other cell

Please find the below code. I am not sure where am I going wrong in my code.
My purpose is to check the value in D44 cell(drop down list) and based on the value lock/unlock D45 cell.
Values in D44 are NO,13 fracto,18 fracto,Any Other Fracto"
User should be able to edit the cell D45 only if the D44 cell value is set to "Any Other Fracto".
Sub TheSelectCase()
Select Case Range("D44").Value
Case "Any Other Fracto"
Range("D45").Locked = False
Range("D45").Activate
Case = "NO"
Range("D45").Locked = True
Range("D45").Clear
Case <> "NO" Or "Any Other Fracto"
Range("D45").Locked = True
End Select
End Sub
Unless the dropdown is an ActiveX control, you'll need to do this via Worksheet_Change event handler, and also, you only have two cases: 1) A case where user is allowed to edit ("Any other fracto") and 2) any other value in which the user is not allowed to edit.
Assuming you're using a Validation List, do this in the worksheet's Worksheet_Change event:
Private Sub Worksheet_Change(ByVal Target As Range)
'Exit on any other cell
If Intersect(Target, Range("D44")) Is Nothing Then Exit Sub
Application.EnableEvents = False
Dim inputCell As Range
Set inputCell = Range("D45")
Select Case Trim(LCase(Target.Value))
Case "any other fracto"
inputCell.Locked = False
inputCell.Activate
Case Else
'This handles **ANY** other value in the dropdown
inputCell.Locked = True
InputCell.Clear
End Select
Application.EnableEvents = True
End Sub

unhiding rows based on cell value for data entry - refresh error

I've set up a worksheet that will allow the user to select preset options from a data validation list in a cell (B23). The user's selection off this one cell will then trigger certain rows to be unhidden, guiding the user to input data into only the appropriate rows. The VBA code I am using for unhiding the appropriate rows works fine, EXCEPT for the fact that whenever a user enters data into one of the unhidden rows, all the rows will hide. The user then needs to reselect their option from the initial data validation list (cell B23) to unhide the appropriate rows again. The value they enter is entered and saved in the cell, but they need to reselect their initial choice between each data entry step, which is annoying and what I'd like to fix.
I suspect that:
1)the VBA code I hobbled together doesn't account for the fact that users will be entering data into rows that are hidden / will be triggered to unhide, and/or
2) the crux of the problem is refreshing the cell with the data validation list (B23) that triggers which rows to be unhidden. I unfortunately have no idea how to do this.
Any help would be very much appreciated!!
My VBA code to hide rows is below.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim allRows As Range
Set allRows = Rows("27:64")
allRows.Hidden = True
If Not Intersect(Target, Range("B23")) Is Nothing Then
If Target.Value = "A1" Then
Rows("27:31").Hidden = False
ElseIf (Target.Value = "A10-A-S" Or Target.Value = "A10-A-P" Or Target.Value = "A10-A-T") Then
Rows("32:36").Hidden = False
ElseIf (Target.Value = "A10-B-S" Or Target.Value = "A10-B-P" Or Target.Value = "A10-B-T") Then
Rows("37:44").Hidden = False
ElseIf (Target.Value = "E19S" Or Target.Value = "E19P" Or Target.Value = "E19T") Then
Rows("46:54").Hidden = False
ElseIf (Target.Value = "E20S" Or Target.Value = "E20P" Or Target.Value = "E20T") Then
Rows("56:64").Hidden = False
End If
End If
End Sub
You're right that as soon as anyone changes anything on the worksheet, the Worksheet_Change event will fire and hide those rows.
A simple option would probably be to wrap that code around a check that the change was triggered by your dropdown:
With Target
If .Count = 1 Then
If .Row = 23 And .Column = 2 Then ' Assumes your list result is B23?
allRows.Hidden = True
' do your other checks and updates here...
End If
End If
End With
You should check if the target is B23 and if not Exit Sub. Maybe Something like this.
If Intersect(Target, Range("B23")) Is Nothing Then
Exit Sub
End If