I'm having issues getting the multiple If statement to work after the second statement. I have 2500 rows of data questions sets that are tied to a 217 item drop down list. What I'm trying to code is, that the questions applicable will populate based on the selected operation of the drop down list. Questions applicable per operation vary from 3 - 12, and questions not applicable to the selection should automatically hide the rows. I've tried multiple variations of code, using ElseIf, If, combination If and ElseIf, combination If and Or_ (this is the most recent) as shown below. Can someone please advise on this? I don't know what else to try and I need to add the additional 213 variables to the code.....Thanks
Sub Hide_Rows()
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim TrigerCell As Range
Set Triggercell = Range("$J$14")
If Not Application.Intersect(Triggercell, Target) Is Nothing Then
If Triggercell.Value = "Electrician, farm based business" Then
Rows("19:2500").Hidden = False
Rows("26:2500").Hidden = True
Or_
If Triggercell.Value = "Plumbing and heating contractors, farm based business" Then
Rows("19:2500").Hidden = False
Rows("19:25", "47:2500").Hidden = True
Or_
If Triggercell.Value = "Plumbing contractors (plumber), farm based business" Then
Rows("19:2500").Hidden = False
Rows("19:46", "55:2500").Hidden = True
Or_
If Triggercell.Value = "Assembly and installation of agricultural equipment in farm outbuildings, for others, farm based business" Then
Rows("19:2500").Hidden = False
Rows("19:55", "61:2500").Hidden = True
End If
End If
End Sub
End Sub
End Sub
Or_ is not something that exists in VBA, so it's not surprising that you're getting a compile error when you try to use it. This usage is unusual enough that it's probably confusing the compiler, which may be why you don't get an error message until the second or third of them (or maybe even on an unrelated statement).
You can make this work with a Select Case statement or by using ElseIf between conditions. I think Select Case is a little more natural for this problem. It should look like this:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim TriggerCell As Range
Set Triggercell = Range("$J$14")
If Application.Intersect(TriggerCell, Target) Is Nothing Then Exit Sub
Select Case Triggercell.Value
Case "Electrician, farm based business"
Rows("19:2500").Hidden = False
Rows("26:2500").Hidden = True
Case "Plumbing and heating contractors, farm based business"
Rows("19:2500").Hidden = False
Rows("19:25").Hidden = True
Rows("47:2500").Hidden = True
'Etc.
End Select
End Sub
Note that (per comment on this answer) you can't specify two separate ranges to Rows, which was an issue with several of the blocks in the original code. I've updated the answer accordingly.
Related
My goal is to be able to have a drop down list that hides certain non-contiguous rows in excel based off the name of the individual in the list I create. I have this code which I found off Youtube and was wondering what was wrong with it as it was not working. I am relatively new to VBA
Private Sub Worksheet_Calculate()
Dim Andrew, Robert, Michael As Range
Set Andrew = Range("K30")
Set Robert = Range("K30")
Set Michael= Range ("K30")
Select Case Andrew
Case Is = "Andrew": Rows("8:10").EntireRow.Hidden = True
Rows("11:12").EntireRow.Hidden = False
Rows("13:13").EntireRow.Hidden = True
Rows("14:25").EntireRow.Hidden = False
End Select
Select Case Robert
Case Is = "Robert"
Rows("6:20").EntireRow.Hidden = True
Rows("21:25").EntireRow.Hidden = False
End Select
Select Case Michael
Case Is = "Michael"
Rows("1:5").EntireRow.Hidden = True
Rows("6:25").EntireRow.Hidden = False
End Select
End Sub
I created a dummy test Excel worksheet and inserted your VBA code into a new module. It worked fine for me, albeit is a bit clunky.
Some suggestions to help:
Always set Option Explicit at the top of your module, because this means any undeclared variables and other little things like that get picked up immediately. It's good practice to get into that habit early when starting out with VBA.
Always qualify your .Range statement with the prefix for the specific workbook/worksheet your code needs to work on. This may be why it isn't working for you, but ran fine for me. As it stands, your code will only run on whatever worksheet happens to be active at the time.
You have made this a Private Sub (private subroutine). If you have done the proverbial copy & paste then this subroutine will not show up in your list of macros, which could be another reason you cannot run it. I highly recommend you have a read of this ExcelOffTheGrid article, which breaks down the different types nicely. If you have inserted this into the Worksheet object of your VBA Project, then it may need to be moved into its own Module.
You have assigned three different names (Andrew, Robert, Michael) to the same .Range reference. This shouldn't really be allowed (although weirdly didn't flag an error when I copied your code) because what it is saying is that those text strings - and they could be anything, not just those names - all refer to the same specific cell on your worksheet. This hasn't affected your code, because you don't actually refer to them later on. In your Select Case logical tests you have used double quotes " " around each name, telling VBA it is a string of characters not a variable you have defined.
I would suggest something like this:
COPY & PASTE INTO A NEW MODULE
Option Explicit
'
'
Sub HideRows()
' This macro will hide specific non-contiguous rows based upon criteria in my drop down combo box.
'
Dim wkMyBook As Workbook
Dim wsMainSheet As Worksheet
Dim rName As Range
'
With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With
Set wkMyBook = ActiveWorkbook
Set wsMainSheet = wkMyBook.Sheets("ENTER SHEET NAME HERE")
Set rName = wsMainSheet.Range("K30")
Select Case rName
Case Is = "Andrew"
wsMainSheet.Rows("8:10").EntireRow.Hidden = True
wsMainSheet.Rows("11:12").EntireRow.Hidden = False
wsMainSheet.Rows("13:13").EntireRow.Hidden = True
wsMainSheet.Rows("14:25").EntireRow.Hidden = False
Case Is = "Robert"
wsMainSheet.Rows("6:20").EntireRow.Hidden = True
wsMainSheet.Rows("21:25").EntireRow.Hidden = False
Case Is = "Michael"
wsMainSheet.Rows("1:5").EntireRow.Hidden = True
wsMainSheet.Rows("6:25").EntireRow.Hidden = False
End Select
With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With
End Sub
COPY & PASTE INTO THE WORKBOOK OBJECT
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
' This code will run whenever a change is made to your worksheet
If Target.Address = "$K$30" Then
Select Case Target.Value
Case Is = "Andrew", "Robert", "Michael"
Call HideRows
End Select
End If
End Sub
This has bought your ticket, given you the lift, dropped you off right at the door. Now you gotta do that final step to put this together to make it work. Read the article I linked, learn about bit about how VBA is constructed and then next time you should be a bit further along the path before you need a pick up. Good luck!
Drop Down Worksheet Change
When you change a value in a cell via 'drop down', the Worksheet.Change event is triggered.
Copy the first code into the appropriate sheet module e.g. Sheet1.
Copy the second code into a standard module, e.g. Module1.
You do not run anything, it is automatically showing or hiding rows.
Sheet1
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Const RangeAddress As String = "K30"
If Not Intersect(Target, Me.Range(RangeAddress)) Is Nothing Then
manipulateRows Me, Target.Value
End If
End Sub
Module1
Option Explicit
Sub manipulateRows(Sheet As Worksheet, checkString As String)
With Sheet
Select Case checkString
Case "Andrew"
.Rows("8:10").Hidden = True
.Rows(13).Hidden = True
.Rows("11:12").Hidden = False
.Rows("14:25").Hidden = False
Case "Michael"
.Rows("1:5").Hidden = True
.Rows("6:25").Hidden = False
Case "Robert"
.Rows("6:20").Hidden = True
.Rows("21:25").Hidden = False
Case Else ' When DEL is pressed (Empty Cell), shows all rows.
.Rows("1:25").Hidden = False
End Select
End With
End Sub
I have an interactive worksheet where I have people input yes or no answers. I have a grouping of questions that if someone answers no in the first one, the next two are not required. How do I create a function that will hide the rows once a no is given?
I am relatively new to advanced functionality in Excel so I have mostly been looking at different forms of code that my colleagues have provided.
ActiveSheet.Range("B6") = "no"
Rows("7:8").EntireRow.Hidden = False
End Function
I think you're looking for a Worksheet_Change() event - try placing this in the corresponding Sheet module under Microsoft Excel Objects:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$6" Then
If Target.Value = "no" Then
Rows("7:8").EntireRow.Hidden = True
Else
Rows("7:8").EntireRow.Hidden = False
End If
End If
End Sub
I have a project that uses a Worksheet_Change sub to make certain images visible or invisible based on the value of a particular cell (in this case B23).
Now I'm trying to add a second criteria to make a different set of images visible/invisible based on the value in a different cell (in this case B24).
The problem is that I'm now getting a "Invalid or Unqualified Reference" Error, and it looks like it has to do with the ".pictures" piece. Here is the code I'm trying to run:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Me.Range("$B$23,$B$24")) Is Nothing Then Exit Sub
If Target.Address = "$B$23" Then
Select Case Target.Value
Case "driving"
.Pictures("Auto_Map_Labeled").Visible = True
.Pictures("Bicycle_Map_Labeled").Visible = False
.Pictures("Pedestrian_Map_Labeled").Visible = False
Case "bicycling"
.Pictures("Auto_Map_Labeled").Visible = False
.Pictures("Bicycle_Map_Labeled").Visible = True
.Pictures("Pedestrian_Map_Labeled").Visible = False
Case "walking"
.Pictures("Auto_Map_Labeled").Visible = False
.Pictures("Bicycle_Map_Labeled").Visible = False
.Pictures("Pedestrian_Map_Labeled").Visible = True
End Select
ElseIf Target.Address = "$B$24" Then
Select Case Target.Value
Case "visible"
.Pictures("Thumbs_Up").Visible = True
Case "invisible"
.Pictures("Thumbs_Up").Visible = False
End Select
End If
End Sub
Any ideas what might be going wrong? I should note that I'm very new to VBA, so looking for the simplest solution possible.
I am making an Excel form with some activeX controls and am having a problem incorporating the following functionallity:
I wish for the users to select a number in ComboBox11. If the number be 0, the form changes so, that comboboxes 9 and 10 become disabled (using VBA code) and the table below 'fades out' (using conditional formatting), informing the user not to fill it out.
On the other hand if the user selects a number larger than 0, the form stays as it is. Under the table is a checkbox (checkbox1) used to expand the table (unhiding previously hidden rows) if data needeed to be put in the form is larger than the table size.
The VBA code behind combobox 11 is:
Private Sub ComboBox11_change()
Dim ws As Worksheet
Set ws = Sheets("Form")
If Not Me.ComboBox11.Text = "" Then ws.Range("J24") = CInt(Me.ComboBox11.Text) 'to write integer instead of text into linked cell
If Me.ComboBox11.Value = 0 Then
Me.ComboBox9.Enabled = False
Me.ComboBox10.Enabled = False
If Me.CheckBox1.Value = True Then Me.CheckBox1.Value = False 'if combobox11 is 0 than the table doesn't need to be expanded
Me.CheckBox1.Enabled = False
Else
Me.ComboBox9.Enabled = True
Me.ComboBox10.Enabled = True
Me.CheckBox1.Enabled = True
End If
End Sub
And the code behind CheckBox1 is:
Private Sub CheckBox1_Change()
Dim ws As Worksheet
Set ws = Sheets("Form")
If CheckBox1.Value = False Then ws.Rows("46:71").Hidden = True
If CheckBox1.Value = True Then ws.Rows("46:71").Hidden = False
End Sub
So, if I select 0 in combobox11 the result is:
So far so good. But if I select something larger than 0, say 1 in combobox11 and then try to expand the table by clicking on the checkbox1, the table expands, but I get an error message:
Run-time error '1004': Not possible to set properties: enabled class:
OLEObject
(not sure about the exact error text, since I'm not using English MSOffice)
When pressing the Debug button, the following line in Sub ComboBox11_Change() lights up:
Me.ComboBox9.Enabled = True
The Strange thing is, that this error does not appear when the combobox11 is left blank ( a value is not selected).
I have no idea why the checkbox would interact with the other comboboxes. I am bewildered and any help would be much appreciated.
To reproduce this:
Have a sheet like this:
A1:A6 is the ListFillRange of the ComboBox.
Then hiding any row between 1:6 using VBA code in CheckBox1_Change() will throw the error.
Private Sub CheckBox1_Change()
If CheckBox1.Value = False Then Me.Rows("7:13").Hidden = True
If CheckBox1.Value = True Then Me.Rows("7:13").Hidden = False
'If CheckBox1.Value = False Then Me.Rows("6:13").Hidden = True 'ERROR
'If CheckBox1.Value = True Then Me.Rows("6:13").Hidden = False 'ERROR
End Sub
Private Sub ComboBox1_Change()
If Me.ComboBox1.Value = 0 Then
If Me.CheckBox1.Value = True Then Me.CheckBox1.Value = False
Me.CheckBox1.Enabled = False
Else
Me.CheckBox1.Enabled = True
End If
End Sub
If we create a name named "list" which is related to a whole column like this:
and use this "list" as the ListFillRange of the ComboBox, then the error occurs ever if rows in this sheet were hidden from code. This is independent on whether the hidden rows are within the real active "list" rows 1-6 or not.
If we not reference a whole column in the name but for example only rows 1-10 like:
=INDEX(Sheet1!$A$1:$A$10;1):INDEX(Sheet1!$A$1:$A$10;6)
then the error only occurs if the code hides rows from 1 to 10 but not if it hides rows from 11 upwards.
Edit:
To continue my example:
Moved the numbers from Sheet1!A:A to Sheet2!A:A and created a named range "list" related to
=Sheet2!$A$1:INDEX(Sheet2!$A$1:$A$40;COUNTIF(Sheet2!$A$1:$A$40;"<>"))
Then the following code to set Sheet1.ComboBox1.ListFillRange to "list" will work if it is within the Sheet2 class module:
Private Sub Worksheet_Change(ByVal Target As Range)
ThisWorkbook.Worksheets(1).ComboBox1.ListFillRange = "list"
End Sub
It will produce the error if setting the ListFillRange is tried from within the Sheet1 class module.
Because comments are too short to explain whad I did to solve the issue, I am posting this answer.
First of all thanks to Axel Richter, who took his time to elaborate on my problem.
The Combobox11 was filled with a generated ListFillRange in the name manager:
The described error stopped appearing, as soon as I changed the ListFillRange. At first I tried a simple alternative: "=list!AU1:AU40" Although I don't understand the problem it is now solved!
Afterwards I used the following code to create a dynamic list for combobox11.
Dim zadnji As Integer
zadnji = Sheets("Form").Range("T9").Value + 1
Me.OLEObjects("combobox11").ListFillRange = "=lists!AU1:AU" & zadnji
Just as the title says, I'm trying to disable or have the opposing filter default to "All" if the other is selected.
For instance I have a pivot table with two filters - "WEEK" and "MONTH"
If someone selects a value in the week filter, i want the month filter to default to "(all)" and vice versa.
Pretty simple but I'm not sure how to attack this (VBA or formula) and furthermore the code.
Thanks guys!
Unfortunately, there is no event which would trace pivottable field change. Therefore my idea is as follow.
Step 1. Place somewhere public variables:
Public tmpM As Boolean
Public tmpW As Boolean
Step 2. In the sheet module where your pivottable is placed put the following code:
Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
On Error GoTo ErrorHandler
Application.EnableEvents = False
If Target.PivotFields("week").AllItemsVisible = False And tmpW = True Then
Target.PivotFields("month").ClearAllFilters
End If
If Target.PivotFields("month").AllItemsVisible = False And tmpM = True Then
Target.PivotFields("week").ClearAllFilters
End If
tmpM = Target.PivotFields("month").AllItemsVisible
tmpW = Target.PivotFields("week").AllItemsVisible
Application.EnableEvents = True
Exit Sub
ErrorHandler:
Application.EnableEvents = True
End Sub
It works fine with my example data.
Edit: error handling in code above.