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

VC++ 6.0 整合水晶報表 9:COM 介面動態載入報表、設定資料庫連線、SQL 查詢、列印

     編輯:VC 教學

前言

水晶報表 是企業級報表工具標準。VC++ 透過 `#import` 匯入其 Type Library(`craxdrt9.dll` / `craxddrt9.dll`),以 COM 智慧指標操作報表引擎:開啟 `.rpt` 範本、設定資料庫登入、動態指定 SQL 查詢/篩選公式、指派給 `CCrystalReportViewer9` 控制項預覽列印。本文提供最小完整整合範例,適用 Crystal Reports 9 / 10 / XI(DLL 名稱調整即可)。

一、環境準備與 #import


// 根據實際安裝路徑調整
#import "C:\\Program Files\\Common Files\\Crystal Decisions\\2.5\\bin\\craxdrt9.dll" no_namespace rename("Copy", "CRCopy")
#import "C:\\Program Files\\Common Files\\Crystal Decisions\\2.5\\bin\\craxddrt9.dll" no_namespace rename("Copy", "CRCopy")

// 對話方塊加入 ActiveX 控制項:Crystal Report Viewer Control 9
// ClassWizard 關聯變數:CCrystalReportViewer9 m_viewer;

二、核心介面指標宣告


// 應用程式類別或對話方塊類別成員
IApplicationPtr m_pApp;      // 報表應用程式物件
IReportPtr m_pReport;        // 報表文件物件

三、初始化與開啟報表


BOOL CReportDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    try
    {
        // 1. 建立 Application 物件
        m_pApp.CreateInstance(__uuidof(Application));

        // 2. 開啟 .rpt 範本檔案
        _bstr_t bstrPath = _T("D:\\Reports\\Staff.rpt");
        m_pReport = m_pApp->OpenReport(bstrPath);

        // 3. 設定報表標題、作者
        m_pReport->put_ReportTitle(_bstr_t("員工名冊"));
        m_pReport->put_ReportAuthor(_bstr_t("資訊部"));

        // 4. 設定資料庫連線登入(每個 Table 皆需設定)
        // 假設報表只有一個主 Table (Index 1)
        m_pReport->Database->Tables->Item[1]->SetLogOnInfo(
            _bstr_t("(local)"),   // Server
            _bstr_t("StaffDB"),   // Database
            _bstr_t("sa"),        // User
            _bstr_t("password")   // Password
        );

        // 5. 動態指定 SQL 查詢(覆蓋範本內預設 SQL)
        m_pReport->put_SQLQueryString(_bstr_t("SELECT * FROM Employee WHERE DeptID=10 ORDER BY EmpID"));

        // 6. 或使用篩選公式(Crystal Syntax)
        m_pReport->PutRecordSelectionFormula(_bstr_t("{Employee.DeptID}=10 AND {Employee.Status}='Active'"));

        // 7. 不顯示重複記錄
        m_pReport->PutEnableSelectDistinctRecords(VARIANT_TRUE);

        // 8. 綁定給 Viewer 控制項
        m_viewer.SetReportSource(m_pReport);
        m_viewer.SetDisplayToolbar(TRUE);
        m_viewer.SetDisplayGroupTree(FALSE);
        m_viewer.SetDisplayBorder(FALSE);

        // 9. 重新整理並顯示
        m_viewer.Refresh();
        m_viewer.ViewReport();
    }
    catch (_com_error& e)
    {
        CString msg; msg.Format(_T("水晶報表錯誤: %s"), e.ErrorMessage());
        AfxMessageBox(msg);
    }
    return TRUE;
}

四、列印與匯出


void CReportDlg::OnBtnPrint()
{
    try
    {
        // 直接列印到預設印表機
        m_pReport->PrintOut(FALSE, 0, 0); // bPrompt=FALSE, nCopies=0(預設), nCollate=0
    }
    catch (_com_error& e) { AfxMessageBox(e.ErrorMessage()); }
}

void CReportDlg::OnBtnExportPdf()
{
    try
    {
        // 匯出 PDF 需使用 ExportOptions
        IExportOptionsPtr pExp = m_pReport->ExportOptions;
        pExp->put_ExportDestinationType(crEDTDiskFile);
        pExp->put_ExportFormatType(crEFTPortableDocFormat);
        pExp->put_DiskFileName(_bstr_t("D:\\Output\\Staff.pdf"));
        m_pReport->Export(FALSE); // FALSE=不顯示對話框
        AfxMessageBox(_T("PDF 匯出完成"));
    }
    catch (_com_error& e) { AfxMessageBox(e.ErrorMessage()); }
}

五、常見問題與解決

  • DLL 版本不符:`#import` 路徑必須指向正確版本的 `craxdrt.dll`。CR9=9.dll, CR10=10.dll, XI=11.dll。
  • 資料庫登入失敗:報表中每個 Table(含子報表)皆需呼叫 `SetLogOnInfo`。用 `Tables->GetCount()` 迴圈逐一設定。
  • 中文路徑/欄位名:使用 `_bstr_t` 自動處理 Unicode 轉換,確保專案設定為 Unicode 字元集。
  • Viewer 控制項不顯示:確認 `CCrystalReportViewer9` 已正確子類化(`DDX_Control`),且 `SetReportSource` 在 `OnInitDialog` 之後呼叫。
  • 部署機器無 Crystal Runtime:需安裝 Crystal Reports Runtime (合併模組 `.msm` 或獨立安裝程式)。

六、進階:完全無檔案動態建立報表

不依賴 `.rpt` 檔,完全以代碼建立 `IReport`、加入 `Sections`、`FieldObjects`、`Database`、`Tables`、`SQL`,適合高度動態報表需求,但代碼量大,建議配合報表設計器預先設計版面再動態注入資料。

七、結語

VC++ 整合水晶報表核心流程:`#import` → `CreateInstance` → `OpenReport` → `SetLogOnInfo` → `SQLQueryString`/`RecordSelectionFormula` → `Viewer.SetReportSource` → `ViewReport`。掌握 COM 智慧指標錯誤處理(`try/catch(_com_error)`)、資料庫逐表登入、動態 SQL/公式注入,即可在 MFC 應用中嵌入專業級報表列印/預覽/匯出功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved