Sie sind auf Seite 1von 95

What is ODBC?

Answer: Abbreviation of Open DataBase Connectivity, a standard database access method developed by Microsoft Corporation. The aim of ODBC is to make it possible to access any data from any application, regardless of which database management system (DBMS) is handling the data. ODBC manages this by inserting a middle layer, called a database driver, between an application and the DBMS. The purpose of this layer is to translate the application's data queries into commands that the DBMS understands. For this to work, both the application and the DBMS must be ODBCcompliant -- that is, the application must be capable of issuing ODBC commands and the DBMS must be capable of responding to them. 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 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 ADO was Universal Data Access (UDA), where one database access method could be used for any data source; it was designed to replace both DAO and RDO. DAO remains a viable technology for interacting with MS Access databases as it is faster than ADO for that purpose; however, ADO is more flexible using ADO, one could develop 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 is concerned, no new versions of it have been developed beyond the version that shipped with Visual Basic, and there 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 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 .

About this Tutorial

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.

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 other versions of Windows, some steps may vary slightly.

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.

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 -> 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 Name DataSourceName SQL

Value adoBiblio Biblio select * from authors

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

Name txtAuthor txtAuID txtYearBorn

DataSource adoBiblio adoBiblio adoBiblio

DataField Author Au_ID 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 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 cmdNameOrder cmdYearOrder cmdIDOrder

Caption Order by Name Order by Year Order by ID

Put the following code in the cmdNameOrder_Click event:

adoBiblio.SQL = "select * from authors order by author" adoBiblio.Refresh

Put the following code in the cmdYearOrder_Click event:

adoBiblio.SQL = "select * from authors order by [year born]" adoBiblio.Refresh

Put the following code in the cmdIDOrder_Click event:

adoBiblio.SQL = "select * from authors order by au_id" adoBiblio.Refresh

Save and run the program and see what happens when you click the buttons.

A screen-shot of the sample app at run-time is shown below:

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 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:

Column Name PROPNO

Data Type Number (Long Integer)

Notes 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

EMPNO

Number (Long Integer)

ADDRESS CITY STATE ZIP NEIGHBORHOOD HOME_AGE

Text (20) Text (15) Text (2) Text (5) Text (15) Number (Long Integer)

BEDS BATHS

Number (Long Integer) Number (Single)

FOOTAGE ASKING BID SALEPRICE

Number (Long Integer) Number (Long Integer) Number (Long Integer) Number (Long Integer)

sample database). A number that identifies the real estate agent selling the property. In a real system, this would be the foreign key to the employee number in an Employee table (such a table is not present in the sample database). The street address of the property. The city where the property is located. The state where the property is located (2character US state abbreviation). The zip code where the property is located. The descriptive name of the neighborhood in which the property is located. Age in years of the home. (A better table design choice would be to have this field be the date in which the property was built and have the application compute the age based on the current date.) Number of bedrooms in the property. 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"). The footage of the property. Asking price of the property in whole dollars. Bid amount of the potential buyer in whole dollars. 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 the previous sample application.

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 cmdMoveFirst cmdMovePrevious cmdMoveNext cmdMoveLast

Caption << < > >>

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

Name MultiLine Locked

txtCurrentQuery True True

The command buttons have the following properties:

Name cmdAllData cmdGetData

Caption Reload All Records Run Query Now

Enabled True False

In the "Select Criteria" frame:

The check boxes are an array: Name chkCriteria(0) chkCriteria(1) chkCriteria(2) Caption EmpNo City State

The labels are also an array: Name lblCriteria(0) lblCriteria(1) lblCriteria(2) Caption = Like Like Enabled False False False

The textboxes are also an array: Name txtCriteria(0) txtCriteria(1) txtCriteria(2) Caption EmpNo City State Enabled False False 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 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 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 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.

'---------------------------------------------------------------------------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

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 all the 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 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 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:

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

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 adOpenForwardOnly

adOpenStatic

adOpenDynamic

adOpenKeyset

Description (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. Forwardonly cursors are sometimes referred to as firehose cursors. 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. 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. 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 adLockReadOnly

adLockPessimistic

adLockOptimistic adLockBatchOptimistic

Description (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. 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. Specifies optimistic locking. The provider locks records only when you call the Update method, not when you start editing. 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

adCmdTable adCmdStoredProc adCmdUnknown

adExecuteAsync adFetchAsync

Indicates that the provider should evaluate CommandText as a textual definition of a command. This options is used SQL statements. Indicates that the provider should evaluate CommandText as a table. Indicates that the provider should evaluate CommandText as a stored procedure. 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. Indicates that the command should execute asynchronously. Indicates that the remaining rows after the initial quantity specified in the CacheSize property should be fetched asynchronously.

'---------------------------------------------------------------------------Private Sub OpenNewRecordset() '---------------------------------------------------------------------------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 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

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

'---------------------------------------------------------------------------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 to the first, last, next, or previous record, respectively. '---------------------------------------------------------------------------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() '---------------------------------------------------------------------------On Error GoTo LocalError

mobjADORst.MoveNext If mobjADORst.EOF Then Beep mobjADORst.MoveLast End If Call DataLoad 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 Call DataLoad Exit Sub LocalError: 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, 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.

'---------------------------------------------------------------------------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

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.

'---------------------------------------------------------------------------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 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: 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 a single character. For example, entering "M%" for the City criteria would return all rows where the city field begins with the letter "M".

Download the project files for this sample application here.

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 txtPropNo txtEmpNo txtAddress txtCity txtState txtZip txtBeds txtBaths txtAsking

Properties MaxLength: 5 MaxLength: 4 MaxLength: 20 MaxLength: 15 MaxLength: 2 MaxLength: 5 MaxLength: 1 MaxLength: 3 (allows fractional amount, like 1.5) MaxLength: 0 (not specified)

Set up the Command Buttons as follows:

Name cmdMoveFirst cmdMovePrevious cmdMoveNext cmdMoveLast cmdAdd cmdUpdate cmdDelete cmdSave

Caption << < > >> Add Update Delete Save

cmdCancel cmdExit

Cancel 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:

CenterForm ValidKey ConvertUpper SelectTextBoxText TabToNextTextBox

UnFormatNumber

Sub to center a form on the screen Function to validate a keystroke for use in the KeyPress event of a textbox Function to convert an alphabetic character entered in a textbox to uppercase, used in the KeyPress event of a textbox Sub to highlight the text of a textbox when it receives focus. Used in the GotFocus event of a textbox. Sub to "autotab" from one textbox to another when maximum number of characters that can be entered into the first textbox has been reached. Function to strip out non-numeric characters (dollar signs, commas, etc.) from a formatted number.

Option Explicit

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 _ 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) <= "z" Then pintKeyValue = pintKeyValue - 32 End If

ConvertUpper = pintKeyValue

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 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, 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

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 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 programmerdefined 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

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 minimum asking 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

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

'---------------------------------------------------------------------------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" _ & " 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

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.

'---------------------------------------------------------------------------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 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 number of the current record at the bottom of the screen using the AbsolutePosition and RowCount properties of the Recordset 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 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.

'---------------------------------------------------------------------------Private Sub SetFormState(pblnEnabled As Boolean) '----------------------------------------------------------------------------

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

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

Private Sub Form_Unload(Cancel As Integer) '----------------------------------------------------------------------------

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-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. Force uppercase on the state textbox. When the asking textbox receives focus, the value in there should be unformatted. When the asking textbox loses focus, its value should be formatted as currency.

'---------------------------------------------------------------------------' Textbox events

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

' 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

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() 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 & ".") ' 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

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. '---------------------------------------------------------------------------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

