Autofill cells based on drop down list in excel - excel

I am trying to creata a VBA that gives me automatic values based on drop down list in a form. The problem is that when I run the macro then it is causing an error and excel stops working. Any help in this case is most welcome.
Private Sub Worksheet_Change(ByVal Target As Range)
If Range("$G$11") = "UD Sheet" Then
Rows("20:25").EntireRow.Hidden = False
Else
Rows("21:25").EntireRow.Hidden = True
End If
If Range("G12").Value = "Flex Tape" Then
Range("B20").Value = "None"
Else
Range("B20").Value = ""
End If
exitHandler:
Application.EnableEvents = True
Exit Sub
End Sub

First thing first, in your code, no need to put an Exit Sub before the End Sub.
The code will end after that line so this is a redundancy.
The next thing that you need to understand is that the Change Event will keep triggering if you will not disable it explicitly. So it means that when you hide a row on that Sheet, the Change Event will keep on happening since there will be changes that will happen on the Sheet. i.e. (Hiding Rows).
To do that you need to disable the EventsListeners of the application using the Application.EnableEvents = False. So the application can do a single thing based on that first event.
The next thing that you need to keep in mind is to track where the Changes occur and fire your program. Target is a Range Object that will return the Range where the specific change occurs on the Sheet.
In order to do that, you need to validate if you need to trigger the routine based on the target using the Intersect function.
The whole code is as follows:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Not Intersect(Target, Range("G11")) Is Nothing Then
If Range("$G$11") = "UD Sheet" Then
Rows("20:25").EntireRow.Hidden = False
Else
Rows("21:25").EntireRow.Hidden = True
End If
End If
If Not Intersect(Target, Range("G12")) Is Nothing Then
If Range("G12").Value = "Flex Tape" Then
Range("B20").Value = "None"
Else
Range("B20").Value = ""
End If
End If
Application.EnableEvents = True
End Sub

Related

Multiple VBA targets for data validation on a single sheet

There are similar posts relating to my question, but I have struggled to adapt them to my problem. I currently have the following code which works just fine:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Application.ScreenUpdating = True
Set Target = Range("B4")
If Target.Value = "Yes" Then
Call DropDownListOn
Else
Call DropDownListOff
End If
Application.EnableEvents = True
End Sub
and the macros that are being called are:
Option Explicit
Sub DropDownListOn()
Sheet1.Activate
Sheet1.Range("A5").Value = "Plot default probability"
Sheet1.Range("B5").Validation.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Formula1:="Yes, No"
End Sub
and
Option Explicit
Sub DropDownListOff()
Sheet1.Range("A5").Value = ""
Sheet1.Range("B5").Validation.Delete
End Sub
Essentially what it does is as follows: Cell B4 is dropdown list. If "Yes" is chosen, then by calling the macro "DropDownListOn", it generates a new dropdown list in cell B5. This part works just fine; but, say, that once the dropdown list in cell B5 appears, I want to call another macro if B5 is chosen to be "Yes" (e.g., generating another dropdown list in cell B6). Given that only one target can be assigned to each sheet, this does not seem to be very straightforward. There seem to be suggestions for ways around this obstacle on Stackoverflow, but I struggle to adopt these to my own case. Any help and/or sample code will very much be appreciated.
Please, try the next updated event:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address(0, 0) = "B4" Then
If Target.Value = "Yes" Then
Call DropDownListOn 'it let it creating the drop-down in "B5", TRIGGERING the change event
'but delete the charts ONE BY ONE!
Else
Application.EnableEvents = False
Call DropDownListOff 'the event is not triggered here.
'if you want to also clear "B6", you should place such a code line in the above Sub...
Application.EnableEvents = True
End If
ElseIf Target.Address(0, 0) = "B5" Then
Application.EnableEvents = False
'Place here the sub able to create the drop-down validation in "B6"
'it let it creating something else, but without triggering the event
Application.EnableEvents = Trud
End If
End Sub

