Определение, нажата ли кнопка Отмена, где переменная InputBox объявлена ​​как Double - PullRequest
1 голос
/ 07 марта 2019

Моя переменная объявлена ​​как double, поэтому я могу выполнять с ней математические операции.

Я пытаюсь определить, когда нажата кнопка отмены.

Dim thckmax As Double

thckmax = InputBox("What is the maximum nominal thickness?", "Enter Max Nominal Thickness Measurement")
If thckmax = 0 Then
     GoTo Line3
End If

thckmin = InputBox("What is the minimum nominal thickness?", "Enter Min Nominal Thickness Measurement")
If thckmin = 0 Then
     GoTo Line3
End If
thcknom = (thckmax + thckmin) / 2
Worksheets(1).Range("C" & cols + 2).Value = thcknom
.
.
.
Line3: ...

Я знаю, что использовал GoTo.Это было быстрое и простое исправление, чтобы получить код и запустить его.

Я получаю ошибку времени выполнения 13 несоответствие типов.Я также попытался CDbl(...), StrPtr(...), IsEmpty(...), и вместо того, чтобы установить их равными нулю, я также попытался

If thckmax = "" Then
    GoTo Line3
End If`

Я не могу заставить что-либо работать до определения, была ли нажата кнопка отменыи переходя к Line3:.

Все найденные мной сообщения указывают объявленную переменную в виде строки, у меня двойная.

Ответы [ 3 ]

5 голосов
/ 07 марта 2019

Вы можете попробовать что-то подобное, чтобы проверить, отменено ли поле ввода и является ли оно числовым.

Dim thckmaxTest As String
Dim thckmax As Double

thckmaxTest = InputBox("What is the maximum nominal thickness?", "Enter Max Nominal Thickness Measurement")
If thckmaxTest <> vbNullString and IsNumeric(thckmaxTest) then thckmax = CDbl(thckmaxTest)
If thckmax = 0 Then
     GoTo Line3
End If

Dim thckminTest As String
Dim thckmin As Double 

thckminTest = InputBox("What is the minimum nominal thickness?", "Enter Min Nominal Thickness Measurement")
If thckminTest <> vbNullString and IsNumeric(thckmibTest) then thckmin = CDbl(thckminTest)
If thckmin = 0 Then
     GoTo Line3
End If
thcknom = (thckmax + thckmin) / 2
Worksheets(1).Range("C" & cols + 2).Value = thcknom
4 голосов
/ 07 марта 2019

Как отмечается в документации Microsoft , функция InputBox возвращает строку.

Как тогда, вы можете спросить, можете ли вы иногда сохранять возвращаемое значение из InputBoxк целочисленному значению?Из-за неявного принуждения.По сути, если вы пытаетесь сохранить значение в несовместимой переменной, VBA пытается привести значение к нужному типу данных.Если вы попытаетесь сохранить значение string в переменной Double, VBA попытается привести строку к нужному типу данных.Это происходит независимо от того, используете ли вы InputBox или жестко заданную строку.Например, следующие фрагменты эквивалентны:

Dim x as Double
x = "5"
''''''''''''''''''''''''''''''''''''''
Dim x As Double
x = InputBox("Enter a number")
' user enters 5

При использовании InputBox вы, конечно, не можете контролировать, вводит ли пользователь допустимый ввод.Именно поэтому (как упоминает @Dude_Scott) вы должны сохранить введенные пользователем данные в строку, а затем убедиться, что у вас есть правильное значение.

Если пользователь нажимает Отмена в поле ввода,возвращается пустая строка (согласно документации выше).Поскольку пустая строка не может быть неявно приведена к двойному, генерируется ошибка.Это то же самое, что произойдет, если пользователь введет «apple» в поле ввода.

Как отмечает @Dude_Scott, вы должны использовать IsNumeric (или что-то подобное), чтобы убедиться, что пользовательский ввод - это то, что вынеобходимость.Однако вам не нужно включать проверку на нулевую или пустую строку (поскольку IsNumeric возвращает False для этих значений).Так что вам действительно нужно что-то вроде этого:

Public Sub foo()
    Dim xDouble As Double, xString As String

    xString = InputBox("Enter a number")

    If IsNumeric(xString) Then
        xDouble = CDbl(xString)
        MsgBox xDouble
    Else
        MsgBox "Invalid number"
    End If
End Sub

Для получения дополнительной информации о принуждении см. Следующие статьи Microsoft:

3 голосов
/ 07 марта 2019

Все остальные, которые я нашел, указывают на объявленную переменную в виде строки, моя - DOUBLE

Вы не можете иметь Double. Функция возвращает String, и вы не можете это изменить. Использование Double для захвата результата рано или поздно вызовет .

То, что я пытался объяснить в поле для комментариев ранее, это то, что существует вероятность того, что 0 может быть допустимым вводом, поэтому немедленное преобразование ввода в Double лишает вас возможности сообщить об отмене из 0 - независимо от ошибки несоответствия типов, которая гарантированно произойдет, если результат не числовой.

Как показывают другие ответы, это включает в себя немало сантехники: достаточно, чтобы оправдать втягивание в свою собственную выделенную функцию-обертку.

Проблема в том, что функции возвращают одно значение, поэтому вы можете вернуть Double и выбрать конкретное «магическое значение», означающее «вход был отменен», но это плохая практика.

Лучший способ - заставить функцию-оболочку возвращать Boolean и использовать параметр ByRef для возврата результата - такая функция возвращает False, если пользователь отменяет приглашение, True, если запрос не был отменен, и outResult будет либо 0 для нечислового ввода, либо входом, преобразованным в Double:

Public Function TryGetDoubleInput( _
    ByVal prompt As String, _
    ByVal title As String, _
    ByVal default As String, _
    ByRef outResult As Double) _
As Boolean
    Dim result As String
    result = VBA.Interaction.InputBox(prompt, title, default)
    TryGetDoubleInput = StrPtr(result) <> 0 'return false if cancelled
    If IsNumeric(result) Then outResult = CDbl(result)
End Function

Можно использовать так:

Dim value As Double
If TryGetDoubleInput("Enter a numeric value:", "Prompt", "0.00", value) Then
    If value = 0 Then
        MsgBox "You entered either 0 or a non-numeric value"
    Else
        MsgBox "You entered " & CStr(value) ' note the irony
    End If
Else
    MsgBox "You cancelled the prompt"
End If

Теперь, если вам нужно обрабатывать недопустимые значения иначе, чем 0 (т. Е. Если 0 является допустимым вводом), подумайте о том, чтобы выдать ошибку:

Public Function TryGetDoubleInput( _
    ByVal prompt As String, _
    ByVal title As String, _
    ByVal default As String, _
    ByRef outResult As Double) _
As Boolean
    Dim result As String
    result = VBA.Interaction.InputBox(prompt, title, default)
    If StrPtr(result) = 0 Then Exit Function 'return false if cancelled

    If IsNumeric(result) Then 
        outResult = CDbl(result)
        TryGetDoubleInput = True
    Else
        Err.Raise 555, "TryGetDoubleInput", "Non-numeric input is invalid."
    End If
End Function

И теперь вы можете использовать обработку ошибок для обработки недопустимых вводов, и теперь вы можете сказать действительное 0 из отмененного поля ввода из произвольного неверного ввода:

On Error GoTo ErrHandler
Dim value As Double
If TryGetDoubleInput("Enter a numeric value:", "Prompt", "0.00", value) Then
    MsgBox "You entered " & CStr(value) ' note the irony
Else
    MsgBox "You cancelled the prompt"
End If

Exit Sub
ErrHandler:
    MsgBox Err.Description ' "Non-numeric input is invalid."
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...