Create and open an Access database based on the documents/views/framework architecture of ADO, ADOX, and MFC

Source: Internet
Author: User
Tags access properties
This article describes how to use ADO and ADOX to create and open a database in the framework of the MFC Document view. Read MFC technical Article TN025: Document, View, andFrameCreation Microsoft Knowledge Base Article Q183606ActiveXDataObjects (ADO) FrequentlyAskedQuestionsQ169496INFO: UsingActi

This article describes how to use ADO and ADOX to create and open a database in the MFC documentation/View/framework architecture. Read MFC technical Article TN025: Document, View, and Frame Creation Microsoft Knowledge Base Article Q183606 ActiveX Data Objects (ADO) Frequently Asked Questions Q169496 INFO: Using Acti

This article describes how to use ADO and ADOX to create and open a database in the MFC documentation/View/framework architecture.

Preparation

MFC technical article

  • TN025: Document, View, and Frame Creation

Microsoft Knowledge Base Article

  • Q183606 ActiveX Data Objects (ADO) Frequently Asked Questions
  • Q169496 INFO: Using ActiveX Data Objects (ADO) via # import in VC ++
  • Q317881 how to: Create an Access Database Using ADOX and Visual C #. NET
  • Q252908 HOWTO: Create a Table with Primary Key Through ADOX
  • Q201826 PRB: Error 3265 When You Access Properties Collection

Office VBA reference

  • Creating and Modifying Access Tables