'---------------------------------------------------------------------------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 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 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() '----------------------------------------------------------------------------

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

'---------------------------------------------------------------------------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

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 rows 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:

RecordsetObject.Find Criteria, SkipRows, SearchDirection, Start 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; multicolumn 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. '---------------------------------------------------------------------------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 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

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.

'---------------------------------------------------------------------------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: 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 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.

'---------------------------------------------------------------------------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 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 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

'------------------------------------------------------------------------------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 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. '---------------------------------------------------------------------------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_Unload event, 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.

Similar links

Naming Database Objects Access SQL VB6 With Access Oracle and Visual Basic using ADO Database Access with RDO (Remote Data Objects) Using Crystal Reports Database Access with the Data Control Using ADO and the ListView control Creating PDF files in Visual Basic VB6 Animated Charts (With FusionCharts) 498962 reads

Fri, 02/03/2012 - 23:11 Purushottam (not verified)

SQL connectivity problem on client machine


I am using VB 6 with sql 2000 server and using connectivity for follwoing code program is running on self machine but on client machine it is not running. so plz hel me asap. Cn.Open "Driver={SQL Server};" & _ "Server=dataserver;" & _ "Address=192.168.1.171,1433;" & _ "Network=DBMSSOCN;" & _ "Database=master;" & _ "Uid=sa;" & _ "Pwd=sa" Thanks & regards. Purushottam

reply

Tue, 11/15/2011 - 21:14 fkwinna (not verified)

how to add a new field to a table(access) by vb6 code


Hi I have a databse (access2000) with table named sunny , I need to add a new text field and a new long field to that table , by visual basic 6 code kindly help me, if there an example , it will be nice methode Thank's for all

reply

Thu, 11/03/2011 - 04:31 soni parth

connect vb with oracle


Please give us step by step instructions for easy understanding that how to connect vb6.0 with oracle 9i. And also pleas tell us how to create ODBC connections.....

reply

Sat, 10/29/2011 - 22:29 Anonymous (not verified)

can u pl include more


can u pl include more tutorials with examples for connecting oracle10 with vb6..? the tutorial is very informativr btw

reply

Tue, 10/11/2011 - 00:20 ayatots (not verified)

thankyou
tnx .. it help us to practice our program . please debug it thank you :D

reply

Tue, 10/11/2011 - 00:37 anoninos (not verified)

wow ?!
wow ?!

reply

Sat, 09/10/2011 - 04:53 Anonymous (not verified)

Thank you
This tutorial is the most useful one about "VB6 and ADO" that I've read. Thank you very much.

reply

Mon, 08/15/2011 - 00:33 Anonymous (not verified)

hehe
thank you so much .. it is so helping ty

reply

Sun, 06/26/2011 - 21:47 krunalmsheth

Data not save in data base


I have complete my all procedure to add, del., save, move but when i will enter data in form, & i use save command then no error found but data not save in my backend file. i will use array for textbox & data connect through adodb.recordset function in module. I will give right table no in coding for the same form.

reply

Wed, 06/22/2011 - 02:49 NKaze7 (not verified)

Thanks for the Tutorial!

Thank you for providing this tutorial!! It helped me out in my studies.

reply

Fri, 06/03/2011 - 05:40 Anisul (not verified)

Help With SQL server 2000 and Data source ODBC


Hello Every1, I m a student of a private University in Bangladesh. I m using windows xp. i installed the SQL server 2000. But i can't get connected with Data source ODBC... Can anybody help me or refer me to know Sql Server 2000 installation process and how to connect Data source ODBC. PLease help..

reply

Fri, 05/20/2011 - 07:24 march11 (not verified)

Setting ADOSB character set


I am reading a few cells from Excell into Access VBA using ADODB. One of the columns in the spreadsheet contain Japanese characters. How can I set the character set to receive these into the VBA variable, now they come in as "??????" ? Thanks

reply

Fri, 04/29/2011 - 03:36 Anonymous (not verified)

thanhk so much!!!!! :)
thanhk so much!!!!! :)

reply

Thu, 04/21/2011 - 12:02 MAHI (not verified)

Very helpful tutorial..... it


Very helpful tutorial..... it helps me a lot....

reply

Tue, 04/12/2011 - 00:02 Anonymous (not verified)

thank u guys!
thank u guys!

reply

Wed, 03/30/2011 - 04:14 BABANGIDA ZACHARIAH (not verified)

i love your effort so far and


i love your effort so far and would like to be as great you are. please can you help send me codes that connects to a database, search for a record(as in login) typed by a user?

reply

Wed, 02/16/2011 - 04:34 Harshal Pande (not verified)

Exteremely Good
The Tutorial is exteremely good and useful.

reply

Fri, 02/11/2011 - 03:43 Anonymous (not verified)

tutorial is very helpful.


tutorial is very helpful. but i m having some problems. the ADO control you used in section 1 of this tutorial and you shown three properties i.e. 1 DataSourceName 2 SQL 3 Name the property name is ok but i cannt find the rest of the two properties in property window of ado. kindly help. i also want to know how i can use data reports in vb and how to print them. i m waiting for your favorable reply thanks & regards

reply

Mon, 10/03/2011 - 06:57 Anonymous (not verified)

In the ADO data control on

In the ADO data control on the form to access: DatasourceName: Click on Connection string then select source of connection and radio button Use ODBC data source name, Then select Biblio SQL: Click on Recordsource... Property Page, Enter Value in Command Text (SQL) Name: Is just name.

