I have an input box asking user to enter a date. How do I let the program know to stop if the user click cancel or close the input dialog instead of press okay.
Something like
if str=vbCancel then exit sub
Currently, user can hit OK or Cancel but the program still runs
str = InputBox(Prompt:="Enter Date MM/DD/YYY", _
Title:="Date Confirmation", Default:=Date)
If the user clicks Cancel, a zero-length string is returned. You can't differentiate this from entering an empty string. You can however make your own custom InputBox class...
EDIT to properly differentiate between empty string and cancel, according to this answer.
Your example
Private Sub test()
Dim result As String
result = InputBox("Enter Date MM/DD/YYY", "Date Confirmation", Now)
If StrPtr(result) = 0 Then
MsgBox ("User canceled!")
ElseIf result = vbNullString Then
MsgBox ("User didn't enter anything!")
Else
MsgBox ("User entered " & result)
End If
End Sub
Would tell the user they canceled when they delete the default string, or they click cancel.
See http://msdn.microsoft.com/en-us/library/6z0ak68w(v=vs.90).aspx
Following example uses InputBox method to validate user entry to unhide sheets:
Important thing here is to use wrap InputBox variable inside StrPtr so it could be compared to '0' when user chose to click 'x' icon on the InputBox.
Sub unhidesheet()
Dim ws As Worksheet
Dim pw As String
pw = InputBox("Enter Password to Unhide Sheets:", "Unhide Data Sheets")
If StrPtr(pw) = 0 Then
Exit Sub
ElseIf pw = NullString Then
Exit Sub
ElseIf pw = 123456 Then
For Each ws In ThisWorkbook.Worksheets
ws.Visible = xlSheetVisible
Next
End If
End Sub
The solution above does not work in all InputBox-Cancel cases. Most notably, it does not work if you have to InputBox a Range.
For example, try the following InputBox for defining a custom range ('sRange', type:=8, requires Set + Application.InputBox) and you will get an error upon pressing Cancel:
Sub Cancel_Handler_WRONG()
Set sRange = Application.InputBox("Input custom range", _
"Cancel-press test", Selection.Address, Type:=8)
If StrPtr(sRange) = 0 Then 'I also tried with sRange.address and vbNullString
MsgBox ("Cancel pressed!")
Exit Sub
End If
MsgBox ("Your custom range is " & sRange.Address)
End Sub
The only thing that works, in this case, is an "On Error GoTo ErrorHandler" statement before the InputBox + ErrorHandler at the end:
Sub Cancel_Handler_OK()
On Error GoTo ErrorHandler
Set sRange = Application.InputBox("Input custom range", _
"Cancel-press test", Selection.Address, Type:=8)
MsgBox ("Your custom range is " & sRange.Address)
Exit Sub
ErrorHandler:
MsgBox ("Cancel pressed")
End Sub
So, the question is how to detect either an error or StrPtr()=0 with an If statement?
If your input box is an array, it does not work. I have solved it by adding a check for if it is an array first.
Dim MyArrayCheck As String
Dim MyPlateMapArray as variant
MyPlateMapArray = Application.InputBox("Select ....", Type:=8)
MyArrayCheck = IsArray(MyPlateMapArray)
If MyArrayCheck = "False" Then
Exit Sub
End If
I have solved it with a False like below
MyLLOQ = Application.InputBox("Type the LLOQ number...", Title:="LLOQ to be inserted in colored cells.", Type:=1)
If MyLLOQ = False Then Exit Sub
If user click cancel the sub will exit.
Another suggestion.
Create a message box when inputbox return null value. Example:
Dim PrC as string = MsgBox( _
"No data provided, do you want to cancel?", vbYesNo+vbQuestion, "Cancel?")
Sub TestInputBox()
Dim text As String
text = InputBox("Type some text")
If text = "" Then
MsgBox "button cancel pressed or nothing typed"
Else
MsgBox text
End If
End Sub
Inputbox send a boolean False value when Cancel is pressed.
contenidoy = Application.InputBox("Cantidad = ", titulox, contenidox, , , , , Type:=1)
'ESC or CANCEL
If contenidoy = False Then
MsgBox "Cancelado"
Else
MsgBox "Edición aceptada"
'End If
Related
This question already has an answer here:
How to handle the InputBox cancel button?
(1 answer)
Closed 1 year ago.
The below code unprotects all sheets in the workbook and prompts for the password only once.
What I am trying to achieve is:
If user presses "cancel" on the password input window, the sub exits.
If user presses "ok" without entering anything, it should behave in the same way as entering the wrong password i.e. go to the error popup.
The issue is on pressing "ok" or "cancel" it doesnt behave as above, rather, in both cases, it brings up the default password prompt 3 more times, 1 for each sheet.
I am struggling with perfecting the if/then logic and have swapped things around many times, almost getting there but never quite.
Sub UnprotectAllSheets()
Dim ws As Worksheet
Dim pass As String
If ActiveSheet.ProtectContents = False Then
MsgBox "Already Unprotected"
Exit Sub
Else
pass = InputBox("Password?")
On Error GoTo Popup:
For Each ws In ThisWorkbook.Worksheets
ws.Unprotect pass
Next ws
If ActiveSheet.ProtectContents = False Then
MsgBox "Sheets now Unprotected"
ElseIf StrPtr(pass) = "" Then 'if press OK on blank entry
MsgBox "Incorrect Password", vbCritical, "Admin"
ElseIf pass = 0 Then 'if press CANCEL
Exit Sub
End If
End If
Popup:
If err.Number = 1004 Then
MsgBox "Incorrect Password", vbCritical, "Admin"
End If
End Sub
InputBox behaves similarly for cases of pressing Cancel, inputting an empty string or pressing window corner x, in terms of String return.
The next sub gives a possibility to separate the above cases:
Sub testInputBox()
Dim pass
pass = InputBox("Password?")
'standard behavior without checking the result:
MsgBox "Pass is " & pass 'it will be an empty string in case of Cancel, empty string, pressing window corner X
If StrPtr(pass) = 0 Then
MsgBox ("Cancel pressed...") 'the same message if window corner `X` is pressed
ElseIf pass = vbNullString Then
MsgBox ("Empty string..") 'OK for an empty string
Else
MsgBox ("You entered " & pass)
End If
End Sub
No need of error handling if you use the above way of identification.
And I should modify your code to act in this way:
Sub UnprotectAllSheets()
Dim ws As Worksheet, pass As String, myPass As String, i As Long
myPass = "1234"
TryAgain:
pass = InputBox("Password?")
If StrPtr(pass) = 0 Then Exit Sub 'for Cancel and window corner 'X' pressed
If pass = vbNullString Then MsgBox "You did not enter any password!", vbCritical, "Admin": Exit Sub
If pass <> myPass Then
MsgBox "Incorrect Password" & vbCrLf & _
IIf(i < 3, "Please, try again!", "We stop here..."), vbCritical, "Admin"
If i >= 3 Then Exit Sub
i = i + 1
GoTo TryAgain
End If
For Each ws In ThisWorkbook.Worksheets
If ws.ProtectContents = True Then
ws.Unprotect pass
End If
Next ws
End Sub
I am using a Excel VBA userform to change the font case as below picture. When RefEdit control have correct Range, then it is working fine. But if I click "Apply" button keeping RefEdit blank/ only Space/ any word(invalid Range), Userform disappear without showing any error notification.
For Uppercase code:-
Sub UpperCaseFont()
For Each x In Range(CaseRefEdit.Value)
If Not IsEmpty(x.Value) Then
x.Value = UCase(x.Value)
End If
Next
MsgBox "Done"
End Sub
LowerCase code:-
Sub LowerCaseFont()
For Each x In Range(CaseRefEdit.Value)
If Not IsEmpty(x.Value) Then
x.Value = LCase(x.Value)
End If
Next
MsgBox "Done"
End Sub
Propercase code:-
Sub ProperCaseFont()
For Each x In Range(CaseRefEdit.Value)
If Not IsEmpty(x.Value) Then
x.Value = WorksheetFunction.Proper(x.Value)
End If
Next
End Sub
CommandButton code:-
Private Sub CaseApplyCommandButton_Click()
If UpperCase = True Then Call UpperCaseFont
If LowerCase = True Then Call LowerCaseFont
If ProperCase = True Then Call ProperCaseFont
For that reason, I have tried to modified as below, But still i am facing the problem that if RefEdit is blank and I click on "Apply" button then userform disappear and also found that other all userform start unknown problem to initialize.
Private Sub CaseApplyCommandButton_Click()
'Font Case
Dim Rng As Range
On Error Resume Next
Set Rng = Range(Me.CaseRefEdit.Value)
MsgBox Rng
On Error GoTo 0
If Rng Is Nothing Then
MsgBox "Select the Cells to change the case"
Else
If UpperCase = True Then Call UpperCaseFont
If LowerCase = True Then Call LowerCaseFont
If ProperCase = True Then Call ProperCaseFont
End If
End Sub
I have found that problem is started when I add below code:-
Private Sub CaseRefEdit_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Range(CaseRefEdit.Value).Select
End Sub
As per my understanding when RefEdit is not giving any range for input any number or word or keeping blank, then userform disappear. Any solution for this?
On the second question.
The [if IsError (range ("Hello") then ...] expression first evaluates the range ("Hello"), and if it is invalid, an error occurs before calling the function. Therefore, it is better to pass the address of the range to the IsError function, and calculate the range inside the function and determine its correctness.
Function IsError(addr As String) As Boolean
Dim rng As Range
On Error Resume Next
Set rng = Range(addr)
IsError = rng Is Nothing
End Function
Sub test1()
If IsError("%$%W34") Then
Debug.Print "Range is invalid"
Else
Debug.Print "Range is correct"
End If
End Sub
my problem is solved as below. Thanks #Алексей Р.
Private Sub CaseRefEdit_Exit(ByVal Cancel As MSForms.ReturnBoolean)
On error resume next
Range(CaseRefEdit.Value).Select
End Sub
Anyone know, how to check Range("etc")/ Range(123) is valid or not? Like-
If IsError(range("etc")) then
...
else
....
end if
You may use On Error statement, for example:
Function testRNG(addr As String) As Range ' returns correct Range object or Nothing otherwise
' initially testRNG = Nothing
On Error Resume Next
Set testRNG = Range(addr) ' if the address is correct, testRNG returns Range, otherwise an error occurs, the expression is not evaluated and testRNG remains Nothing
End Function
Sub foo()
Dim addr As String
addr = "W12"
Set Rng = testRNG(addr)
If Rng Is Nothing Then
Debug.Print "Address " & addr & " is wrong"
Else
Debug.Print "Range " & Rng.Address & " is correct"
End If
End Sub
I'm trying to write a code to trace every change made by the user on any worksheet. The user will input data and from time to time will erase said data and/or correct the original value they inserted. If the change is either deletion or modification, an Userform will pop up and the user will include a reason for that change. Right now I'm able to display the form everytime the user makes one of the changes mentioned before, but I'm not able to retrieve the reason, could you guys help me?
This is what I have for the UserForm
Private Sub CommandButton1_Click()
Dim msgvalue As VbMsgBoxResult
Dim value As String
msgvalue = MsgBox("Do you wish to save the change?", vbYesNo + vbInformation, "Confirm")
If msgvalue = vbNo Then GoTo Command
If msgvalue = vbYes Then
value = UserForm1.txtCmmt.Value
If value = "" Then GoTo Command
End
End If
Command:
MsgBox ("A reason must be provided")
With UserForm1
.txtCmmt.Value = ""
End With
End Sub
So if a user tries to delete a value, the code is the following:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim sLastAction As String
Dim Cell As Range
sLastAction = Application.CommandBars("Standard").Controls("&Undo").List(1)
For Each Cell In Target
If sLastAction = "Clear" Or sLastAction = "Delete" Or Left(sLastAction, 9) = "Typing ''" Then
UserForm1.Show 'this is where I'm stuck, I'm not sure how to retrieve the value from the form
End If
'the code continues to retrieve other info from the changes made, including the "reason"
Thanks for the help!
Try the next way, please:
Let us say that your text box where the comment will be written is named "txtComment".
Put this code in its Exit event:
Private Sub txtComment_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If Me.txtComment.text <> "" Then
If ActiveSheet.Name <> "LogDetails" Then
Application.EnableEvents = False
Sheets("LogDetails").Range("A" & rows.count).End(xlUp).Offset(0, 5).Value = Me.txtComment.text
Application.EnableEvents = True
Unload Me
End If
End If
End Sub
Let the existing Worksheet_Change event as it is, only launching the form and maybe making a Public boolean variable (from a standard module) True (something boolStop) which will not allow changing anything in any worksheet until it is not False.
Then fill the text you need in the text box ("txtComment", or however you named it) and press Enter. If my above suggestion looks interesting for you, the last line of the text box event will be boolStop = False.
If you understand how to implement the above simple solution, you maybe will forget about a user form and use a simple InputBox, as in the next example:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address(0, 0) <> "E1" Then Exit Sub
Dim sLastAction As String, comValue As String
Dim Cell As Range
sLastAction = Application.CommandBars("Standard").Controls("&Undo").list(1)
For Each Cell In Target
If sLastAction = "Clear" Or sLastAction = "Delete" Or left(sLastAction, 9) = "Typing ''" Then
WritePlease:
comValue = InputBox("Please write the reason for cell """ & Cell.Address & """ (" & sLastAction & ").", "Reason, please")
If comValue = "" Then GoTo WritePlease
If ActiveSheet.Name <> "LogDetails" Then
Application.EnableEvents = False
'Stop
Sheets("LogDetails").Range("A" & rows.count).End(xlUp).Offset(0, 5).Value = comValue
Application.EnableEvents = True
End If
End If
Next
End Sub
Sub Export_Click()
Dim Rng As Range
Dim WorkRng As Range
Dim vFile As Variant
Dim x As Range
On Error Resume Next
TitleId = "Export to CSV file"
x = WorkRng
Set WorkRng = Range("D12:I100")
Set WorkRng = Application.InputBox("Range", TitleId, WorkRng.Address, Type:=8)
If x = "" Then Exit Sub
Application.ActiveSheet.Copy
Application.ActiveSheet.Cells.Clear
WorkRng.Copy Application.ActiveSheet.Range("A1")
vFile = Application.GetSaveAsFilename(InitialFileName:=".csv", _
FileFilter:="CSV files (*.csv), *.csv, All files (*.*), *.*")
If vFile <> False Then ThisWorkbook.SaveAs Filename:=vFile, FileFormat:=xlCS
End Sub
I have a macro that exports a set range to CSV file. I would like the macro to Exit Sub if Cancel is selected on the InputBox but to execute the code if OK is selected.
The code I have above exits sub no matter if OK or Cancel is selected.
Without the If x = "" Then Exit Sub statement the code exports to csv no matter if ok or Cancel is selected. I've tried some other options below and it looks like the issue might be with the input being a range. I'm relatively inexperienced and have run out of ideas searching this site and others.
I have tried variations of the code with reference to the link:
Handle cancellation of InputBox to select range
I have also tried incorporating the below code, however it leads to exit sub no matter if OK or cancel is selected:
sub inputbox_verification()
text=inputbox("type the text")
if StrPtr(text)=0 then
'if it entenrs here then the user pressed "cancel"
endif
if text=""
'if enters here the user left in blank
end if
if text<>""
'if enters here the user entered some text
end if
end sub
Inputbox returns False if Cancel is selected, so following code required:
Dim Text As Variant 'You can ommit "As Variant"
Text = Inputbox("Type the text")
'Check for Text type
If TypeName(Text) = "Boolean" Then
'Check if it is False
If Not Text Then Exit Sub
End If
If WorkRng = False Then Exit Sub
Let me start with the fact that I am NOT a programmer. I am self taught some VB with Excel and MS Access. I know just enough to be dangerous.
I have the following code to prompt the user to select a range. The Input box has an OK and Cancel button. If you do not select any cells and hit the OK or select Cancel it generates an errors.
Private Sub Copy_St5_50_Ramp_Click()
Dim sCell As Range
Set sCell = Application.InputBox("Select the Column of data below that is valid Ramp Data STARTING With 24 Minutes!!!", "Station 5", Type:=8)
If sCell Is Nothing Then Exit Sub
If sCell.Cells.Count < 2 Then Application.InputBox ("You Did not Select Enough Cells"), ("ERROR"), vbOK
sCell.Copy
Worksheets("50 Ramp Data").Range("CJ13").PasteSpecial Paste:=xlPasteValues
'Clear Clipboard (removes "marching ants" around your original data set)
Application.CutCopyMode = False
Worksheets("50 Ramp Data").Range("L4").Select
End Sub
I need it to not error but just close the input box and maybe prompt with a message box as to what went wrong
I've added 2 events to trap the possible errors:
If the user hits cancel >> On Error Resume Next , and later check If Err.Number <> 0 Then.
If the user didn't select any cell, use another parameter in the Application.InputBox of Default:=Selection.Address. So you compare if the Selection.Address after the InputBox is the same as the Selection.Address before the InputBox. If it is, then no new selection was made >> abort the operation.
Code
Option Explicit
Private Sub Copy_St5_50_Ramp_Click()
Dim sCell As Range
Dim CurrentSelectionRng As String
CurrentSelectionRng = Selection.Address
On Error Resume Next
Set sCell = Application.InputBox(prompt:="Select the Column of data below that is valid Ramp Data STARTING With 24 Minutes!!!", Title:="Station 5", Default:=Selection.Address, Type:=8)
' trap a case when the user selectes "Cancel"
If Err.Number <> 0 Then
MsgBox "You chose cancel !", vbCritical
Exit Sub
End If
' if the user didn't select anything (but the cell curser stayed on previous selection)
If sCell.Address = CurrentSelectionRng Then
MsgBox "No cell was selected !", vbCritical
Exit Sub
End If
If sCell Is Nothing Then Exit Sub
If sCell.Cells.Count < 2 Then Application.InputBox ("You Did not Select Enough Cells"), ("ERROR"), vbOK
sCell.Copy
Worksheets("50 Ramp Data").Range("CJ13").PasteSpecial xlPasteValues
'Clear Clipboard (removes "marching ants" around your original data set)
Application.CutCopyMode = False
Worksheets("50 Ramp Data").Range("L4").Select
End Sub