Read our blogs, tips and tutorials
Try our exercises or test your skills
Watch our tutorial videos or shorts
Take a self-paced course
Read our recent newsletters
License our courseware
Book expert consultancy
Buy our publications
Get help in using our site
551 attributed reviews in the last 3 years
Refreshingly small course sizes
Outstandingly good courseware
Whizzy online classrooms
Wise Owl trainers only (no freelancers)
Almost no cancellations
We have genuine integrity
We invoice after training
Review 30+ years of Wise Owl
View our top 100 clients
Search our website
We also send out useful tips in a monthly email newsletter ...
Using a VBA input box to capture numbers and dates works well until somebody enters a value of the wrong type:
If your code is expecting the user to enter a number, what happens when they don't?
You can click here to download the file needed for this part of the lesson.
You can click here to download the completed code.
Extract and open the workbook linked to in the Files Needed section above. In Module1, find the subroutine called TypeMismatchErrors. In the previous part of the lesson you saw that you can use the VBA input box to capture non-string values such as dates and numbers. The TypeMismatchErrors subroutine attempts to capture a Date value from an input box:
You can attempt to return the value of an input box to a variable of any data type.
The problem is that there is no control over what values your users type into the input box:
Rebellious users may have ideas of their own...
This leaves your code prone to causing type mismatch errors:
This is not the sort of message that inspires confidence in your users.
Clicking Debug on the dialog box shown above indicates the line that has caused the error:
Unsurprisingly, it's the line which attempts to store a value in the Date variable.
You can also cause a run-time error by cancelling the input box. Clicking Cancel causes the input box to return an empty string, which can't be stored in either a Date or an Integer variable.
A simple way to avoid this sort of problem is to initially store all values returned from input boxes as strings. Find the subroutine called StoringStrings in Module1:
Storing the result of each input box as a String eliminates the risk of a type mismatch.
Once you've safely captured the value in a string variable, you can use a function to determine if it could be converted into another data type. Add an If statement to the StoringStrings subroutine to test if the DOBString variable contains a valid date:
Use the IsDate function to test if the variable contains a value that can be converted into a date. If the value of the variable can't be converted into a date we inform the user and then exit the procedure.
If the user enters an invalid date, instead of a standard run-time error message they'll see a more user-friendly version:
You could provide some friendly instructions to help the user to enter a valid value the next time they run the procedure.
You can test if a value is a number in a similar way, using the IsNumeric function. Add another If statement to the StoringStrings subroutine to check if the HeightCmString variable contains a value that can be converted into a number:
If the value of the variable can't be converted into a number, the user will see a message and then the procedure will end.
Once you've established that a value can be treated as another type, you may wish to store it in a variable of the correct type. This can be useful if you want to perform calculations on a number or a date later in the procedure. The example below shows how you could explicitly convert a string into a date using the CDate function and store the result in a separate variable:
It's quite a lot of effort to ensure that your users can't enter invalid data into a VBA input box!
Using explicit type conversion functions makes code easier to read, but you don't technically need to use them. You could omit the CDate function in the above example and rely on implicit data type conversion:
'Convert the string to a date
DoB = DoBString
You can take the same approach to explicitly convert a string into a number:
You should also make sure that the number is within the range of the data type you're using. If the user entered a value of greater than 32,767 (the upper limit of the Integer data type) they would see another run-time error message.
To practise avoiding type mismatch errors:
Sub HowManyDays()
Dim DoBString As String
DoBString = InputBox("Enter date of birth")
End Sub
Sub HowManyDays()
Dim DoBString As String
DoBString = InputBox("Enter date of birth")
If Not IsDate(DoBString) Then
MsgBox "That's not a date!", vbCritical
Exit Sub
End If
End Sub
Sub HowManyDays()
Dim DoBString As String
Dim DoB As Date
DoBString = InputBox("Enter date of birth")
If Not IsDate(DoBString) Then
MsgBox "That's not a date!", vbCritical
Exit Sub
End If
DoB = CDate(DoBString)
End Sub
Sub HowManyDays()
Dim DoBString As String
Dim DoB As Date
Dim DaysOld As Long
DoBString = InputBox("Enter date of birth")
If Not IsDate(DoBString) Then
MsgBox "That's not a date!", vbCritical
Exit Sub
End If
DoB = CDate(DoBString)
DaysOld = DateDiff("d", DoB, Date)
MsgBox _
"You are " & DaysOld & " days old", _
vbInformation
End Sub
Suddenly, one's age in years doesn't seem quite so bad.
Although it's quite simple, it's better than seeing a run-time error message.
Kingsmoor House
Railway Street
GLOSSOP
SK13 2AA
Landmark Offices
99 Bishopsgate
LONDON
EC2M 3XD
Holiday Inn
25 Aytoun Street
MANCHESTER
M1 3AE
© Wise Owl Business Solutions Ltd 2024. All Rights Reserved.