I noticed that Windows 7 still uses the Windows 3.1 dialog box for selecting database with ODBC Microsoft Access Setup, not the easiest to use now that we have filenames longer than 8 characters.

Can Microsoft add this to bug list fix as the old dialog box here from Windows 3.1 brings back memories, but it can be very difficult to select databases with long file names from this tiny file browser.

To see what I'm talking about:

1. Open the app ODBC Data Source Administrator in Windows 7 (search ODBC from Start Menu). 2. Under User DSN tab, click the Add... button. 3. In the Create New Data Source dialog select Microsoft Access Driver (*.mdb), click Finish button. 4. A new dialog box opens, called ODBC Microsoft Access Setup, now click Select button to select database, notice the Windows 3.1 browse box to find the database.

It works but needs to be fixed and updated with new Windows file browser system.
o o

Reply Quote

Answers

Friday, August 21, 2009 7:48 AM

Steven Cheng - MSFT

(MSFT) 12,085

Sign In to Vote Hi LukeJR, Regarding on the ODBC Microsoft Access Driver datasource configuration UI, I've tested it it according to your description. Yes, the file browsing dialog still use the old one which may cause some inconvenience for long pathname files. I think the behavior is likely due to most of the ODBC component drivers are moved from former OS without changes so the configure UI also remains. But I do think your suggestion is very good and reasonable. I would also suggeste you post the feedback to the connect site: https://connect.microsoft.com/directory/ under some windows opeating system or data access component categories.

Please remember to mark the replies as answers if they help and unmark them if they provide no help.
o o o o

Marked As Answer byLukeJRFriday, August 21, 2009 9:28 AM Reply Quote

All Replies

Friday, August 21, 2009 7:48 AM

Steven Cheng - MSFT (MSFT) 12,085

Sign In to Vote Hi LukeJR, Regarding on the ODBC Microsoft Access Driver datasource configuration UI, I've tested it it according to your description. Yes, the file browsing dialog still use the old one which may cause some inconvenience for long pathname files. I think the behavior is likely due to most of the ODBC component drivers are moved from former OS without changes so the configure UI also remains. But I do think your suggestion is very good and reasonable. I would also suggeste you post the feedback to the connect site: https://connect.microsoft.com/directory/ under some windows opeating system or data access component categories.

Please remember to mark the replies as answers if they help and unmark them if they provide no help.
o o o o

Marked As Answer byLukeJRFriday, August 21, 2009 9:28 AM

Reply Quote Friday, August 21, 2009 9:27 AM

LukeJR Software Developer (Partner) 35

Sign In to Vote I cannot find where to log this on Connect Microsoft site, cannot provide feedback. Also note that I am using RTM release and the feedback run command: rundll32.exe FeedbackTool.dll,ShowWizard

Does not work in the RTM.

Thanks, Reply Quote Wednesday, February 09, 2011 9:16 PM


o o

Live n0w 0

Sign In to Vote LOST where is "ODBC Data Source Administrator"now located in Windows Control Panel .. I find it ridiculous there is no F1 help information on where program Icon for ODBC Data Source Administrator in windows Control Panel. Its nut to expect every user has to search windows help... which when you do comes up with no listed items for "ODBC Data Source Administrator" .. then do a connect to the net to find a help link which says lick here to run. .. But where is the app now located!! NO ONE KNOWS. Microsoft OS= Lost productivity, Higher TCO.. Reply Quote Sunday, April 17, 2011 10:32 PM
o o

Scott CE 0

Sign In to Vote LOST where is "ODBC Data Source Administrator"now located in Windows Control Panel .. I find it ridiculous there is no F1 help information on where program Icon for ODBC Data Source Administrator in windows Control Panel. Its nut to expect every user has to search windows help... which when you do comes up with no listed items for "ODBC Data Source Administrator" .. then do a connect to the net to find a help link which says lick here to run. .. But where is the app now located!! NO ONE KNOWS. Microsoft OS= Lost productivity, Higher TCO.. 1. Open Control Panel A. For the Category view, click System and Security, then Administrative Tools B. For one of the icon views, double-click Administrative Tools C. If you have Control Panel in list mode on the Start Menu, single-click Administrative Tools 2. Double-click Data Sources (ODBC) I currently build a "classic" ASP web application that uses a backend database of MS Access through an ODBC system DSN connection. This works fine on all 32 bit platforms from XP, Vista and I can easily configure and run it with ODBC. I am now trying to run the application with Windows 7 64 bit. I have configured the 32 bit ODBC Access drivers instead of the 64 bit drivers by running the ODBC driver setup page at: C:\Windows\SysWOW64\odbcad32.exe When I try and running the web application that connects to the database, I get the error:
Microsoft OLE DB Provider for ODBC Drivers error '80004005' [Microsoft][ODBC Driver Manager] The specified DSN contains an architecture mismatch between the Driver and Application

Is it possible to run the Access ODBC drivers (32 bit?) on Windows 7 64 bit? Is there a 64 bit version of the driver available.

I am trying to link a table from an oracle rac 10.2.0.4 64 bit install. I have windows 7 with the oracle 64 bit client. in odbc i can create a datasource using the oracle driver and when i try to link a table i get an error : Reserved error (-7732); there is no message for this error. I would like to use the Microsoft ODBC for Oracle Driver but it doesnt exist on my computer. the old one on windows xp used file MSORCL32.DLL is there a MSORCL64.DLL now? Anyone have any help? Jeff Kelly Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle Posts: 151 Posted: Feb 17, 2010 7:46 AM in response Registered: 05/03/06 to: jefferam It would be nice if someone could answer this question. I am having the same issue. Regards, Kelly Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle Posted: Feb 17, 2010 2:41 PM in response to: Kelly There is currently no Oracle software supported on Win7. For Windows 7 support information refer to the following notes on My Oracle Support: Statement of Direction: Oracle Database 10g Release 2 (10.2.0.5) Client on Microsoft Windows 7 and Microsoft Windows Server 2008 R2 Read My Oracle Support Note 1061272.1 to learn about Oracle Database Client 10.2.0.5 planned support for Windows 7 and Windows Server 2008 R2. Statement of Direction: Oracle Database 11g Release 2 on Microsoft Windows 7 and Microsoft Windows Server 2008 R2 Read My Oracle Support Note 867040.1 to learn about Oracle Database's planned support for

Legend Guru : 2500 - 1000000 pts Expert : 1000 - 2499 pts Pro : 500 - 999 pts Journeyman : 200 - 499 pts Newbie : 0 - 199 pts Oracle ACE Director Oracle ACE Member Oracle Employee ACE Java Champion Helpful Answer (5 pts) Correct Answer (10 pts)

gdarling Posts: 1,808 Registered: 01/10/01

Windows 7 and Windows Server 2008 R2. 32 bit software requires 32 bit odbc driver and 32 bit client. 64 bit software requires 64 bit odbc driver and 64 bit client. Office2010 comes in both 32 bit and 64 bit flavors as I understand it, so you'll need the right version of odbc/client depending on which you have installed. Microsoft only makes a 32 bit ODBC driver for Oracle. Hope it helps, Greg Edited by: gdarling on Mar 2, 2010 11:13 AM Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle Posted: Feb 28, 2010 5:00 PM in response to: gdarling Hi, Do you have an ETA on the Win 7 oracle client with the ODBC dirver(Q1CY2010 is that end of march 2010)? 32 bit will do at this stage. I have many applications that depend on a working oracle ODBC dirver, MS Access, Intellij, Xcase, etc. Older versions of the oracle client fail to install on OS version checks. Thx Kevin Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle Posted: Mar 1, 2010 8:27 AM in response to: user4845342 I've heard no new information other than what is in the statements of direction Greg Edited by: gdarling on Mar 2, 2010 11:14 AM Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle Posted: Mar 2, 2010 4:44 PM in response to: gdarling I have contacted Metalink. All they said is that it will be available soon but no specific date is available.

user4845342 Posts: 1 Registered: 03/01/10

gdarling Posts: 1,808 Registered: 01/10/01

Kelly Posts: 151 Registered: 05/03/06

Kelly Jam Re: Windows 7 - ODBC for Office 2010 64 bit - MS The ODBC Driver for Oracle Man Posted: Mar 30, 2010 12:38 PM in response to: jefferam Posts: 2 Here's the solution. Registered: 03/29/10 My operating system is Windows 7 64-bit, using Office 2010 64-bit. Trying to connect to an ODBC data source through Excel. The data source is an Oracle9i 32-bit database on a Windows Server 2003 32-bit server. However, the database version or server operating system is arbitrary; it could be an 8i, 9i, 10g, or even an 11g 32bit or 64-bit database on a UNIX or Windows server. If you're using Windows 7 64-bit and you want to connect to an ODBC data source through Excel to an Oracle database, you must use Office 2010 64-bit. You cannot use Office 2003 or 2007, for example. Follow these steps on your Windows 7 64-bit PC to connect to your ODBC data source. 1. Through Oracle's web site, go to Instant Client Downloads for Microsoft Windows (x64). Currently, the address to that page is: http://www.oracle.com/technology/software/tech/oci/insta ntclient/htdocs/winx64soft.html 2. Download the two following files, found under the version 11.1.0.7.0 heading: Instant Client Package - Basic (instantclient-basic-winx86-64-11.1.0.7.0.zip) Instant Client Package - ODBC (instantclient-odbc-winx86-64-11.1.0.7.0.zip) 3. Extract both zip files to the same directory (such as c:\oracle\instantclient_11_1). 4. Launch the Command Prompt (DOS command window) by running it as administrator. Go to Start > All Programs > Accessories, then right click Command Prompt and select Run as Administrator. 5. From within the Command Prompt, navigate to c:\oracle\instantclient_11_1, and run odbc_install.exe. You should receive a message saying Oracle ODBC Driver is installed successfully. The name of the new ODBC driver that was just installed is Oracle in instantclient11_1 -- use this driver when creating your ODBC connection.

6. Create a new system environment variable. Set the value of the variable name as TNS_ADMIN, and the value of the variable path as the directory that contains the tnsnames.ora and sqlnet.ora files. On my PC, I have another Oracle client already installed which has its own tnsnames.ora and sqlnet.ora files. Therefore, I set the value of variable path as c:\orant\net80\admin (the directory that contains my tnsnames.ora and sqlnet.ora files). If you don't have another Oracle client installed on your PC, create a new directory such as c:\oracle\instantclient_11_1\network\admin, and place the tnsnames.ora and sqlnet.ora files in that directory. Then, set c:\oracle\instantclient_11_1\network\admin as the value for the variable path. 7. To create the ODBC connection, go Start > Control Panel > Administrative Tools > Data Sources (ODBC). Alternatively, you can create the connection right from within Excel. user575710 Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle Posts: 2 Posted: Apr 1, 2010 6:51 AM in response to: Jam Registered: 05/21/07 The Man Hi, I think this link makes these excellent details more clear: http://robertoschiabel.wordpress.com/2008/02/28/window s-x64-32bit-odbc-vs-64bit-odbc/ This describes how to verify 32/64 bit ODBC connections (because they are treated separately) on Win7 64-bit. I downloaded both 32/64 bit Oracle clients + their ODBC driver to my computer, and I was able to register both ODBC driver successfully based on your explanation. So now, I can use my Office 2007 with the 32bit Instantclient ODBC package, and probably I could use Office 2010 with the 64bit one (I don't have Office 2010 ) So don't forget. Setup 32bit ODBC connections with %WINDIR%\SysWOW64\odbcad32.exe and use %WINDIR%\System32\odbcad32.exe for the 64bit driver. Cheers Kelly Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle

Posts: 151 Registered: 05/03/06

Posted: Apr 1, 2010 7:10 PM to: Jam The Man Hello,

in response

I have to say I am pleased people are trying to help; however, I can not get this solution to work. I followed Jam The Man's instructions completely. I am getting the following error: TNS:lost contact I am running Windows 7 64 bit OS. user575710, When you say, So don't forget. Setup 32bit ODBC connections with %WINDIR%\SysWOW64\odbcad32.exe and use %WINDIR%\System32\odbcad32.exe for the 64bit driver. I simply don't know what you mean... Any help is appreciated. Kelly Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle Posted: Apr 2, 2010 6:56 AM in response to: Kelly Kelly, I've implemented that solution for a number of clients of ours, so I know those steps work. The error you're getting, TNS:lost contact, may be indicative of another problem. What is the database (or data source) that you're trying to connect to? Can you connect to it from another machine, for example? Are you getting that error through the ODBC Administrator panel when trying to do a test connection, or were you getting that error through Excel? What is your connection to the network, I've seen issues when the client PC was on a wireless network trying to connect to an Oracle db? The other question you had. On Windows 7 64bit, there are two ODBC Administrator control panels. There's a 32-bit one, and a 64-bit one. 32bit apps (like Office 2007) cannot use the 64-bit ODBC drivers. 64-bit apps (like Office 2010 64bit) cannot use 32-bit ODBC drivers. So in

Jam The Man Posts: 2 Registered: 03/29/10

Windows 7 64-bit, Microsoft created two ODBC Administrator consoles for setting up the appropriate drivers. 32-bit ODBC connections are setup in %WINDIR%\SysWOW64\odbcad32.exe - this you can launch from the Command Prompt 64-bit ODBC connections are setup in %WINDIR%\System32\odbcad32.exe - this is what launches when you go to Control Panel > Administrative Tools > Data Sources (ODBC) user575710, I tried using the standard 32-bit ODBC driver "Microsoft ODBC for Oracle" when I attempted to try to connect to an ODBC source through Excel 2007 (32-bit) or Office 2010 (32-bit), yet it was failing to connect (on Windows XP 32-bit or Windows 7 32-bit, that driver works). I did create the DSN through %WINDIR%\SysWOW64\odbcad32.exe. Since it didn't work, that lead me to believe that using a 32-bit ODBC driver on Windows 7 64-bit to connect to your data source through Office 2007 is not possible. Just to be clear, the 32-bit ODBC driver you used to connect through Office 2007 was the one installed by using the 32-bit Instant Client Basic and ODBC packages? If so, I'll give it a try and let you know. Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle Posted: Apr 2, 2010 3:19 PM in response to: Jam The Man Hi, Thanks for steps. I am trying to create ODBC connection for windows 7 64 bit as per the steps you described but i am getting the error "Unable to connect SQLState=08004 ORA12154:TNS:could not resolve the connect identifier specified". TNS Service Name in ODBC setup shows the junk character instead of my service name. May be I missed some configuration. what i am doing wrong. Thanks in advance.

user6166274 Posts: 1 Registered: 04/02/10

Kelly Posts: 151 Registered: 05/03/06

Sumit Agarwal Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle Posted: Apr 3, 2010 1:16 PM in response to: Jam The Man Hello Jam, I can connect to the database fine on another computer using the exact same tnsnames.ora file. I am getting the error through ODBC Administrator panel when trying to do a test connection. I'm on a wired network connection. When i run %WINDIR%\System32\odbcad32.exe, the new driver is available, I just can't seem to connect. However, When I run %WINDIR%\SysWOW64\odbcad32.exe, the new driver is not an option in the list. Best Regards, Kelly Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle Posted: Apr 6, 2010 6:00 AM in response to: Jam The Man Hi Jam, Yes, you are right, I downloaded Instant Client 11.1 (both 32 and 64 bit) onto my computer. So my dir structure looks like: C:\Oracle\Instantclient_11_1 C:\Oracle\Instantclient_11_1.x64 Of course I have only one TNSNAMES.ora file (under .x64 directory) and set the shell environment pointing to that folder. To be able to register both (32 and 64 bit) clients with the appropriate ODBC admin console, and make them available for 32 and 64 bit applications, I had to run the odbc_install.exe from both directories (with admin rights!). So now, I can reach database through InstallClient_11_1 - ODBC (32bit) connection from Excel 2007 and I suppose I could connect to database through InstallClient.x86 - ODBC

user575710 Posts: 2 Registered: 05/21/07

(64bit) connection with Excel 2010 without problem. Microsoft ODBC for Oracle has never worked for me. Sorry, if I was not clear last time. Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle Posted: Apr 7, 2010 8:45 AM in response to: user575710 For us, at this time, we used this method to get it to work for us. Uninstalled the 64bit Oracle client. (while we could get our vbscript to connect to oracle via a DSN, the oracle drivers will connect only 1 oracle version different database) (Microsoft ODBC for Oracle is the desired driver since it will connect to various oracle versions) Installed 10203_vista_w2k8_x86_production_client (I did a custom install to include odbc and utilities) Create a shortcut on the desktop to the 32bit odbc admin. (this is not required, since we prefer to use dsn-less connection strings) (well, thru that admin, we could see that the Microsoft ODBC for Oracle driver was listed) For the server, we found these articles that referred to connecting to 32bit drivers. http://serverfault.com/questions/98257/need-torun-an-iis-website-in-32bit-mode-on-a-64bitwindows-server http://learn.iis.net/page.aspx/201/32-bit-modeworker-processes/ we set on the server: aspnet_regiis -enable -i cscript.exe adsutil.vbs set W3SVC/AppPools/Enable32BitAppOnWin64 true The only downside appears to be: http://serverfault.com/questions/38377/runningmultiple-32-bit-application-pools-on-64-bit-

user5459571 Posts: 3 Registered: 04/05/10

windows-2008 I can't find it now, but there was a page that actually suggested to enable 32bit processes on 64bit windows. Anyways... presently it appears to work. Our vbscript is using a dsn-less connection string specifying the Microsoft ODBC for Oracle driver to connect to our Oracle 8, 10 and 11 databases. (personally, would like to see Oracle step up to the plate and release drivers for current client platforms within a reasonable timeframe of the OS release. Surely, Oracle had access to Server 2008/Windows 7 during the beta period) user12284121 Re: Windows 7 - ODBC for Office 2010 64 bit - MS ODBC Driver for Oracle Posts: 1 Posted: Apr 19, 2010 1:43 PM in response to: Jam Registered: 04/19/10 The Man Jam The Man's solution worked for me. [quote] Here's the solution. My operating system is Windows 7 64-bit, using Office 2010 64-bit. Trying to connect to an ODBC data source through Excel. The data source is an Oracle9i 32-bit database on a Windows Server 2003 32-bit server. However, the database version or server operating system is arbitrary; it could be an 8i, 9i, 10g, or even an 11g 32bit or 64-bit database on a UNIX or Windows server. If you're using Windows 7 64-bit and you want to connect to an ODBC data source through Excel to an Oracle database, you must use Office 2010 64-bit. You cannot use Office 2003 or 2007, for example. Follow these steps on your Windows 7 64-bit PC to connect to your ODBC data source. 1. Through Oracle's web site, go to Instant Client Downloads for Microsoft Windows (x64). Currently, the address to that page is: http://www.oracle.com/technology/software/tech/oci/insta ntclient/htdocs/winx64soft.html 2. Download the two following files, found under the version 11.1.0.7.0 heading: Instant Client Package - Basic (instantclient-basic-winx86-64-11.1.0.7.0.zip) Instant Client Package - ODBC (instantclient-odbc-win-

