Handling non integer in inputbox in VBA - excel

I have a variable called "need" that is defined as an integer. An input box come up and prompts the user. If they type an integer it displays Msgbox "Got your number". If I type a string I get Runtime error '13': type mismatch. I thought if I just used an Else statement, it would say try again. It is not doing that though. Do I need error handling in the Else statement? And if so, what would the line(s) be?
Sub gadgetmanuf()
Dim need As Integer
'Dim rawneed As Single
'Dim rawavailable As Single
need = InputBox("How many gadgets are needed?", "Insert a number")
If TypeName(need) = "Integer" Then
MsgBox ("Got your number")
Else
MsgBox ("Try again")
End If
End Sub

Using an Application.InputBox with type 1 forces the user to enter a number (provides its own error message for text, ranges etc). So all you need to handle is the Cancel option, ie
The code below uses a variant to handle this, as using Cancel with an Integer or Long gives 0 - which could be a valid entry.
Sub TaylorWalker()
redo:
vStr = Application.InputBox("How many gadgets are needed?", "Enter a number", , , , , , Type:=1)
If vStr = False Then GoTo redo
End Sub
longer option
Test that the entered variable is greater than 0
Sub EddieBetts()
Dim StrPrompt As String
Dim lngNum As Long
StrPrompt = "How many gadgets are needed?"
redo:
lngNum = Application.InputBox(StrPrompt, "Enter an integer number (numbers will be rounded)", , , , , , Type:=1)
If lngNum < 1 Then
StrPrompt = "How many gadgets are needed - this must be a postive integer"
GoTo redo
End If
MsgBox "User entered " & lngNum
End Sub

In your example 'need' is an integer data type so it will always be an integer.
Have a look at this:
Sub test()
x = Range("A1").Value
If Int(x) / x = 1 Then
MsgBox "Value is an Integer"
Else
MsgBox "Value is not an Integer"
End If
End Sub
or Assuming A1 has the number, put, in any other cell, the formula:
=IF(INT(A1)=A1,"True","False")

Related

VBA Input Function shows Run time error, type mismatch

I want to create a input box, and put the input into corresponding cells. But it show type mismatch.
Sub Profit_Projection()
Dim rng As Range
Dim psales As Integer
Dim msg1 As String
psales = InputBox("Please enter the predicted growth of sales next month in decimal form.", "Sales Growth", 1)
If StrPtr(psales) = 0 Then
MsgBox "You clicked Cancel button"
Exit Sub
ElseIf psales = "" Then
MsgBox "You didnt enter input"
Exit Sub
Else
Val (psales)
Range("B5") = psales * 100
If Range("B5").IsNumeric = False Then
msg1 = "The number inputted is is not integer. Please try again in decimal form."
MsgBox msg1, vbOKOnly, "Incorrect Input"
End If
End If
End Sub
Your main problem is that InputBox returns a String (see the official documentation), but you assign it to a numeric variable.
If the user enters some non-numeric data, you will get the type mismatch already at the psales = InputBox - statement.
If the user enters a numeric value, VBA will convert it into a number. But then you get a a type mismatch for the statement psales = "" because you cannot compare a number and a string (even if it is an empty string).
So you should assign the result of the InputBox first to a String variable and then check step by step if the entered value was okay:
Sub Profit_Projection()
Dim rng As Range
Dim psales As Integer
Dim answer
Dim msg1 As String
answer = InputBox("Please enter the predicted growth of sales next month in decimal form.", "Sales Growth", 1)
If StrPtr(answer) = 0 Then
MsgBox "You clicked Cancel button"
Exit Sub
End If
If Trim(answer) = "" Then
MsgBox "You didnt enter anything"
Exit Sub
End If
If Not IsNumeric(answer) Then
MsgBox "You didnt enter a number"
Exit Sub
End If
If CInt(answer) <> Val(answer) Then
MsgBox "You didnt enter an integer "
Exit Sub
End If
psales = Val(answer)
ActiveSheet.Range("B5") = psales * 100
End Sub

GoTo is not defined - in VBA

When I on the step F8 click. then say it Goto is not defined. I try to make a inputbox with a messagebox that me the answer give. And I try also to make code when the values not correct is. See, you where I make a mistake in my VBA code:
Sub TwoNumbersinputbox()
Dim bytAnswer1 As String
Dim bytAntwer2 As String
Dim Range As Byte
Dim strNumber1 As String
Dim strNumber2 As String
[C3] = "Number1"
[C4] = "Number2"
Start1:
strNumber1 = InputBox("Give number one?", "Invoer", 5, 567, 567)
If IsNumeric(strNumber1) Then
MsgBox "This must be Number1", vbCritical, _
"Number1 input"
GoTo strNumber1
Else: [B2] = strNumber1
End If
If Not IsNumeric(strNumber1) Then
MsgBox "there is error.", vbCritical, "Number2 input"
bytAnwer1 = MsgBox("Start Again?", vbYesNo)
If bytAnwer1 = vbYes Then GoTo Start
End If
Start2:
strGetal2 = InputBox("Give Number2?", "Input", 5, 567, 567)
If IsNumeric(strNumber2) Then
MsgBox "This must be Number2 ", vbCritical, _
"Number2 input"
GoTo strNumber2
Else: [B3] = strNumber2
End If
If Not IsNumeric(strGetal2) Then
MsgBox "Is there an error.", vbCritical, "Number2 input"
bytAnswer2 = MsgBox("Start Again?", vbYesNo)
If bytAnswer2 = vbYes Then GoTo Start
End If
End Sub
First thing first - never use GOTO. Only in error handling (On Error statement (VBA)).
Second - if you need to use it, a mark is needed. E.g., if it is GoTo somewhere, then in the code it should be defined like this - somewhere:.
Sub DontUseGoTo()
Dim i As Long
i = 0
somewhere:
i = i + 1
Debug.Print i
If i < 10 Then
GoTo somewhere
End If
End Sub

Run time error '1004' Application defined or object defined error on Vlookup function

I am trying to utilize Vlookup function, according to the Textbox1 value user put in in Userform Guntest, automatically looking for corresponding features of the gun.
However the program currently doesn't run as it reminds me
'Runtime error '1004', method 'Range of object' _Global' failed.
The error appears on Retrieve1=…
I will be appreciated if you could help me to check where the problem is as I have really limited knowledge and experience on using VBA.
Thanks in advance.
It looks like some objects is undefined but I can't figure out where.
The module 1 code is:
Public Guncode As String
Option Explicit
Sub Test()
Call Vlookup
End Sub
Sub Vlookup()
Dim Retrieve1 As String
Dim Retrieve2 As String
Dim FinalRow As Long
Dim FinalColumn As Long
Dim WholeRange As String
If GunTest.TextBox1 = "" Then
Exit Sub
If GunTest.TextBox1 <> "" Then
MsgBox Guncode
End If
End If
With Sheets(1)
FinalRow = Range("A65536").End(xlUp).Row
FinalColumn = Range("IV1").End(xlToLeft).Column
WholeRange = "A2:" & CStr(FinalColumn) & CStr(FinalRow)
Retrieve1 = Application.WorksheetFunction.Vlookup(Trim(Guncode), Range(WholeRange), 1, False) 'Locate specific tool according to QR code number
Retrieve2 = Application.WorksheetFunction.Vlookup(Trim(Guncode), Range(WholeRange), 5, False) 'Locate specific gun type according to QR code number
If Guncode = "" Then
MsgBox "This gun doesn't exist in database!"
Else
MsgBox "The tool number is:" & Retrieve1 & vbCrLf & "The gun type is:" & Retrieve2
End If
End With
End Sub
The userform code is:
Option Explicit
Private Sub Label1_Click()
End Sub
Private Sub CommandButton1_Click()
If TextBox1 = "" Then Exit Sub 'Set condition 1 of exiting the program
Guncode = GunTest.TextBox1
With Me
Call Module1.Test
End With
End Sub
Private Sub PartID_Click()
End Sub
Private Sub TextBox1_Change()
End Sub
Private Sub UserForm_Click()
End Sub
It should run properly but it doesn't. Any help would be appreciated, thanks!
First off, you were passing in a number as the column letter value. CSTR() doesnt magically transform it into the letter equivalent but I like your enthusiasm.
Second, your method will bomb if the value isnt found - so you'll need to write your own error handling for it.
Sub Vlookup()
Dim Retrieve1 As String
Dim Retrieve2 As String
Dim FinalRow As Long
Dim FinalColumn As Long
Dim WholeRange As String
Dim vArr
Dim col_Letter As String
If GunTest.TextBox1 = "" Then
Exit Sub
If GunTest.TextBox1 <> "" Then
MsgBox Guncode
End If
End If
With ThisWorkbook.Sheets("Sheet1")
FinalRow = .Range("A65536").End(xlUp).Row
FinalColumn = .Range("IV1").End(xlToLeft).Column
vArr = Split(Cells(1, FinalColumn).Address(True, False), "$")
col_Letter = vArr(0)
WholeRange = "A2:" & col_Letter & CStr(FinalRow) '<---- you were passing a number in as the column value
Retrieve1 = Application.WorksheetFunction.Vlookup(Trim(Guncode), .Range(WholeRange), 1, False) 'Locate specific tool according to QR code number
Retrieve2 = Application.WorksheetFunction.Vlookup(Trim(Guncode), .Range(WholeRange), 5, False) 'Locate specific gun type according to QR code number
If Guncode = "" Then
MsgBox "This gun doesn't exist in database!"
Else
MsgBox "The tool number is:" & Retrieve1 & vbCrLf & "The gun type is:" & Retrieve2
End If
End With
End Sub
1. I am not sure what is the reason using Address(True, False) for row number.
This comes from a combination of these two functions. The true/false setting is telling the funciton to use/not use absolute references in the address.
Split ( expression [,delimiter] [,limit] [,compare] )
https://www.techonthenet.com/excel/formulas/split.php
expression.Address (RowAbsolute, ColumnAbsolute, ReferenceStyle, External, RelativeTo)
https://learn.microsoft.com/en-us/office/vba/api/excel.range.address
Shouldn't Cell (1, FinalColumn) stands for the column number?
No, the cells fucntiosn basically returns an intersection/address of rows & column.
Try this for example: debug.Print; thisworkbook.Sheets("Sheet1").Cells(2,2)
You mentioned CSTR doesn't magically transform to letter equivalent so what would it transform to? Could you further elaborate?
This is a data type conversion function. CSTR(666) essentially does this: this 666 becomes this "666"
2. vArr(0). I am confused with what does the parameter 0 stands for in the bracket. Actually this is a general question I always have regarding to parameter specification.
This is an array position refence. The split function returns an array of strings. Since we're using to capture the column label value, we only need to reference the first position.
(3) I tried copy your code and run it but still reminds me error on the same row.
Works fine for me unless there is no returning value, which returns an error which is what I meant by "bomb."

