首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

ODBC 版學生成績管理系統:多記錄集、動態查詢、列表排序與統計分析

     編輯:關於VC++

系統架構與介面

系統介面

  • **對話框 + 屬性頁**:「班級成績」/「年級成績」兩大功能區
  • **一資料庫、六資料表**:每班三表 (學生成績、科目成績、任課老師)
  • **三記錄集類**:對應三類表,透過 `m_strFilter`/`m_strSort` 切換班級

班級成績頁核心功能

1. 多條件動態查詢 (OnFind)

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(); // 顯示結果
    }
}

2. 點擊欄標排序 (OnColumnclickList3)

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 的動態篩選/排序。

年級成績頁:統計分析

1. 全部記錄匯總 (OnAll)

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);
}

2. 顯示邏輯 (Show)

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;
}

3. 科目統計顯示 (OnShow)

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 匯出、報表列印
可擴充性固定兩班、固定欄位抽象可重用基類,支援動態增班/增科目
程式碼品質層次不清、優化不足分層架構、單元測試、重構
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved