The Masked Edit Control

The Masked Edit control provides restricted data input as well as formatted data output. This control supplies visual cues about the type of data being entered or displayed. It can be useful in data entry applications in that it can prevent the user from entering invalid data.

In my humble opinion, the masked edit box control is suitable for the entry of some types of data items, but woefully inadequate for others.

The masked edit control is GOOD for items that are fixed in length with a defined format, such as Social Security Numbers, phone numbers, zip codes; generally anything with a fixed number of digits and/or letters (account numbers, state abbreviations, etc.).

It is so-so for dates (you must enter all digits and it does not validate the correctness of the date).

The masked edit control is BAD for numeric items with a decimal point where the number of digits before and/or after the decimal point can vary (such money amounts, rates, measurements, etc.). This is because the control will not right-align the value nor line up the decimal point as you enter the value. For these types of numeric values, you are better off using the standard TextBox control and monitoring the user's input "manually" with the KeyPress event. Another option would be to use (or write your own) custom control to incorporate this functionality. (Note: A custom control called TextPlus incorporates this very functionality is available from thevbprogrammer.com website. Check the Extras link on the Tutorials page to learn more.)

The Masked Edit control is an "Active X" control that must be added to the toolbox via the Components dialog box, as shown below.  This dialog box is accessed via the Project menu, Components item.  Once you check "Microsoft Masked Edit Control 6.0 (SP3)" and click OK, the control is added to your toolbox (also shown below, circled).  Then you can double-click it to make it appear on your form, as you would with any other control.

 

The Components Dialog Box

Masked Edit Box Control Added to Toolbox

 

The Mask Property

 

The Mask property is the "heart" of the Masked Edit control. With it, you define the pattern of the data item to be entered into the control. The following characters can be used to set the Mask property:

 

Mask Character

Description

# (number sign)

Digit placeholder. Only the digits 0 through 9 can be entered in this position.

. (period)

Decimal placeholder. The actual character used is the one specified as the decimal placeholder in your international settings.

, (comma)

Thousands separator. The actual character used is the one specified as the thousands separator in your international settings.

: (colon)

Time separator. The actual character used is the one specified as the time separator in your international settings.

/ (forward slash)

Date separator. The actual character used is the one specified as the date separator in your international settings.

\ (backslash)

Treat the next character in the mask string as a literal. This allows you to include the '#', '&', 'A', and '?' characters in the mask.

& (ampersand)

Character placeholder. Valid values for this placeholder are ANSI characters in the following ranges: 32-126 and 128-255.

> ("greater than" symbol)

Convert all the alphabetic characters that follow to uppercase.

< ("less than" symbol)

Convert all the alphabetic characters that follow to lowercase.

A

Alphanumeric character placeholder. Uppercase letters A-Z, lowercase letters a-z, or digits 0-9 can be entered.

a

Alphanumeric character placeholder. Uppercase letters A-Z, lowercase letters a-z, or digits 0-9 can be entered, but are not required.

9

Digit placeholder. Only the digits 0 through 9 can be entered in this position but are not required.

C

Character or space placeholder (entry optional). This operates exactly like the & placeholder.

?

Letter placeholder. Only alphabetic characters a – z or A – Z can be entered.

Any other

Any other symbols are displayed as literals; that is, as themselves.

 

The PromptInclude Property

 

The PromptInclude property is a Boolean value that specifies whether prompt characters (the default prompt character is the underscore) and other literal characters are included in the Text property. For example, if MaskedEdBox1 specified a Mask of "###-##-####" and the user entered "123121234", the control would display "123-12-1234". If PromptInclude is set to True, then the value of MaskedEdBox1.Text would be 123-12-1234, and Len(MaskedEdBox.Text) would be 11.  If PromptInclude is set to False, then the value of MaskedEdBox1.Text would be 123121234, and Len(MaskedEdBox.Text) would be 9. In most cases, it is appropriate to set PromptInclude to False – otherwise, extra logic may be needed to parse out the actual value that the user entered.

 

The AutoTab Property

 

The AutoTab property is a Boolean value that determines whether or not the next control in the tab order receives the focus as soon as the Text property of the Masked Edit control is filled with valid data. Set this property to True to provide auto-tabbing functionality to your form.

 

 

Masked Edit Control Demo Program

 

The demo program associated with this article presents the user with a form containing various input fields (masked edit boxes), as shown below:

 

 

When the user fills in the fields and clicks the Process button, the application validates the entries and reports the results in the multi-line textbox at the bottom of the screen:

 

 

Clicking the Pre-Fill button populates the masked edit boxes with predetermined values (this demonstrates how to populate masked edit controls through code):

 

 

The Clear button clears the contents of the masked edit controls; the Exit button ends the program.

 

 

The form at design-time is shown below:

 

 

To build the sample application, arrange the controls on the form as shown. Set the properties of the six Masked Edit controls as follows:

 

Name

Mask

PromptInclude

AutoTab

mskSSN

###-##-####

False

True

mskPhone

