水晶報表 是企業級報表工具標準。VC++ 透過 `#import` 匯入其 Type Library(`craxdrt9.dll` / `craxddrt9.dll`),以 COM 智慧指標操作報表引擎:開啟 `.rpt` 範本、設定資料庫登入、動態指定 SQL 查詢/篩選公式、指派給 `CCrystalReportViewer9` 控制項預覽列印。本文提供最小完整整合範例,適用 Crystal Reports 9 / 10 / XI(DLL 名稱調整即可)。
// 根據實際安裝路徑調整
#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()); }
}
不依賴 `.rpt` 檔,完全以代碼建立 `IReport`、加入 `Sections`、`FieldObjects`、`Database`、`Tables`、`SQL`,適合高度動態報表需求,但代碼量大,建議配合報表設計器預先設計版面再動態注入資料。
VC++ 整合水晶報表核心流程:`#import` → `CreateInstance` → `OpenReport` → `SetLogOnInfo` → `SQLQueryString`/`RecordSelectionFormula` → `Viewer.SetReportSource` → `ViewReport`。掌握 COM 智慧指標錯誤處理(`try/catch(_com_error)`)、資料庫逐表登入、動態 SQL/公式注入,即可在 MFC 應用中嵌入專業級報表列印/預覽/匯出功能。