程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 一個完善的ODBC數據庫程序

一個完善的ODBC數據庫程序

編輯:關於VC++

大家知道用VC開發數據庫程序,一般有兩種選擇:ODBC或ADO。ODBC出現的較早,用的人也多。ADO是微軟正大力支持和發展的技術,致力於學習VC的程序員應該現在就學習這種技術。

在這個例字中我還是采用了自己更為熟悉的ODBC。程序的實現有兩個關鍵地方:一、ODBC兩個類的運用。二、LISTCONTROL控件的使用。程序的視圖用CRecordView類,具體配置可以參考源程序。程序的實現主要在視圖文件中完成,實現的功能有:增加記錄、刪除記錄、修改記錄、排序記錄、查尋記錄,並且在控件表格中直觀的顯示。本程序采用的是AECESS數據庫,當然也可采用ORACLE等其它數據庫。整個程序的界面簡潔、直觀(見下圖)。

下面介紹具體步驟:

首先根據數據庫的內容確定表格的樣式,這裡如下設計:

1.在視圖頭文件中給List Control控件加入Contrl 變量 m_ListCtrl。在實現文件的OnInitialUpdate()函數中加入如下語句:

//設表格表題和列的寬度
m_ListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
m_ListCtrl.InsertColumn(0,_T("學號"),LVCFMT_IMAGE|LVCFMT_LEFT);
  m_ListCtrl.InsertColumn(1,_T("姓名"));
  m_ListCtrl.InsertColumn(2,_T("數學"));
  m_ListCtrl.InsertColumn(3,_T("英語"));
int j;
for(j=0;j<4;j++)
  {
   m_ListCtrl.SetColumnWidth(j ,90);
  }
這樣列表題就設置好,同時設置列的寬度。還要特別注意的一點,要在List Control控件的屬性頁Styles中設report屬性。因為程序一運行時,要求所有記錄都顯示出來所以接著增加了一個Show()函數,為了它的重用性,我對它進行了封裝。在後面的程序中大家可以看到它的好處。Show()函數如下:int CLhwyView::Show()
{
  int i=0;
  m_pSet->MoveFirst();
  do
   { 
    CString s;
    s.Format("%d",m_pSet->m_column1);
    m_ListCtrl.InsertItem(i,s,0);
     m_ListCtrl.SetItemText(i,1,m_pSet->m_column2);
    s.Format("%d",m_pSet->m_column3);
     m_ListCtrl.SetItemText(i,2,s);
    s.Format("%d",m_pSet->m_column4);
    m_ListCtrl.SetItemText(i,3,s);
    i++;
    m_pSet->MoveNext();
    
    } while(!m_pSet->IsEOF());
    m_pSet->MoveFirst();
    return i;
}

這樣整個程序初始化的工作就基本完成。因為數據庫中域用的是漢字,所以記錄集中出現了

奇怪的m_column變量。如果用的是英文,就不會出現這種不直觀的現象。這裡m_column1對應數據庫中的學號,m_column2對應數據庫中的姓名,其它依次類推。在數據庫中我把姓名字段的數據類型設為文本,其余設為數字。而List Control控件只顯示文本。所以在顯示以前把不是文本的變量都用Format()函數進行了文本格式化。

