leccion 7 - usando ado

Embed Size (px)

Citation preview

  • 8/3/2019 leccion 7 - usando ado

    1/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 1

    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 insteaduse the ADO objects directly. Read on to find out exactly how this can be done.

    Originally Written By TheVBProgramer.

    The "Alphabet Soup" of Database Access

    Prior to VB6 and the introduction of ADO (ActiveX Data Objects), VB programmers would generally use DAO(Data Access Objects) to interact with local databases such as MS Access and use RDO (Remote Data Objects)to interact with client/server databases such as Oracle and SQL Server. The concept behind Visual Basic ADOwas Universal Data Access (UDA), where one database access method could be used for any data source; it wasdesigned to replace both DAO and RDO. DAO remains a viable technology for interacting with MS Accessdatabases as it is faster than ADO for that purpose; however, ADO is more flexible using ADO, one coulddevelop a prototype database application using MS Access in the back-end, and with a "flick of the wrist" (i.e.,

    with very little coding changes) "upsize" that same application to use Oracle or SQL Server. As far as RDO isconcerned, no new versions of it have been developed beyond the version that shipped with Visual Basic, andthere are no future plans for it.

    In the VB4 and VB5 worlds, RDO was the main method used to interact with client/server databases. RDO worksperfectly fine with VB6, so when folks migrated their VB5 applications over to VB6, little or no coding changeswere required. However, ADO is the preferred method of database access for new VB6 applications .

    About this Tutorial

    This tutorial presents three small sample applications using ADO. All three applications use a local MS Accessdatabase.

    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 allowsnavigation and searching of a database table; the third allows navigation and updating on a database table. Allthree connect to an ODBC Data Source, which must be set up through the Windows Control Panel. How to dothis is described below.

    Note: If you have previously set up a DSN for the Biblio database as described in the previous topic on RDO, youcan skip the section on setting up an ODBC data source and resume here.

    Setting Up an ODBC Data Source

    Follow the steps below to set up an ODBC Data Source (this process is also called "setting up a DSN", where"DSN" stands for "Data Source Name"). These steps assume Windows 2000 for the operating system. On otherversions of Windows, some steps may vary slightly.

    Via Windows Control Panel, double-click on Administrative Tools, then Data Sources (ODBC). TheODBC Data Source Administrator screen is displayed, as shown below. Click on the System DSN tab.

  • 8/3/2019 leccion 7 - usando ado

    2/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 2

    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.

  • 8/3/2019 leccion 7 - usando ado

    3/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 3

    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 VisualStudio 6, the BIBLIO.MDB sample database should reside in the folder C:\Program Files\Microsoft VisualStudio\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 nothave 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 bereflected as shown below. Click OK to dismiss this screen.

  • 8/3/2019 leccion 7 - usando ado

    4/59

  • 8/3/2019 leccion 7 - usando ado

    5/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 5

    Sample Application 1: Using the ADO Data Control (ADODC)

    To build the first sample application, follow the steps below.

    Start a new VB project, and from the Components dialog box (invoked from the Project -> Componentsmenu), 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:

  • 8/3/2019 leccion 7 - usando ado

    6/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 6

    Put an ADO Data Control on your form, and set the properties as follows:

    Property ValueName adoBiblio

    DataSourceName BiblioSQL select * from authors

    Now put three text boxes on the form, and set their Name, DataSource, and DataField properties as follows:

    Name DataSource DataFieldtxtAuthor adoBiblio AuthortxtAuID adoBiblio Au_IDtxtYearBorn adoBiblio Year Born

    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 theprogram again. Notice the difference.

    Change the SQL property back to what it was and add three command buttons to the form, and set theirName and Caption properties as follows:

  • 8/3/2019 leccion 7 - usando ado

    7/59

  • 8/3/2019 leccion 7 - usando ado

    8/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 8

    Download the project files for this sample application here.

    Sample Applications 2 and 3: Using ADO Code

    Note: If you have previously downloaded and set up a DSN for the Property database as described in theprevious 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:

    Column Name Data Type NotesPROPNO Number (Long Integer) A number that uniquely identifies the property in the

    table. Should be treated as the Primary Key(although it is not defined as such in the sampledatabase).

    EMPNO Number (Long Integer) A number that identifies the real estate agent sellingthe property. In a real system, this would be theforeign key to the employee number in an Employeetable (such a table is not present in the sample

    database).ADDRESS Text (20) The street address of the property.CITY Text (15) The city where the property is located.STATE Text (2) The state where the property is located (2-character

    US state abbreviation).ZIP Text (5) The zip code where the property is located.NEIGHBORHOOD Text (15) The descriptive name of the neighborhood in which

    the property is located.HOME_AGE Number (Long Integer) Age in years of the home. (A better table design

  • 8/3/2019 leccion 7 - usando ado

    9/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 9

    choice would be to have this field be the date inwhich the property was built and have the applicationcompute the age based on the current date.)

    BEDS Number (Long Integer) Number of bedrooms in the property.BATHS Number (Single) Number of bathrooms in the property (allows for a

    decimal value such as 2.5, indicating 2 bathrooms

    i.e. 2 full bathrooms and 1 "powder room").FOOTAGE Number (Long Integer) The footage of the property.ASKING Number (Long Integer) Asking price of the property in whole dollars.BID Number (Long Integer) Bid amount of the potential buyer in whole dollars.SALEPRICE Number (Long Integer) Sale price (amount the property actually sold for) in

    whole dollars.

    Before coding or running sample application 2 or 3, you must set up an ODBC data source as was done for theprevious sample application.

    After downloading the file, move it to the folder of your choice. Then follow the exact same steps as before to setup 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 highestversion that you have on your system) and click OK.

  • 8/3/2019 leccion 7 - usando ado

    10/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 10

    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.

  • 8/3/2019 leccion 7 - usando ado

    11/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 11

    Create the form shown below. The names of the text boxes in the top frame are shown in the form. Set theEnabled property of the frame to False, which will automatically disable all of the textboxes within it, which isdesired because this application does not allow updating of the data. The settings for the other controls are givenbelow.

    The navigation buttons have the following properties:

    Name CaptioncmdMoveFirst

    The text box in the middle of the form has the following properties:

    Name txtCurrentQueryMultiLine TrueLocked True

  • 8/3/2019 leccion 7 - usando ado

    12/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 12

    The command buttons have the following properties:

    Name Caption EnabledcmdAllData Reload All Records TruecmdGetData Run Query Now False

    In the "Select Criteria" frame:

    The check boxes are an array:

    Name CaptionchkCriteria(0) EmpNochkCriteria(1) CitychkCriteria(2) State

    The labels are also an array:

    Name Caption EnabledlblCriteria(0) = FalselblCriteria(1) Like FalselblCriteria(2) Like False

    The textboxes are also an array:

    Name Caption EnabledtxtCriteria(0) EmpNo FalsetxtCriteria(1) City FalsetxtCriteria(2) State False

    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 andADODB.Recordset, are defined at the form level.

    The ADODB.Connection object represents an open connection to a data source and a specific database on thatdata source, or an allocated but as yet unconnected object, which can be used to subsequently establisha connection.

    The ADODB.Recordset object represents the rows that result from running a query,

  • 8/3/2019 leccion 7 - usando ado

    13/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 13

    Option Explicit

    Dim mobjADOConn As ADODB.Connection

    Dim mobjADORst As ADODB.Recordset

    Dim mstrSQL As String

    3. Code the Form_Load event. Here, the connection object variable mobjADOConn is made available for use bysetting it to a new instance of ADODB.Connection. Then, the ConnectionString property and the Openmethod of the ADODB.Connection object are used.

    The ConnectionString property takes a string with various arguments delimited by semicolons. When using a DSNas we are in this sample application, you typically need just the DSN name, the user id, and thepassword. The Open method then opens the connection to the database.

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

    Private Sub Form_Load()

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

    'set up the form and connect to the data source

    On Error GoTo LocalError

    'center the form:

    Me.Top = (Screen.Height - Me.Height) / 2

    Me.Left = (Screen.Width - Me.Width) / 2

    ' Connect to the Property database:

    Set mobjADOConn = New ADODB.Connection

    mobjADOConn.ConnectionString = "DSN=PropDB;Uid=admin;Pwd=;"

    mobjADOConn.Open

    Call cmdAllData_Click

  • 8/3/2019 leccion 7 - usando ado

    14/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 14

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

    4. Code the cmdAllData_Click event, which sets or resets the ADODB.Recordset object with a query to display allthe rows in the table. The opening of the recordset takes place in the OpenNewRecordset subprocedure,called from this event procedure.

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

    Private Sub cmdAllData_Click()

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

    On Error GoTo LocalError

    Dim lngX As Long

    'select or reload the data to be displayed:

    mstrSQL = "select * from property"

    Call OpenNewRecordset

    'load data into the text boxes

    Call DataLoad

    ' reset the state of the search criteria controls

    For lngX = 0 To 2

    chkCriteria(lngX).Value = vbUnchecked

    Next

    Exit Sub

  • 8/3/2019 leccion 7 - usando ado

    15/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 15

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

    5. Create the user-defined subprocedure OpenNewRecordset.

    Here, the recordset object mobjADORst is made available for use by setting (or resetting) it to a new instance ofADODB.Recordset.

    The CursorLocation property is then set to the built-in constant adUseClient. The term "cursor" refers to thetemporary rows of a recordset. The cursor location determines whether the cursor is stored on the clientor 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 takea long time to build because the data must be pulled over to the client, but once built, traversing thecursor is usually very fast. Client-side cursors often support more features than server-side cursors (thereason this sample application is using a client-side cursor is because we want to use AbsolutePositionproperty later, which only works with a client-side cursor). On the other hand, server-side cursors usuallybuild 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:

    RecordsetObject.Open Source, ActiveConnection, CursorType, LockType, Options

    The Sourceargument is an optional variant that evaluates to a valid Command object, SQL statement, tablename, stored procedure call, or filename of a persisted recordset.

    The ActiveConnectionargument is an optional variant that evaluates to a valid Connection object variable nameor a string containing connection string parameters.

    The CursorTypeargument is an optional value that determines the type of cursor that the provider should usewhen 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 staticsnapshots of data. A recordset that uses a forward-only cursor is not directlyupdateable and can only be scrolled from beginning to end (i.e., "MoveNext" isthe only "Move" method that can be used with this type of cursor). Forward-onlycursors offer optimal performance in exchange for feature limitations. Forward-only cursors are sometimes referred to as firehosecursors.

    adOpenStatic Used to open a static cursor. A static cursor is a static copy of the data in thedata source. Once created, no changes made by other users propagate to therecordset; the recordset never changes. Note: Client side cursors (like the one

  • 8/3/2019 leccion 7 - usando ado

    16/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 16

    used in this sample application) use only adOpenStatic for CursorTypesregardless of which CursorType you select.

    adOpenDynamic Used to open a dynamic cursor. A dynamic cursor is a "live" recordset, meaningthat any and all additions, changes, and deletions by other users affect therecordset. Dynamic-cursor recordsets support all types of navigation, includingbookmarks (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, exceptadditions made by other users are not visible in the recordset. The recordset isaffected by changes and deletions, however.

    The LockTypeargument is an optional value that determines the type of locking that the provider should usewhen opening the recordset. The possible values and their descriptions are given below:

    Value DescriptionadLockReadOnly (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 sourceimmediately upon editing.

    adLockOptimistic Specifies optimistic locking. The provider locks records only when you call theUpdate 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-sidecursors.

    The Optionsargument is an optional Long value that indicates how the Source should be evaluated. The possiblevalues and their descriptions are given below:

    Value DescriptionadCmdText 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 inpoor 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.

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

    Private Sub OpenNewRecordset()

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

  • 8/3/2019 leccion 7 - usando ado

    17/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 17

    Set mobjADORst = New ADODB.Recordset

    mobjADORst.CursorLocation = adUseClient

    mobjADORst.Open mstrSQL, mobjADOConn, adOpenStatic, , adCmdText

    ' display current query

    txtCurrentQuery.Text = mstrSQL

    End Sub

    6. Create the user-defined subprocedure DataLoad. This subprocedure gets the data from the recordset and putseach 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 orwithout specifying Fields, either by the field name in quotes or by its ordinal position in the resultset. Thefield can also be referenced with the bang (!) operator. All of the following would be valid ways ofreferencing the field "propno":

    mobjADORst.Fields("propno")

    mobjADORst ("propno")

    mobjADORst.Fields(0)

    mobjADORst(0)

    mobjADORst!propno

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

    Private Sub DataLoad()

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

    On Error GoTo LocalError

    'copy the data from the recordset to the text boxes:

    txtPropNo.Text = mobjADORst.Fields("propno")

    txtEmpNo.Text = mobjADORst.Fields("empno")

  • 8/3/2019 leccion 7 - usando ado

    18/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 18

    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:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

    7. Create the user-defined subprocedure SetRecNum. This sub displays the number of the current record at thebottom of the screen. The AbsolutePosition and RecordCount properties of the Recordset are usedhere.

    The AbsolutePosition property specifies the current row in a recordset. Note: For AbsolutePosition to return avalid value with Access (Jet) databases (like the one used in the sample application), the CursorLocationmust 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 validvalue with all cursor types (for example, RecordCount will return -1 with a forward-only cursor.) To ensurea valid RecordCount value, use either adOpenKeyset or adOpenStatic as the CursorType for server sidecursors or use a client side cursor.

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

    Private Sub SetRecNum()

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

    StatusBar1.SimpleText = "row " & mobjADORst.AbsolutePosition _

    & " of " & mobjADORst.RecordCount

    End Sub

    8. Code the events for the navigation buttons as shown below, using the recordset "Move" methods to move tothe first, last, next, or previous record, respectively.

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

  • 8/3/2019 leccion 7 - usando ado

    19/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 19

    Private Sub cmdMoveFirst_Click()

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

    On Error GoTo LocalError

    mobjADORst.MoveFirst

    Call DataLoad

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

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

    Private Sub cmdMoveLast_Click()

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

    On Error GoTo LocalError

    mobjADORst.MoveLast

    Call DataLoad

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

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

    Private Sub cmdMoveNext_Click()

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

  • 8/3/2019 leccion 7 - usando ado

    20/59

  • 8/3/2019 leccion 7 - usando ado

    21/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 21

    MsgBox Err.Number & " - " & Err.Description

    End Sub

    9. When one of the check boxes is clicked, the label and text box next to it should be enabled (or disabled, ifclicking the check box unchecks it). Note also that the cmdGetData button (the one with the "Run QueryNow" caption) should only be enabled if one of the checkboxes is checked.

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

    Private Sub chkCriteria_Click(Index As Integer)

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

    ' disable the 'Run Query Now' button

    cmdGetData.Enabled = False

    'when the user clicks on a check box, enable the label and text

    'box that go with it.

    If chkCriteria(Index).Value = vbChecked Then

    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

  • 8/3/2019 leccion 7 - usando ado

    22/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 22

    10. After the user has selected which fields to use and entered values in the text boxes, they click thecmdGetData 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 thequery is not run.

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

    Private Sub cmdGetData_Click()

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

    'run the query that the user has created

    On Error GoTo LocalError

    Dim blnFirstOne As Boolean

    blnFirstOne = True

    mstrSQL = "select * from property where "

    If chkCriteria(0).Value = vbChecked Then

    If (txtCriteria(0).Text = "") Or (Not IsNumeric(txtCriteria(0).Text)) Then

    MsgBox "Employee number is missing or non-numeric. Query not run.", _

    vbExclamation, _

    "ADO Example"

    Exit Sub

    End If

    blnFirstOne = False

    mstrSQL = mstrSQL & "empno = " & txtCriteria(0).Text

    End If

    If chkCriteria(1).Value = vbChecked Then

    If txtCriteria(1).Text = "" Then

  • 8/3/2019 leccion 7 - usando ado

    23/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 23

    MsgBox "City criteria is missing. Query not run.", _

    vbExclamation, _

    "ADO Example"

    Exit Sub

    End If

    If blnFirstOne = False Then

    mstrSQL = mstrSQL & " and"

    End If

    blnFirstOne = False

    mstrSQL = mstrSQL & " city like '" & txtCriteria(1).Text & "'"

    End If

    If chkCriteria(2).Value = vbChecked Then

    If txtCriteria(2).Text = "" Then

    MsgBox "State criteria is missing. Query not run.", _

    vbExclamation, _

    "ADO Example"

    Exit Sub

    End If

    If blnFirstOne = False Then

    mstrSQL = mstrSQL & " and"

    End If

    blnFirstOne = False

    mstrSQL = mstrSQL & " state like '" & txtCriteria(2).Text & "'"

    End If

    OpenNewRecordset

    'make sure that the query did not return 0 rows:

  • 8/3/2019 leccion 7 - usando ado

    24/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 24

    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"

    'reload the form with all the records

    cmdAllData_Click

    Else

    MsgBox "Your query returned " & mobjADORst.RecordCount & " records.", _

    vbInformation, _

    "ADO Example"

    'load data into the text boxes

    Call DataLoad

    End If

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    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 asingle character. For example, entering "M%" for the City criteria would return all rows where the city fieldbegins with the letter "M".

    Download the project files for this sample application here.

    Sample Application 3

  • 8/3/2019 leccion 7 - usando ado

    25/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 25

    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 thenumber of records they want to work with (i.e., "I only want to work with properties that are selling for $200,000 ormore). If the user wants to work with all properties, they would simply accept the default of 0 from the prompt. Ifthe 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, thescreen is in "browse" mode, where the user can use the navigation buttons to move to the first, previous, next orlast record. The data cannot be edited in this mode. If they want to initiate an add or an update, delete a record, orexit 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 theinformation for the new property. All buttons except Save and Cancel are now disabled. After the user has madeentries in the fields, he or she would click Save to add the new record to the database table, or, if they changedtheir mind, would click Cancel to discard the new record. In either case (clicking Save or Cancel) the user isreturned to browse mode. When Save is clicked, the application validates the entries and will only save the recordif all fields pass edit (otherwise, a message will appear indicating the problem entry and focus will be set to theproblem field).

  • 8/3/2019 leccion 7 - usando ado

    26/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 26

    If the user clicks the Update button, the fields on the screen are enabled and the user can modify any or all of thefields (except for the Property Number, which is the primary key of the table). All buttons except Save and Cancelare now disabled. After the user has made modifications in the desired fields, he or she would click Save toupdate 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, theapplication validates the entries and will only save the record if all fields pass edit (otherwise, a message willappear indicating the problem entry and focus will be set to the problem field).

  • 8/3/2019 leccion 7 - usando ado

    27/59

  • 8/3/2019 leccion 7 - usando ado

    28/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 28

    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 andclick OK.

  • 8/3/2019 leccion 7 - usando ado

    29/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 29

    Create the form shown below. The settings for the various controls are given below.

  • 8/3/2019 leccion 7 - usando ado

    30/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 30

    There are nine textboxes in the main frame of the form. The names and MaxLength settings for these aregiven below:

    Name PropertiestxtPropNo MaxLength: 5txtEmpNo MaxLength: 4

    txtAddress MaxLength: 20txtCity MaxLength: 15txtState MaxLength: 2txtZip MaxLength: 5txtBeds MaxLength: 1txtBaths MaxLength: 3 (allows fractional amount, like 1.5)txtAsking MaxLength: 0 (not specified)

    Set up the Command Buttons as follows:

    Name CaptioncmdMoveFirst cmdAdd AddcmdUpdate UpdatecmdDelete DeletecmdSave SavecmdCancel CancelcmdExit 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 containsprocedures described as follows:

    CenterForm Sub to center a form on the screenValidKey Function to validate a keystroke for use in the KeyPress event of a textbox ConvertUpper Function to convert an alphabetic character entered in a textbox to uppercase,

    used in the KeyPress event of a textboxSelectTextBoxText Sub to highlight the text of a textbox when it receives focus. Used in the

    GotFocus event of a textbox.TabToNextTextBox Sub to "autotab" from one textbox to another when maximum number of

    characters that can be entered into the first textbox has been reached.UnFormatNumber Function to strip out non-numeric characters (dollar signs, commas, etc.) from a

    formatted number.

    Option Explicit

  • 8/3/2019 leccion 7 - usando ado

    31/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 31

    Public Const gstrNUMERIC_DIGITS As String = "0123456789"

    Public Const gstrUPPER_ALPHA_PLUS As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ,'-"

    Public gblnPopulating As Boolean

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

    Public Sub CenterForm(pobjForm As Form)

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

    With pobjForm

    .Top = (Screen.Height - .Height) / 2

    .Left = (Screen.Width - .Width) / 2

    End With

    End Sub

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

    Public Function ValidKey(pintKeyValue As Integer, _

    pstrSearchString As String) As Integer

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

    ' Common function to filter out keyboard characters passed to this

    ' function from KeyPress events.

    '

    ' Typical call:

    ' KeyAscii = ValidKey(KeyAscii, gstrNUMERIC_DIGITS)

    '

    If pintKeyValue < 32 _

  • 8/3/2019 leccion 7 - usando ado

    32/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 32

    Or InStr(pstrSearchString, Chr$(pintKeyValue)) > 0 Then

    'Do nothing - i.e., accept the control character or any key

    ' in the search string passed to this function ...

    Else

    'cancel (do not accept) any other key ...

    pintKeyValue = 0

    End If

    ValidKey = pintKeyValue

    End Function

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

    Public Function ConvertUpper(pintKeyValue As Integer) As Integer

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

    ' Common function to force alphabetic keyboard characters to uppercase

    ' when called from the KeyPress event.

    ' Typical call:

    ' KeyAscii = ConvertUpper(KeyAscii)

    '

    If Chr$(pintKeyValue) >= "a" And Chr$(pintKeyValue)

  • 8/3/2019 leccion 7 - usando ado

    33/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 33

    End Function

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

    Public Sub SelectTextBoxText(pobjTextbox As TextBox)

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

    With pobjTextbox

    .SelStart = 0

    .SelLength = Len(.Text)

    End With

    End Sub

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

    Public Sub TabToNextTextBox(pobjTextBox1 As TextBox, pobjTextBox2 As TextBox)

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

    If gblnPopulating Then Exit Sub

    If pobjTextBox2.Enabled = False Then Exit Sub

    If Len(pobjTextBox1.Text) = pobjTextBox1.MaxLength Then

    pobjTextBox2.SetFocus

    End If

    End Sub

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

    Public Function UnFormatNumber(pstrNumberIn As String) As String

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

    Dim lngX As Long

    Dim strCurrChar As String

  • 8/3/2019 leccion 7 - usando ado

    34/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 34

    Dim strNumberOut As String

    strNumberOut = ""

    For lngX = 1 To Len(pstrNumberIn)

    strCurrChar = Mid$(pstrNumberIn, lngX, 1)

    If InStr("0123456789.", strCurrChar) > 0 Then

    strNumberOut = strNumberOut & strCurrChar

    End If

    Next

    UnFormatNumber = strNumberOut

    End Function

    Code the General Declarations section as shown below. Here, as in the previous sample application, twoADO object variables, mobjADOConn and mobjADORst, are defined at the form level, as are some otherform-level variables that will be needed.

    Option Explicit

    Dim mobjADOConn As ADODB.Connection

    Dim mobjADORst As ADODB.Recordset

    Private mstrSQL As String

    Private mdblMinAsking As Double

    Private mblnUpdatePending As Boolean

    Private mstrUpdateType As String

    Private mavntUSStates As Variant

    Code the Form_Load event as shown below. In it, a programmer-defined Sub named GetMinimumAskingis called (that routine is the one that displays the initial prompt to the user to enter the minimum asking priceof the properties they want to work with). Then, the variant array mavntUSStates is loaded with the 50 USstate abbreviations, needed for validating the state input by the user. This is followed by a call to theCenterForm sub. Then, the ADO connection object (mobjADOConn) is instantiated, its ConnectionString

  • 8/3/2019 leccion 7 - usando ado

    35/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 35

    property is set, and the Open methodis 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 createthe 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).

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

    Private Sub Form_Load()

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

    On Error GoTo LocalError

    ' obtain the minimum asking price for the properties to be worked with

    GetMinimumAsking

    ' load the array of states to be used for validation

    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")

    'center the form:

    CenterForm Me

    ' Connect to the Property database:

    Set mobjADOConn = New ADODB.Connection

    mobjADOConn.ConnectionString = "DSN=PropDB;Uid=admin;Pwd=;"

    mobjADOConn.Open

    Call GetPropertyData

  • 8/3/2019 leccion 7 - usando ado

    36/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 36

    SetFormState False

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

    Code the GetMinimumAsking Sub, which uses the InputBox function to prompt to the user to enter the minimumasking price of the properties they want to work with. The resulting value is then stored in the form-level variable

    mdblMinAsking.

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

    Private Sub GetMinimumAsking()

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

    Dim strInputBoxPrompt As String

    Dim strAsking As String

    strInputBoxPrompt = "Enter the minimum asking price (for example, 200000) " _

    & "for the properties that you want to work with this session." _

    & vbNewLine _

    & "To work with ALL properties, leave the default of zero."

    strAsking = InputBox(strInputBoxPrompt, "Minimum Asking Price", "0")

    If strAsking = "" Then

    ' user clicked Cancel button on the input box, so end the app

    End

    End If

  • 8/3/2019 leccion 7 - usando ado

    37/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 37

    mdblMinAsking = Val(strAsking)

    End Sub

    Code the GetPropertyData Sub, which builds the SQL to get the property records meeting the minimum askingprice condition. The Recordset object is then instantiated, its CursorLocation property is set, and its Open methodis invoked to execute the SQL and return the resultset. This is done in a loop in case the resultset does not returnany records due to the fact no records in the table met the asking price condition. In that situation, the user isgiven the opportunity to specify a different asking price value. Following this, the programmer-defined SubPopulateFormFields is called (which displays the fields from the current record in their corresponding textboxeson the form).

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

    Private Sub GetPropertyData()

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

    On Error GoTo LocalError

    Dim blnGotData As Boolean

    blnGotData = False

    Do

    'select or reload the data to be displayed:

    mstrSQL = "select propno" _

    & " , empno" _

    & " , address" _

    & " , city" _

    & " , state" _

    & " , zip" _

    & " , beds" _

    & " , baths" _

    & " , asking" _

    & " from property" _

  • 8/3/2019 leccion 7 - usando ado

    38/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 38

    & " where asking >= " & mdblMinAsking _

    & " order by propno"

    Set mobjADORst = New ADODB.Recordset

    mobjADORst.CursorLocation = adUseClient

    mobjADORst.Open mstrSQL, mobjADOConn, adOpenDynamic, adLockOptimistic, adCmdText

    If mobjADORst.EOF Then

    If MsgBox("There are no properties with an asking price >= " _

    & Format$(mdblMinAsking, "Currency") _

    & ". Do you want to try again with a different value?", _

    vbYesNo + vbQuestion, _

    "Asking Price") _

    = vbYes Then

    GetMinimumAsking

    Else

    End

    End If

    Else

    blnGotData = True

    End If

    Loop Until blnGotData

    'load data into the text boxes

    Call PopulateFormFields

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

  • 8/3/2019 leccion 7 - usando ado

    39/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 39

    End Sub

    Code the PopulateFormFields Sub, which assigns the fields from the current record to their correspondingtextboxes 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 eventprocedures for some of these textboxes. The Sub SetRecNum is then called.

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

    Private Sub PopulateFormFields()

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

    On Error GoTo LocalError

    gblnPopulating = True

    'copy the data from the resultset to the text boxes:

    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")

    txtAsking.Text = Format$(mobjADORst.Fields("asking"), "Currency")

    gblnPopulating = False

    Call SetRecNum

  • 8/3/2019 leccion 7 - usando ado

    40/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 40

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

    Code the SetRecNum Sub. This sub is identical to the one used in Sample Application 2. It displays the numberof the current record at the bottom of the screen using the AbsolutePosition and RowCount properties of theRecordset object.

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

    Private Sub SetRecNum()

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

    StatusBar1.SimpleText = "row " & mobjADORst.AbsolutePosition _

    & " of " & mobjADORst.RecordCount

    End Sub

    Code the SetFormState Sub, which takes in a Boolean argument used to set the Enabled property of the controlson the form. Based on whether the value True or False is passed to this sub, this sub ensures that the textboxesare enabled for adds and updates and disabled for browsing; it also ensures that the various command buttonsare enabled or disabled at the appropriate time. This Sub also sets the form-level Boolean variablemblnUpdatePending.

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

    Private Sub SetFormState(pblnEnabled As Boolean)

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

    txtPropNo.Enabled = pblnEnabled

    txtEmpNo.Enabled = pblnEnabled

    txtAddress.Enabled = pblnEnabled

    txtCity.Enabled = pblnEnabled

  • 8/3/2019 leccion 7 - usando ado

    41/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 41

    txtState.Enabled = pblnEnabled

    txtZip.Enabled = pblnEnabled

    txtBeds.Enabled = pblnEnabled

    txtBaths.Enabled = pblnEnabled

    txtAsking.Enabled = pblnEnabled

    cmdSave.Enabled = pblnEnabled

    cmdCancel.Enabled = pblnEnabled

    cmdAdd.Enabled = Not pblnEnabled

    cmdUpdate.Enabled = Not pblnEnabled

    cmdDelete.Enabled = Not pblnEnabled

    cmdExit.Enabled = Not pblnEnabled

    cmdMoveFirst.Enabled = Not pblnEnabled

    cmdMoveNext.Enabled = Not pblnEnabled

    cmdMovePrevious.Enabled = Not pblnEnabled

    cmdMoveLast.Enabled = Not 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 addor update and then clicks the "X" button on the upper-right corner of the form, they will receive the message thatthey must save or cancel prior to exiting the application, and the form will NOT be unloaded (because we areassigning a non-zero value to the Cancel argument in that situation). Provided that an add or update is not inprogress, we set the database objects to Nothing and the Unload will complete.

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

    Private Sub Form_Unload(Cancel As Integer)

  • 8/3/2019 leccion 7 - usando ado

    42/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 42

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

    If mblnUpdatePending Then

    MsgBox "You must save or cancel the current operation prior to exiting.", _

    vbExclamation, _

    "Exit"

    Cancel = 1

    Else

    Set mobjADORst = Nothing

    Set mobjADOConn = Nothing

    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-tabto the next textbox.

    Only numeric digits should be entered into the property number, employee number, zip codes, and bedstextboxes.

    Only numeric digits and optionally one decimal point should be entered into the baths and asking textboxes.

    Force uppercase on the state textbox.

    When the asking textbox receives focus, the value in there should be unformatted. When the asking textboxloses focus, its value should be formatted as currency.

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

    ' Textbox events

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

  • 8/3/2019 leccion 7 - usando ado

    43/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 43

    ' property #

    Private Sub txtPropNo_GotFocus()

    SelectTextBoxText txtPropNo

    End Sub

    Private Sub txtPropNo_KeyPress(KeyAscii As Integer)

    KeyAscii = ValidKey(KeyAscii, gstrNUMERIC_DIGITS)

    End Sub

    Private Sub txtPropNo_Change()

    TabToNextTextBox txtPropNo, txtEmpNo

    End Sub

    ' emp #

    Private Sub txtEmpNo_GotFocus()

    SelectTextBoxText txtEmpNo

    End Sub

    Private Sub txtEmpNo_KeyPress(KeyAscii As Integer)

    KeyAscii = ValidKey(KeyAscii, gstrNUMERIC_DIGITS)

    End Sub

    Private Sub txtEmpNo_Change()

    TabToNextTextBox txtEmpNo, txtAddress

    End Sub

    ' address

    Private Sub txtAddress_GotFocus()

    SelectTextBoxText txtAddress

  • 8/3/2019 leccion 7 - usando ado

    44/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 44

    End Sub

    Private Sub txtAddress_Change()

    TabToNextTextBox txtAddress, txtCity

    End Sub

    ' city

    Private Sub txtCity_GotFocus()

    SelectTextBoxText txtCity

    End Sub

    Private Sub txtCity_Change()

    TabToNextTextBox txtCity, txtState

    End Sub

    ' state

    Private Sub txtState_GotFocus()

    SelectTextBoxText txtState

    End Sub

    Private Sub txtState_KeyPress(KeyAscii As Integer)

    KeyAscii = ConvertUpper(KeyAscii)

    End Sub

    Private Sub txtState_Change()

    TabToNextTextBox txtState, txtZip

    End Sub

    ' zip

    Private Sub txtZip_GotFocus()

  • 8/3/2019 leccion 7 - usando ado

    45/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 45

    SelectTextBoxText txtZip

    End Sub

    Private Sub txtZip_KeyPress(KeyAscii As Integer)

    KeyAscii = ValidKey(KeyAscii, gstrNUMERIC_DIGITS)

    End Sub

    Private Sub txtZip_Change()

    TabToNextTextBox txtZip, txtBeds

    End Sub

    ' beds

    Private Sub txtBeds_GotFocus()

    SelectTextBoxText txtBeds

    End Sub

    Private Sub txtBeds_KeyPress(KeyAscii As Integer)

    KeyAscii = ValidKey(KeyAscii, gstrNUMERIC_DIGITS)

    End Sub

    Private Sub txtBeds_Change()

    TabToNextTextBox txtBeds, txtBaths

    End Sub

    ' baths

    Private Sub txtBaths_GotFocus()

    SelectTextBoxText txtBaths

    End Sub

    Private Sub txtBaths_KeyPress(KeyAscii As Integer)

    KeyAscii = ValidKey(KeyAscii, gstrNUMERIC_DIGITS & ".")

  • 8/3/2019 leccion 7 - usando ado

    46/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 46

    ' if text already has a decimal point, do not allow another ...

    If Chr$(KeyAscii) = "." And InStr(txtBaths.Text, ".") > 0 Then

    KeyAscii = 0

    End If

    End Sub

    Private Sub txtBaths_Change()

    TabToNextTextBox txtBaths, txtAsking

    End Sub

    ' asking price

    Private Sub txtAsking_GotFocus()

    txtAsking.Text = UnFormatNumber(txtAsking.Text)

    SelectTextBoxText txtAsking

    End Sub

    Private Sub txtAsking_KeyPress(KeyAscii As Integer)

    KeyAscii = ValidKey(KeyAscii, gstrNUMERIC_DIGITS & ".")

    ' if text already has a decimal point, do not allow another ...

    If Chr$(KeyAscii) = "." And InStr(txtAsking.Text, ".") > 0 Then

    KeyAscii = 0

    End If

    End Sub

    Private Sub txtAsking_LostFocus()

    txtAsking.Text = Format$(txtAsking.Text, "Currency")

    End Sub

  • 8/3/2019 leccion 7 - usando ado

    47/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 47

    Code the events for the navigation buttons as shown below, using the resultset "Move" methods to move to thefirst, last, next, or previous record, respectively.

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

    Private Sub cmdMoveFirst_Click()

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

    On Error GoTo LocalError

    mobjADORst.MoveFirst

    Call PopulateFormFields

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

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

    Private Sub cmdMoveLast_Click()

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

    On Error GoTo LocalError

    mobjADORst.MoveLast

    Call PopulateFormFields

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

  • 8/3/2019 leccion 7 - usando ado

    48/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 48

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

    Private Sub cmdMoveNext_Click()

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

    On Error GoTo LocalError

    mobjADORst.MoveNext

    If mobjADORst.EOF Then

    Beep

    mobjADORst.MoveLast

    End If

    Call PopulateFormFields

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

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

    Private Sub cmdMovePrevious_Click()

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

    On Error GoTo LocalError

    mobjADORst.MovePrevious

    If mobjADORst.BOF Then

    Beep

    mobjADORst.MoveFirst

    End If

  • 8/3/2019 leccion 7 - usando ado

    49/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 49

    Call PopulateFormFields

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    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 allthe other buttons), set the form-level variable mstrUpdateType to "A" (indicating that an add is pending) and setsfocus to the Property Number field.

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

    Private Sub cmdAdd_Click()

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

    On Error GoTo LocalError

    'clear all the text boxes:

    txtPropNo.Text = ""

    txtEmpNo.Text = ""

    txtAddress.Text = ""

    txtCity.Text = ""

    txtState.Text = ""

    txtZip.Text = ""

    txtBeds.Text = ""

    txtBaths.Text = ""

    txtAsking.Text = ""

    SetFormState True

  • 8/3/2019 leccion 7 - usando ado

    50/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 50

    mstrUpdateType = "A"

    txtPropNo.SetFocus

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

    Code the Click event for the cmdUpdate button. In it, the SetFormState sub is called (passing it a parameter ofTrue, which will enable the textboxes and the Save and Cancel buttons and disable all the other buttons), set theform-level variable mstrUpdateType to "U" (indicating that an update is pending), disables the Property Numberfield (because it is the primary key and should not be changed) and sets focus to the Employee Number field.

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

    Private Sub cmdUpdate_Click()

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

    On Error GoTo LocalError

    SetFormState True

    mstrUpdateType = "U"

    ' being that propno is the primary key, it should not be updatable

    txtPropNo.Enabled = False

    txtEmpNo.SetFocus

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

  • 8/3/2019 leccion 7 - usando ado

    51/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 51

    Code the Click event for the cmdSave button. The user would click this button after they have completed entriesfor an add or update. This sub first invokes the ValidateAllFields function, which returns a Boolean indicatingwhether or not all entries passed their edit checks. If not, we exit the sub and the record is not saved; the userremains 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 anadd or an update.

    If we are dealing with an add, we invoke the AddNew method of the Recordset object. The AddNew methodprepares a new row you can edit and subsequently add to the Recordset object using the Update method. Afteryou 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 thecontent 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 hasbeen selected) unlike DAO and RDO, ADO does not use an Edit method. Changes made to the current rowscolumns are copied to the copy buffer. After you make the desired changes to the row, use the Update method tosave 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 Updatemethod saves the contents of the copy buffer row to a specified updatable Recordset object and discards thecopy buffer.

    The mstrUpdateType variable is checked once again, and if we are dealing with an add, there is some extrawork 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 queryon which the object is based. The Find method is then used to position to the new record. The ADO Find methodhas the following syntax:

    RecordsetObject.Find Criteria, SkipRows, SearchDirection, Start

    The Criteriaargument is a String value that specifies the column name, comparison operator, and value to use inthe search. Only a single-column name may be specified in criteria; multi-column searches are notsupported. The comparison operator may be ">" (greater than), "=" (greaterthan or equal), " #7/22/97#"). These values can contain hours, minutes, and seconds toindicate time stamps, but should not contain milliseconds or errors will occur. If the comparison operatoris "like", the string value may contain an asterisk (*) to find one or more occurrences of any character orsubstring. For example, "state like 'M*'" matches Maine and Massachusetts. You can also use leadingand 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 theasterisk as a leading wildcard ('*str'), or embedded wildcard ('s*r'). This will cause an error.

    SkipRowsis an optional Long value, whose default is zero, that specifies the row offset from the current row (orbookmark row specified by the Startargument, if present) to begin the search. By default, the search willstart on the current row.

  • 8/3/2019 leccion 7 - usando ado

    52/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 52

    SearchDirectionis an optional value that determines in which direction the search is performed. The value isspecified by the constants adSearchForward (the default) or adSearchBackward, which equate tovalues of 1 or -1, respectively.

    Startis 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 recordpointer 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. TheSetFormState sub is then called with a parameter of False, which causes the textboxes and the Save and Cancelbuttons 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, ourUnFormatNumber function is used to strip off the non-numeric characters. This is because we are using adisplay format that includes a dollar sign and commas on the txtAsking control, and an error would occur if weattempted to assign this directly to the asking field, which is defined as numeric.

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

    Private Sub cmdSave_Click()

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

    On Error GoTo LocalError

    If Not ValidateAllFields Then Exit Sub

    If mstrUpdateType = "A" Then

    mobjADORst.AddNew

    Else

    ' We can just update the fields. No explicit Edit method

    ' is available or needed.

    End If

    'save the data to the database:

    mobjADORst.Fields("propno") = txtPropNo.Text

    mobjADORst.Fields("empno") = txtEmpNo.Text

    mobjADORst.Fields("address") = txtAddress.Text

  • 8/3/2019 leccion 7 - usando ado

    53/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 53

    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

    If mstrUpdateType = "A" Then

    'after the new record is added, the db must be re-queried

    'so that the resultset contains the new record:

    mobjADORst.Requery

    ' reposition to the record just added

    mobjADORst.Find "propno = " & txtPropNo.Text

    'display status info about the new record

    SetRecNum

    End If

    Reset:

    SetFormState False

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    Resume Reset

    End Sub

  • 8/3/2019 leccion 7 - usando ado

    54/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 54

    Code the Click event for the cmdDelete button. The user is first asked to confirm that they want to delete therecord, and if so, the Delete method of the resultset object is invoked, which deletes the current row in anupdatable resultset object. The Requery method is then invoked so that the record is removed from the resultsetthat the user is working with. The Find method is then invoked to position the next record after the deleted one. Ifit 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.

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

    Private Sub cmdDelete_Click()

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

    On Error GoTo LocalError

    'when the current record is deleted, the current location in the recordset

    'is invalid. use the Requery method to re-execute the query and update

    'the data.

    If MsgBox("Are you sure you want to delete this record?", _

    vbYesNo + vbQuestion, _

    "Delete") = vbNo Then

    Exit Sub

    End If

    mobjADORst.Delete

    mobjADORst.Requery

    ' reposition to one past the record just deleted

    mobjADORst.Find "propno > " & txtPropNo.Text

    ' 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

    ' us to the "new" last record ...

    If mobjADORst.EOF Then mobjADORst.MoveLast

    'load data into the text boxes:

  • 8/3/2019 leccion 7 - usando ado

    55/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 55

    Call PopulateFormFields

    Exit Sub

    LocalError:

    MsgBox Err.Number & " - " & Err.Description

    End Sub

    The ValidateAllFields function, which returns a Boolean value indicating whether or not all fields have passedvalidation checks. This function calls upon two "helper" functions: PropertyExists and ValidState. When the useris doing an add, the PropertyExist function is called to see whether or not the proposed Property Number isalready 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 toensure that the user has entered a valid US state. The code for all three functions is shown below.

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

    Private Function ValidateAllFields() As Boolean

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

    ValidateAllFields = False 'guilty until proven innocent

    If mstrUpdateType = "A" Then

    If txtPropNo.Text = "" Then

    MsgBox "Property # must not be blank.", vbExclamation, "Property #"

    txtPropNo.SetFocus

    Exit Function

    ElseIf PropertyExists Then

    MsgBox "Property # already exists. Please use a different #.", _

    vbExclamation, _

    "Property #"

    txtPropNo.SetFocus

  • 8/3/2019 leccion 7 - usando ado

    56/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 56

    Exit Function

    End If

    End If

    If txtEmpNo.Text = "" Then

    MsgBox "Emp # must not be blank.", vbExclamation, "Emp #"

    txtEmpNo.SetFocus

    Exit Function

    End If

    If txtAddress.Text = "" Then

    MsgBox "Address must not be blank.", vbExclamation, "Address"

    txtAddress.SetFocus

    Exit Function

    End If

    If txtCity.Text = "" Then

    MsgBox "City must not be blank.", vbExclamation, "City"

    txtCity.SetFocus

    Exit Function

    End If

    If Not ValidState Then

    MsgBox "Missing or invalid state.", vbExclamation, "State"

    txtState.SetFocus

    Exit Function

    End If

    If txtZip.Text = "" Or Len(txtZip.Text) = 5 Then

    ' it's OK

    Else

  • 8/3/2019 leccion 7 - usando ado

    57/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 57

    MsgBox "Zip code must either be blank or exactly 5 digits.", _

    vbExclamation, _

    "Zip Code"

    txtZip.SetFocus

    Exit Function

    End If

    If Val(txtBeds.Text) = 0 Then

    MsgBox "Beds must not be zero.", vbExclamation, "Beds"

    txtBeds.SetFocus

    Exit Function

    End If

    If Val(txtBaths.Text) = 0 Then

    MsgBox "Baths must not be zero.", vbExclamation, "Baths"

    txtBaths.SetFocus

    Exit Function

    End If

    If Val(UnFormatNumber(txtAsking.Text)) = 0 Then

    MsgBox "Asking must not be zero.", vbExclamation, "Asking"

    txtAsking.SetFocus

    Exit Function

    End If

    ' if we make it here, all fields have passed edit

    ValidateAllFields = True

    End Function

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

  • 8/3/2019 leccion 7 - usando ado

    58/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    Leccion 7 Usando ADO Pgina 58

    Private Function ValidState() As Boolean

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

    Dim lngX As Long

    Dim blnStateFound As Boolean

    blnStateFound = False

    For lngX = 0 To UBound(mavntUSStates)

    If txtState.Text = mavntUSStates(lngX) Then

    blnStateFound = True

    Exit For

    End If

    Next

    ValidState = blnStateFound

    End Function

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

    Private Function PropertyExists() As Boolean

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

    Dim objTempRst As New ADODB.Recordset

    Dim strSQL As String

    strSQL = "select count(*) as the_count from property where propno = " &txtPropNo.Text

    objTempRst.Open strSQL, mobjADOConn, adOpenForwardOnly, , adCmdText

    If objTempRst("the_count") > 0 Then

    PropertyExists = True

  • 8/3/2019 leccion 7 - usando ado

    59/59

    [VISUAL BASIC CON BASE DE DATOS] IDSYSTEMS 2012

    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, theydecide to abandon the operation. Here, PopulateFormFields is called to reset the textboxes to their content priorto the user clicking the Add or Update button, and SetFormState is called with a parameter of False, whichcauses the textboxes and the Save and Cancel buttons to be disabled and all other buttons to be enabled.

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

    Private Sub cmdCancel_Click()

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

    PopulateFormFields

    SetFormState False

    End Sub

    Code the Click event for the cmdExit button, which issues the Unload Me statement to fire the Form_Unloadevent, which will unload the form and end the application.

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

    Private Sub cmdExit_Click()

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

    Unload Me

    End Sub

    Download the project files for this sample application here.