
void CBaDialog::OnFind() {
CFinDialog dlg;
if (dlg.DoModal() == IDOK) {
this->Select(); // 重新 Select 記錄集
m_bSet.Close();
// 建構 Filter 字串
if (dlg.m_Getstring2 == _T(">="))
m_Set.m_strFilter.Format(_T("[%s]>=%.2f"), dlg.m_Getstring1, dlg.m_find);
else if (dlg.m_Getstring2 == _T("="))
m_Set.m_strFilter.Format(_T("[%s]=%.2f"), dlg.m_Getstring1, dlg.m_find);
else if (dlg.m_Getstring2 == _T("<="))
m_Set.m_strFilter.Format(_T("[%s]<=%.2f"), dlg.m_Getstring1, dlg.m_find);
m_ListCtrlx.DeleteAllItems();
m_Set.Requery(); // 套用 Filter 重查
if (m_Set.IsEOF()) {
AfxMessageBox(_T("無符合條件記錄"));
m_Set.Close(); return;
}
this->Show(); // 顯示結果
}
}
void CBaDialog::OnColumnclickList3(NMHDR* pNMHDR, LRESULT* pResult) {
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
if (!m_bS) { // 防重入旗標
int k = pNMListView->iSubItem;
Sort(!m_bIsAsc, k); // 切換升/降序
m_ListCtrlx.DeleteAllItems();
this->Show();
}
*pResult = 0;
}
void CBaDialog::Sort(BOOL isAsc, int secol) {
if (m_Set.IsOpen()) m_Set.Close();
this->Select();
m_bSet.Close();
CODBCFieldInfo fieldInfo;
m_Set.GetODBCFieldInfo(secol, fieldInfo); // 取得欄位名
if (isAsc) {
m_Set.m_strSort = fieldInfo.m_strName + _T(" ASC");
m_bIsAsc = TRUE;
} else {
m_Set.m_strSort = fieldInfo.m_strName + _T(" DESC");
m_bIsAsc = FALSE;
}
m_Set.Requery(); // 套用 Sort 重查
}
關鍵技術:MFC `CRecordset` 的 `m_strFilter`/`m_strSort` 配合 `Requery()` 實現無需重新 Open 的動態篩選/排序。
void CNaDilalog::OnAll() {
if (m_Set.IsOpen()) m_Set.Close();
m_ListCtrlx.DeleteAllItems();
m_Set.m_strFilter.Empty();
m_Set.Open();
m_nRecordCount = this->Show(); // 顯示第一個表
m_Set.Open(AFX_DB_USE_DEFAULT_TYPE, _T("[NO2STUDENT]")); // 切換第二個表
m_nRecordCount += this->Show(); // 累加顯示
CString s; s.Format(_T("%d"), m_nRecordCount);
GetDlgItem(IDC_STATICALL)->SetWindowText(s);
GetDlgItem(IDC_SHOW)->EnableWindow(TRUE);
}
int CNaDilalog::Show() {
int k = 0;
do {
CString s;
s.Format(_T("%d"), m_Set.m_column1); m_ListCtrlx.InsertItem(k, s, 0);
m_ListCtrlx.SetItemText(k, 1, m_Set.m_column2);
s.Format(_T("%.1f"), m_Set.m_column3); m_ListCtrlx.SetItemText(k, 2, s);
s.Format(_T("%.1f"), m_Set.m_column4); m_ListCtrlx.SetItemText(k, 3, s);
s.Format(_T("%.1f"), m_Set.m_column5); m_ListCtrlx.SetItemText(k, 4, s);
s.Format(_T("%.1f"), m_Set.m_column6); m_ListCtrlx.SetItemText(k, 5, s);
s.Format(_T("%.1f"), m_Set.m_column7); m_ListCtrlx.SetItemText(k, 6, s);
s.Format(_T("%.1f"), m_Set.m_column8); m_ListCtrlx.SetItemText(k, 7, s);
s.Format(_T("%.2f"), m_Set.m_column9); m_ListCtrlx.SetItemText(k, 8, s);
k++; m_Set.MoveNext();
} while (!m_Set.IsEOF());
m_Set.Close(); return k;
}
void CNaDilalog::OnShow() {
m_ListCtrlj.DeleteAllItems();
m_bSet.Open(); int i=0;
m_bSet.MoveFirst();
do {
m_ListCtrlj.InsertItem(i, m_bSet.m_column1, 0); i++;
m_bSet.MoveNext();
} while (!m_bSet.IsEOF());
m_bSet.MoveFirst();
for (i=0; i<=4; i++) { // 累加各科總分
score[i][1] = m_bSet.m_column2;
score[i][3] = (float)m_bSet.m_column4;
score[i][4] = (float)m_bSet.m_column5;
if (i!=4) m_bSet.MoveNext();
}
m_bSet.Close();
m_bSet.Open(AFX_DB_USE_DEFAULT_TYPE, _T("[NO2OBJECT]")); // 另一張表
for (i=0; i<5; i++) {
score[i][1] += m_bSet.m_column2;
score[i][2] = score[i][1] / m_nRecordCount; // 平均
score[i][3] += (float)m_bSet.m_column4;
score[i][4] += (float)m_bSet.m_column5;
if (!m_bSet.IsEOF()) m_bSet.MoveNext();
}
m_bSet.Close();
// 寫入 ListCtrl
for (i=0; i<5; i++) {
CString s;
s.Format(_T("%.1f"), score[i][1]); m_ListCtrlj.SetItemText(i, 1, s);
s.Format(_T("%.2f"), score[i][2]); m_ListCtrlj.SetItemText(i, 2, s);
s.Format(_T("%d"), (int)score[i][3]); m_ListCtrlj.SetItemText(i, 3, s);
s.Format(_T("%d"), (int)score[i][4]); m_ListCtrlj.SetItemText(i, 4, s);
}
}
| 項目 | 現狀 | 建議改進 |
|---|---|---|
| 資料源註冊 | 程式啟動時寫入登錄表 | 啟動前檢查是否已存在,避免重複/損壞登錄 |
| 刪除確認 | ListCtrl 選取後直接刪除 | 加入密碼驗證/權限控制 |
| 修改流程 | 選取後彈出對話框 | 可改為就地編輯 |
| 匯出/列印 | 無 | 加入 CSV/Excel 匯出、報表列印 |
| 可擴充性 | 固定兩班、固定欄位 | 抽象可重用基類,支援動態增班/增科目 |
| 程式碼品質 | 層次不清、優化不足 | 分層架構、單元測試、重構 |