2.為了實現程序的基本功能,在視圖上增加了五個按鈕,在視圖實現文件中對按鈕響應。五個函數如下://增加記錄
void CLhwyView::OnAdd()
{
  // TODO: Add your control notification handler code here
  
 CAddDialog dlg;
  if( dlg.DoModal()==IDOK)
   { 
    if(dlg.m_Xuehao==0)
    {
     AfxMessageBox("學號不可為零!");
    }
    else
    {
     m_pSet->AddNew();
     m_pSet->m_column1=dlg.m_Xuehao;
    m_pSet->m_column2=dlg.m_strName;
     m_pSet->m_column3=dlg.m_Maths;
     m_pSet->m_column4=dlg.m_English;
    m_pSet->Update();
     m_pSet->Requery();
     m_pSet->MoveLast();
    CString s;
   s.Format("%d",dlg.m_Xuehao);
   m_ListCtrl.InsertItem(0,s,0);
    m_ListCtrl.SetItemText(0,1,dlg.m_strName);
    s.Format("%d",dlg.m_Maths);
    m_ListCtrl.SetItemText(0,2,s);
    s.Format("%d",dlg.m_English);
    m_ListCtrl.SetItemText(0,3,s);
    }
  } 
    m_pSet->MoveFirst();
}
//刪除記錄
void CLhwyView::OnDelect()
{
  // TODO: Add your control notification handler code here
  CDeleteDialog dlg;
  if(dlg.DoModal()==IDOK)
  {
   if(dlg.m_Password!=1234)
   AfxMessageBox("你沒有權限刪除記錄!請重輸入密碼:");
   else
    { 
     BOOL b=FALSE;
     m_pSet->MoveFirst();
     do
     {
     if(dlg.m_Xuehao!=m_pSet->m_column1)
     m_pSet->MoveNext();
     else
      { 
       m_ListCtrl.DeleteAllItems();
       b=TRUE;
       m_pSet->Delete();
          
       m_pSet->Requery();
       this->Show();
       m_pSet->MoveFirst();
       break;
      }
    }while(!m_pSet->IsEOF());
       
  if(b==FALSE)
  AfxMessageBox("沒有此記錄");
   }
  }
}
//查尋記錄
void CLhwyView::OnFind()
{
  // TODO: Add your control notification handler code here
  BOOL k=FALSE;
  CFindDialog dlg;
  if(dlg.DoModal()==IDOK)
  {
   m_pSet->MoveFirst();
   m_ListCtrl.DeleteAllItems();
   do{
    if(dlg.m_Maths!=m_pSet->m_column3)
    m_pSet->MoveNext();
    else
      {
       k=TRUE;
       CString s;
       s.Format("%d",m_pSet->m_column1);
       m_ListCtrl.InsertItem(0,s);
       m_ListCtrl.SetItemText(0,1,m_pSet->m_column2);
       s.Format("%d",m_pSet->m_column3);
       m_ListCtrl.SetItemText(0,2,s);
       s.Format("%d",m_pSet->m_column3);
       m_ListCtrl.SetItemText(0,3,s); 
       m_pSet->MoveNext();
    }
  } while(!m_pSet->IsEOF());
    
  if(k==FALSE)
  AfxMessageBox("沒有符和條件的記錄");
  }
}
//修改記錄
void CLhwyView::OnEdit()
{
  // TODO: Add your control notification handler code here
 CEditDialog dlg;
 if(dlg.DoModal()==IDOK)
  {
   if(dlg.m_Password!=1234)
   AfxMessageBox("你沒有權限更改記錄!請重輸入密碼:");
   else
     { 
      BOOL b=FALSE;
      m_pSet->MoveFirst();
      do
      {
       if(dlg.m_Xuehao!=m_pSet->m_column1)
       m_pSet->MoveNext();
       else
        {   
        m_ListCtrl.DeleteAllItems();
        m_pSet->Edit();
        b=TRUE;
        m_pSet->m_column1=dlg.m_Xuehao;
        m_pSet->m_column2=dlg.m_strName;
        m_pSet->m_column3=dlg.m_Maths;
        m_pSet->m_column4=dlg.m_English;
        m_pSet->Update();
          
        m_pSet->Requery();
        this->Show();
        m_pSet->MoveFirst();
        break;
        }
      }while(!m_pSet->IsEOF());
       if(b==FALSE)
       AfxMessageBox("沒有此記錄");
    }
  }
  
}
//取全部記錄
void CLhwyView::OnAll()
{
  m_ListCtrl.DeleteAllItems();
  this->Show();
}
//排序記錄
void CLhwyView::OnSort()
{
  m_ListCtrl.DeleteAllItems();
  m_pSet->m_strSort="[學號]";
  m_pSet->Requery();
  this->Show();
}
因為在查尋記錄後,有時需要看所有記錄。所以增加了一個onAll()函數用來顯示所有記錄。在修改記錄和刪除記錄中設置密碼(1234)必需加以確認。這樣整個程序就大致完成。

3.對程序的界面進行了美化,可以參考源程序。

特別說明:

在使用程序前請先使用控制面板中的ODBC配置工具注冊ODBC數據源,選擇Microsoft Access Driver,數據庫選擇源程序目錄lhwy下的student數據庫。程序中對應的代碼看 ClhwySet.cpp如下程序行:

CString CLhwySet::GetDefaultConnect()
{               //注冊說明
  return _T("ODBC;DSN=not"); //在注冊數據源庫時,數據源名取not。當然也可換名,
}               //但程序中的not也換成同樣的名
CString CLhwySet::GetDefaultSQL()
{
  return _T("[fen]");      //表名,選fen表
}

假如您從方便用戶的角度考慮,可以采用在程序中動態創建數據源,請參考VC知識庫中的這篇文章《用Visual C++程序實現設置ODBC數據源 》

最後這個程序還可以有許多可以完善和增強功能的地方。例如可以做一個完善的學生成績管理軟件,增加統計功能,計算個人總成績和平均成績。再增加一個記錄集輔助顯示班級各科目的平均成績、及格率、優秀率等。增強查尋功能(本程序只完成了據數學成績查尋記錄),可以據學號、姓名、科目查尋,也可以查尋及格、優秀的記錄。增強排序功能,按各種情況排序。有興趣的讀者可以完善它。也可以變化一下用在工程項目中,我正在做的一個通訊程序中上位機要存放下面傳來各種信息,並且值班員要不時查尋一些有用的信息,這個程序變化一下用在裡面效果很好。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved