Visual Basic 6 (VB6)
Visual Basic 6 (VB6)
Search
Navigate To
Home
Tutorials
VB.NET Tutorials
Forums
Articles
External Links
Advertise Here!
Contact Us
Guides
• Beginner Guide
• Controls Guide
o Database Guide
Introduction to SQL
Using RDO
Using ADO
ADO and ListView
User login
Username: *
Password: *
Log in
Home › Tutorials
Rank:
(3 votes)
This tutorial describes how you can use ADO objects in VB6. Now days, almost
any time you write full fledged database application you will want to use ADO. Along with
this, as your applications become more and more complex you will probably not want to
rely on Visual Basic's data controls, but instead use the ADO objects directly. Read on to
In the VB4 and VB5 worlds, RDO was the main method used to interact with client/server
databases. RDO works perfectly fine with VB6, so when folks migrated their VB5 applications
over to VB6, little or no coding changes were required. However, ADO is the preferred method of
database access for new VB6 applications .
This tutorial presents three small sample applications using ADO. All three applications use a
local MS Access database.
The first sample application introduces the ADO Data Control (ADODC) which demonstrates a
"quick and dirty" way to connect to a remote database. The second and third applications use
ADO code: the second allows navigation and searching of a database table; the third allows
navigation and updating on a database table. All three connect to an ODBC Data Source, which
must be set up through the Windows Control Panel. How to do this is described below.
Note: If you have previously set up a DSN for the Biblio database as described in the previous
topic on RDO, you can skip the section on setting up an ODBC data source and resume here.
• Via Windows Control Panel, double-click on Administrative Tools, then Data Sources
(ODBC). The ODBC Data Source Administrator screen is displayed, as shown below. Click
on the System DSN tab.
• Click the Add button. The Create New Data Source dialog box will appear. Select
Microsoft Access Driver (*.mdb) from the list and click the Finish button.
• The ODBC Microsoft Access Setup dialog box will appear. For Data Source Name, type
Biblio. If desired, you can type an entry for Description, but this is not required.
• Click the Select button. The Select Database dialog box appears. On a default installation of
VB6 or Visual Studio 6, the BIBLIO.MDB sample database should reside in the folder
C:\Program Files\Microsoft Visual Studio\VB98. Navigate to that folder, select
BIBLIO.MDB from the file list, and click OK.
Note: If VB was installed in a different location on your system, navigate to the appropriate folder.
If you do not have the BIBLIO.MDB sample database file on your system at all, you can
download it here. In that case, copy the file to the folder of your choice, and navigate to
that folder to select the database for this step.
• When you are returned to the ODBC Microsoft Access Setup screen, the database you
selected should be reflected as shown below. Click OK to dismiss this screen.
• When you are returned to the ODBC Data Source Administrator screen, the new DSN should
appear as shown below. Click OK to dismiss this screen.
At this point, the Biblio database is ready to be used with RDO in the sample application.
• Start a new VB project, and from the Components dialog box (invoked from the Project ->
Components menu), select Microsoft ADO Data Control 6.0 (SPx) as shown below and
click OK.
The ADO Data Control should appear in your toolbox as shown below:
• Put an ADO Data Control on your form, and set the properties as follows:
Property Value
Name adoBiblio
DataSourceName Biblio
SQL select * from authors
• Now put three text boxes on the form, and set their Name, DataSource, and DataField
properties as follows:
• Save and run the program. Notice how it works just like the other data control.
• Now change the SQL property of the data control to select * from authors order by author
and run the program again. Notice the difference.
• Change the SQL property back to what it was and add three command buttons to the form,
and set their Name and Caption properties as follows:
Name Caption
cmdNameOrder Order by Name
cmdYearOrder Order by Year
cmdIDOrder Order by ID
adoBiblio.Refresh
adoBiblio.Refresh
adoBiblio.Refresh
• Save and run the program and see what happens when you click the buttons.
Note: If you have previously downloaded and set up a DSN for the Property database as
described in the previous topic on RDO, you can skip the set up steps below and resume here.
Sample applications 2 and 3 use a database called PROPERTY.MDB and can be downloaded
here.
The Property database contains just one table called "Property". The columns of this table are
defined as follows:
After downloading the file, move it to the folder of your choice. Then follow the exact same steps
as before to set up the DSN, with these two exceptions:
(1) On the ODBC Microsoft Access Setup dialog box, type PropDB for the Data Source Name.
(2) In the Select Database dialog box, navigate to the location where you have placed the
PROPERTY.MDB file.
Sample Application 2
To build Sample Application 2, start a new VB project and perform the following steps.
• From the Project -> References menu, check Microsoft ActiveX Data Objects 2.x (where
x is the highest version that you have on your system) and click OK.
• This project uses the StatusBar control, so include the Microsoft Windows Common
Controls 6.0 (SP6) from the Components dialog box, accessed from the Project ->
Components menu.
• Create the form shown below. The names of the text boxes in the top frame are shown in the
form. Set the Enabled property of the frame to False, which will automatically disable all of
the textboxes within it, which is desired because this application does not allow updating of
the data. The settings for the other controls are given below.
The navigation buttons have the following properties:
Name Caption
cmdMoveFirst <<
cmdMovePrevious <
cmdMoveNext >
cmdMoveLast >>
The text box in the middle of the form has the following properties:
Name txtCurrentQuery
MultiLine True
Locked True
Name Caption
chkCriteria(0) EmpNo
chkCriteria(1) City
chkCriteria(2) State
Place the StatusBar on the form and set its Style property to 1 – sbrSimple.
2. Code the General Declarations section as shown below. Here, two ADO objects,
ADODB.Connection and ADODB.Recordset, are defined at the form level.
The ADODB.Connection object represents an open connection to a data source and a specific
database on that data source, or an allocated but as yet unconnected object, which can
be used to subsequently establish a connection.
The ADODB.Recordset object represents the rows that result from running a query,
Option Explicit
Dim mobjADOConn As ADODB.Connection
3. Code the Form_Load event. Here, the connection object variable mobjADOConn is made
available for use by setting it to a new instance of ADODB.Connection. Then, the
ConnectionString property and the Open method of the ADODB.Connection object are
used.
The ConnectionString property takes a string with various arguments delimited by semicolons.
When using a DSN as we are in this sample application, you typically need just the DSN
name, the user id, and the password. The Open method then opens the connection to the
database.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
mobjADOConn.ConnectionString = "DSN=PropDB;Uid=admin;Pwd=;"
mobjADOConn.Open
Call cmdAllData_Click
Exit Sub
LocalError:
End Sub
4. Code the cmdAllData_Click event, which sets or resets the ADODB.Recordset object with a
query to display all the rows in the table. The opening of the recordset takes place in the
OpenNewRecordset subprocedure, called from this event procedure.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
Call OpenNewRecordset
Call DataLoad
For lngX = 0 To 2
chkCriteria(lngX).Value = vbUnchecked
Next
Exit Sub
LocalError:
End Sub
Here, the recordset object mobjADORst is made available for use by setting (or resetting) it to a
new instance of ADODB.Recordset.
The CursorLocation property is then set to the built-in constant adUseClient. The term "cursor"
refers to the temporary rows of a recordset. The cursor location determines whether the
cursor is stored on the client or the server, specified by the values adUseClient and
adUseServer, respectively. Server-side cursor (adUseServer) is the default. There are
tradeoffs using both types of cursors. Client-side cursors can take a long time to build
because the data must be pulled over to the client, but once built, traversing the cursor is
usually very fast. Client-side cursors often support more features than server-side cursors
(the reason this sample application is using a client-side cursor is because we want to
use AbsolutePosition property later, which only works with a client-side cursor). On the
other hand, server-side cursors usually build faster but often support fewer features that
client-side cursors.
The Open method of the recordset is then executed. The Open method has the following syntax:
The Source argument is an optional variant that evaluates to a valid Command object, SQL
statement, table name, stored procedure call, or filename of a persisted recordset.
The ActiveConnection argument is an optional variant that evaluates to a valid Connection object
variable name or a string containing connection string parameters.
The CursorType argument is an optional value that determines the type of cursor that the
provider should use when opening the recordset. The possible values and their
descriptions are given below:
Value Description
adOpenForwardOnly (default) Used to open a forward-only cursor. Forward-only cursors
create static snapshots of data. A recordset that uses a forward-only
cursor is not directly updateable and can only be scrolled from
beginning to end (i.e., "MoveNext" is the only "Move" method that can
be used with this type of cursor). Forward-only cursors offer optimal
performance in exchange for feature limitations. Forward-only cursors
are sometimes referred to as firehose cursors.
adOpenStatic Used to open a static cursor. A static cursor is a static copy of the data
in the data source. Once created, no changes made by other users
propagate to the recordset; the recordset never changes. Note: Client
side cursors (like the one used in this sample application) use only
adOpenStatic for CursorTypes regardless of which CursorType you
select.
adOpenDynamic Used to open a dynamic cursor. A dynamic cursor is a "live" recordset,
meaning that any and all additions, changes, and deletions by other
users affect the recordset. Dynamic-cursor recordsets support all types
of navigation, including bookmarks (if bookmarks are supported by the
provider). Dynamic cursors offer the most features of any cursor type,
but at the expense of increased overhead.
adOpenKeyset Used to open a keyset cursor. Keyset cursors are like dynamic cursors,
except additions made by other users are not visible in the recordset.
The recordset is affected by changes and deletions, however.
The LockType argument is an optional value that determines the type of locking that the provider
should use when opening the recordset. The possible values and their descriptions are
given below:
Value Description
adLockReadOnly (default) Specifies read-only locking. Records can be read, but data
cannot be added, changed, or deleted. This is the locking method
used with static cursors and forward-only cursors.
adLockPessimistic Specifies pessimistic locking. The provider does what is necessary to
ensure successful editing of records, usually by locking records at the
data source immediately upon editing.
adLockOptimistic Specifies optimistic locking. The provider locks records only when you
call the Update method, not when you start editing.
adLockBatchOptimistic Specifies optimistic batch locking. Records are locked in batch update
mode, as opposed to immediate update mode. This option is required
for client-side cursors.
The Options argument is an optional Long value that indicates how the Source should be
evaluated. The possible values and their descriptions are given below:
Value Description
adCmdText Indicates that the provider should evaluate CommandText as a textual
definition of a command. This options is used SQL statements.
adCmdTable Indicates that the provider should evaluate CommandText as a table.
adCmdStoredProc Indicates that the provider should evaluate CommandText as a stored
procedure.
adCmdUnknown Indicates that the type of command in the CommandText argument is
not known and that the provider should attempt to interpret it. Typically
results in poor performance.
adExecuteAsync Indicates that the command should execute asynchronously.
adFetchAsync Indicates that the remaining rows after the initial quantity specified in
the CacheSize property should be fetched asynchronously.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
mobjADORst.CursorLocation = adUseClient
txtCurrentQuery.Text = mstrSQL
End Sub
6. Create the user-defined subprocedure DataLoad. This subprocedure gets the data from the
recordset and puts each field into a text box. Data from the recordset is accessed via the
Fields collection.
The Fields collection in ADO works identically to the Fields collection in DAO. A field can be
referenced with or without specifying Fields, either by the field name in quotes or by its
ordinal position in the resultset. The field can also be referenced with the bang (!)
operator. All of the following would be valid ways of referencing the field "propno":
mobjADORst.Fields("propno")
mobjADORst ("propno")
mobjADORst.Fields(0)
mobjADORst(0)
mobjADORst!propno
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
txtPropNo.Text = mobjADORst.Fields("propno")
txtEmpNo.Text = mobjADORst.Fields("empno")
txtAddress.Text = mobjADORst.Fields("address")
txtCity.Text = mobjADORst.Fields("city")
txtState.Text = mobjADORst.Fields("state")
txtZip.Text = mobjADORst.Fields("zip")
Call SetRecNum
Exit Sub
LocalError:
End Sub
7. Create the user-defined subprocedure SetRecNum. This sub displays the number of the
current record at the bottom of the screen. The AbsolutePosition and RecordCount
properties of the Recordset are used here.
The AbsolutePosition property specifies the current row in a recordset. Note: For
AbsolutePosition to return a valid value with Access (Jet) databases (like the one used in
the sample application), the CursorLocation must be set to adUseClient. An invalid value
(-1) will be returned if adUseClient is specified.
The RecordCount property the total number of rows in the recordset. Note: RecordCount will not
return a valid value with all cursor types (for example, RecordCount will return -1 with a
forward-only cursor.) To ensure a valid RecordCount value, use either adOpenKeyset or
adOpenStatic as the CursorType for server side cursors or use a client side cursor.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
End Sub
8. Code the events for the navigation buttons as shown below, using the recordset "Move"
methods to move to the first, last, next, or previous record, respectively.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
mobjADORst.MoveFirst
Call DataLoad
Exit Sub
LocalError:
End Sub
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
mobjADORst.MoveLast
Call DataLoad
Exit Sub
LocalError:
End Sub
'----------------------------------------------------------------------
-------
mobjADORst.MoveNext
If mobjADORst.EOF Then
Beep
mobjADORst.MoveLast
End If
Call DataLoad
Exit Sub
LocalError:
End Sub
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
mobjADORst.MovePrevious
If mobjADORst.BOF Then
Beep
mobjADORst.MoveFirst
End If
Call DataLoad
Exit Sub
LocalError:
9. When one of the check boxes is clicked, the label and text box next to it should be enabled (or
disabled, if clicking the check box unchecks it). Note also that the cmdGetData button
(the one with the "Run Query Now" caption) should only be enabled if one of the
checkboxes is checked.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
cmdGetData.Enabled = False
'when the user clicks on a check box, enable the label and text
txtCriteria(Index).Enabled = True
lblCriteria(Index).Enabled = True
txtCriteria(Index).SetFocus
txtCriteria(Index).SelStart = 0
txtCriteria(Index).SelLength = Len(txtCriteria(Index).Text)
' enable the 'Run Query Now' button only if a box is checked.
cmdGetData.Enabled = True
Else
txtCriteria(Index).Enabled = False
lblCriteria(Index).Enabled = False
End If
End Sub
10. After the user has selected which fields to use and entered values in the text boxes, they click
the cmdGetData button to create a new recordset with new data. Note that if the user
selects (checks) a field, but does not enter search criteria in the corresponding textbox,
an error message is generated and the query is not run.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
blnFirstOne = True
vbExclamation, _
"ADO Example"
Exit Sub
End If
blnFirstOne = False
End If
vbExclamation, _
"ADO Example"
Exit Sub
End If
End If
blnFirstOne = False
mstrSQL = mstrSQL & " city like '" & txtCriteria(1).Text & "'"
End If
vbExclamation, _
"ADO Example"
Exit Sub
End If
End If
blnFirstOne = False
mstrSQL = mstrSQL & " state like '" & txtCriteria(2).Text & "'"
End If
OpenNewRecordset
If mobjADORst.EOF Then
MsgBox "Your query (" & mstrSQL & ") returned no records! " _
& "The default query to return all records will now be rerun.", _
vbExclamation, _
"ADO Example"
cmdAllData_Click
Else
MsgBox "Your query returned " & mobjADORst.RecordCount & " records.", _
vbInformation, _
"ADO Example"
Call DataLoad
End If
Exit Sub
LocalError:
End Sub
11. Save and run. Note: When entering the "Like" criteria for City and/or State, you can use the
wildcard character % to represent any number of characters and the wildcard character _
(underscore) the represent a single character. For example, entering "M%" for the City
criteria would return all rows where the city field begins with the letter "M".
Sample Application 3
Sample Application 3 demonstrates how to add, update, and delete records with ADO.
When the application is first run, the user is prompted to enter a minimum asking price to possibly
limit the number of records they want to work with (i.e., "I only want to work with properties that
are selling for $200,000 or more). If the user wants to work with all properties, they would simply
accept the default of 0 from the prompt. If the user clicks the Cancel button, the application will
end.
Once the user has entered the minimum asking price, the main screen of the application is
displayed. Initially, the screen is in "browse" mode, where the user can use the navigation buttons
to move to the first, previous, next or last record. The data cannot be edited in this mode. If they
want to initiate an add or an update, delete a record, or exit the application, they may do so via
the appropriate button. Saving or cancelling is not applicable in this mode, so those buttons are
disabled.
If the user clicks the Add button, the fields on the screen are enabled and cleared, and the user
can enter the information for the new property. All buttons except Save and Cancel are now
disabled. After the user has made entries in the fields, he or she would click Save to add the new
record to the database table, or, if they changed their mind, would click Cancel to discard the new
record. In either case (clicking Save or Cancel) the user is returned to browse mode. When Save
is clicked, the application validates the entries and will only save the record if all fields pass edit
(otherwise, a message will appear indicating the problem entry and focus will be set to the
problem field).
If the user clicks the Update button, the fields on the screen are enabled and the user can modify
any or all of the fields (except for the Property Number, which is the primary key of the table). All
buttons except Save and Cancel are now disabled. After the user has made modifications in the
desired fields, he or she would click Save to update the record to the database table, or, if they
changed their mind, would click Cancel to discard the changes. In either case (clicking Save or
Cancel) the user is returned to browse mode. When Save is clicked, the application validates the
entries and will only save the record if all fields pass edit (otherwise, a message will appear
indicating the problem entry and focus will be set to the problem field).
If the user clicks the Delete button, the user is asked to confirm that they want to delete the
current record. If they respond Yes, the record is deleted from the database table, and the main
screen shows the next record in the table.
To build Sample Application 3, start a new VB project and perform the following steps.
• From the Project -> References menu, check Microsoft ActiveX Data Objects 2.x Library
and click OK.
• This project uses the StatusBar control, so include the Microsoft Windows Common
Controls 6.0 (SP6) from the Components dialog box, accessed from the Project ->
Components menu. Check this item and click OK.
• Create the form shown below. The settings for the various controls are given below.
• There are nine textboxes in the main frame of the form. The names and MaxLength settings
for these are given below:
Name Properties
txtPropNo MaxLength: 5
txtEmpNo MaxLength: 4
txtAddress MaxLength: 20
txtCity MaxLength: 15
txtState MaxLength: 2
txtZip MaxLength: 5
txtBeds MaxLength: 1
txtBaths MaxLength: 3 (allows fractional amount, like 1.5)
txtAsking MaxLength: 0 (not specified)
Name Caption
cmdMoveFirst <<
cmdMovePrevious <
cmdMoveNext >
cmdMoveLast >>
cmdAdd Add
cmdUpdate Update
cmdDelete Delete
cmdSave Save
cmdCancel Cancel
cmdExit Exit
• All controls on your form should have their TabIndex property set such that the tabbing order
is correct.
• Add a Module to the project, name it modCommon, and enter the code shown below. The
code contains procedures described as follows:
Option Explicit
'----------------------------------------------------------------------
--
With pobjForm
End With
End Sub
'----------------------------------------------------------------------
--
'----------------------------------------------------------------------
--
'
'
If pintKeyValue < 32 _
Else
pintKeyValue = 0
End If
ValidKey = pintKeyValue
End Function
'----------------------------------------------------------------------
--
'----------------------------------------------------------------------
--
'
pintKeyValue = pintKeyValue - 32
End If
ConvertUpper = pintKeyValue
End Function
'----------------------------------------------------------------------
-------
With pobjTextbox
.SelStart = 0
.SelLength = Len(.Text)
End With
End Sub
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
pobjTextBox2.SetFocus
End If
End Sub
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
Dim lngX As Long
strNumberOut = ""
End If
Next
UnFormatNumber = strNumberOut
End Function
• Code the General Declarations section as shown below. Here, as in the previous sample
application, two ADO object variables, mobjADOConn and mobjADORst, are defined at the
form level, as are some other form-level variables that will be needed.
Option Explicit
• Code the Form_Load event as shown below. In it, a programmer-defined Sub named
GetMinimumAsking is called (that routine is the one that displays the initial prompt to the
user to enter the minimum asking price of the properties they want to work with). Then, the
variant array mavntUSStates is loaded with the 50 US state abbreviations, needed for
validating the state input by the user. This is followed by a call to the CenterForm sub. Then,
the ADO connection object (mobjADOConn) is instantiated, its ConnectionString property is
set, and the Open method is invoked so that we can use the Property database in the
application. This is followed by a call to the programmer-defined Sub GetPropertyData
(which runs the query to create the recordset that will be used to browse the Property table
records), followed by a call to the programmer-defined Sub SetFormState (which enables
and disables controls at the appropriate time).
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
' obtain the minimum asking price for the properties to be worked with
GetMinimumAsking
CenterForm Me
mobjADOConn.ConnectionString = "DSN=PropDB;Uid=admin;Pwd=;"
mobjADOConn.Open
Call GetPropertyData
SetFormState False
Exit Sub
LocalError:
End Sub
Code the GetMinimumAsking Sub, which uses the InputBox function to prompt to the user to
enter the minimum asking price of the properties they want to work with. The resulting value is
then stored in the form-level variable mdblMinAsking.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
& "for the properties that you want to work with this session." _
& vbNewLine _
& "To work with ALL properties, leave the default of zero."
End
End If
mdblMinAsking = Val(strAsking)
End Sub
Code the GetPropertyData Sub, which builds the SQL to get the property records meeting the
minimum asking price condition. The Recordset object is then instantiated, its CursorLocation
property is set, and its Open method is invoked to execute the SQL and return the resultset. This
is done in a loop in case the resultset does not return any records due to the fact no records in
the table met the asking price condition. In that situation, the user is given the opportunity to
specify a different asking price value. Following this, the programmer-defined Sub
PopulateFormFields is called (which displays the fields from the current record in their
corresponding textboxes on the form).
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
blnGotData = False
Do
mobjADORst.CursorLocation = adUseClient
If mobjADORst.EOF Then
vbYesNo + vbQuestion, _
"Asking Price") _
= vbYes Then
GetMinimumAsking
Else
End
End If
Else
blnGotData = True
End If
Call PopulateFormFields
Exit Sub
LocalError:
MsgBox Err.Number & " - " & Err.Description
End Sub
Code the PopulateFormFields Sub, which assigns the fields from the current record to their
corresponding textboxes on the form. Note that the gblnPopulating Boolean variable is set to True
prior to the assignments and set to False after the assignments. This value is used to control
whether or not certain code executes in the event procedures for some of these textboxes. The
Sub SetRecNum is then called.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
gblnPopulating = True
txtPropNo.Text = mobjADORst.Fields("propno")
txtEmpNo.Text = mobjADORst.Fields("empno")
txtAddress.Text = mobjADORst.Fields("address")
txtCity.Text = mobjADORst.Fields("city")
txtState.Text = mobjADORst.Fields("state")
txtZip.Text = mobjADORst.Fields("zip")
txtBeds.Text = mobjADORst.Fields("beds")
txtBaths.Text = mobjADORst.Fields("baths")
gblnPopulating = False
Call SetRecNum
Exit Sub
LocalError:
End Sub
Code the SetRecNum Sub. This sub is identical to the one used in Sample Application 2. It
displays the number of the current record at the bottom of the screen using the
AbsolutePosition and RowCount properties of the Recordset object.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
End Sub
Code the SetFormState Sub, which takes in a Boolean argument used to set the Enabled
property of the controls on the form. Based on whether the value True or False is passed to this
sub, this sub ensures that the textboxes are enabled for adds and updates and disabled for
browsing; it also ensures that the various command buttons are enabled or disabled at the
appropriate time. This Sub also sets the form-level Boolean variable mblnUpdatePending.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
txtPropNo.Enabled = pblnEnabled
txtEmpNo.Enabled = pblnEnabled
txtAddress.Enabled = pblnEnabled
txtCity.Enabled = pblnEnabled
txtState.Enabled = pblnEnabled
txtZip.Enabled = pblnEnabled
txtBeds.Enabled = pblnEnabled
txtBaths.Enabled = pblnEnabled
txtAsking.Enabled = pblnEnabled
cmdSave.Enabled = pblnEnabled
cmdCancel.Enabled = pblnEnabled
mblnUpdatePending = pblnEnabled
End Sub
Code the Form_Unload event. In it, the form-level Boolean variable mblnUpdatePending is
tested to see if (well, an update is pending – i.e., whether an add or update is in progress). If the
user is in the middle of an add or update and then clicks the "X" button on the upper-right corner
of the form, they will receive the message that they must save or cancel prior to exiting the
application, and the form will NOT be unloaded (because we are assigning a non-zero value to
the Cancel argument in that situation). Provided that an add or update is not in progress, we set
the database objects to Nothing and the Unload will complete.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
If mblnUpdatePending Then
vbExclamation, _
"Exit"
Cancel = 1
Else
End If
End Sub
Code the events for the various Textboxes as shown below. The code in these events ensure the
following:
• For all, highlight the text in the textbox when it receives focus.
• For all but the last textbox, if the maximum number of characters typed into the textbox is
reached, auto-tab to the next textbox.
• Only numeric digits should be entered into the property number, employee number, zip
codes, and beds textboxes.
• Only numeric digits and optionally one decimal point should be entered into the baths and
asking textboxes.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
' property #
SelectTextBoxText txtPropNo
End Sub
End Sub
End Sub
' emp #
SelectTextBoxText txtEmpNo
End Sub
End Sub
End Sub
' address
SelectTextBoxText txtAddress
End Sub
End Sub
' city
SelectTextBoxText txtCity
End Sub
End Sub
' state
SelectTextBoxText txtState
End Sub
KeyAscii = ConvertUpper(KeyAscii)
End Sub
End Sub
' zip
SelectTextBoxText txtZip
End Sub
End Sub
End Sub
' beds
SelectTextBoxText txtBeds
End Sub
End Sub
End Sub
' baths
SelectTextBoxText txtBaths
End Sub
' if text already has a decimal point, do not allow another ...
KeyAscii = 0
End If
End Sub
Private Sub txtBaths_Change()
End Sub
txtAsking.Text = UnFormatNumber(txtAsking.Text)
SelectTextBoxText txtAsking
End Sub
' if text already has a decimal point, do not allow another ...
KeyAscii = 0
End If
End Sub
End Sub
Code the events for the navigation buttons as shown below, using the resultset "Move" methods
to move to the first, last, next, or previous record, respectively.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
mobjADORst.MoveFirst
Call PopulateFormFields
Exit Sub
LocalError:
End Sub
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
mobjADORst.MoveLast
Call PopulateFormFields
Exit Sub
LocalError:
End Sub
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
mobjADORst.MoveNext
If mobjADORst.EOF Then
Beep
mobjADORst.MoveLast
End If
Call PopulateFormFields
Exit Sub
LocalError:
End Sub
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
mobjADORst.MovePrevious
If mobjADORst.BOF Then
Beep
mobjADORst.MoveFirst
End If
Call PopulateFormFields
Exit Sub
LocalError:
End Sub
Code the Click event for the cmdAdd button. In it, the textboxes are cleared, the SetFormState
sub is called (passing it a parameter of True, which will enable the textboxes and the Save and
Cancel buttons and disable all the other buttons), set the form-level variable mstrUpdateType to
"A" (indicating that an add is pending) and sets focus to the Property Number field.
'----------------------------------------------------------------------
-------
Private Sub cmdAdd_Click()
'----------------------------------------------------------------------
-------
txtPropNo.Text = ""
txtEmpNo.Text = ""
txtAddress.Text = ""
txtCity.Text = ""
txtState.Text = ""
txtZip.Text = ""
txtBeds.Text = ""
txtBaths.Text = ""
txtAsking.Text = ""
SetFormState True
mstrUpdateType = "A"
txtPropNo.SetFocus
Exit Sub
LocalError:
End Sub
Code the Click event for the cmdUpdate button. In it, the SetFormState sub is called (passing it
a parameter of True, which will enable the textboxes and the Save and Cancel buttons and
disable all the other buttons), set the form-level variable mstrUpdateType to "U" (indicating that
an update is pending), disables the Property Number field (because it is the primary key and
should not be changed) and sets focus to the Employee Number field.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
SetFormState True
mstrUpdateType = "U"
' being that propno is the primary key, it should not be updatable
txtPropNo.Enabled = False
txtEmpNo.SetFocus
Exit Sub
LocalError:
End Sub
Code the Click event for the cmdSave button. The user would click this button after they have
completed entries for an add or update. This sub first invokes the ValidateAllFields function,
which returns a Boolean indicating whether or not all entries passed their edit checks. If not, we
exit the sub and the record is not saved; the user remains in "update pending" mode and has the
opportunity to correct the entries. Provided that validation is successful, the sub proceeds. The
mstrUpdateType variable is checked to see whether we are dealing with an add or an update.
If we are dealing with an add, we invoke the AddNew method of the Recordset object. The
AddNew method prepares a new row you can edit and subsequently add to the Recordset object
using the Update method. After you modify the new row, you must use the Update method to
save the changes and add the row to the result set. No changes are made to the database until
you use the Update method. (The Update method is invoked after the content of the textboxes
has been assigned to the database fields.)
If we are dealing with an update, we can just start modifying the fields (provided an appropriate
cursor type has been selected) – unlike DAO and RDO, ADO does not use an Edit method.
Changes made to the current row’s columns are copied to the copy buffer. After you make the
desired changes to the row, use the Update method to save your changes or the CancelUpdate
method to discard them. (If you move on to another record without invoking Update, your
changes will be lost.)
The content of the textboxes is assigned to the database fields, then the Update method is
invoked. The Update method saves the contents of the copy buffer row to a specified updatable
Recordset object and discards the copy buffer.
The mstrUpdateType variable is checked once again, and if we are dealing with an add, there is
some extra work to do. Although the new record has been added, the original resultset still does
not contain the new record. The Requery method must be invoked, which updates the data in a
Recordset object by re-executing the query on which the object is based. The Find method is
then used to position to the new record. The ADO Find method has the following syntax:
The Criteria argument is a String value that specifies the column name, comparison operator, and
value to use in the search. Only a single-column name may be specified in criteria; multi-
column searches are not supported. The comparison operator may be ">" (greater than),
"<" (less than), "=" (equal), ">=" (greater than or equal), "<=" (less than or equal), "<>"
(not equal), or "like" (pattern matching). The value may be a string, floating-point number,
or date. String values are delimited with single quotes or "#" (number sign) marks (for
example, "state = 'WA'" or "state = #WA#"). Date values are delimited with "#" (number
sign) marks (for example, "start_date > #7/22/97#"). These values can contain hours,
minutes, and seconds to indicate time stamps, but should not contain milliseconds or
errors will occur. If the comparison operator is "like", the string value may contain an
asterisk (*) to find one or more occurrences of any character or substring. For example,
"state like 'M*'" matches Maine and Massachusetts. You can also use leading and trailing
asterisks to find a substring contained within the values. For example, "state like '*as*'"
matches Alaska, Arkansas, and Massachusetts. Asterisks can be used only at the end of
a criteria string, or together at both the beginning and end of a criteria string, as shown
above. You cannot use the asterisk as a leading wildcard ('*str'), or embedded wildcard
('s*r'). This will cause an error.
SkipRows is an optional Long value, whose default is zero, that specifies the row offset from the
current row (or bookmark row specified by the Start argument, if present) to begin the
search. By default, the search will start on the current row.
SearchDirection is an optional value that determines in which direction the search is performed.
The value is specified by the constants adSearchForward (the default) or
adSearchBackward, which equate to values of 1 or -1, respectively.
Start is an optional Variant bookmark that functions as the starting position for the search.
Note: Unlike DAO, ADO does not have a "NoMatch" property. If the ADO Find method is
unsuccessful, the record pointer is positioned at the end of the Recordset.
The SetRecNum sub is then be called to display the status bar information about the new record.
The SetFormState sub is then called with a parameter of False, which causes the textboxes and
the Save and Cancel buttons to be disabled and all other buttons to be enabled.
Note that in the statement that assigns the contents of the txtAsking textbox to the asking field
of the table, our UnFormatNumber function is used to strip off the non-numeric characters. This
is because we are using a display format that includes a dollar sign and commas on the txtAsking
control, and an error would occur if we attempted to assign this directly to the asking field, which
is defined as numeric.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
mobjADORst.AddNew
Else
End If
mobjADORst.Fields("propno") = txtPropNo.Text
mobjADORst.Fields("empno") = txtEmpNo.Text
mobjADORst.Fields("address") = txtAddress.Text
mobjADORst.Fields("city") = txtCity.Text
mobjADORst.Fields("state") = txtState.Text
mobjADORst.Fields("zip") = txtZip.Text
mobjADORst.Fields("beds") = txtBeds.Text
mobjADORst.Fields("baths") = txtBaths.Text
mobjADORst.Fields("asking") = UnFormatNumber(txtAsking.Text)
mobjADORst.Update
mobjADORst.Requery
SetRecNum
End If
Reset:
SetFormState False
Exit Sub
LocalError:
Resume Reset
End Sub
Code the Click event for the cmdDelete button. The user is first asked to confirm that they want
to delete the record, and if so, the Delete method of the resultset object is invoked, which deletes
the current row in an updatable resultset object. The Requery method is then invoked so that the
record is removed from the resultset that the user is working with. The Find method is then
invoked to position the next record after the deleted one. If it was the last record that was deleted,
then we position to the "new" last record using the MoveLast property. PopulateFormFields
must then be called to display the contents of the new current record.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
'is invalid. use the Requery method to re-execute the query and update
'the data.
vbYesNo + vbQuestion, _
Exit Sub
End If
mobjADORst.Delete
mobjADORst.Requery
' If it was the last record that was deleted, the Find method will
' come back with EOF, in which case we should MoveLast to position
Call PopulateFormFields
Exit Sub
LocalError:
End Sub
The ValidateAllFields function, which returns a Boolean value indicating whether or not all fields
have passed validation checks. This function calls upon two "helper" functions: PropertyExists
and ValidState. When the user is doing an add, the PropertyExist function is called to see
whether or not the proposed Property Number is already being used in the Property table. If so,
the user is informed that they can't use that number (because it is the primary key and must be
unique) and so they must use a different number. The ValidState routine is called to ensure that
the user has entered a valid US state. The code for all three functions is shown below.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
ValidateAllFields = False 'guilty until proven innocent
txtPropNo.SetFocus
Exit Function
vbExclamation, _
"Property #"
txtPropNo.SetFocus
Exit Function
End If
End If
txtEmpNo.SetFocus
Exit Function
End If
txtAddress.SetFocus
Exit Function
End If
txtCity.SetFocus
Exit Function
End If
txtState.SetFocus
Exit Function
End If
' it's OK
Else
vbExclamation, _
"Zip Code"
txtZip.SetFocus
Exit Function
End If
If Val(txtBeds.Text) = 0 Then
txtBeds.SetFocus
Exit Function
End If
If Val(txtBaths.Text) = 0 Then
txtBaths.SetFocus
Exit Function
End If
If Val(UnFormatNumber(txtAsking.Text)) = 0 Then
txtAsking.SetFocus
Exit Function
End If
ValidateAllFields = True
End Function
'----------------------------------------------------------------------
----------
'----------------------------------------------------------------------
----------
blnStateFound = False
blnStateFound = True
Exit For
End If
Next
ValidState = blnStateFound
End Function
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
strSQL = "select count(*) as the_count from property where propno = " &
txtPropNo.Text
objTempRst.Open strSQL, mobjADOConn, adOpenForwardOnly, , adCmdText
PropertyExists = True
Else
PropertyExists = False
End If
End Function
Code the Click event for the cmdCancel button. The user would click this button if, during an add
or update, they decide to abandon the operation. Here, PopulateFormFields is called to reset
the textboxes to their content prior to the user clicking the Add or Update button, and
SetFormState is called with a parameter of False, which causes the textboxes and the Save and
Cancel buttons to be disabled and all other buttons to be enabled.
'----------------------------------------------------------------------
-------
'----------------------------------------------------------------------
-------
PopulateFormFields
SetFormState False
End Sub
Code the Click event for the cmdExit button, which issues the Unload Me statement to fire the
Form_Unload event, which will unload the form and end the application.
'----------------------------------------------------------------------
-------
Unload Me
End Sub
ancel Rating
20
40
60
80
100
• Printer Friendly
• 176943 reads
Comments
Thu, 01/21/2010 - 08:50 — Abo Omar (not verified)
Thanks alot
Hi
Good Bye
• reply
Help
i m using Visual Basib 6.0 and and MS-Access database..my database is on Web Server
Nikunj
• reply
a very good tutorial and I am proud as you can provide much inspiration for beginners
and very helpful. I'm from Indonesia pleased with you and your tutorial helped me a lot.
Thanks
Didin
• reply
Great
great......
• reply
• reply
Sat, 10/03/2009 - 02:28 — Anonymous (not verified)
help
i always get an error 445 object doesnt support this action which points to the
recodset.update
• reply
thank you i understand now how ado works.. thank so much for sharing your knowlegde
• reply
ADO tutorial
Iam so glad i found the right website for the VB6 tutorial it really help me a lot. Thanks a
lot.
Question: When am going to enable the Reference :Microsoft ActiveX Data Object 2.7
library i have found error: Name conflicts with existing module , project or object library.
• reply
...
• reply
HELP!!!
can you please help me in my project..
• reply
Kudos
• reply
Superb
Cudos!
Congratulations
• reply
here's my email
[email protected]
• reply
here's my email
• reply
GREAT!
Hi
i'm thankful.
• reply
I heartily say thanks to you for such a great tutorial on ADO and Databases. It extremely
helped me because you explained it with 3 different examples, which were still all parallel
with each other. When I read them fully and practiced with it, then it was easy to
understand the theory behind these codes. I am so happy that I found your website for
wow..really great article which explains everything about ADO.Thanks a lot buddy.keep
• reply
Database?
can anybody please tel me where can i find second database?That is propery Database..I
• reply
VB6
Hi, Why visual basic can't recognized the access 2000 file format? Help me pls..
ThankYou!!
• reply
This is a great tutorial!It helped me to finally understand ADO with databases.Thank you
very much.
• reply
Thats called
• reply
Tue, 04/14/2009 - 19:56 — Anonymous (not verified)
need help
pls. help me to make a program about library inventory system, wherein the librarian can
identify which books are borrowed and which are available, thanks!!
• reply
error
adoBiblio.Refresh
adoBiblio.Refresh
adoBiblio.Refresh
· Save and run the program and see what happens when you click the buttons.
• reply
best tutorials
Great Tutorial
• reply
help me please!
Ex.
''''''''''''''''''''''''''
''''''''''''''''''''''''''
Book '
''''''''''''''''''''''''''
'''''''''''''''''''''''''''
'''''''''''''''''''''''''''
Science
''''''''''''''''''''''''''
Mathematics
''''''''''''''''''''''''''
English
'''''''''''''''''''''''''''
how can i update all of the content of book(field name) in just a single click?
What I'm trying to say is to make all of the contents of the book = "" just a single click...
''''''''''''''''''''''''''
Book '
''''''''''''''''''''''''''
'''''''''''''''''''''''''''
(no text)
''''''''''''''''''''''''''
(no text)
''''''''''''''''''''''''''
(no text)
'''''''''''''''''''''''''''
thankz...
• reply
Very Nice
• reply
Thanks a lot!!
Excellent Work!! It helped me finally understand how ADODB actually works. this is a
• reply
hi
windows..
• reply
whatta article
whatta article
• reply
plzzzz
record?..plzzz tnx
• reply
• reply
dcsHay folks this is owsm!!!!! Keep focus and help us to make world better. Thanks!
• reply
This seems like a great tutorial but I'm having problems. I add the ADO Data Control but
the 'DataSourceName' and 'SQL' fields do not appear in the property tab.
If I right-click on the control and select 'ADODC Properties' I can change the field 'Use
ODBC Data Source Name' to 'Biblio' and on the 'RecordSource' tab I can change the
adoBiblio.Refresh
End Sub
The program runs as expected but I'm concerned about having to use different code.
• reply
Thanks a lot!
Hi! Thank you so much for the tips and sample programs and codes in programming. It
was really of great help to me. I hope I will be able to share some of my programs
soon. :)
• reply
fdf Hi, I am new to VB6 i did some programing in c++ and java. I am struglling to make
common module from which i can use connection and recordset so that i dont have to
make seperate connection and recorset for each form. we can do that in c++ by making
class. In vb6 i am confused. i was able to make sub in connecting sub in module but i not
able to pass connection object to different forms to create different recordsets. thanks
• reply
• reply
hi,
then to
next:
e.g.
next
in form_load()
event
• reply
Computerized registration
different type of organizaton using microsoft access in VB6...pls, thanks and god bless.....
• reply
Hi
• reply
Marvelous
Thank you very much. This tutorial DOES HELP me a lot to understand ADO with Visual
Basic. I manage to learn a lot fundamental but essential and neccessary knowledge about
• reply
Great Article
Thank You very much. I was looking for a tutorial to learn the basics of ADO and your
• reply
help
I'm trying to update something and a run time error occurs, its
nad
• reply
good work
• reply
You are the one...if anyone is come to give u thanks he is a celever man Remember the
story of leprosy in the bible..only one man return and gave thanks to Jesus...thanks to
those who gave thanks to u...I am thinking of writing a site like this but use it in my
language...I am so happy with you...I know youre blessed with all these good works....
• reply
wow!!!
• reply
**You are an asset to the development community. Please, keep up the great work. You
Jamie
• reply
• reply
Good work
This is how a tutorial should be. Especially the fact that there are three tutorials in
progressive complexity with about the right increase of complexity from one to the other.
Thank you
Mo
• reply
• reply
I'm a free lance system developer (programmer) mainly create my program through VB6,
with a little add-ons on different support programs, ei Crystal report etc. I like the review
on the locktypes, cursortypes, and cursorlocations, coz i kinda takeforgranted those basic
option (like the locktype and cursortype, my combination are always, adopendynamic and
adlockoptimistic ) till now im still using such combination, because when i use different
attribute, some of my program malfunction, specially when using the network or via web.
I guess im used to it, and don't give a thing on other options. still it would be a good help
can you enumerate all or atleast some major factor that give different affect on different
cursorlocation.
thanx
• reply
• reply
dear all
i tried the sample-3 , given under the tutorial ado samples, as soon as i enter the initial
declaration
it gives me an error
can anyone explain me how to solve it
• reply
I want to compliment you in writing such a great tutorial article on using ADO and
Databases. It was extremely helpful because you displayed 3 different examples, which
were still all parallel with each other. The more that I read through each of the examples
and practiced with it, the clearer I started to understand the theory behind these codes. I
am so glad that I came across your weblink and want to thank you once again.
Respectfully,
Sam Maldonado
• reply
E-mail:
The content of this field is kept private and will not be shown publicly.
Homepage:
Subject:
Comment: *
• Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt>
<dd>
• You may post block code using <blockcode [type="language"]>...</blockcode> tags. You
Preview comment
• Access SQL