(###) ###-####

False

True

mskDate

##/##/####

True

True

mskState

>??

False

True

mskUSZip

####-####

False

True

mskCanZip

>?#? #?#

False

True

 

Set the properties of the four command buttons as follows:

 

Name

Caption

cmdProcess

Process

cmdPreFill

Pre-Fill

cndClear

Clear

cmdExit

Exit

 

Set the properties of the multi-line textbox as follows:

 

Property

Value

Name

txtResults

MultiLine

True

Scrollbars

2 - Vertical

Locked

True

 

Code the General Declarations section as follows (there is one form-level variable, a Variant named mavntUSStates, which will store the 50 valid US state abbreviations):

 

Option Explicit

 

Private mavntUSStates   As Variant

 

Code the Form_Load event as follows (the values of the array declared above are assigned):

 

'--------------------------------------------------------------------------------

Private Sub Form_Load()

'--------------------------------------------------------------------------------

 

    mavntUSStates = Array("AK", "AL", "AR", "AZ", "CA", "CO", "CT", "DC", _

                          "DE", "FL", "GA", "HI", "IA", "ID", "IL", "IN", _

                          "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN", _

                          "MO", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", _

                          "NM", "NV", "NY", "OH", "OK", "OR", "PA", "RI", _

                          "SC", "SD", "TN", "TX", "UT", "VA", "VT", "WA", _

                          "WI", "WV", "WY")

 

End Sub

 

Code the cmdProcess_Click event as follows. Note that the tests for the lengths of the Text property of all the masked edit controls except for the mskDate control test for the length of the item excluding the mask characters - because the PromptInclude property for those was set to False. The length test for mskDate is 10 rather than 8 because the PromptInclude property for that control is set to True.

 

'--------------------------------------------------------------------------------

Private Sub cmdProcess_Click()

'--------------------------------------------------------------------------------

 

    If Len(mskSSN.Text) = 9 Then

        DisplayMessage "SSN is OK."

    Else

        DisplayMessage "SSN is missing or incomplete."

    End If

   

    If Len(mskPhone.Text) = 10 Then

        DisplayMessage "Telephone Number is OK."

    Else

        DisplayMessage "Telephone Number is missing or incomplete."

    End If

   

    If Len(mskDate.Text) = 10 Then

        If IsDate(mskDate.Text) Then

            DisplayMessage "Date is OK."

        Else

            DisplayMessage "Date is invalid."

        End If

    Else

        DisplayMessage "Full date in MM/DD/YYYY format is required."

    End If

   

    If ValidState Then

        DisplayMessage "U.S. State is OK."

    Else

        DisplayMessage "U.S. State is invalid."

    End If

   

    If Len(mskUSZip.Text) = 5 Or Len(mskUSZip.Text) = 9 Then

        DisplayMessage "U.S. Zip is OK."

    Else

        DisplayMessage "U.S. Zip is missing or incomplete."

    End If

   

    If Len(mskCanZip.Text) = 6 Then

        DisplayMessage "Canadian Zip is OK."

    Else

        DisplayMessage "Canadian Zip is missing or incomplete."

    End If

 

End Sub

 

Code the cmdPreFill_Click event as follows. Once again, the PromptInclude issue comes into play. Note that we are assigning "raw" data to each of the masked edit controls except for mskDate, where the slashes are included. When PromptInclude is set to True, the data assigned to the control must match the mask - otherwise, an error will occur.

 

'--------------------------------------------------------------------------------

Private Sub cmdPreFill_Click()

'--------------------------------------------------------------------------------

 

    mskSSN.Text = "123121234"

    mskPhone.Text = "1112223333"

    mskDate.Text = Format$(Date, "mm/dd/yyyy")

    mskState.Text = "WV"

    mskUSZip.Text = "123451234"

    mskCanZip.Text = "R3C0V8"

   

    txtResults.Text = ""

   

End Sub

 

Code the cmdClear_Click event as follows. Here, the contents of the masked edit controls are cleared by assigning the zero-length string ("") to each control. However, for the mskDate control, where the PromptInclude property is set to True, a special technique is required. We must first clear the Mask property, then clear the Text property. After that is done, we can reset the Mask property.

 

'--------------------------------------------------------------------------------

Private Sub cmdClear_Click()

'--------------------------------------------------------------------------------

 

    mskSSN.Text = ""

    mskPhone.Text = ""

   

    mskDate.Mask = ""

    mskDate.Text = ""

    mskDate.Mask = "##/##/####"

   

    mskState.Text = ""

    mskUSZip.Text = ""

    mskCanZip.Text = ""

   

    txtResults.Text = ""

 

    mskSSN.SetFocus

 

End Sub

 

Code the cmdExt_Click event as follows to end the program.

 

'--------------------------------------------------------------------------------

Private Sub cmdExit_Click()

'--------------------------------------------------------------------------------

    End

End Sub

 

Code the DisplayMessage Sub as follows. This Sub is used to build the information that appears in the multi-line textbox on the lower half of the form.

 

'--------------------------------------------------------------------------------

Private Sub DisplayMessage(pstrMsg As String)

'--------------------------------------------------------------------------------

    txtResults.Text = txtResults.Text & vbNewLine & pstrMsg

End Sub

 

Code the ValidState function. This function checks the user's entry in the mskState control against the array of valid US states to determine if a valid state was entered.

 

'--------------------------------------------------------------------------------

Private Function ValidState() As Boolean

'--------------------------------------------------------------------------------

 

    Dim lngX            As Long

    Dim blnStateFound   As Boolean

   

    blnStateFound = False

   

    For lngX = 0 To UBound(mavntUSStates)

        If mskState.Text = mavntUSStates(lngX) Then

            blnStateFound = True

            Exit For

        End If

    Next

   

    ValidState = blnStateFound

   

End Function

 

 

Download the project files for this sample application here.