x86-64-11.1.0.7.0.zip) 3. Extract both zip files to the same directory (such as c:\oracle\instantclient_11_1). 4. Launch the Command Prompt (DOS command window) by running it as administrator. Go to Start > All Programs > Accessories, then right click Command Prompt and select Run as Administrator. 5. From within the Command Prompt, navigate to c:\oracle\instantclient_11_1, and run odbc_install.exe. You should receive a message saying Oracle ODBC Driver is installed successfully. The name of the new ODBC driver that was just installed is Oracle in instantclient11_1 -- use this driver when creating your ODBC connection. 6. Create a new system environment variable. Set the value of the variable name as TNS_ADMIN, and the value of the variable path as the directory that contains the tnsnames.ora and sqlnet.ora files. On my PC, I have another Oracle client already installed which has its own tnsnames.ora and sqlnet.ora files. Therefore, I set the value of variable path as c:\orant\net80\admin (the directory that contains my tnsnames.ora and sqlnet.ora files). If you don't have another Oracle client installed on your PC, create a new directory such as c:\oracle\instantclient_11_1\network\admin, and place the tnsnames.ora and sqlnet.ora files in that directory. Then, set c:\oracle\instantclient_11_1\network\admin as the value for the variable path. 7. To create the ODBC connection, go Start > Control Panel > Administrative Tools > Data Sources (ODBC). Alternatively, you can create the connection right from within Excel. [/quote] Thanks man it worked for me. My host environment is windows 7 x64 ultimate and I have my oracle 10g in centos installed in VMware. Previously I had vista home premium x64 there instantclient 10.2 basic and odbc worked but in windows 7 it wasn't working. Thanks again. Pages: 3 [ 1 2 3 | Next ] Back to Thread List

Windows 7 ODBC Data Source Administrator


Posted by Onuora Amobi on December 15, 2011 in Windows 7 Features | 0 Comments and 0 Reactions

Windows 7 allows you to configure and manage multiple data sources. You can then connect to these sources for exports, imports and queries. The ODBC Data Source Administrator screen gives you control over your ODBC data sources. These contain stored information about how to connect to an indicated data provider.

In the ODBC Data Source Administrator screen you can add, delete, or set up data sources with user data source names, known as DSNs. A user data source is only visible to you and be used only on the current computer. The Drivers tab enables you to vies and configure the ODBC drivers on your system. These allow ODBC-enabled programs to obtain information from ODBC data sources. The Tracing tab enables you to use the ODBC tracing feature. This allows you to create logs of the calls to ODBC drivers for use by your support staff, and to assist you in debugging your applications. The Visual Studio tracing feature enables Microsoft Visual Studio tracing for ODBC. The Connection Pooling tab gives you access to control how applications reuse open connection handles, which saves them round-trips to the server.

Back to Windows 7 Features

Subscribe to our Windows Newsletter. You'll receive the most comprehensive news and updates about Microsoft's Windows 8 sent to your email inbox. In addition, I'll send you my eBook "The Case for Windows 8 - Volume 1". Sign up here

I am sorry if this has been asked previously. I have Win 7 Ultimate 64 bit, which is an upgrade from Vista Business 64 bit. I have the following problem when trying to install an ODBC connection (*mdb). When I run odbcad32.exe, from the SysWOW64 directory, and try to install the 32 bit MS Access Driver, I get the following fault message: "The setup routines for the Microsoft Access Driver (*mdb) ODBC driver could not be found. Please reinstall the driver" And then "Component not found in the registry". Obviously something is missing. I have looked at the ODBC entries in the registry but they are empty. Can anyone advise me on how to resolve this problem. Any help appreciated.

My System Specs 03-13-2010 kegobeer Windows 7 Ultimate x86 1,866 posts #2 (permalink)

Try re-registering
odbcconf.dll. Open an elevated command prompt and type:

Code:
regsvr32 odbcconf.dll

My System Specs 03-14-2010 Eisbahn #3 (permalink)

Win 7 Ultimate 64 bit 7 posts

Quote: Originally Posted by kegobeer Try re-registering odbcconf.dll. Open an elevated command prompt
and type:

Code:
regsvr32 odbcconf.dll

Thanks for the reply. I tried this suggestion and received an error message "The specified module could not be found" even though the file is in the directory C:\Windows\SysWOW64\odbcconfig.dll. I typed in the command "regsvr32 c:\Windows\SysWOW64\odbcconfig.dll" My System Specs . 03-14-2010 Capt.Jack Sparrow Windows 7 Ultimate, Quote: Originally Posted by Eisbahn Ubuntu 10.04 LTS - the Thanks for the reply. Lucid Lynx I tried this suggestion and received an error message "The 4,470 posts specified module could not be found" even though the file is in the directory C:\Windows\SysWOW64\odbcconfig.dll. I typed in the command "regsvr32 c:\Windows\SysWOW64\odbcconfig.dll" Hello Welcome to SF, I guess since the MS Access driver is missing the best bet would be to reinstall Office that might fix it. Hope this helps, Captain My System Specs 03-14-2010 Eisbahn #5 (permalink) #4 (permalink)

Win 7 Ultimate 64 bit 7 posts

Quote: Originally Posted by Capt.Jack Sparrow Quote: Originally Posted by Eisbahn Thanks for the reply. I tried this suggestion and received an error message "The specified module could not be found" even though the file is in the directory C:\Windows\SysWOW64\odbcconfig.dll. I typed in the command "regsvr32 c:\Windows\SysWOW64\odbcconfig.dll" Hello Welcome to SF, I guess since the MS Access driver is missing the best bet would be to reinstall Office that might fix it. Hope this helps, Captain Thanks for the suggestion but I don't have MS Office. I just need to use the driver to connect to a mdb database in Flight Simulator X.

My System Specs 03-14-2010 kegobeer Windows 7 Ultimate x86 1,866 posts #6 (permalink)

Quote: Originally Posted by Eisbahn Quote: Originally Posted by kegobeer Try re-registering odbcconf.dll. Open an elevated command prompt
and type:

Code:
regsvr32 odbcconf.dll

Thanks for the reply. I tried this suggestion and received an error message "The specified module could not be found" even though the file is in the directory C:\Windows\SysWOW64\odbcconfig.dll. I typed in the command "regsvr32 c:\Windows\SysWOW64\odbcconfig.dll" The file is odbcconf.dll, not obdcconfig.dll. If it doesn't exist, then you
need to download and install Microsoft Data Access Components. If this is for a game, I suggest asking for some assistance at the game's

