excel vba - msgbox abort/retry/ignore - vba

I am validating input in an Excel worksheet. When the user enters invalid data a MsgBox is shown, giving the option to Abort/Retry/Ignore.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If IsNumeric(Range("i17")) Then
If [I17] < 0 Then
result = MsgBox("Critical Error Encountered", vbAbortRetryIgnore + vbCritical, "Error Encountered")
If result = 3 Then
ActiveCell.Value = Empty
End If
End If
End If
End sub
Since I have written this code in SelectionChange when I click enter then only it show the message box and since I'm writing Active.Cell = Empty it is deleting the next cell, but I mean it to clear the cell which contains invalid data.

If you use the SelectionChange event, the Target range is the cell just selected and not the cell which has just been changed. If you use the Change event of the worksheet, then Target refers to the cell that has been changed. So, assuming that cell I17 is some kind of subtotal/validation cell and not the cell into which the user enters data, try this:
Private Sub Worksheet_Change(ByVal Target As Range)
If IsNumeric(Range("i17")) Then
If [I17] < 0 Then
result = MsgBox("Critical Error Encountered", vbAbortRetryIgnore + vbCritical, "Error Encountered")
If result = 3 Then
Target.Value = Empty
Target.Select
End If
End If
End If
End Sub
This code will clear the cell just changed and change the selection back to that cell if the user selects the Abort button in the message.

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

VBA code to popup msgbox and return to the previous value

I need a VBA code that pops up error/warning message when the cell value is exceeds more than 100.
For example, if value entered in B2, F2 cells updates automatically. Higher the B2 value will lead F2 value cross 100 and sheet becomes error.
So, I need to give message here to uses, when F2 goes beyond 100 and B2 should return to last value.
My current code is very basic. Please help me to get thru this.
If Sheets("200L_50°C").Range("L2").Value < 100 Then
MsgBox "No further pressure drop at higher operating temperatures", vbOKOnly, "High temperature"
Update, this is the code I put in my worksheet. I get error on the first line:
Public G1Value As Integer
Private Sub Worksheet_Change(ByVal Target As Range)
If Target = Range("G1") Then
If Range("L2") > 100 Then
MsgBox "Error. Invalid value for G1"
Range("G1") = G1Value
Else: End If
Else: End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target = Range("G1") Then
G1Value = Range("G1")
Else: End If
End Sub
Hold up, I think I have a better understanding of your question now. When a user puts something in B2, if that change causes cell F2 to go higher than 100, then you want to output an error message and return cell B2 to the value that it was. Here's how you can do that easily:
Go to the view code of the worksheet you are on by right-clicking the worksheet tab name:
Then add in this code (if a duplicate method exists, then comment out the old code or replace it if it's unimportant).
Public B2Value As Integer
Private Sub Worksheet_Change(ByVal Target As Range)
If Target = Range("B2") Then
If Range("L2") > 100 Then
MsgBox "Error. Invalid value for B2"
Range("B2") = B2Value
Else: End If
Else: End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target = Range("B2") Then
B2Value = Range("B2")
Else: End If
End Sub
I'm not sure if I get your question, but it seems you could use data validation in cell B2 to prevent users from inputting values higher than 100. Click on cell B2, go to the "Data" tab, and click on "Data Validation". Modify the conditions like the image below, and on the "Error Alert" tab, put in the message you want them to see when they try to enter a value higher than 100.

How to Throw an Error when the User Hit Save in VBA

In my Column A, I have a selection that lets the user to select "Yes" or "No". There's a required cell for both selection.
Example:
If User selects "YES"
Mandatory cells will be in Colum A, D and E
If User selects "No"
Mandatory cells will be in Colum B, C and G
Lets say the in Row 1, the User selects "Yes" and entered a value on A1 and E1 but he forgot to add value in cell D1.
In Row 2, The user selects "No" and entered a value on B2 and C2 and forgot to enter a value on cell G2.
When he hit save, I want to throw an error saying the "Enter a value of the following cells. D1, G2.
I have this code below:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim Target As Range
If Not Intersect(Target, Range("A:A")) Is Nothing Then
If Target = "YES" Then
For i = 1 To 15
If Target.Offset(0, i).Value = "" Then
MsgBox "Enter values on the mandatory cells (green)", vbCritical, ""
End If
Next i
Cancel = True
ElseIf Target = "NO" Then
For i = 16 To 30
If Target.Offset(0, i).Value = "" Then
MsgBox "Enter values on the mandatory cells (green)", vbCritical, ""
End If
Next i
Cancel = True
End If
End If
End Sub
Use the workbook beforeSave event and handle accordingly:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, _
Cancel as Boolean)
'your code here
End Sub
Edit for OP's new code:
You never defined what Target is in your code, so the intersect method will always return nothing (if it even works at all). I think you are confusing the Worksheet_change method (which includes a "Target" range), with that of Save. You'll have to define what the Target is when the BeforeSave method runs. I'd recommend running a loop through the specific range of values and checking that all the desired conditions are met. If some aren't as desired, then you can display a message for the user pointing them to the missing data and prevent the save.
Try with one of these two lines. It is not a good idea to throw errors like this, but if you want so much...
This is a message box:
msgbox "Enter a value of the following cells. D1 G2"
This is an error:
err.Raise 1, description:= "Enter a value of the following cells. D1 G2"

VBA Nested IF statement

I want to show a message box when a specific cell has a particular value in it. I have done this with the following code;
If Range("P8") = "Y" Then
MsgBox "Message here"
End If
This is within the Worksheet_Change sub so shows the message box everytime another cell value changes. I have tried to get around this by adding a boolean variable, set to true when the messagebox has been shown the first time;
If Range("P8") = "Y" Then
If messageshown = False Then
messageshown = True
MsgBox "Message here"
Else
End If
Else
End If
However the message box still shows every time I change a cell in the worksheet. I have a feeling it';s to do with the way I have written the nested if statement but have tried various different ways and orders of where I place else and end if but to no avail.
Use the Target argument instead - this refers to the actual cell being changed, which is what you are interested in. Test the address of the Target to see if it's the cell you need and then act accordingly. This will stop the message showing when another cell is changed.
Private Sub Worksheet_Change(ByVal Target As Range)
With Target
If .Address = "$P$8" And .Value = "Y" Then MsgBox "Message here"
End With
End Sub
Try this code, it first checks which cell is changed, if it is anything but P8, it will not pop the messagebox.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$P$8" Then
If Range("P8") = "Y" Then
MsgBox "This works"
End If
End If
End Sub
As pointed out by Macro Man, there is a more optimal, more efficient option.

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