All others I have found indicate the declared variable as a string, mine is a DOUBLE
You can't have a Double
. The function returns a String
, and you can't change that. Using a Double
to capture the result will cause problems sooner or later.
What I was trying to explain in a comment box earlier, is that there's a possibility that 0
might be a valid input, so immediately converting the input into a Double
is preventing you from being able to tell cancellation from a legit 0
- regardless of the type mismatch error that's guaranteed to happen whenever the resut isn't numeric.
As other answers show, this involves quite a bit of plumbing: enough to warrant being pulled into its own dedicated wrapper function.
The problem is that functions return one value, so you can return a Double
and pick a specific "magic value" to mean "input was cancelled", but that's a poor practice.
A better way is to make the wrapper function return a Boolean
, and leverage a ByRef
parameter to return the result - a function like this returns False
if the user cancels the prompt, True
if the prompt was not cancelled, and outResult
will be either 0
for a non-numeric input, or the input converted to a 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
Can be used like this:
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
Now if you need to treat invalid values differently than 0
(i.e. if 0
is a legit input), consider throwing an error:
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
And now you can use error handling to handle invalid inputs, and you can now tell a legit 0
from a cancelled inputbox from an arbitrary invalid input:
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."