大家知道用VC開發數據庫程序,一般有兩種選擇:ODBC或ADO。ODBC出現的較早,用的人也多。ADO是微軟正大力支持和發展的技術,致力於學習VC的程序員應該現在就學習這種技術。
在這個例字中我還是采用了自己更為熟悉的ODBC。程序的實現有兩個關鍵地方:一、ODBC兩個類的運用。二、LISTCONTROL控件的使用。程序的視圖用CRecordView類,具體配置可以參考源程序。程序的實現主要在視圖文件中完成,實現的功能有:增加記錄、刪除記錄、修改記錄、排序記錄、查尋記錄,並且在控件表格中直觀的顯示。本程序采用的是AECESS數據庫,當然也可采用ORACLE等其它數據庫。整個程序的界面簡潔、直觀(見下圖)。
下面介紹具體步驟:
首先根據數據庫的內容確定表格的樣式,這裡如下設計:
1.在視圖頭文件中給List Control控件加入Contrl 變量 m_ListCtrl。在實現文件的OnInitialUpdate()函數中加入如下語句:
//設表格表題和列的寬度
這樣列表題就設置好,同時設置列的寬度。還要特別注意的一點,要在List Control控件的屬性頁Styles中設report屬性。因為程序一運行時,要求所有記錄都顯示出來所以接著增加了一個Show()函數,為了它的重用性,我對它進行了封裝。在後面的程序中大家可以看到它的好處。Show()函數如下:
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);
}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.為了實現程序的基本功能,在視圖上增加了五個按鈕,在視圖實現文件中對按鈕響應。五個函數如下://增加記錄
因為在查尋記錄後,有時需要看所有記錄。所以增加了一個onAll()函數用來顯示所有記錄。在修改記錄和刪除記錄中設置密碼(1234)必需加以確認。這樣整個程序就大致完成。
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();
}
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數據源 》
最後這個程序還可以有許多可以完善和增強功能的地方。例如可以做一個完善的學生成績管理軟件,增加統計功能,計算個人總成績和平均成績。再增加一個記錄集輔助顯示班級各科目的平均成績、及格率、優秀率等。增強查尋功能(本程序只完成了據數學成績查尋記錄),可以據學號、姓名、科目查尋,也可以查尋及格、優秀的記錄。增強排序功能,按各種情況排序。有興趣的讀者可以完善它。也可以變化一下用在工程項目中,我正在做的一個通訊程序中上位機要存放下面傳來各種信息,並且值班員要不時查尋一些有用的信息,這個程序變化一下用在裡面效果很好。