|
Обсуждение вопросов, связанных с Crystal Reports 2008, Crystal Reports Server, Crystal Xcelsius, BusinessObjects Enterprise, BusinessObjects Edge и другими продуктами Business Objects.
Тема "Использование CR в VС++.net"
Автор:
Denis
|
Дата: 30.07.2006 22:56 |
| Oleg пишет 27.07.2006 20:20: >Дайте, плиз, пример как подключить report1.rpt в код VС++. > Отчёты Crystal Reports для Visual C++ 6
Автор: Илья Гуня Недавно я начал писать один небольшой проект на VC с отчетом Crystal Reports 8 и столкнулся со следующей проблемой: я не знал, как написать отчет. После поиска материалов на эту тему в интернете, у меня сложилось впечатление, что перед разработчиками на VC не стоит проблема создания отчетов. На CodeGuru в разделе Databases я не нашел ни одного материала на эту тему. Пришлось копать эту тему самому. К сожалению, у меня оказался только один пример, в котором довольно сложный отчет полностью создаётся в run-time без использования редактора отчетов. Это автоматически означало, что мне нужно будет изучить несколько десятков, а то и сотен килобайт текста, прежде чем я выдам первый отчет. Времени на это у меня не было. Поэтому для создания отчета я воспользовался следующей технологией, которая и описывается ниже.
Для выполнения этого проекта необходимо:
Visual C++ 6 Crystal Reports 8 Приступим.
Для начала, создадим наш отчет. Запускаем Crystal Report Designer. Создаем blank report. Добавляем ODBC connection, указывающее, на пример, на БД pubs на вашем SQL сервере, или на какую-нибудь таблицу в mdb-файле. Выбираем таблицу pubs.dbo.authors, давим add кнопку, закрываем окно. В появившемся окне дизайнера отчетов перетаскиваем в область Details нужные поля: au_id, au_fname, au_lname. Сохраняем отчёт.
Создаём простой Dialog-based проект со всеми настройками по умолчанию. В меню Projects->Add to project->Components and controls добавляем Crystal Report Viewer Control. В окне Confirm classes давим OK. Закрываем окно Components and controls. Добавляем Crystal Report Viewer Control на диалог. В окне ClassWizard для диалога добавляем обработчик WM_SHOWWINDOW. At the Member variables tab добавляем переменную m_CRView1. В начало файла SampRepDlg.cpp добавляем строки
#import <craxdrt.tlb> no_namespace #import <msado15.dll> rename ("EOF", "adoEOF")
(подразумевается, что файл craxdrt.tlb находится в одной из стандартных папок для include. Изначально он находится в каталоге C:\Program Files\Seagate Software\Crystal Reports\Developer Files\include\)
так же добавляем следующие строки в начале файла RepSampDlg.cpp
const CLSID CLSID_Application = {0xb4741fd0,0x45a6,0x11d1,{0xab,0xec,0x00,0xa0,0xc9,0x27,0x4b,0x91}}; const IID IID_IApplication = {0x0bac5cf2,0x44c9,0x11d1,{0xab,0xec,0x00,0xa0,0xc9,0x27,0x4b,0x91}};
const CLSID CLSID_ReportObjects = {0xb4741e60,0x45a6,0x11d1,{0xab,0xec,0x00,0xa0,0xc9,0x27,0x4b,0x91}}; const IID IID_IReportObjects = {0x0bac59b2,0x44c9,0x11d1,{0xab,0xec,0x00,0xa0,0xc9,0x27,0x4b,0x91}};
Переходим к обработчику CRepSampDlg::OnShowWindow. Я обычно создаю стандартное окружение для работы с COM-объектами:
try{ } catch(const _com_error& e) { _bstr_t bstrSource(e.Source()); _bstr_t bstrDescription(e.Description()); CString strError; strError.Format("_com_error catched at CRepSampDlg::OnShowWindow\n" "Source : %s\nDescription : %s", (LPCSTR)bstrSource,(LPCSTR)bstrDescription); AfxMessageBox(strError); } В try-блоке присоединяем наш файл отчета:
HRESULT hr=S_OK; IApplicationPtr pApp; IReportPtr pRep; hr=CoCreateInstance(CLSID_Application, NULL, CLSCTX_INPROC_SERVER , IID_IApplication, (void **) &pApp); if(FAILED(hr)) _com_issue_error(hr); pRep = pApp->OpenReport(_bstr_t("d:\\projects\\RepSamp\\Report1.rpt")); m_CRView1.SetReportSource(pRep); m_CRView1.ViewReport(); Собираем проект, и запускаем. Появится отчет, который в качестве источника данных использует свои настройки по умолчанию. Теперь давайте подставим ему в качестве источника данных необходимый нам Recordset. Я предпочитаю ADO. Следующий код я добавил сразу после строки "HRESULT hr=S_OK;" :
ADODB::_ConnectionPtr pConn; pConn.CreateInstance(__uuidof(ADODB::Connection)); if(FAILED(hr)) _com_issue_error(hr); CString sConnStr("Provider=SQLOLEDB.1;" "Integrated Security=SSPI;Persist Security Info= False;" "Initial Catalog= pubs;Data Source= DATACENTER"); hr= pConn->Open(_bstr_t(sConnStr),_bstr_t(L""), _bstr_t(L""), ADODB::adConnectUnspecified); if(FAILED(hr)) _com_issue_error(hr); ADODB::_RecordsetPtr pRs; pRs.CreateInstance(__uuidof(ADODB::Recordset)); CString sSQL("SELECT * FROM authors"); pRs->Open(_bstr_t(sSQL), pConn.GetInterfacePtr(), ADODB::adOpenDynamic, ADODB::adLockOptimistic,ADODB::adCmdText); if(FAILED(hr)) _com_issue_error(hr); теперь запихиваем наш recordset в отчет:
IApplicationPtr pApp; IReportPtr pRep; hr=CoCreateInstance(CLSID_Application, NULL, CLSCTX_INPROC_SERVER , IID_IApplication, (void **) &pApp); if(FAILED(hr)) _com_issue_error(hr); pRep=pApp->OpenReport(_bstr_t("d:\\proj\\SampRep\\Report1.rpt")); m_CRView1.SetReportSource(pRep); IDatabasePtr pDatabase = 0; IDatabaseTablesPtr pTables = 0; IDatabaseTablePtr pTable = 0; pRep->get_Database((IDatabase**) &pDatabase); pDatabase->get_Tables((IDatabaseTables**) &pTables); VARIANT var, var2; VariantInit(&var); VariantInit(&var2); var.vt = VT_DISPATCH; var.pdispVal = (IDispatch*)pConn; var2.vt = VT_DISPATCH; var2.pdispVal = (IDispatch*)pRs->GetActiveCommand(); hr = pDatabase->AddADOCommand(var, var2); ASSERT(SUCCEEDED(hr)); собираем проект. Всё готово. |
Ответить на сообщение » |
|