website/forum. Hopefully someone else has had this problem and knows exactly how to fix it.

My System Specs 03-15-2010 Eisbahn Win 7 Ultimate 64 bit 7 posts #7 (permalink)

Quote: Originally Posted by kegobeer Quote: Originally Posted by Eisbahn Quote: Originally Posted by kegobeer Try re-registering odbcconf.dll. Open an elevated command prompt
and type:

Code:
regsvr32 odbcconf.dll

Thanks for the reply. I tried this suggestion and received an error message "The specified module could not be found" even though the file is in the directory C:\Windows\SysWOW64\odbcconfig.dll. I typed in the command "regsvr32 c:\Windows\SysWOW64\odbcconfig.dll" The file is odbcconf.dll, not obdcconfig.dll. If it doesn't exist, then you
need to download and install Microsoft Data Access Components. If this is for a game, I suggest asking for some assistance at the game's website/forum. Hopefully someone else has had this problem and knows exactly how to fix it.

I have already tried all the forums, including the forum for the addon in question. Judging by the number of posts on the web this is a very well known problem. However, nobody seems to have an answer. Apart from a complete clean reinstall of the complete OS, i.e not from an upgrade disk, which is what I have. My System Specs 03-15-2010 kegobeer Windows 7 Ultimate x86 Did you download and install MDAC? #8 (permalink)

1,866 posts

My System Specs 03-16-2010 Eisbahn Win 7 Ultimate 64 bit 7 posts #9 (permalink)

Quote: Originally Posted by kegobeer Did you download and install MDAC? As far as I can see there is no MDAC download for Windows 7 64 bit. The components are part of the OS. The Vista MDAC does not work.

My System Specs 03-16-2010 kegobeer Windows 7 Ultimate x86 I saw your post over at the Microsoft Social forum. It looks like 1,866 posts you are out of luck getting a connection to your mdb. Have you considered installing the free Office 2007 trial? It has Access, and maybe you could attempt to connect to the mdb via odbc that way? My System Specs Page 1 of 2 1 2 > #10 (permalink)

ODBC Setup Problem problems?


Click here to Fix Windows 7 Errors and Optimize Your Computer

High CPU Utilization while streaming through Xbox | Logon issue

Similar Threads for: ODBC Setup Problem

Similar Threads for: ODBC Setup Problem Thread ODBC connection problem ODBC Setup Problem odbc ODBC Issue problem about postgresql ODBC driver installation on W7 Forum Network & Sharing Microsoft Office Software Network & Sharing Drivers

This tutorial aims to provide an intermediate Visual Basic 6 user with the basic skills required to retrieve and manipulate data from many commercial databases and any ODBC compliant database. It assumes that those reading it have an understanding of the Object Oriented methodology of Visual Basic 6, and also of the typical programming structures found in Visual Basic. For example, no explanation of what a method is will be given, and it will be assumed that readers will know how the For Each Obj in Collection structure works. Finding this tutorial helpful? Why not
to help cover the bandwidth it chews up? It's the most popular page on this site bar none!

Introduction
Visual Basic 6 obsoletes the previously used database access technology provided by Jet and provides a new one known as ADO or Active Data Objects. This technology allows users to access data easily from many existing databases (such as Access or Paradox) or from ODBC compliant databases like Oracle or MS SQL Server. Using ADO is quite simple and allows programmers to provide flexible database front ends to users that are reliable and include many features. As a VB6 programmer ADO is important to know as most commercial VB programming exercises involve providing a front end to some sort of database. Following are some of the key objects found in the ADO object model and some of their key methods and properties.

Connection Object
This object represents an open connection to the data source. This connection can be a local connection (say App.Path) or can be across a network in a client server application. Some of the methods and properties of this object are not available depending on the type of data source connected to.
Key Properties

Name

Data Type

Description

Defines in string form the location of the data source you wish to connect to. Key fields in the string you will use are the "Provider=" and the "Data Source=" fields. You may also use the "Mode=" field. See descriptions of those properties for a more detailed view of each one. Some examples of connection strings follow: ConnectionString String Data Source=c:\test.mdb;Mode=Read|Write;Persist Connects to an Access database with read/write/persist permissions driver={SQL Server) server=bigsmile;uid=sa;pwd=pwd;database=pu bs - Connects to an SQL Server database called bigsmile as user sa with password pwd to database pubs. A string defining the provider of a connection object. An example follows: Provider String Provider=Microsoft.Jet.OLEDB.4.0 -This string connects to a MS Jet 4.0 compliant database (an Access DB for example.)

Mode

Sets (or returns) the permissions for modifying data across the open connection. Available permissions connectModeEnum include Read, Write, Read/Write, and various Share/Deny types. Sets the location of the cursor engine. You can cursorLocationEnu select client side or server side, for simpler m databases (like Access) client side is the only choice. Time in seconds that a connection will attempt to be opened before an error is generated. Time in seconds that an command will attempt to be executed before an error is generated.

CursorLocation

ConnectionTimeou Long t CommandTimeout Long


Key Methods

Name Description Close Closes an open connection. Open Opens a connection with the settings in the ConnectionString property.

Command Object
A command object specifies a specific method you intend to execute on or against the data source accessed by an open connection.

Key Properties

Name ActiveConnection

Data Type conConnection as ADODB.Connection

Description Defines the Connection object the command belongs to. Contains the text of the command you want to execute against a data source. This can be a table name, a valid SQL string, or the name of a stored procedure in the data source. Which one you use is determined by the CommandType property. Defines the type of the command. The three most commonly used would be adCmdText, adCmdTable, and adCmdStoredProc. The setting adCmdText causes the CommandText string to be evaluated as an SQL string. The setting adCmdTable causes the CommandText string to be evaluated as a table name and will return the all of the records and columns in a table. The setting adCmdStoredProc causes the CommandText string to be evaluated as a stored procedure in the data source.

CommandText

String

CommandType

commandTypeEnum

Key Methods

Name

Description Executes the query, SQL statement, or stored procedure specified in the Execute CommandText property and returns a RecordSet object.

RecordSet Object
The RecordSet object represents a complete set of records from an executed command or from an underlying base table in the database. A key thing to note is that a RecordSet object references only one record at a time as the current record.
Key Properties

Name

