the code I have prompt a popup requesting which row to delete, unfortunately when I press escape or cancel, whichever cell is active on the worksheet ends up getting deleted.
What I am looking for is a function where if I press escape on the keyboard or 'x' on the popup window it does not delete the row
Here is what I have so far:
Sub DeleteRow()
Dim rng As Range
Dim iRowCount As Integer
Dim iForCount As Integer
On Error Resume Next
Set selectedRng = Application.Selection
Set selectedRng = Application.InputBox("Range", , selectedRng.Address, Type:=8)
iRowCount = selectedRng.Rows.Count
For iForCount = iRowCount To 1 Step -1
If Application.WorksheetFunction.CountA(selectedRng.Rows(iForCount)) = 0 Then
selectedRng.Rows(iForCount).EntireRow.Delete
selectedRnd.Rows(iForCount).Delete
End If
Next
Application.ScreenUpdating = True
End Sub
The InputBox function returns a string, so using SET to assign the result to your selectedRng variable (which has not been declared, so will be considered a variant) will simply be skipped when the user cancels the input box. Therefore the variable will continue to hold the Application.Selection, which you assigned to it in the preceding line.
The input box returns "False" if the user click cancel or "X" or hits Escape.
I would try declaring a string variable to capture the result of the input, as in
dim strResult as string
strResult = Application.InputBox("Range", , selectedRng.Address)
if strResult <> "False" then
set selectedRng = Range(strResult)
'delete the rows now...
end if
Thank you guys,
I decided to completely simplify the code and it works fine now
Sub DeleteRow()
Dim Rng As Range, Num As String
On Error Resume Next
Set Rng = Application.InputBox(prompt:="Please Select Start Row ", Title:="Delete Rows", Type:=8)
If Split(Rng.Address, "$")(2) < 1 Then
'MsgBox "Please choose a Number Greater than 1"
Exit Sub
End If
Num = Application.InputBox(prompt:="Please Insert Number of Rows", Title:="Delete Rows", Type:=1)
If Num = False Then Exit Sub
Rng.Resize(Num).EntireRow.Delete
End Sub
Related
I have the following piece of code:
dim selectRange as Range
Set selectRange = Application.InputBox("Select your range", "Hello", , , , , , 8)
When a user chooses Cancel the InputBox prompt, it returns error of Object not set.
I have tried to use a Variant variable type but I can't handle it. In case of cancelling, it returns False, meanwhile in case of selecting a range, it returns Range of InputBox.
How can I avoid this error?
This is a problem when selection a range with an inputbox. Excel returns an error before the range is returned, and it carries this error on when you press cancel.
You should therefore actively handle this error. If you don't want anything to happen when you press cancel, you can just use the code like this:
Sub SetRange()
Dim selectRange As Range
On Error Resume Next
Set selectRange = Application.InputBox("Select your range", "Hello", , , , , , 8)
Err.Clear
On Error GoTo 0
End Sub
While this question is a bit older I still want to show the proper way to do it without errors. You can do it either to it via function or with a sub.
Your main procedure is something like this:
Sub test()
Dim MyRange As Range
testSub Application.InputBox("dada", , , , , , , 8), MyRange 'doing via Sub
Set MyRange = testFunc(Application.InputBox("dada", , , , , , , 8)) ' doing via function
If MyRange Is Nothing Then
Debug.Print "The InputBox has been canceled."
Else
Debug.Print "The range " & MyRange.Address & " was selected."
End If
End Sub
the Sub-way (funny) would be:
Sub testSub(ByVal a As Variant, ByRef b As Range)
If TypeOf a Is Range Then Set b = a
End Sub
And the function would look like:
Function testFunc(ByVal a As Variant) As Range
If TypeOf a Is Range Then Set testFunc = a
End Function
Now simply use the way you like and delete the unused line.
If calling a sub or a function you do not need to Set the parameter. That said, it doesn't matter if the InputBox returns an object or not. All you need to do, is to check if the parameter is the object you want or not and then act accordingly to it.
EDIT
Another smart way is using the same behavior with a collection like this:
Sub test()
Dim MyRange As Range
Dim MyCol As New Collection
MyCol.Add Application.InputBox("dada", , , , , , , 8)
If TypeOf MyCol(1) Is Range Then Set MyRange = MyCol(1)
Set MyCol = New Collection
If MyRange Is Nothing Then
Debug.Print "The inputbox has been canceled"
Else
Debug.Print "the range " & MyRange.Address & " was selected"
End If
End Sub
If you still have any questions, just ask ;)
I'm late to the party here but this was the only place I could find that explained why I was having trouble just checking my variable for nothing. As explained in the accepted answer, the vbCancel on a range object isn't handled the same way as a string object. The error must be caught with an error handler.
I hate error handlers. So I segregated it to its own function
Private Function GetUserInputRange() As Range
'This is segregated because of how excel handles cancelling a range input
Dim userAnswer As Range
On Error GoTo inputerror
Set userAnswer = Application.InputBox("Please select a single column to parse", "Column Parser", Type:=8)
Set GetUserInputRange = userAnswer
Exit Function
inputerror:
Set GetUserInputRange = Nothing
End Function
Now in my main sub I can
dim someRange as range
set someRange = GetUserInputRange
if someRange is Nothing Then Exit Sub
Anyhow this is not the same as the accepted answer because it allows the user to only handle this error with a specific error handler and not need to resume next or have the rest of the procedure handled the same way. In case anyone ends up here like I did.
I have found that checking for the "Object required" error that you mentioned is one way of handling a cancel.
On Error Resume Next
dim selectRange as Range
' InputBox will prevent invalid ranges from being submitted when set to Type:=8.
Set selectRange = Application.InputBox("Select your range", "Hello", , , , , , 8)
' Check for cancel: "Object required".
If Err.Number = 424 Then
' Cancel.
Exit Sub
End If
On Error GoTo 0
I went with a cleaner solution:
Dim InputValue As Range
On Error Resume Next
Set InputValue = Application.InputBox("Select Range","Obtain Range", Type:=8)
Err.Clear
If InputValue Is Nothing Then
GoTo ExitApp:
End If
This will clear the error message and catch the "nothing" value returned to InputValue. Usefully, this doesn't interrupt a submission of no information, which Excel just loops back to requesting input automatically, but the user may need to add additional error handling for bad data entry.
Down code, add:
ExitApp:
Exit Sub
For exiting, which can be usefully shared between multiple input cancel handlers.
If I use Dirks second answer inside a for loop and I want to exit my sub, it is not enough to execute an Exit Sub inside his IF statement
I found that if I use Exit Sub standalone inside a for loop, I will not exit my sub in all cases, however, in most cases only exit the for loop.
Here you have Dirks code
EDIT
Another smart way is using the same behavior with a collection like
this:
Sub test()
Dim MyRange As Range
Dim MyCol As New Collection
MyCol.Add Application.InputBox("dada", , , , , , , 8)
If TypeOf MyCol(1) Is Range Then Set MyRange = MyCol(1)
Set MyCol = New Collection
If MyRange Is Nothing Then
Debug.Print "The input box has been canceled"
Else
Debug.Print "the range " & MyRange.Address & " was selected"
End If
End Sub
If you still have any questions, just ask ;)
Here is what I made to work as a example:
Sub test()
Dim i as Integer
Dim boolExit as Boolean
Dim MyRange As Range
Dim MyCol As New Collection
boolExit = False
For i = 1 To 5 Then
MyCol.Add Application.InputBox("dada", , , , , , , 8)
If TypeOf MyCol(1) Is Range Then Set MyRange = MyCol(1)
Set MyCol = New Collection
If MyRange Is Nothing Then
Debug.Print "The inputbox has been canceled"
boolExit = True
Exit Sub
Else
Debug.Print "the range " & MyRange.Address & " was selected"
End If
Next i
If boolExit = True Then Exit Sub 'Checks if Sub should be exited
Debug.Print "Program completed"
End Sub
If you press cancel at anytime in the five runs, the Sub is shutdown with the above code and you will never see Program completed printed.
However if you remove boolExit from the above, the code after the For loop is still being run if you press cancel in any of the 1+ runs and you will see Program completed even when that is not true.
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
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
I have the following piece of code:
dim selectRange as Range
Set selectRange = Application.InputBox("Select your range", "Hello", , , , , , 8)
When a user chooses Cancel the InputBox prompt, it returns error of Object not set.
I have tried to use a Variant variable type but I can't handle it. In case of cancelling, it returns False, meanwhile in case of selecting a range, it returns Range of InputBox.
How can I avoid this error?
This is a problem when selection a range with an inputbox. Excel returns an error before the range is returned, and it carries this error on when you press cancel.
You should therefore actively handle this error. If you don't want anything to happen when you press cancel, you can just use the code like this:
Sub SetRange()
Dim selectRange As Range
On Error Resume Next
Set selectRange = Application.InputBox("Select your range", "Hello", , , , , , 8)
Err.Clear
On Error GoTo 0
End Sub
While this question is a bit older I still want to show the proper way to do it without errors. You can do it either to it via function or with a sub.
Your main procedure is something like this:
Sub test()
Dim MyRange As Range
testSub Application.InputBox("dada", , , , , , , 8), MyRange 'doing via Sub
Set MyRange = testFunc(Application.InputBox("dada", , , , , , , 8)) ' doing via function
If MyRange Is Nothing Then
Debug.Print "The InputBox has been canceled."
Else
Debug.Print "The range " & MyRange.Address & " was selected."
End If
End Sub
the Sub-way (funny) would be:
Sub testSub(ByVal a As Variant, ByRef b As Range)
If TypeOf a Is Range Then Set b = a
End Sub
And the function would look like:
Function testFunc(ByVal a As Variant) As Range
If TypeOf a Is Range Then Set testFunc = a
End Function
Now simply use the way you like and delete the unused line.
If calling a sub or a function you do not need to Set the parameter. That said, it doesn't matter if the InputBox returns an object or not. All you need to do, is to check if the parameter is the object you want or not and then act accordingly to it.
EDIT
Another smart way is using the same behavior with a collection like this:
Sub test()
Dim MyRange As Range
Dim MyCol As New Collection
MyCol.Add Application.InputBox("dada", , , , , , , 8)
If TypeOf MyCol(1) Is Range Then Set MyRange = MyCol(1)
Set MyCol = New Collection
If MyRange Is Nothing Then
Debug.Print "The inputbox has been canceled"
Else
Debug.Print "the range " & MyRange.Address & " was selected"
End If
End Sub
If you still have any questions, just ask ;)
I'm late to the party here but this was the only place I could find that explained why I was having trouble just checking my variable for nothing. As explained in the accepted answer, the vbCancel on a range object isn't handled the same way as a string object. The error must be caught with an error handler.
I hate error handlers. So I segregated it to its own function
Private Function GetUserInputRange() As Range
'This is segregated because of how excel handles cancelling a range input
Dim userAnswer As Range
On Error GoTo inputerror
Set userAnswer = Application.InputBox("Please select a single column to parse", "Column Parser", Type:=8)
Set GetUserInputRange = userAnswer
Exit Function
inputerror:
Set GetUserInputRange = Nothing
End Function
Now in my main sub I can
dim someRange as range
set someRange = GetUserInputRange
if someRange is Nothing Then Exit Sub
Anyhow this is not the same as the accepted answer because it allows the user to only handle this error with a specific error handler and not need to resume next or have the rest of the procedure handled the same way. In case anyone ends up here like I did.
I have found that checking for the "Object required" error that you mentioned is one way of handling a cancel.
On Error Resume Next
dim selectRange as Range
' InputBox will prevent invalid ranges from being submitted when set to Type:=8.
Set selectRange = Application.InputBox("Select your range", "Hello", , , , , , 8)
' Check for cancel: "Object required".
If Err.Number = 424 Then
' Cancel.
Exit Sub
End If
On Error GoTo 0
I went with a cleaner solution:
Dim InputValue As Range
On Error Resume Next
Set InputValue = Application.InputBox("Select Range","Obtain Range", Type:=8)
Err.Clear
If InputValue Is Nothing Then
GoTo ExitApp:
End If
This will clear the error message and catch the "nothing" value returned to InputValue. Usefully, this doesn't interrupt a submission of no information, which Excel just loops back to requesting input automatically, but the user may need to add additional error handling for bad data entry.
Down code, add:
ExitApp:
Exit Sub
For exiting, which can be usefully shared between multiple input cancel handlers.
If I use Dirks second answer inside a for loop and I want to exit my sub, it is not enough to execute an Exit Sub inside his IF statement
I found that if I use Exit Sub standalone inside a for loop, I will not exit my sub in all cases, however, in most cases only exit the for loop.
Here you have Dirks code
EDIT
Another smart way is using the same behavior with a collection like
this:
Sub test()
Dim MyRange As Range
Dim MyCol As New Collection
MyCol.Add Application.InputBox("dada", , , , , , , 8)
If TypeOf MyCol(1) Is Range Then Set MyRange = MyCol(1)
Set MyCol = New Collection
If MyRange Is Nothing Then
Debug.Print "The input box has been canceled"
Else
Debug.Print "the range " & MyRange.Address & " was selected"
End If
End Sub
If you still have any questions, just ask ;)
Here is what I made to work as a example:
Sub test()
Dim i as Integer
Dim boolExit as Boolean
Dim MyRange As Range
Dim MyCol As New Collection
boolExit = False
For i = 1 To 5 Then
MyCol.Add Application.InputBox("dada", , , , , , , 8)
If TypeOf MyCol(1) Is Range Then Set MyRange = MyCol(1)
Set MyCol = New Collection
If MyRange Is Nothing Then
Debug.Print "The inputbox has been canceled"
boolExit = True
Exit Sub
Else
Debug.Print "the range " & MyRange.Address & " was selected"
End If
Next i
If boolExit = True Then Exit Sub 'Checks if Sub should be exited
Debug.Print "Program completed"
End Sub
If you press cancel at anytime in the five runs, the Sub is shutdown with the above code and you will never see Program completed printed.
However if you remove boolExit from the above, the code after the For loop is still being run if you press cancel in any of the 1+ runs and you will see Program completed even when that is not true.
I'm working on an Excel user form where the user can input a range. For example, they can put in "B5" and "B20".
I'm trying to do error handling to prevent the user from putting in an incorrect range. For Example, "asdf" and "fdsa".
The following code fails:
Private Sub cmdSend_Click()
Dim beginTerm As String
Dim endTerm As String
beginTerm = TermsBegin.Text
endTerm = TermsEnd.Text
If (IsError(Worksheets("Account Information").Range(beginTerm + ":" + endTerm)) = True) Then
MsgBox "Cell Range is invalid."
Exit Sub
End If
End Sub
I also tried the following:
Private Sub cmdSend_Click()
Dim beginTerm As String
Dim endTerm As String
beginTerm = TermsBegin.Text
endTerm = TermsEnd.Text
Dim myRange As Range
myRange = Worksheets("Account Information").Range(beginTerm + ":" + endTerm)
On Error GoTo ErrHandler
On Error GoTo 0
'other code ...
ErrHandler:
MsgBox "Cell Range is invalid."
Exit Sub
End Sub
My question is how can I handle the case that it fails?
Thanks!
You have to put
On Error GoTo ErrHandler
before the line that could throw the error.
If you need to get a range from a user, I would recommend using Application.InputBox with a Type = 8. This allows the user to select a range from the worksheet.
Check this out:
http://www.ozgrid.com/VBA/inputbox.htm
Also, if you are using a userform, you can also add a command button that will call the Application.InputBox to allow a user to select a range.
Quick example:
Private Sub CommandButton1_Click()
Dim r As Range
On Error Resume Next
Set r = Application.InputBox(Prompt:= _
"Please select a range with your Mouse to be bolded.", _
Title:="SPECIFY RANGE", Type:=8)
If Not r Is Nothing Then MsgBox r.Address
On Error GoTo 0
End Sub