Determining if Cancel Button pressed where InputBox variable declared as Double

I have my variable declared as a double so I can perform mathematical operations on it.
I am trying to determine when the cancel button is pressed.
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: ...
I know I used GoTo. It was a quick and easy fix to get the code up and running.
I get Run-Time error 13 type mismatch. I have also tried CDbl(...),StrPtr(...),IsEmpty(...) and instead of setting them equal to zero I have also tried
If thckmax = "" Then
GoTo Line3
End If`
I cannot get anything to work as far as determining if cancel was pressed and going to Line3:.
All posts I found indicate the declared variable as a string, mine is a double.
You could try something like this to test whether or not the input box was canceled and if it is numeric.
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
As is noted in Microsoft's documentation, the InputBox function returns a string.
How then, you may ask, can you sometimes store the return value from an InputBox to an integer value? Because of implicit coercion. Basically, if you try to store a value in an incompatible variable, VBA attempts to coerce the value to the right data type. If you try to store a string value into a Double variable, VBA attempts to coerce the string into the right data type. This occurs whether you use InputBox or a hard-coded string. For example, the following snippets are equivalent:
Dim x as Double
x = "5"
''''''''''''''''''''''''''''''''''''''
Dim x As Double
x = InputBox("Enter a number")
' user enters 5
When using InputBox, you of course have no control over whether the user enters valid input. Which is why (as #Dude_Scott mentions), you should store user input into a string, and then make sure you have the right value.
If the user clicks Cancel in the inputbox, the empty string is returned (as per documentation above). Since the empty string can't be implicitly coerced to a double, an error is generated. It's the same thing that would happen if the user entered "apples" in the InputBox.
As #Dude_Scott notes, you should use IsNumeric (or something similar) to make sure that the user input is what you need. However, you don't need to include a check for a null or empty string (since IsNumeric returns False for those values). So you really just need something like this:
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
For more information about coercion, see the following Microsoft articles:
Conversions Between Strings and Other Types
Implicit and Explicit Conversions
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."

VBA - Returning Range or Number from Applilcation.InputBox

I am using Applilcation.InputBox to get a number from the user. Further in the code I am multipying a range of cells with that number.
My problem is that I want to know if the number was written manually or chosen by selecting a cell in the worksheet (that means if the user has written „123“ then „123“ and if he has selected a range then return $A$1).
Code:
Dim output As Variant
Set output = Application.InputBox("Enter Number", "Number for multyplying")
Any advice, please?
I don't think you can do this. Either you set the type to 8, and then you can't enter numbers, or you set it to 1 and then you can't enter references. If you combine it to 9, you still have the problem with Set or no Set.
' Works for ranges
Set Output = Application.InputBox("Enter Number", "Number for multyplying", , , , , , 8)
' Works for literals
Output = Application.InputBox("Enter Number", "Number for multyplying", , , , , , 1)
' Could have worked for both, but it doesn't
Set Output = Application.InputBox("Enter Number", "Number for multyplying", , , , , , 9)
I think the cleanest way to solve this is to implement a UserForm with a RefEdit control.
So, with Application.InputBox I wasn't able to achieve the desired functionality, allthough I still think it's possible somehow... :-)
This is what I came up with (using a UserForm with RefEdit and other tools):
Pay no attention to the picture in the background. I was just trying out stuff... :-) Allthough, I quite like it after all :-)
And this is the code for the commandButton:
(ref_Input being the RefEdit, txb_number the TextBox)
Public gNmr As Variant
Private Sub cmd_OK_Click()
Dim adr As String
If ref_Input.Value <> vbNullString And txb_number.Value <> vbNullString Then
MsgBox "Choose just one option, please.", , "Wrong input"
Exit Sub
Else
If ref_Input.Value = vbNullString And txb_number.Value = vbNullString Then
MsgBox "No input, please try again.", , "Wrong input"
Exit Sub
Else
If txb_number.Value = vbNullString Then
adr = ref_Input.Value
gNmr = adr
Else
If ref_Input.Value = vbNullString Then
gNmr = txb_number.Value
End If
End If
End If
End If
Unload Me
End Sub

Resources