Description This sets or returns the location of the cursor engine for the database. The options are client side and server CursorLocation CursorLocationEnum side, for less advanced databases like Access you may only be able to select client side. CursorType CursorTypeEnum Sets the cursor type. CursorType typically determines when and to whom database changes are immediately visible to. For client side cursor locations only one type of CursorType is available, adOpenStatic. End Of File and Beginning Of File. When at the first record of an open RecordSet BOF will be true, when at the last EOF will be true. If you ever return a RecordSet with no records then EOF and BOF will be

Data Type

EOF and BOF Boolean

true. This provides an ideal way of testing if any records have been returned by a query. Returns a collection of the field objects for an open record set. Database fields can be accessed by their name using the RecordSet!FieldName schema, by their index RecordSet.Fields(intIndex) or sometimes by their name from the fields collection RecordSet.Fields("FieldName"). I find in the situation where you know a database structure that the RecordSet!FieldName method is best, where structure is not known, then the RecordSet.Fields(intIndex) may be best. sets the lock type on records when they are open for editing. If a client side cursor location is selected then only optimistic and batch optimistic locking are available. Returns the number of records in an open RecordSet. If for some reason ADO cannot determine the number of records then this will be set to -1.

Fields

Collection

LockType

LockTypeEnum

RecordCount
Key Methods

Long

Name AddNew Close MoveNext MoveFirst MoveLast Open Update

Description Sets up an open record set to add a new record, once the required values have been set call the Update (or UpdateBatch) method to commit the changes. Closes an open RecordSet object, make sure that any changes are committed using the Update (or UpdateBatch) method before closing or an error will be generated. Causes an open RecordSet object to move to the next record in the collection, if the current record is the last record then EOF is set to true. Causes an open RecordSet object to move to the first record in the collection. Causes an open RecordSet object to move to the last record in the collection. Opens the RecordSet, typically this is done with a valid Command object that includes the command text (or SQL) to get the records you want. Causes any changes made to the current record to be written to disk.

Causes any changes you have made in batch mode to be written to disk. The UpdateBatch way to use batch updates is to open the RecordSet object with the LockType adLockBatchOptimistic.

Putting It All Together


I like to think of using ADO as a three step process

Define and open a Connection to a data source Decide what data you need from the data source and define Command objects that will retrieve this data.

Retrieve the data you require by executing the command objects and manipulate the data using RecordSet objects.

To start using ADO create a new Standard EXE project in your VB6 environment. You'll need to add a reference to the ADO library using the Project -> References menu and selecting the "Microsoft ActiveX Data Objects 2.5 Library" or the "Microsoft ActiveX Data Objects 2.6 Library". Then on the form add a single command button and add the code below to the click event of the button. Save the project and then open Microsoft Access and create a new database called "database.mdb" in the directory where you have saved your VB project. Add a table called "tabTestTable" to the database. Add two columns to this table with a text data type, the column names do not matter. Add a couple of records to the table with some values in the columns. Then you can safely run your project and see the results. If you dont want to do this I have created a VB project that includes all of this that can be downloaded. Just unzip this to a directory and open the project in Visual Studio and try it out. Got questions? Feel free to ask me at questions@timesheetsmts.com Why not

to help cover the bandwidth this page chews up and you'll be much more likely to get an answer!
Private Sub Command1_Click() 'Define the three objects that we need, ' A Connection Object - connects to our data source ' A Command Object - defines what data to get from the data source ' A RecordSet Object - stores the data we get from our data source Dim conConnection As New ADODB.Connection Dim cmdCommand As New ADODB.Command Dim rstRecordSet As New ADODB.Recordset 'Defines the connection string for the Connection. Here we have used fie lds 'Provider, Data Source and Mode to assign values to the properties ' conConnection.Provider and conConnection.Mode conConnection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data S ource=" & _ App.Path & "\" & "database.mdb;Mode=Read|Write" 'Define the location of the cursor engine, in this case we are opening an Access database 'and adUseClient is our only choice. conConnection.CursorLocation = adUseClient 'Opens our connection using the password "Admin" to access the database. If there was no password

'protection on the database this field could be left out. conConnection.Open 'Defines our command object ' .ActiveConnection tells the command to use our newly created command ob ject. ' .CommandText tells the command how to get the data, in this case the co mmand ' will evaluate the text as an SQL string and we will return all ' records from a table called tabTestTable ' .CommandType tells the command to evaluate the .CommandText property as an SQL string. With cmdCommand .ActiveConnection = conConnection .CommandText = "SELECT * FROM tabTestTable;" .CommandType = adCmdText End With 'Defines our RecordSet object. ' .CursorType sets a static cursor, the only choice for a client side cu rsor ' .CursorLocation sets a client side cursor, the only choice for an Acce ss database ' .LockType sets an optimistic lock type ' .Open executes the cmdCommand object against the data source and store s the ' returned records in our RecordSet object. With rstRecordSet .CursorType = adOpenStatic .CursorLocation = adUseClient .LockType = adLockOptimistic .Open cmdCommand End With 'Firstly test to see if any records have been returned, if some have been returned then 'the .EOF property of the RecordSet will be false, if none have been retu rned then the 'property will be true. If rstRecordSet.EOF = False Then 'Move to the first record rstRecordSet.MoveFirst 'Lets move through the records one at a time until we reach the last re cord 'and print out the values of each field Do 'Access the field values using the fields collection and print them t

o a message box. 'In this case I do not know what you might call the columns in your d atabase so this 'is the safest way to do it. If I did know the names of the columns in your table 'and they were called "Column1" and "Column2" I could reference their values using: ' ' rstRecordSet!Column1 rstRecordSet!Column2

MsgBox "Record " & rstRecordSet.AbsolutePosition & " " & _ rstRecordSet.Fields(0).Name & "=" & rstRecordSet.Fields(0) & " " & _ rstRecordSet.Fields(1).Name & "=" & rstRecordSet.Fields(1) 'Move to the next record rstRecordSet.MoveNext Loop Until rstRecordSet.EOF = True 'Add a new record With rstRecordSet .AddNew .Fields(0) = "New" .Fields(1) = "Record" .Update End With 'Move back to the first record and delete it rstRecordSet.MoveFirst rstRecordSet.Delete rstRecordSet.Update 'Close the recordset rstRecordSet.Close Else MsgBox "No records were returned using the query " & cmdCommand.Command Text End If 'Close the connection conConnection.Close 'Release your variable references Set conConnection = Nothing Set cmdCommand = Nothing Set rstRecordSet = Nothing End Sub

Generated using PrettyCode.Encoder

Products

Support

Free Software

Contact Us

About Us

Site Map Disclaimer

Moving Target Software (2002-4) Email Us

Das könnte Ihnen auch gefallen