处理取消 InputBox 以选择范围
Posted
技术标签:
【中文标题】处理取消 InputBox 以选择范围【英文标题】:Handle cancellation of InputBox to select range 【发布时间】:2013-11-05 17:32:31 【问题描述】:我有以下代码:
dim selectRange as Range
Set selectRange = Application.InputBox("Select your range", "Hello", , , , , , 8)
当用户选择取消输入框提示时,它返回error of Object not set
。
我尝试使用 Variant 变量类型,但我无法处理它。取消时返回False
,同时选择范围时返回InputBox的Range。
我怎样才能避免这个错误?
【问题讨论】:
问题不在于这两行代码,可能出在它们后面的那几行。向我们展示这些台词。 【参考方案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 的“无”值。有用的是,这不会中断没有信息的提交,Excel 只是自动循环回请求输入,但用户可能需要为错误的数据输入添加额外的错误处理。
下载代码,添加:
ExitApp:
Exit Sub
用于退出,可以在多个输入取消处理程序之间有效共享。
【讨论】:
我喜欢这个解决方案【参考方案2】:如果我在 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 将使用上述代码关闭,您将永远不会看到 Program completed 打印。
但是,如果您从上面删除 boolExit,如果您在任何 1 次以上的运行中按取消,则 For 循环之后的代码仍在运行,您将看到 程序已完成,即使这是不是真的。
【讨论】:
【参考方案3】:虽然这个问题有点老了,但我仍然想展示正确的方法来做到这一点而不会出错。您可以通过函数或子函数对其进行处理。
你的主要程序是这样的:
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 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
如果你还有任何问题,尽管问;)
【讨论】:
指的是“子路(搞笑)”。我认为这可能会导致单个单元格出现问题。由于输入框被缓存在一个变体中,它将被转换并丢失范围类型。使用“Set b = a”后是不可能的。【参考方案4】:这是在使用输入框选择范围时出现的问题。 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
【讨论】:
谢谢你,我认为必须像这样处理 vbcancel 上的错误很糟糕,但别无选择。【参考方案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
或以相同方式处理其余过程。以防有人像我一样来到这里。
【讨论】:
【参考方案6】:我发现检查您提到的“需要对象”错误是处理取消的一种方法。
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
【讨论】:
以上是关于处理取消 InputBox 以选择范围的主要内容,如果未能解决你的问题,请参考以下文章
确定是否按下了取消按钮,其中InputBox变量声明为Double
vba inputBox:如何用空文本框区分“取消”和“确定”之间的区别
Excel VBA 输入框 - 选择范围(类型 8)但不是固定范围,即 A1 不是 $A$1