我有以下代码:
dim selectRange as Range
Set selectRange = Application.InputBox("Select your range", "Hello", , , , , , 8)
当用户选择取消InputBox提示时,它将返回error of Object not set
。
我曾尝试使用Variant变量类型但我无法处理它。在取消的情况下,它返回False
,同时在选择范围的情况下,它返回InputBox的范围。
如何避免此错误?
答案 0 :(得分:7)
使用输入框选择范围时出现问题。 Excel在返回范围之前返回错误,并在您按取消时执行此错误。
因此,您应该主动处理此错误。如果您在按取消时不希望发生任何事情,您可以使用如下代码:
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
答案 1 :(得分:6)
虽然这个问题有点老了,但我还是想显示正确的方式来做到这一点而不会出错。你可以通过函数或子函数来实现它。
您的主要程序是这样的:
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
Sub -way(有趣)将是:
Sub testSub(ByVal a As Variant, ByRef b As Range)
If TypeOf a Is Range Then Set b = a
End Sub
功能看起来像:
Function testFunc(ByVal a As Variant) As Range
If TypeOf a Is Range Then Set testFunc = a
End Function
现在只需使用您喜欢的方式并删除未使用的行。
如果调用子函数或函数,则不需要Set
参数。也就是说,InputBox
是否返回一个对象并不重要。您需要做的就是检查参数是否是您想要的对象,然后根据它进行操作。
修改强>
另一种聪明的方法是对这样的集合使用相同的行为:
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
如果您还有任何疑问,请询问;)
答案 2 :(得分:5)
我在这里参加派对的时间已经很晚了,但这是我能找到的唯一一个解释为什么我无法检查变量的麻烦的地方。如接受的答案中所述,范围对象上的vbCancel
的处理方式与字符串对象的处理方式不同。 必须错误才会被错误处理程序捕获。
我讨厌错误处理程序。所以我把它隔离到了自己的功能
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
现在我的主要内容我可以
dim someRange as range
set someRange = GetUserInputRange
if someRange is Nothing Then Exit Sub
无论如何这与接受的答案不同,因为它允许用户仅使用特定的错误处理程序处理此错误,而不需要resume next
或者以相同的方式处理其余的过程。如果有人像我一样在这里结束。
答案 3 :(得分:1)
我发现检查您提到的“需要对象”错误是处理取消的一种方法。
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
答案 4 :(得分:1)
我采用了更清洁的解决方案:
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
这将清除错误消息,并捕获返回给InputValue的“ nothing”值。有用的是,这不会中断没有信息的提交,Excel只会自动循环回到请求输入,但是用户可能需要为错误的数据输入添加其他错误处理。
下码,添加:
ExitApp:
Exit Sub
退出时,可以在多个输入取消处理程序之间共享它。
答案 5 :(得分:0)
如果我在for循环中使用Dirks的第二个答案并且要退出我的子程序,仅在他的IF语句中执行Exit Sub是不够的
我发现,如果我在for循环中独立使用Exit Sub,我不会在所有情况下都退出sub,但是,在大多数情况下,仅退出for循环。
这里有Dirks代码
编辑
另一种聪明的方法是对类似的集合使用相同的行为 这个:
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
如果您还有任何疑问,请问;)
这里是我作为示例进行的工作:
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
如果您在五次运行中的任何时间按取消,则Sub会使用以上代码关闭,并且您将永远不会看到程序已完成打印。
但是,如果从上面删除boolExit,则如果在1次以上运行的任何一次中按“取消”,则For循环后的代码仍在运行,即使已执行 Program 不是。