Hide Entire given rows if a specified cell is blank

I am a newbie in VBA coding.
I am trying to achieve that inside my function
sub Private Sub Worksheet_Change(ByVal Target As Range)
where it checks some specified cells value change to run a given macro. The additional macro that i want to add is that when ever cell a62 is Empty, it will hide rows a56:a61. and consecutively if a82 is empty, it will hide rows a78:a82.
i have the following code but it only hides the rows from the first empty cell until end of sheet.
Sub Test()
Dim i As Long
For i = 4 To 800
If Sheets("Results").Cells(i, 1).Value = "" Then
Rows(i & ":" & Rows.Count).EntireRow.Hidden = True
Rows("1:" & i - 1).EntireRow.Hidden = False
Exit Sub
End If
Next
End Sub
Please, check the next event code:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$62" Or Target.Address = "$A$82" Then
Select Case Target.Address
Case "$A$62"
If Target.Value = "" Then
Range("A56:A61").EntireRow.Hidden = True
Else
Range("A56:A61").EntireRow.Hidden = False
End If
Case "$A$82"
If Target.Value = "" Then
Range("A78:A81").EntireRow.Hidden = True
Else
Range("A78:A81").EntireRow.Hidden = False
End If
End Select
End If
End Sub
It will be triggered only if you MANUALLY change the value of one of the two required cells.
If their value is the result of a formula, Worksheet_Calculate event must be used, but in a different way. This event does not have any argument (no Target) and you must check the two cells in discussion and act according to their value, independent if they were changed or not when the Calculate event is triggered. If this is the case, I can post such an event code, too.
Edited:
For the version which does not involve the manual changing of the values, please copy this event code in the sheet code module:
Private Sub Worksheet_Calculate()
If Me.Range("A62").Value = "" Then
Me.Range("A56:A61").EntireRow.Hidden = True
Else
Me.Range("A56:A61").EntireRow.Hidden = False
End If
If Me.Range("A82").Value = "" Then
Me.Range("A78:A82").EntireRow.Hidden = True
Else
Me.Range("A78:A82").EntireRow.Hidden = False
End If
'Edited:
'The part for both analyzed ranges being empty:
If Me.Range("A62").Value = "" And _
Me.Range("A82").Value = "" Then
'Do here what you need...
End If
End Sub

Excel images to appear based on cell value