Procedure
  1. Install MDAC2.5 or above on your computer
  2. Open VC. First, we use the MFC Application Wizard to create a standard MDI program. Here I name this project Passport, and then import ADOX in stdafx. h.
    # Include
    # Import "c:/Program Files/Common Files/system/ado/Msado15.dll" rename ("EOF", "adoEOF") rename ("DataTypeEnum", "adoDataTypeEnum ")
    # Import "c:/Program Files/Common Files/System/ADO/Msadox. dll" rename ("EOF", "adoXEOF") rename ("DataTypeEnum", "adoXDataTypeEnum ")
    # Import "c:/program files/common files/System/ado/MSJRO. DLL"

    Depending on the installation path of ADO on your computer, the path here may be different.
  3. Declare the database connection ADODB: _ ConnectionPtr m_pConn; and the record set ADODB: _ RecordsetPtr m_pSet; in the document class, And reload the DeleteContents () and OnNewDocument () of the document class () the OnOpenDocument () function is used to disconnect a database, create a database and a table, and open an existing database.
    (The author complained that the CSDN Article center should be changed, so code layout is so troublesome)
    Void CPassportDoc: DeleteContents ()
    {
    Try
    {
    If (m_pSet ){
    ESRecordsetClose (m_pSet );
    }
    If (m_pConn)
    If (m_pConn-> State & ADODB: adStateOpen)
    M_pConn-> Close ();
    M_pConn = NULL;
    }
    Catch (_ com_error & e ){
    ESErrPrintProviderError (m_pConn );
    ESErrPrintComError (e );
    }
    CDocument: DeleteContents ();
    } BOOL CPassportDoc: OnNewDocument ()
    {
    If (! CDocument: OnNewDocument ())
    Return FALSE;
    CFileDialog dlgFile (FALSE, _ T (". mdb "), NULL, OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, _ T (" Access Database (*. mdb) | *. mdb | all files (*. *) | *. * | "));
    If (dlgFile. DoModal ()! = IDOK)
    Return FALSE;
    CString strDBPath = dlgFile. GetPathName ();
    If (! CreateDB (strDBPath) return FALSE;
    // Create
    CString strConnect;

    StrConnect. Format (_ T ("Provider = Microsoft. Jet. OLEDB.4.0; Data Source = % s"), strDBPath );
    COleVariant Connect (strConnect );
    // TODO: add reinitialization code here
    // (SDI documents will reuse this document)
    Try {
    M_pConn.CreateInstance (_ T ("ADODB. Connection "));
    M_pSet.CreateInstance (_ T ("ADODB. Recordset "));
    M_pConn-> PutCommandTimeout (30 );
    M_pConn-> PutConnectionTimeout (30 );
    M_pConn-> put_CursorLocation (ADODB: adUseClient );
    M_pConn-> Open (_ bstr_t (strConnect), _ bstr_t (), _ bstr_t (), ADODB: adConnectUnspecified );
    : ESRecordsetOpen (_ T ("Passport"), m_pConn, m_pSet );
    SetPathName (strDBPath );
    Return TRUE;
    }
    Catch (_ com_error & e ){
    ESErrPrintProviderError (m_pConn );
    ESErrPrintComError (e );
    }
    Catch (...){
    }
    M_pConn = NULL;
    Return FALSE;
    }
    BOOL CPassportDoc: OnOpenDocument (LPCTSTR lpszPathName)
    {
    If (! CDocument: OnOpenDocument (lpszPathName ))
    Return FALSE;
    ADODB: _ ConnectionPtr tempConnn;
    CString strConnect;
    CString strDBPath = lpszPathName;
    StrConnect. Format (_ T ("Provider = Microsoft. Jet. OLEDB.4.0; Data Source = % s"), strDBPath );
    COleVariant Connect (strConnect );
    // TODO: add reinitialization code here
    // (SDI documents will reuse this document)
    Try {
    TempConnn. CreateInstance (_ T ("ADODB. Connection "));
    TempConnn-> PutCommandTimeout (30 );
    TempConnn-> PutConnectionTimeout (30 );
    TempConnn-> put_CursorLocation (ADODB: adUseClient );
    TempConnn-> Open (_ bstr_t (strConnect), _ bstr_t (), _ bstr_t (), ADODB: adConnectUnspecified );
    SetPathName (strDBPath );
    M_pConn = tempConnn;
    M_pSet = NULL;
    M_pSet.CreateInstance (_ T ("ADODB. Recordset "));
    : ESRecordsetOpen (_ T ("Passport"), m_pConn, m_pSet );
    UpdateAllViews (NULL, UpdateHintRefresh );
    Return TRUE;
    }
    Catch (_ com_error & e ){
    ESErrPrintProviderError (tempConnn );
    ESErrPrintComError (e );
    }
    Catch (...){
    }
    Return FALSE;
    }
  4. Compile an auxiliary function for creating databases, tables, and indexes.
    BOOL CPassportDoc: CreateDB (LPCTSTR lpszFile)
    {
    If (: PathFileExists (lpszFile )){
    CString strTemp;
    StrTemp. Format (IDS_TARGET_EXISTS, lpszFile );
    AfxMessageBox (lpszFile );
    Return FALSE;
    }
    ADODB: _ ConnectionPtr tempConnn;
    ADOX: _ CatalogPtr pCatalog = NULL;
    ADOX: _ TablePtr pTable = NULL;
    ADOX: _ IndexPtr pIndexNew = NULL;
    ADOX: _ IndexPtr pIndex = NULL;
    CString strConnect;
    CString strDBPath = lpszFile;
    StrConnect. Format (_ T ("Provider = Microsoft. Jet. OLEDB.4.0; Data Source = % s"), strDBPath );
    COleVariant Connect (strConnect );
    Try {
    PCatalog. CreateInstance (_ T ("ADOX. Catalog "));
    PCatalog-> Create (LPCTSTR) strConnect); // Create a database
    TempConnn. CreateInstance (_ T ("ADODB. Connection "));
    TempConnn-> PutCommandTimeout (30 );
    TempConnn-> PutConnectionTimeout (30 );
    TempConnn-> put_CursorLocation (ADODB: adUseClient );
    TempConnn-> Open (_ bstr_t (strConnect), _ bstr_t (), _ bstr_t (), ADODB: adConnectUnspecified );
    PCatalog-> PutActiveConnection (_ variant_t (IDispatch *) tempConnn ));
    PTable. CreateInstance (_ T ("ADOX. Table "));
    PTable-> ParentCatalog = pCatalog;
    PTable-> Name = "Passport ";
    ADOX: ColumnsPtr pCols = pTable-> Columns;
    PCols-> Append (_ T ("RecordID"), ADOX: adInteger, 0); // automatically numbered field
    PCols-> Append (_ T ("Name"), ADOX: adWChar, 255); // text field
    PCols-> Append (_ T ("DateOfBirth"), ADOX: adDate, 0); // Date Field
    PCols-> Append (_ T ("OtherInfo"), ADOX: adLongVarWChar, 0); // remarks field
    PCatalog-> Tables-> Refresh ();
    Long lCount = pCols-> Count;
    For (long I = 0; I PCols-> GetItem (I)-> ParentCatalog = pCatalog; // important! Set Catalog, see Q201826 PRB: Error 3265 When You Access Properties Collection
    ADOX: PropertiesPtr pProperties = pCols-> GetItem (I)-> Properties;
    If (pProperties) {// here is the property display code for debugging
    Long lp = pProperties-> Count;
    TRACE ("Properties for Col % s/r/n", (LPCTSTR) pCols-> GetItem (I)-> Name );
    For (long j = 0; j TRACE ("/rProperty % s: % s/r/n", g_GetValueString (pProperties-> GetItem (j)-> Name)
    , G_GetValueString (pProperties-> GetItem (j)-> Value ));
    }
    }
    }
    PCols-> GetItem (_ T ("RecordID")-> Properties-> GetItem (_ T ("Description ")) -> Value = _ T ("Record Number"); // comment
    PCols-> GetItem (_ T ("RecordID")-> Properties-> GetItem (_ T ("AutoIncrement")-> Value = true; // automatic ID
    PCols-> GetItem (_ T ("Name")-> Properties-> GetItem (_ T ("Jet OLEDB: Compressed UniCode Strings")-> Value = true;
    PCols-> GetItem (_ T ("Name")-> Properties-> GetItem (_ T ("Description")-> Value = _ T ("Name ");
    PCols-> GetItem (_ T ("DateOfBirth")-> Properties-> GetItem (_ T ("Description ")) -> Value = _ T ("Date of Birth ");
    PCols-> GetItem (_ T ("OtherInfo")-> Properties-> GetItem (_ T ("Jet OLEDB: Compressed UniCode Strings")-> Value = true;
    PCols-> GetItem (_ T ("OtherInfo")-> Properties-> GetItem (_ T ("Description ")) -> Value = _ T ("other information ");
    PCatalog-> Tables-> Append (_ variant_t (IDispatch *) pTable); // Add a table
    PCatalog-> Tables-> Refresh (); // Refresh
    PIndexNew. CreateInstance (_ T ("ADOX. Index "));
    PIndexNew-> Name = "RecordID"; // index Name
    PIndexNew-> Columns-> Append ("RecordID", ADOX: adInteger, 0); // index Field
    PIndexNew-> PutPrimaryKey (-1); // Primary Index
    PIndexNew-> PutUnique (-1); // unique index
    PTable-> Indexes-> Append (_ variant_t (IDispatch *) pIndexNew); // create an index
    PIndexNew = NULL;
    PCatalog-> Tables-> Refresh (); // Refresh
    Return TRUE;
    }
    Catch (_ com_error & e ){
    ESErrPrintProviderError (tempConnn );
    ESErrPrintComError (e );
    Return FALSE;
    }
    Catch (...){
    }
    Return FALSE;
    }
  5. Auxiliary database functions. Because these functions were previously written for a project by Jiangsheng. So the name is a bit strange. Some codes of the MFC class CDaoRecordset are used for reference.
    # Define _ countof (array) (sizeof (array)/sizeof (array [0])
    BOOL ESRecordsetOpen (
    LPCTSTR lpszSQL
    , ADODB: _ ConnectionPtr pConnection
    , ADODB: _ RecordsetPtr & rst
    , ADODB: CursorTypeEnum CursorType // = adOpenDynamic
    , ADODB: LockTypeEnum LockType // = ado20: adLockOptimistic
    , Long lOptions // = adCmdUnspecified
    )
    {
    _ Bstr_t bstrQuery;
    Const TCHAR _ afxParameters2 [] = _ T ("PARAMETERS ");
    Const TCHAR _ afxSelect2 [] = _ T ("SELECT ");
    Const TCHAR _ afxTransform2 [] = _ T ("TRANSFORM ");
    Const TCHAR _ afxTable2 [] = _ T ("TABLE ");
    // Construct the default query string
    If (_ tcsnicmp (lpszSQL, _ afxSelect2, _ countof (_ afxSelect2)-1 )! = 0 )&&
    (_ Tcsnicmp (lpszSQL, _ afxParameters2, _ countof (_ afxParameters2)-1 )! = 0 )&&
    (_ Tcsnicmp (lpszSQL, _ afxTransform2, _ countof (_ afxTransform2)-1 )! = 0 )&&
    (_ Tcsnicmp (lpszSQL, _ afxTable2, _ countof (_ afxTable2)-1 )! = 0 )){
    CString strTemp;
    StrTemp. Format ("SELECT * FROM (% s)", lpszSQL );
    BstrQuery = (LPCTSTR) strTemp;
    }
    Else
    BstrQuery = lpszSQL;
    If (rst! = NULL ){
    Rst-> CursorLocation = ADODB: adUseClient;
    Rst-> Open (bstrQuery, _ variant_t (pConnection. GetInterfacePtr (), true), CursorType, LockType, lOptions );
    }
    TRACE ("Open Recordset: % s/n", lpszSQL );
    Return ESRecordsetIsOpen (rst );
    }
    BOOL ESRecordsetIsOpen (const ADODB: _ RecordsetPtr & rst)
    {
    If (rst! = NULL ){
    Return rst-> State & ADODB: adStateOpen;
    }
    Return FALSE;
    }
    Void ESRecordsetClose (ADODB: _ RecordsetPtr & rst)
    {
    If (rst! = NULL ){
    If (rst-> State & ADODB: adStateOpen)
    Rst-> Close ();
    }
    }
    CString g_GetValueString (const _ variant_t & val)
    {
    CString strVal;
    _ Variant_t varDest (val );
    If (! G_varIsValid (val )){
    Return strVal;
    }
    If (val. vt = VT_BOOL ){
    If (val. boolVal = VARIANT_FALSE ){
    Return _ T ("no ");
    }
    Else
    Return _ T ("yes ");
    }
    Else {
    }
    If (varDest. vt! = VT_BSTR ){
    HRESULT hr =: VariantChangeType (& varDest, & varDest, VARIANT_NOUSEROVERRIDE | VARIANT_LOCALBOOL, VT_BSTR );
    If (FAILED (hr )){
    Return strVal;
    }

    }
    StrVal = (LPCTSTR) _ bstr_t (varDest );
    Return strVal;
    }
  6. Error Handling Code
    Void ESErrPrintComError (_ com_error & e)
    {
    _ Bstr_t bstrSource (e. Source ());
    _ Bstr_t bstrDescription (e. Description ());
    CString strTemp;
    StrTemp. format (_ T ("'error/n/t error code: % 08lx/n/t meaning: % s/n/t from: % s/n/t description: % s/n "),
    E. Error (), e. ErrorMessage (), (LPCSTR) bstrSource, (LPCSTR) bstrDescription );
    // Print COM errors.
    : AfxMessageBox (strTemp );
    # Ifdef _ DEBUG
    AfxDebugBreak ();
    # Endif
    }
    Void ESErrPrintProviderError (ADODB: _ ConnectionPtr pConnection)
    {
    If (pConnection = NULL) return;
    Try {
    // Print Provider Errors from Connection object.
    // PErr is a record object in the Connection's Error collection.
    ADODB: ErrorPtr pErr = NULL;
    ADODB: ErrorsPtr pErrors = pConnection-> Errors;
    If (pErrors ){
    If (pErrors-> Count)> 0 ){
    Long nCount = pErrors-> Count;
    // Collection ranges from 0 to nCount-1.
    For (long I = 0; I <nCount; I ++ ){
    PErr = pErrors-> GetItem (I );
    CString strTemp;
    StrTemp. Format (_ T ("/t error code: % x/t % s"), pErr-> Number, pErr-> Description );
    }
    }
    }
    }
    Catch (_ com_error & e ){
    ESErrPrintComError (e );
    }
    }
Summary

Integration of database access in the document, view, and framework architecture is not difficult in general. Microsoft provides many sample codes. Most of the work is to rewrite the sample code from other languages to VC. The main task is to understand the documentation, views, and framework architecture of MFC and call the code as appropriate.

Although I opened a record set while opening the database, I did not provide the code to display the record set content, which is beyond the scope of this article. The prompt I can give is to Use the ready-made data list Control for display. Microsoft Knowledge Base Article Q229029 SAMPLE: AdoDataGrid.exe Demonstrates How to Use ADO DataGrid Control Using Visual C ++ can be used as a reference.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.