Working With The ADO Data Control
Working With The ADO Data Control
In this chapter, we'll examine the flexible ADO Data Control, to see how it facilitates connecting to a
database, and inputting and retrieving data through VB forms. The aim of this chapter is to provide a
solid understanding of the Data Control and how it allows us to connect to databases without having to
worry too much about its object model.
In this chapter:
❑ We begin by using the Visual Data Manager to build a database, which will contain addresses
and phone numbers.
❑ Then we'll build an application that allows us to view the data present in our database. We'll
extend our application to include a navigation bar that allows us to add, delete, modify, and
search for data.
❑ Finally, we'll take a look at some of the other controls that we didn't use in the example, but
are readily available for you to use in your projects.
Application Walk-Through
The application that we will build in this chapter consists of a form that houses the ADO Data Control.
This control connects to a database containing addresses. The database doesn't exist yet, so we'll build it
using Visual Basic's Visual Data Manager (VisData) program. This database will have one table, which
holds address information such as name, phone number, and address. The application will be able to:
❑ Indicate the current record and the record count in a status label
❑ Add and delete records
❑ Locate a record, given a search string
Even looking forward to .NET, the Jet engine remains a viable and attractive option for some
applications. It is the only database engine from Microsoft that doesn't have complex or expensive
licensing requirements. Although SQL Server 2000 has its Personal Edition, more commonly known as
MSDE, its license is quite restrictive. Jet's license is simple, and the technology is even more usable in
VB6 than it was in earlier versions.
So we'll create a Jet database using Microsoft's VisData. Note that Jet databases do not require Access;
any database that uses Jet as its database engine is a Jet database, and VisData lets us create them
without Access installed.
VisData can:
❑ Build and maintain Jet databases and tables (as well as other formats)
❑ Create indexes on tables
❑ Enter/edit data in tables
❑ Create queries
❑ Repair or compact any Jet database
❑ Create and test SQL statements
Although Jet is inexpensive and easy to use, it is quite limited in its capabilities and can only support a
handful of concurrent users, unlike SQL Server. The ADO Data Control is quite capable of connecting
to SQL Server data stores, and the procedures involved are very similar to those for Jet that we'll look at
as we work through this chapter.
Our database will be fairly simple with just one table, called Address, with the following fields:
AddressID, Last_Name, First_Name, Street, City, State, Zip, Phone, and Comments. The
AddressID will be created as a long number, with an auto counter activated. This field will also be our
primary key. The Last_Name and First_Name fields will be created with indexes attached. Although
we won't be using SQL commands in this chapter, it's always better to plan for future sorting and data
selection requirements.
96
Working with the ADO Data Control
Let's get started. Open Visual Basic, and choose Visual Data Manager from the Add-Ins menu. When
the VisData program opens, select File | New | Microsoft Access | Version 7.0 MDB.
Versions of Access prior to Access 95 use version 2.0 MDB, so if you have such a
version and wish to view the database from Access (which isn't necessary for our
application), choose version 2.0 instead of 7.0.
We are now prompted to choose a location and name for our database. Create a folder called wrox, and
create the database in this new folder as Address. The extension .mdb will automatically be appended.
VisData creates an Access database without any tables, so the next thing to do is add one. Right-click
the Properties node in the Database Window and select New Table.
The Properties item of the Database Window pane allows you to view any associated
properties of the database that is currently opened. These properties include database
location, the version that the database was created in and time-out parameters for
queries. Properties exist on databases, tables, and even fields. They are an intricate
part of the schema of the database as a whole.
This opens the Table Structure dialog, which allows us to create a new table. Enter Address in the
Table Name box, and we can start adding the fields by clicking the Add Field button to bring up the
Add Field dialog.
Type AddressID in the Name box for our first field. This field will store a long number and will
automatically increment when a new record is added, so select Long from the Type drop-down and
check the AutoIncrField box. Lastly, click the Required checkbox. Although the database assigns a
value automatically, this ensures the user won't remove the value later. The dialog should look like the
following screenshot:
97
Chapter 4
❑ Size: The maximum number of characters the user can enter. Primarily for text data types.
❑ FixedField/VariableField: Specifies if the data in the field can be less than the maximum
allowed, or if it is fixed. Text fields only.
❑ AllowZeroLength: Indicates if a zero length value is acceptable, such as empty strings or nulls.
❑ OrdinalPosition: The order of the fields in the table. This is zero-based, so the first field is
zero, the second is one, and so on. This is significant if you reference the field based on its
ordinal position (although it's not a common practice) rather than field name. Additionally,
this is the default tab order, and the order that your fields will be added to the form when you
use form wizards.
❑ ValidationText: The error message that will be shown if the user breaks the validation rule.
❑ ValidationRule: A rule that limits the acceptable values for the field. For example, a rule of
>10 would cause an error for values below 11.
❑ DefaultValue: The value to use if the user leaves the field blank.
For this example, we won't add any validation text or descriptions, so just click OK and the field will be
added. Add a further eight fields, according to the following table:
98
Working with the ADO Data Control
* Although this would be the best place to ensure the Last_Name and First_Name fields are
populated, we'll leave this unchecked for now so that later we can demonstrate how to implement
business rules in code.
Once you have finished adding the fields, click the Close button, and the Table Structure dialog should now
appear as in the following screenshot. As you click each field, the corresponding properties are presented:
The final step before building the table is to specify the indexes by clicking the Add Index button. When
the Add Index to Address dialog appears, click the AddressID field to add it to the Indexed Fields list
box. Then copy and paste it into the Name box as the name for the index. This way, you won't
accidentally misspell it (if you need to rationalize being lazy!). In this table, the AddressID field will be
classified as a primary key and will always be unique, so leave both boxes checked:
99
Chapter 4
After adding these indexes, we're ready for the final step of building the table. Click the Build the Table
button at the bottom of the Table Structure dialog.
Once the table has been built, you'll be able to review the properties of the table, fields, and indexes in
the Database Window pane. Double-clicking the properties of the various fields in the Database
Window allows you to modify them where possible.
We can insert the first record in the database using VisData's graphical user interface. Select Open from
the table's context menu in the Database Window, or simply double-click the table name, and then click
Add on the dialog that appears. Enter some data and click Update:
Alternatively, you could create the record by typing a SQL statement, such as that shown below, into
the SQL Statement pane and clicking the Execute button:
100
Working with the ADO Data Control
Click No when asked if the statement is a SQLPassThrough query. Such queries are for databases that
handle SQL themselves, perhaps in a slightly modified dialect of SQL. Clicking No allows the client
application to optimize the query if appropriate.
Now that we've built the table and added a record, let's add some more data. Click on the Use DBGrid
Control on New Form button (the sixth from left button on the VisData toolbar). When you now open
the Address table, it will appear in a grid format:
Add two or three records for use later when testing our interface. You can now close VisData and return
to Visual Basic.
4. Save the form and project as Address.vbp and Address.frm in a suitable folder off the
wrox one we created earlier.
To open the Components dialog, you can also right-click the toolbox and select Components.
101
Chapter 4
After selecting this, click OK and the ADO Data Control will be added to the Toolbox. It looks like a
horizontal scrollbar with a yellow database symbol attached.
Add an ADO Data Control to your form, and set its Align property to vbAlignBottom:
The ADO Data Control requires a connection string, which allows it to connect to virtually any database
server. In fact, the ADO Data Control can access data sources other than databases, such as LDAP data
sources, e-mail data sources, text data sources, and so on. The connection string contains the information
required to connect, such as the drivers to use, security details, and the location of the data source.
102
Working with the ADO Data Control
This dialog prompts you to choose one of three mechanisms for connecting to the database:
❑ Use Data Link File: Allows you to specify a file that contains the connection information.
These files are can be created in Windows Explorer by choosing Microsoft Data Link from the
list of New items. When saved, the file will have an extension of .UDL.
❑ Use ODBC Data Source Name: Allows you to specify an ODBC Data Source Name (DSN).
DSNs are created from the ODBC Data Source Administrator located in the Control Panel.
❑ Use Connection String: Allows you to build a connection string that specifies drivers,
database location and password information.
Ensure the Use Connection String option button is selected and click Build. The next dialog prompts
you to select the database provider:
103
Chapter 4
This dialog lists all the OLE DB providers installed on your system, so you may have a different
number available. If you have Access 2000 or greater installed on your machine, select Microsoft Jet
4.0 OLE DB Provider; otherwise select Microsoft Jet 3.51 OLE DB Provider. Then click Next to move
to the Connection tab:
The Connection tab is where you specify the location of the database, and the username and password
if required. Click the ellipsis button and locate the Address.mdb database. You can leave the username
and password as they appear.
Click the Test Connection button and the wizard will attempt to connect to the database. If everything
is configured correctly, the following message box should appear:
While we're here, click the Advanced tab. This tab allows you to set protection levels for database
servers using a network, the time-out for the connection attempt in seconds, and the access permissions
for the database. Finally, open the All tab. This displays all properties relevant to your data source, and
varies according to the source you are connecting to. To modify a property, select it and click the Edit
Value button.
104
Working with the ADO Data Control
Click the OK button at the bottom of the dialog and the connection string now appears in the Use
Connection String textbox:
Notice that the connection string details the provider, security, and data source. We could have
manually typed in this connection string had we wanted, but the wizard does prevent typos that can
sometimes be hard to track down.
Click the ellipsis button for the RecordSource property which opens the following Property Pages
dialog. Select adCmdTable from the drop-down at the top, which should enable the Table or Stored
Procedure Name listbox:
105
Chapter 4
Select Address in the second drop-down, to make our control connect directly to this specific table.
Click OK, and our ADO Data Control is now configured to connect to the Address table of the
Address database on startup.
Finally, ensure the BOFAction property is set to adDoMoveFirst, which will prevent the user passing
the beginning of the recordset and causing an error.
2. Name the label lblField, and set its BorderStyle property to Fixed Single, its
Alignment property to Center and its BackColor property to pale yellow.
3. Name the textbox txtField, and clear its Text property. Set its DataSource property to
Adodc1. All textboxes that we add will be bound to this data source. Later, we'll assign
specific fields in the DataField property of each.
106
Working with the ADO Data Control
We'll need nine textboxes in total to display each of the fields in our database. To achieve this,
multiselect both the label and textbox we have already, and copy and paste eight more instances of
them. The textboxes will have duplicate names, so we are asked if we wish to create a control array
when we paste. Click Yes, and our controls will then be distinguished by a unique index value in the
array. Copying them at this stage means we don't have to set the properties of each individual control.
Paste and arrange the controls as shown, working from left to right, and top to bottom:
Although all labels have the name lblField and the textboxes are all called txtField, we can specify
one particular control using its index value, ranging from 0 to 8. This allows us to manipulate the
controls in our code by using a loop. The alternative of giving each control a unique name can often,
depending on your functional requirements, require you to write more code as this array approach
wouldn't be possible. For example, to change the BackColor property of all nine labels at run time, we
can easily loop through all of them through their indices in the control array.
Saying this though, if we chose not to create a control array, we could loop through each controls with a
For Each loop, which is fairly simple if we wish to change all controls that are of type 'Textbox'. If only
a few of the textboxes were to be changed, we could use the Tag property to 'mark' those controls and
check this value as we loop through them. The control array is more elegant I feel, but it's really down
to personal preference.
Now change the Caption properties of the labels, again working from left to right, and top to bottom.
Make sure the index matches that shown in the table below:
107
Chapter 4
The Comments textbox will need to accommodate multiple lines of text so change its MultiLine
property to True, and its ScrollBars property to Vertical.
As you recall, the AddressID field is automatically generated by the database, so we don't want to
allow the user to change its value. Change the following properties of the Address ID textbox:
Property Value
Enabled False
TabStop False
Locked True
The next step is to specify which field each textbox will be bound to. Let's begin with the first textbox,
which will contain the surname. Select Last_Name from the DataField property drop-down.
Using the following table, change the DataField properties of the remaining textboxes:
Although we don't need to in this example, the DataFormat property brings up a useful dialog for
customizing how numbers and dates are presented.
108
Working with the ADO Data Control
We're now ready to test the application. Save your work and run the project. You'll notice that the
application opens with the first record displayed in the textboxes. Navigate through the records using
the data control and modify some of the fields. Test out the Comments box by adding multiple lines
of text.
By navigating to the end of the records, we can even add new records simply by filling in the empty
form that appears and moving back to the previous record when done:
You may notice hard drive activity as you edit and move through the records. This is because each
record is saved as you move off an edited record, a feature of the Jet Database Engine.
Without writing a single line of code, we have successfully built an application that connects to a
database, allows us to navigate through the records, updating fields and adding new records. We'll
continue our exploration of ADO by adding to this functionality later in the chapter.
What's Going On
Thankfully, this is all taken care of for us, and we can simply set the required properties and have the
control handle the details.
The ADO Data Control we added is capable of navigating through the records of the database that we
configure it to connect to. The records are stored in memory in a recordset; a subset of records from a
table (or group of joined tables) based on a very specific criteria. The size of the recordset depends on
how many records are returned by the query, the cache size limit, and the ADO's MaxRecords
property. When a change is made to a record in the recordset, that change is made in the database if
there is a call to the Update method of the ADO Data Control's Recordset object, which happens
implicitly when the user navigates off the current record.
Once connected to a database, the ADO Data Control takes on the responsibility of passing data back
and forth between the database and all the bound controls. In the case of our project, the first textbox is
bound to the Last_Name field of the Address table. Thus, ADO uses the current record's Last_Name
field to populate that textbox, and conversely, if any changes are made to the textbox, ADO uses the
new value to update the appropriate field in the database accordingly.
109
Chapter 4
The Masked Edit Control lets us accomplish this, and it can be added by opening the Components
dialog and checking Microsoft Masked Edit Control 6.0 to add it to the Toolbox. It appears after the
ADO Data Control as the text ##|.
To create a mask for the phone number field, delete that textbox, and add a Masked Edit Control in its
place. Name the new control mskPhone, and bind it to the ADO Data Control by setting its
DataSource property to Adodc1 and its DataField property to Phone.
Open the property pages of the Masked Edit Control by right-clicking it and selecting Properties.
Uncheck the PromptInclude checkbox, and type (###) ###-#### in the Mask text box. Type the same
into the Format box (or just copy and paste):
It's important to configure this control correctly, as it may not bind to the data source properly if you set
a property erroneously.
The PromptInclude checkbox indicates whether the literals and prompt values, such as underscores and
hash characters, should be included as part of the text to be passed to the database when the value is
not populated.
The Mask property is a sort of template for text entered in that textbox. You can probably work out that
our mask will display hyphens and brackets to separate numeric values represented by the hash
character. The valid placeholders are:
❑ # – Digits only
❑ ? – Letters only
❑ & – Any character allowed
110
Working with the ADO Data Control
The Format property defines how the data should be displayed once the value has been entered, and
the PromptChar property specifies the character that will take the place of values before anything has
been entered. We'll just keep it as the underscore.
Change the TabIndex of the Masked Edit Control so that it replaces the removed textbox in the
Tab order.
Run the application and you'll see that blank phone numbers appear filled in with underscores. The
Masked Edit Control can give your application a professional look and feel, and help in validating data
for certain fields.
❑ Your navigation bar can reflect your GUI style. Command buttons can contain images or any
caption that fits your needs.
❑ You can enable and disable portions of the navigation bar as required.
❑ It provides more flexibility for custom error trapping.
❑ It lets you apply business rules such as validation against the data before moving to the
next record.
Because we're no longer using the ADO Data Control to navigate, the first thing to do is change its
Visible property to False to hide it at run time. It will still be there to do our work for us, but we
don't want to show it.
Add a single command button named cmdNavigate and set its Font property to Arial, 10, Bold –
place over the top of the ADO control. Copy the command button and paste it on the form three times,
creating a control array as before. Add a new label to the form, and set its BackColor property to pale
yellow. Arrange the command buttons and label below the Comments textbox as shown in the
next screenshot:
111
Chapter 4
Change the other properties of the new controls according to the following table. Note that the buttons
are ordered from left to right:
112
Working with the ADO Data Control
The next, previous, first, and last records can be located with a single line of code calling the
MoveFirst, MoveLast, MoveNext, or MovePrevious method on the ADO Recordset object. These
methods retrieve the specific record and refresh the bound controls. If an error occurs during the
navigation, we'll display an error message in a message box.
When locating the next record or the previous record, we need to check to see if the EOF has been
reached after we call the MoveNext method. If we have reached EOF, we move to the last record by
stepping back one position. The same applies after we call the MovePrevious method, except we
check for BOF, and call MoveFirst if so. If we didn't do this, we'd get an error on passing the start or
end of records. Although we could handle this with our error handler, we should always avoid an error
situation if we can.
Click on one of the command buttons, and enter the following code for the handler:
With Adodc1.Recordset
End With
Exit Sub
goNavigateErr:
MsgBox Err.Description
End Sub
113
Chapter 4
View the code for the form, and select Adodc1 from the Object drop-down. Then select MoveComplete
from the Procedure drop-down box on the right, and add the following code to the event handler:
End Sub
This code updates the label with the absolute position of the current record in the recordset and the
total number of records using the following two properties of the ADO Recordset object:
If we were still using the ADO Data Control to navigate through our recordset, we could have
assigned the same concatenated string to its Caption property.
Now we can test the new form. Our new command buttons should navigate through the recordset just as
the ADO Data Control buttons did. Note that navigation does not need to use command buttons, as we
can call the MoveFirst, MoveNext, and related methods from anywhere in code.
Further Enhancements
We're almost done with our first sample application. First, we will add code to:
To begin, add a single command button to the form and name it cmdAction. As you might have
guessed, we'll create a control array to handle our logic. Copy the command button and paste it four
more times. Arrange the new command buttons as shown below, changing the captions to match, and
making sure the indices go left to right from 0 to 4. Again, place the controls over the ADO Data
Control as it will be invisible at run time:
114
Working with the ADO Data Control
Now add the following code for the cmdAction_Click event handler:
With Adodc1
Case 0 'Add
If cmdAction(0).Caption = "&Add" Then
varBookMark = .Recordset.Bookmark
.Recordset.AddNew
txtField(0).SetFocus
cmdAction(0).Caption = "&Cancel"
SetVisible False
Else
.Recordset.CancelUpdate
If varBookMark > 0 Then
.Recordset.Bookmark = varBookMark
Else
.Recordset.MoveFirst
End If
cmdAction(Index).Caption = "&Add"
SetVisible True
End If
Case 1 'Delete
If .Recordset.EditMode = False Then
.Recordset.Delete
.Recordset.MoveNext
115
Chapter 4
Case 2 'Find
frmFind.Show
Case 3 'Update
.Recordset.Update
varBookMark = .Recordset.Bookmark
.Recordset.Requery
If varBookMark > 0 Then
.Recordset.Bookmark = varBookMark
Else
.Recordset.MoveLast
End If
cmdAction(0).Caption = "&Add"
SetVisible True
Case 4 'Restore
varBookMark = .Recordset.Bookmark
.Restore
If varBookMark > 0 Then
.Recordset.Bookmark = varBookMark
Else
.Recordset.MoveLast
End If
End Select
End With
Exit Sub
goActionErr:
MsgBox Err.Description
End Sub
With the form's code window open, select Tools | Add Procedure from Visual Basic's menu, and supply
a name of SetVisible. Modify the procedure to receive a Boolean argument called blnStatus, and
type the following code as the procedure body:
116
Working with the ADO Data Control
For intIndex = 0 To 3
cmdNavigate(intIndex).Enabled = blnStatus
Next intIndex
End Sub
We'll call this procedure to disable command buttons when we call the Add method, and to re-enable
them once the new record is finished or canceled.
In the General Declarations section of your code, add a new variable called varBookMark. This
variable will be used by a few of our command buttons to return to the record that we were working
with prior to the Add method being called. Add Option Explicit too if it's not there already:
Option Explicit
Dim varBookMark As Variant
In this application, the Add command button (cmdAction index 0) will be used as a toggle to add or
cancel a new record. When we click the command button, we'll check the Caption and if it's &Add,
we'll set varBookMark to the current record position and then call the AddNew method.
In the AddNew method, we set the focus to the Last Name textbox, ready for the user to enter data,
change the button caption to &Cancel, and disable all buttons except Add (now Cancel) and Update.
On the other hand, if the button caption isn't &Add, then it must be &Cancel, and we call the
CancelUpdate method. We revert back to the original record that the user was viewing before they
clicked the Add button by setting the Bookmark property to the value of varBookMark. Finally, all
command buttons are re-enabled.
Deleting Records
When the user clicks the Delete button, we check to see if they have modified any data fields using the
EditMode property of the Recordset, which is True whenever the user has edited a bound control. If
the user attempts to delete a record which they have changed, the Update or Restore method must be
called first. Once we've deleted the record, we move to the next record.
Updating Records
The Update method propagates any changes made to the database. In this sample, we follow the
Update method with the Requery method. The only reason for this is so that we can display the value
of the AutoNumber field once the new record has been submitted.
Again, we set a bookmark when updating so that the user is returned to the current record. The last step
is to ensure the cmdAction(0) button's Caption is set to &Add, as it may have been &Cancel, and re-
enable all command buttons by calling the SetVisible procedure.
117
Chapter 4
Restoring Records
To abandon changes and restore the data in the database table, we use the Restore method. This is
called against the ADO Data Control, not against the Recordset object, and it reloads the data as it is
in the database table. The Restore method moves us to the first record, just as when first connecting to
the database, which could be quite annoying if a user has already located a specific record. Thus, we'll
avoid this by bookmarking the current record before the call.
Note that if another user has deleted the record, it will not be possible to move back to
the bookmark, and an error would be returned. In a production application, you may
wish to code for such an eventuality.
The Restore method can also be useful in situation where more than one user modifies the same
record. When one has made updates, the second can call the Restore method to view their changes.
Finding Records
If the user clicks the Find button, we open a new form called frmFind where the user can enter their
search text. We could use Visual Basic's InputBox command, but we'll implement a second form for
greater flexibility. This form will have several buttons, allowing the user to locate the first occurrence of
the string, the next occurrence of the string, or cancel the operation.
Select Project | Add Form from the menu. Save the new form as Find.frm in the same directory as
Address.frm. Add three buttons and a textbox, setting their Caption/Text properties as shown:
Item Name
Form frmFind
Textbox txtSearch
We now need a procedure to scan through the records, searching for a match. Add a procedure to the
frmFind form named FindString. It starts off by declaring variables and error handling:
118
Working with the ADO Data Control
Next, we initiate a loop to search for the requested text until the end of the ADO Data Control
Recordset is reached:
strFind = Trim(txtSearch)
With frmAddress.Adodc1.Recordset
Do Until .EOF
The procedure only searches the first and last name textboxes, txtField(0) and txtField(1):
For intFields = 0 To 1
We use the InStr function to look for the string in any part of the field. It returns an integer indicating
the start position of the substring if found, or else it returns zero, so if it is greater than 0, we highlight
the text and exit the search routine. Note that we use a search type of vbTextCompare, which provides
a more general search, avoiding misses due to case sensitivity and other anomalies:
To highlight the string we're searching for; we use the SelStart and SelLength properties of the
textbox. First, we establish where the highlighted text begins by finding the start position and
subtracting 1 from it. To find the start position, we use the InStr function in exactly the same way as
above. We must subtract one because InStr will return the text position and the SelStart property
needs to be set equal to the value just before the character we want to highlight:
frmAddress.txtField(intFields).SelStart = InStr(1, _
frmAddress.txtField(intFields), strFind, vbTextCompare) - 1
The Len keyword is used to determine the length of the string we're looking for. Once we have this, we
highlight the string by setting the SelLength property of the textbox equal to the length of the string
that was searched for:
frmAddress.txtField(intFields).SelLength = Len(strFind)
frmAddress.txtField(intFields).SetFocus
Exit Sub
End If
Next
.MoveNext
DoEvents
119
Chapter 4
Loop
MsgBox "Record not found"
.MoveFirst
End With
Exit Sub
FindError:
MsgBox Err.Description
Err.Clear
End Sub
The search could be easily modified to include other textboxes by changing the start and end values of
the For loop. However, don't forget that we deleted the textbox for the phone number, so it can't be
accessed using that index, which was 6. We could either re-index the control array, or add a line to skip
over Index 6. Alternatively, we could use a For Each loop to run through all textboxes, or check all
fields individually.
Next, add the handler for the click event of the cmdFind button. If the search string is not empty, the
above method is called to locate the first instance of the string. If the RecordCount property of the
Recordset is less than one, there is no need to continue. To ensure that the data is searched from the
beginning, we need to move to the first record before calling the FindString procedure:
End Sub
When searching for the next instance of the string, we don't need to move to the first record, but we do
need to move to the next record so that the FindString procedure doesn't find the same record again.
Of course, if we call the MoveNext method, we need to check for the EOF marker. In this scenario, if we
reached the end of the file, there's no need to continue searching:
With frmAddress.Adodc1.Recordset
.MoveNext
If .EOF Then
.MoveLast
MsgBox "End of File Reached!"
120
Working with the ADO Data Control
Else
Call FindString
End If
End With
End Sub
Finally, if a user clicks the Cancel button, we can close the form by calling its Unload method. The Me
keyword refers to the object containing the current code, which in this case is frmFind:
Unload Me
Set frmFind = Nothing
End Sub
We could have used Unload frmFind instead, or even called frmFind.Hide. However, to save
resources, it's better practice to unload the form out of memory.
The application will search through the records until a match is found, or EOF is reached. If a match is
made, the search string will appear highlighted:
121
Chapter 4
Moving sequentially through all records looking for a match works well in this case because the table
size is small, but for a larger table, it would be better to apply a SQL statement to the Recordset, or
use the Filter property of the Recordset object.
These are just a few of the controls that can be bound to an ADO Data Control. Don't forget that if you
don't find a control that suits your needs, you can always build a custom one. In addition, a great
number of vendor controls are available, although these do vary greatly in price. But if the control fits
your needs and is cheaper than building it in-house, it's worth the investment.
The Label
Binding to a label control works similarly to the textbox, with the difference that it prevents the user
entering, selecting, or copying the displayed value. If you bind a label to a data source, the user would
only be able to view that data.
The Checkbox
A checkbox offers a neat way to let the user enter Boolean data, and really makes an app seem more
professional when used for appropriate fields. The checkbox can take one of three possible values:
❑ Unchecked = 0
❑ Checked = 1
❑ Grayed (not applicable) = 2
DataGrid Control
The DataGrid control has been around for some time, and allows the user to view and edit multiple
records at once. It works and looks similar to the table view of Access, so many non-technical people
will already be comfortable with using it as an interface to data:
122
Working with the ADO Data Control
The control also allows many display formats to be applied to data it contains, with shading and font
styles. Due to its complexity, the Hierarchical FlexGrid control is probably best set up and configured
by running the Data Form Wizard to create the form where it will live. This wizard can be found in the
Add-Ins menu.
123
Chapter 4
The DataCombo provides a drop-down that can be used to select one of many options from a database
with minimal wasted space. The DataList on the other hand offers the user a range of choices at once:
There are four data-binding properties for both of these two controls, which are used to set up the
record sources mentioned above:
❑ RowSource – The data control from which the DataCombo or DataList will be filled.
❑ ListField – The field from which the DataCombo or DataList will be filled.
❑ DataSource – The ADO data control that specifies where the selected data will be stored.
❑ DataField – The field that will be populated with the selected data.
124
Working with the ADO Data Control
Summary
In this chapter, we've reviewed the basics of the ADO Data Control, and some of the controls that can
be bound to it. We also demonstrated that even if you don't have a database program on your
computer, you can create a database quickly with the VisData add-in. In particular we looked at:
125
Chapter 4
126