I have 2 sheets on excel, one called Raw and one called Graphs. What I want to do is have some cells in Raw and it they =TRUE then I want a shape to appear on the Graphs page.
I am pretty new to VBA so i havent tried much :(
Private Sub Worksheet_Calculate()
With Worksheets("Graph")
If Me.Range("FK45").Value = True Then
.Shapes("Test1").Visible = True
Exit Sub
ElseIf Me.Range("FK45").Value = False Then
.Shapes("Test1").Visible = False
Exit Sub
End If
End With
End Sub
I can get this to work so if FK45 is TRUE the image shows but if FK45 is FALSE it doesn't, But what I want to be able to do is add more to this e.g.
Private Sub Worksheet_Calculate()
With Worksheets("Graph")
If Me.Range("FK45").Value = True Then
.Shapes("Test1").Visible = True
Exit Sub
ElseIf Me.Range("FK45").Value = False Then
.Shapes("Test1").Visible = False
Exit Sub
End If
End With
With Worksheets("Graph")
If Me.Range("FK46").Value = True Then
.Shapes("Test2").Visible = True
Exit Sub
ElseIf Me.Range("FK46").Value = False Then
.Shapes("Test2").Visible = False
Exit Sub
End If
End With
End Sub
I want them all to be independent from each other and be able to add more if necessary
If FK45 is TRUE Image1 shows
If FK45 is FALSE Image1 doesn't show
and/or
If FK46 is TRUE Image2 shows
If FK46 is FALSE Image2 doesn't show
and/or
If FK47 is TRUE Image3 shows
If FK47 is FALSE Image3 doesn't show
and so on...
This is how I would do it
In VB Editor find your Worksheet and Shape objects and rename their system name to something intutive in their respective property windows.
This way you can get rid of With Worksheets("Graph") construction, instead you can call them by their system name like With Graph. This will also come in handy if you wish to rename your worksheets or shapes.
Note that you Exit Sub after each cell check, your procedure stops after first cell and doesn't proceed any further.
Instead of Worksheet.Calculate event I advise using Worksheet.Change. This way you can iterate through your cells one by one.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngCell As Range
Dim shpImage As Shape
For Each rngCell In Target.Cells
' check if change was made in "FK"
If Not Intersect(rngCell, Me.Columns("FK")) Is Nothing Then
Select Case rngCell.Row
Case 45: Set shpImage = Graph.MyImage_1
Case 46: Set shpImage = Graph.MyImage_2
End Select
' if only boolean values present, no need for IF construction
shpImage.Visible = rngCell.Value : Set shpImage = Nothing
End If
Next
End Sub
If you had separate column for image name it would be much easier, you could check like this (for example, shape names are located in "FL" column)
Graph.Shapes(rngCell.Offset(0, 1).Value).Visible = rngCell.Value

VBA: hide and unhide code not working

I'm new to VBA and have been trying to write a code that hides and unhides rows based on the input value of a certain cell address. However, it doesn't work and I don't why. I have posted my code below:
Sub Hide()
If Worksheets("IS").Range("B8").Value = "Show All" Then
Worksheets("IS").Rows("12:165").EntireRow.Hidden = False
End If
If Worksheets("IS").Range("B8").Value = "Just Revenue" Then
Worksheets("IS").Rows("12:165").EntireRow.Hidden = False
Worksheets("IS").Rows("28:165").EntireRow.Hidden = True
End If
If Worksheets("IS").Range("B8").Value = "Just Expenses" Then
Worksheets("IS").Rows("12:165").EntireRow.Hidden = False
Worksheets("IS").Rows("12:27").EntireRow.Hidden = True
Worksheets("IS").Rows("160:165").EntireRow.Hidden = True
End If
If Worksheets("IS").Range("B8").Value = "Just Cogs" Then
Worksheets("IS").Rows("12:165").EntireRow.Hidden = False
Worksheets("IS").Rows("12:27").EntireRow.Hidden = True
Worksheets("IS").Rows("64:165").EntireRow.Hidden = True
End If
If Worksheets("IS").Range("B8").Value = "Just Totals" Then
Worksheets("IS").Rows("12:165").EntireRow.Hidden = False
Worksheets("IS").Rows("12:25").EntireRow.Hidden = True
Worksheets("IS").Rows("28:61").EntireRow.Hidden = True
Worksheets("IS").Rows("64:91").EntireRow.Hidden = True
Worksheets("IS").Rows("93:155").EntireRow.Hidden = True
End If
End Sub
Any help with why my code doesn't work or any tips to improve it would be much appreciative.
Rewriting for Worksheet_Change:
In your VBE, paste this code into the code sheet for the "IS" worksheet (double click it in the Project - VBAProject pane. If the Project - VBAProject pane is not visible in your VBE, go to View>>Project Explorer):
Private Sub Worksheet_Change(ByVal Target As Range)
'Ensure that we don't trigger another change event while this code is running
Application.EnableEvents = False
'Check if cell B8 triggered this change:
If Not Intersect(Target, Range("B8")) Is Nothing Then
'B8 changed... which means B8 is "Target" variable
Select Case Target.Value
Case "Show All"
Worksheets("IS").Rows("12:165").EntireRow.Hidden = False
Case "Just Revenue"
Worksheets("IS").Rows("12:165").EntireRow.Hidden = False
Worksheets("IS").Rows("28:165").EntireRow.Hidden = True
Case "Just Expenses"
Worksheets("IS").Rows("12:165").EntireRow.Hidden = False
Worksheets("IS").Rows("12:27").EntireRow.Hidden = True
Worksheets("IS").Rows("160:165").EntireRow.Hidden = True
Case "Just Cogs"
Worksheets("IS").Rows("12:165").EntireRow.Hidden = False
Worksheets("IS").Rows("12:27").EntireRow.Hidden = True
Worksheets("IS").Rows("64:165").EntireRow.Hidden = True
Case "Just Totals"
Worksheets("IS").Rows("12:165").EntireRow.Hidden = False
Worksheets("IS").Rows("12:25").EntireRow.Hidden = True
Worksheets("IS").Rows("28:61").EntireRow.Hidden = True
Worksheets("IS").Rows("64:91").EntireRow.Hidden = True
Worksheets("IS").Rows("93:155").EntireRow.Hidden = True
End Select
End If
'Turn events back on so this code triggers again
Application.EnableEvents = True
End Sub
There are quite a few events that we can hook VBA to (SelectionChange, DoubleClick, Workbook_Close, etc). In this case we are hooking to Worksheet_Change().
This code gets triggered every time this worksheet experiences a change. The Target variable will hold the range that triggered the event. So we test to see if that Target intersects with Range("B8") which means B8 was changed. Then we perform the code inside the If block.
I switched your If/ElseIf over to a Select/Case just because it makes for cleaner code since we are testing a single condition (the value of B8) over and over again.
In this code we also toggle off the Excel Applications EnableEvents feature. This feature is what allowed this Worksheet_Change() to get triggered in the first place. Often times in the code we make more changes to the worksheet (hiding rows or columns, for instance) which will trigger the application to run Worksheet_Change() again... while it's running Worksheet_Change() already. This can cause code to run superfluously and, often, cause an endless loop that makes excel crash.
This code needs to be pasted on the sheet where you want are wanting to execute the code. You will not need to qualify your ranges with the sheets once the code is there as well.
You can just refer directly to your range without the Worksheets("IS"). as so:
Rows("so and so").EntireRow.Hidden = True
You can also just refer to your TargetRange by variable now like so:
If MyTarget = "Just Revenue" Then
I inserted one of your conditions in the code as an example
Option Explicit
Private Sub worksheet_change(ByVal target As Range)
Dim MyTarget As Range
Set MyTarget = Range("B8")
If Not Intersect(target, MyTarget) Is Nothing Then
Application.EnableEvents = False
'Your CODE HERE
If MyTarget = "Show All" Then
Rows("12:165").EntireRow.Hidden = False
End If
Application.EnableEvents = True
End If
End Sub

Clear Merged Cell Contents Based on Data Validation List Selection

I'm trying to clear the contents of a merged cell based on the selection from a data validation list (the list is also in merged cells). And yes, "Don't use merged cells!" is great advice (I prefer "center across") but would complicate things in this case. I've tried naming the merged cells, using "MergeArea," etc. but I haven't been successful in finding a solution yet.
Below is the latest iteration I have. Please note I've been trying to make just one selection ("Yes." in this case) work before adding in the second selection (or "blank" in this case).
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Range("Max_Advance").MergeArea Then
If Range.Validation.Type = 2 Then
Range("Days_Needed").MergeArea.ClearContents
End If
End If
exitHandler:
Application.EnableEvents = True
Exit Sub
End Sub
Can anyone help? I've also attached a picture to visually show what I'm working with:
Does this work for you?
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address(0, 0) = "A2" Then
On Error GoTo exitHandler
Application.EnableEvents = False
If LCase(Target.Value) <> "no. please enter." Then
Range("Days_Needed").MergeArea.ClearContents
End If
End If
exitHandler:
Application.EnableEvents = True
Exit Sub
End Sub
You can usually clear the contents of a merged cell by treating it as if it was the first cell in the merge.
for example:
Range("A2")=""

Resources