Using VBA to hide rows in Excel if a Value returns 0 - vba

I'm trying to create an automated proposal document, and when a certain value returns 0 in my spreadsheet, I want to hide a bunch of extraneous rows/graphics that are in those rows to reduce clutter and make a clean pdf to send out.
Private Sub Worksheet_Change(ByVal Target As Range)
If .Range("F15").Value = "0" Then
Rows("7:25").EntireRow.Hidden = True
ElseIf Range("f15").Value Then
Rows("7:25").EntireRow.Hidden = False
End If
End Sub
Where should I go from here? If f15 returns as a value greater than 0, I wish for the rows to be shown.

try this, holp it works
Private Sub Worksheet_Change(ByVal Target As Range)
If .Range("F15").Value = "0" Then
Rows("7:25").EntireRow.Hidden = True
Else
Rows("7:25").EntireRow.Hidden = False
End If
End Sub

Related

How do I error handle when a cell is blank and there are many routines

I have a sheet with a lot of code that I have worked on throughout the last couple of years but I am new to VBA and did not incorporate any error handling. I tried a few things but I could never make it work. It did not really affect me until recently. Most of my routines are driven by a cell that contains a sales price (cell D5). I am using Worksheet_Change ByVal target as range to change things when different cells are changed so when the sales price is changed it starts running routines.
What I have noticed is that this particular routine is the first one that gives me a VBA error if I delete the sales price in cell D5. So I thought I can ask someone to give me a simple code to catch the empty cell before the routine fires and maybe a popup saying "Sales Price cannot be blank" and perhaps revert to the previous value of that cell. The debug error takes me to the line of code that starts with "If Sheets("Main").Range("D6").Value < 0.8001"
Sub Calc_MI()
If Sheets("Main").Range("D12").Value = "FHA" Then
Sheets("Main").Range("D16").Value = 0.85
Else
If Sheets("Main").Range("D6").Value < 0.8001 Or
Sheets("Main").Range("D12").Value = "VA" Then
Sheets("Main").Range("D16").Value = ""
Else
If Sheets("Main").Range("G14").Value > 0.45 Then
Sheets("Main").Range("D16").Value = (Sheets("Closing
Costs").Range("BP100").Value + Sheets("Closing
Costs").Range("BP101").Value + Sheets("Closing
Costs").Range("BP102").Value)
Else
Sheets("Main").Range("D16").Value = (Sheets("Closing
Costs").Range("BP100").Value + Sheets("Closing
Costs").Range("BP102").Value)
End If
End If
End If
End Sub
any help would be greatly appreciated :-)
you could place this in "Main" sheet code pane
Option Explicit
Dim oldVal As Variant
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$D$5" Then
If IsEmpty(Target) Then
MsgBox "Sales Price cannot be blank"
Application.EnableEvents = False ' disable events to prevent change event fire in an infinite loop
Target.Value = oldVal ' restore old backup value
Application.EnableEvents = True ' enable events back
End If
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Address = "$D$5" Then oldVal = Target.Value ' if D5 selected then backup its value
End Sub

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

How to clear cell when enter invalid data in Excel using VBA

I have an Excel sheet in which I am accepting value from the user when user enter a value a VBA will run which check the data is valid or not and if the data is not valid it will prompt a message saying invalid data. Here is my code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$D$12" Or Target.Address = "$D$13" Or Target.Address = "$D$14" Or Target.Address = "$D$15" Then
Call Room
End If
End Sub
Room method is
Sub Room()
Dim lastRow As Long
If IsNumeric(Range("i17")) Then
If [I17] < 0 Then
MsgBox "msg "
End If
End If
End Sub
In I17 cell I have a formula
=C6-(D12+(2*D13) + (2*D14) + (3*D15))
My problem is when wrong data is enter in any of the cells (D12, D13, D14, D15) then the cell should be clear automatically after showing prompt message.
How can this be done?
The first thing that you should do is clean up how you check what Target is. It could be multiple cells (Fill Down, paste a range, ...). This is accomplished by intersecting Target with the range you are interested in, and We'll store into a range variable, for later. If there is no overlap, then intersect will return an empty object, which we can test for with is Nothing.
The next thing to note is that odd things (infinite recursion) can happen if we allow the Worksheet_Change event to fire by changing a cell. To prevent this, we will turn off events before calling Room, and turn it back on after we're done.
Next we pass the range that has changed into room, so we can modify it from within that subroutine.
And, finally we modify the affected range after displaying the message. Note that I have used a command to literally clear the cell. Since you are performing calculations based on that data, you might prefer to set it to default value, like 0, using a.value = 0 instead.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim a As Range
Set a = Intersect(Target, Range("D12:D15"))
If Not a Is Nothing Then
Application.EnableEvents = False
Room a
Application.EnableEvents = True
End If
End Sub
Sub Room(a As Range)
Dim lastRow As Long
If IsNumeric(Range("I17")) Then
If Range("I17").Value < 0 Then
MsgBox "msg "
a.ClearContents
End If
End If
End Sub
As a side note, I have a used a bad variable name a, since I don't know what that range represents. You should pick something that describes to future maintainers what is going on.
use this
Private Sub Worksheet_Change(ByVal Target As Range)
Dim t As Range
Set t = Intersect(Target, [D12:D15])
Application.EnableEvents = 0
If Not t Is Nothing Then
Call Room
If [I17] < 0 Then Target.Value = ""
End If
Application.EnableEvents = 1
End Sub

VBA Excel Toggle Button: With 10 rows, how do I unhide each row separately and not in a group?

I'm working in VBA and Excel 2007 with active control toggle button, which I'm trying to figure out how to get to function the way I need it to. Will someone please help me out?
This works for only unhiding a single row at a time for two hidden rows:
Private Sub ToggleButton1_Click()
If ToggleButton1 Then
Rows(76).EntireRow.Hidden = False
Else
Rows(77).EntireRow.Hidden = False
End If
End Sub
This does not work for only unhiding a single row at a time for more than two hidden rows:
Private Sub ToggleButton1_Click()
If ToggleButton1 Then
Rows(76).EntireRow.Hidden = False
Else
Rows(77).EntireRow.Hidden = False
Else
Rows(78).EntireRow.Hidden = False
End If
End Sub
What do I need to do to get this to work? This is all I need the toggle button to do. Each row has identical information (text fields, field names, etc.), but I need each row to only become visible upon clicking just one toggle button. I know multiple toggle buttons will works like a breeze, but I really am wanting to just use one toggle button to unhide each row, one at a time. By default, the rows will be hidden first, too.
You can use a counter and then count down and you should be able to do what you are looking for. In this example if the counter is 0 we hide the rows 1-3 and then show each row untill we are back to 0 and then hide them again when we click the button.
Dim counter As Integer
Private Sub ToggleButton1_Click()
If counter = 0 Then
Rows(1).EntireRow.Hidden = True
Rows(2).EntireRow.Hidden = True
Rows(3).EntireRow.Hidden = True
counter = 3
Else
Rows(counter).EntireRow.Hidden = False
counter = counter - 1
End If
End Sub
Hope it helps
//KH
Try this:
Private Sub ToggleButton1_Click()
Dim rng As Range
Dim myrow As Range
Set rng = Me.Rows("75:85")
If Me.ToggleButton1 Then
For Each myrow In rng
If Not myrow.Hidden Then
myrow.Hidden = True
If myrow.row = 85 Then
myrow.Offset(-10, 0).Hidden = False
Else
myrow.Offset(1, 0).Hidden = False
End If
Exit For
End If
Next
End If
End Sub
This hides and unhides Rows76-85 simultaneously.
You start with all 10 Rows hidden.
After 1st click, Row 76 will appear and so on.
All will be hidden again after Row 85 was shown.
I used 10 rows based on your question title, adjust it to suit your needs.
Edit1:
Private Sub ToggleButton1_Click()
Dim rng As Range
Dim myrow As Range
Set rng = Me.Rows("76:85")
If Me.ToggleButton1 Then
For Each myrow In rng
If myrow.Hidden Then
myrow.Hidden = False
Exit Sub
End If
Next
rng.Hidden = True
End If
End Sub
Above will work as you want it.
Although you already accepted an answer, I still would want to correct my code.
At least for you and others reference.

Custom function will not update automatically (settings are set to auto calculations!)

I have a custom function that detects if a cell is bold
Function isBold(cellBold)
If cellBold.Font.Bold = True Then
isBold = 1
ElseIf cellBold.Font.Bold = False Then
isBold = 0
Else
isBold = 0
End If
End Function
Puts 1 in a cell if the reference cell is bold and 0 if it is not bold
This works well and all the first time around but if I make the reference cell bold the number stays at 0. Automatic calculations are on, the only way for the function to calculate again is to retype the function
Adding Application.Volatile to the top of your function will make it auto update when the workbook change event is fired.
Function isBold(cellBold)
Application.Volatile
If cellBold.Font.Bold = True Then
isBold = 1
ElseIf cellBold.Font.Bold = False Then
isBold = 0
Else
isBold = 0
End If
End Function
This will not help you if you just bold a result but you can add an event to the sheet you're working on
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Calculate
End Sub
If both of these things are in place, your formula will update every time you select a different cell which may work well enough for you. However, I suggest using this method with caution because if you have a very large number of formulas this could slow things down.
-Edit- This should fix the copy paste issue.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim col As Range
For Each col In ActiveSheet.UsedRange.Columns
col.Calculate
Next
End Sub
OK, So I'll be the first to admit this is not an ideal solution, and is pretty hackish. But i think it will fix your solution.
After adding the volatile line to your code as so:
Function isBold(cellBold)
Application.Volatile True
If cellBold.Font.Bold = True Then
isBold = 1
ElseIf cellBold.Font.Bold = False Then
isBold = 0
Else
isBold = 0
End If
End Function
First Change your Workbook_Open to this:
Private Sub Workbook_Open()
Sheets("Sheet1").rngLastCell = Range("A1").Address
Sheets("Sheet1").fntLastCell = Range("A1").Font.Bold
End Sub
Then on the worksheet you are working with (In my example Sheet1) Add this to the Worksheet function:
Option Explicit
Public fntLastCell As Boolean
Public rngLastCell As String
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Sheets("Sheet1").Range(rngLastCell).Font.Bold <> fntLastCell Then
Calculate
End If
Sheets("Sheet1").rngLastCell = Target.Address
Sheets("Sheet1").fntLastCell = Target.Font.Bold
End Sub
Now to have it work you must Save then close, Then re open your worksheet.
This works by setting 2 global variables each time you select a new cell.
a Boolean variable that states weather the Last Cell selected WAS PREVIOUSLY Bold or not. And a String Variable that references that same Cell. So, you can now check the Bold state of the cell you exited (when it was entered) against the Current Bold State of the cell you just existed and if there was a change it will calculate the workbook. Otherwise nothing will happen.
Hope this works and helps,
Cheers