Дескриптор отмены InputBox для выбора диапазона


У меня есть следующий фрагмент кода:

dim selectRange as Range
Set selectRange = Application.InputBox("Select your range", "Hello", , , , , , 8)

Когда пользователь выбирает отменить приглашение InputBox, он возвращает error of Object not set.

Я пытался использовать тип переменной Variant, но я не могу справиться с этим. В случае отмены, он возвращает False, в то время как в случае выбора диапазона, он возвращает диапазон InputBox.

Как мне избежать этой ошибки?

4 6

4 ответа:

Это проблема при выборе диапазона с помощью inputbox. 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 в диапазоне обрабатывается не так, как объект string. Ошибка должна быть поймана обработчиком ошибок.

Я ненавижу обработчики ошибок. Поэтому я разделил его на его собственную функцию

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 или обработки остальной части процедуры таким же образом. На случай, если кто-нибудь окажется здесь, как я.

Хотя этот вопрос немного старше, я все же хочу показать правильный способ сделать это без ошибок. Вы можете сделать это либо с помощью функции, либо с помощью суб.

Ваша основная процедура выглядит примерно так:

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
Теперь просто используйте то, что вам нравится, и удалите неиспользуемую строку.

Если вызов sub или функции не требуется Set то параметр. Тем не менее, не имеет значения, возвращает ли InputBox объект или нет. Все, что вам нужно сделать, это проверить, является ли параметр объектом, который вы хотите или нет, а затем действовать в соответствии с ним.

EDIT

Другой разумный способ-использовать то же самое поведение с коллекцией, как это:

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

Если у вас все еще есть какие-либо вопросы, просто спросите ;)

Я обнаружил, что проверка на наличие ошибки "требуется объект", о которой Вы упомянули, является одним из способов обработки отмены.

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