Ok,
here is my environment:
1 - I have Crysta Reports 9 runtime installed under C:\Programmi\Crystal Decisions\Report Designer Component
2 - I have a rpt file created with Crystal Reports 8
3 - I have an MFC application made in VC++ 6
4 - I access crystal with this class:
// Crw9Wrapper.h
// Interface for the class CCrw9Wrapper
#pragma once
#import "C:\Programmi\Crystal Decisions\Report Designer Component\craxdrt9.dll"
class CCrw9Wrapper
{
public:
CCrw9Wrapper();
~CCrw9Wrapper();
private:
CRAXDRT::IApplicationPtr m_pApplication;
CRAXDRT::IReportPtr m_pReport;
public:
BOOL OpenReport(CString ReportName);
BOOL SetConnection(CString Server, CString DBName, CString UserID, CString Passwo);
BOOL SetTableLocation(CString Name, CString Location);
BOOL SetSelectionFormula(CString SelFormula);
BOOL SetFormulaValue(CString Name, CString Value);
BOOL AddSortField(CString FieldName, bool ascending = true);
BOOL SetSQLQuery(CString Query);
BOOL ExportPDF(CString DocumentName);
protected:
void DumpCOMError(_com_error &e);
};
// Crw9Wrapper.cpp
// Implementation for the class: CCrw9Wrapper
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions (including VB)
#include <afxdb.h> // MFC database classes
#include <atlbase.h>
#include <atldbcli.h>
#include <process.h>
#include <comdef.h>
#include "Crw9Wrapper.h"
using namespace CRAXDRT;
CCrw9Wrapper::CCrw9Wrapper(){}
CCrw9Wrapper::~CCrw9Wrapper()
{
try
{
if(m_pReport.GetInterfacePtr())
{
m_pReport.Release();
}
if(m_pApplication.GetInterfacePtr())
{
m_pApplication.Release();
}
}
catch(_com_error &e)
{
DumpCOMError(e);
}
}
BOOL CCrw9Wrapper::OpenReport(CString ReportName)
{
try
{
if(!m_pApplication.GetInterfacePtr())
{
m_pApplication.CreateInstance("CrystalRuntime.Application");
}
_bstr_t FileName(ReportName);
m_pReport = m_pApplication->OpenReport(FileName);
}
catch(_com_error &e)
{
DumpCOMError(e);
return FALSE;
}
return TRUE;
}
BOOL CCrw9Wrapper::SetConnection(CString Server, CString DBName, CString UserID, CString Passwo)
{
try
{
long TableCount = m_pReport->Database->Tables->Count;
long i, j;
// Collego le tabelle del report
for(i = 1; i <= TableCount; i++)
{
CString loc = (TCHAR*)m_pReport->Database->Tables->Item[i ]->Name;
if(loc.Find("__") < 0)
m_pReport->Database->Tables->GetItem(i)->SetLogOnInfo((LPCTSTR)Server, (LPCTSTR)DBName, (LPCTSTR)UserID, (LPCTSTR)Passwo);
else
m_pReport->Database->Tables->GetItem(i)->SetLogOnInfo((LPCTSTR)Server, "tempdb", (LPCTSTR)UserID, (LPCTSTR)Passwo);
}
// Collego le tabelle dei sottoreport
CRAXDRT::IReportObjectPtr pRepObject = NULL;
CRAXDRT::IReportPtr pSubreport = NULL;
for(i = 1; i <= m_pReport->GetSections()->GetCount(); i++) // CICLO PER LE SEZIONI DEL REPORT
{
if(!m_pReport->GetSections()->GetItem(i)->GetReportObjects()->GetCount() == 0)
{
for(j = 1; j <= m_pReport->GetSections()->GetItem(i)->GetReportObjects()->GetCount(); j++)
{
pRepObject = m_pReport->GetSections()->GetItem(i)->GetReportObjects()->GetItem(j);
if(pRepObject->GetKind() == crSubreportObject)
{
pSubreport = ((ISubreportObjectPtr)pRepObject)->OpenSubreport();
TableCount = pSubreport->Database->Tables->Count;
for(long tn = 1; tn <= TableCount; tn++)
{
CString loc = (TCHAR*)pSubreport->Database->Tables->Item[(i)]->Name;
if(loc.Find("__") < 0)
pSubreport->Database->Tables->GetItem(i)->SetLogOnInfo((LPCTSTR)Server, (LPCTSTR)DBName, (LPCTSTR)UserID, (LPCTSTR)Passwo);
else
pSubreport->Database->Tables->GetItem(i)->SetLogOnInfo((LPCTSTR)Server, "tempdb", (LPCTSTR)UserID, (LPCTSTR)Passwo);
}
}
}
}
}
if(pSubreport != NULL) pSubreport.Release();
if(pRepObject != NULL) pRepObject.Release();
}
catch(_com_error &e)
{
DumpCOMError(e);
return FALSE;
}
return TRUE;
}
BOOL CCrw9Wrapper::SetSelectionFormula(CString SelFormula)
{
try
{
m_pReport->PutRecordSelectionFormula((LPCTSTR)SelFormula);
}
catch(_com_error &e)
{
DumpCOMError(e);
return FALSE;
}
return TRUE;
}
BOOL CCrw9Wrapper::SetFormulaValue(CString Name, CString Value)
{
try
{
m_pReport->FormulaFields->GetItemByName((LPCTSTR)Name)->PutText((LPCTSTR)Value);
}
catch(_com_error &e)
{
DumpCOMError(e);
return FALSE;
}
return TRUE;
}
BOOL CCrw9Wrapper::SetTableLocation(CString Name, CString Location)
{
try
{
long i, count;
_bstr_t name((LPCTSTR)Name);
count = m_pReport->Database->Tables->Count;
for(i = 1; i <= count; i++)
{
if(m_pReport->Database->Tables->Item[(i)]->Name == name)
{
m_pReport->Database->Tables->Item[(i)]->Location = (LPCTSTR)Location;
break;
}
}
}
catch(_com_error &e)
{
DumpCOMError(e);
return FALSE;
}
return TRUE;
}
BOOL CCrw9Wrapper::SetSQLQuery(CString Query)
{
try
{
//m_pReport->put_SQLQueryString(_bstr_t((LPCTSTR)Query));
m_pReport->PutSQLQueryString(_bstr_t((LPCTSTR)Query));
}
catch(_com_error &e)
{
DumpCOMError(e);
return FALSE;
}
return TRUE;
}
BOOL CCrw9Wrapper::AddSortField(CString FieldName, bool ascending)
{
try
{
CRAXDRT::IDatabaseFieldDefinitionPtr pDbFieldDef;
pDbFieldDef = m_pReport->Database->Tables->GetItem(1)->Fields->GetItemByName((LPCTSTR)FieldName);
m_pReport->RecordSortFields->Add((IFieldDefinitionPtr)pDbFieldDef, ascending ? crAscendingOrder : crDescendingOrder);
}
catch(_com_error &e)
{
DumpCOMError(e);
return FALSE;
}
return TRUE;
}
BOOL CCrw9Wrapper::ExportPDF(CString DocumentName)
{
try
{
m_pReport->ExportOptions->DiskFileName = (LPCTSTR)DocumentName;
m_pReport->ExportOptions->DestinationType = crEDTDiskFile;
m_pReport->ExportOptions->FormatType = crEFTPortableDocFormat;
m_pReport->Export(false);
}
catch(_com_error &e)
{
DumpCOMError(e);
return FALSE;
}
return TRUE;
}
void CCrw9Wrapper::DumpCOMError(_com_error &e)
{
CString Titolo;
CString strMsg;
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
Titolo.Format("Attenzione: Errore 0x%08lX", e.Error());
strMsg.Format(
"Errore:\n\t%s\n"
"Fonte:\n\t%s\n"
"Dettagli:\n\t%s",
e.ErrorMessage(),
(LPCSTR)bstrSource,
(LPCSTR)bstrDescription
);
MessageBox(GetFocus(), strMsg, Titolo, MB_ICONSTOP);
}
Now here is what I do: my report is based on an SQL Server OLEDB connection and uses a single temporary table named ##FORNITO_PDD.
The report is perfectly verifyed and runs OK.
Then in my application I create a table PERFECTLY identical to ##FORNITO_PDD but named ##FORNITO_PDD_USERNAME.
Then I run this code:
CCrw9Wrapper crw;
CString stringa = "myreport.rpt";
if(!crw.OpenReport(stringa))
return;
if(!crw.SetConnection(Server, DBName, UserID, Passwo))
return;
stringa.Format(
"SELECT "
"__FORNITO_PDD.\"TITOLO_INFORETE\", "
"__FORNITO_PDD.\"SOTTOTITOLO\", "
"__FORNITO_PDD.\"CD_INFORETE\", "
"__FORNITO_PDD.\"ADD_ON\", "
"__FORNITO_PDD.\"PREZZO\", "
"__FORNITO_PDD.\"QUANTITA_ORDINATA\", "
"__FORNITO_PDD.\"ANNO_ESTRATTO_CONTO\", "
"__FORNITO_PDD.\"MESE_ESTRATTO_CONTO\", "
"__FORNITO_PDD.\"COPIE_PACCO\", "
"__FORNITO_PDD.\"NOTE_DIFF\", "
"__FORNITO_PDD.\"MULTIPLO\", "
"__FORNITO_PDD.\"PUNTO_DISTRIBUZIONE_ID\", "
"__FORNITO_PDD.\"LOCALITA\", "
"__FORNITO_PDD.\"DS_PDD\", "
"__FORNITO_PDD.\"DATA_USCITA_NAZIONALE\", "
"__FORNITO_PDD.\"DATA_USCITA_ROMA\", "
"__FORNITO_PDD.\"PERC_DL\", "
"__FORNITO_PDD.\"PERIODICITA\", "
"__FORNITO_PDD.\"STATO_ORD\" "
"FROM "
"\"##FORNITO_PDD_%s\" __FORNITO_PDD ",
szComputerName
);
if(!crw.SetSQLQuery(stringa))
return;
if(!crw.AddSortField("PUNTO_DISTRIBUZIONE_ID"))
return;
docname = "C:\mydoc.pdf";
if(!crw.ExportPDF(docname))
return;
What I get is:
Sometimes it works perfectly
sometimes SetSQLQuery dumps:
Attenzione: Errore 0x80043AE5
--------
Errore:
IDispatch error #14565
Fonte:
Crystal Reports ActiveX Designer
Dettagli:
TSLV Record Not Found.
I also noticed that as long as I work in debug mode the thing works.
When I use the release executable to access the report (the same report file) I get the error.
Then the debug version starts to give problems even if I use a backup copy of the report file.
Is there a solution to all this or I have to surrender saying: "OK, Crystal Reports demonstrated once again to be the f****d s**t thas is, I must find another way."
Please help, I don't have any clue.
Thanx
AndreaOk, I added this thing after the SetConnection method call:
stringa.Format("##FORNITO_PDD_%s", szComputerName);
if(!crw.SetTableLocation("__FORNITO_PDD", stringa))
return;
now it always work with my debug executable.
But when in release I continue getting:
--------
Attenzione: Errore 0x80047E44
--------
Errore:
IDispatch error #31812
Fonte:
Crystal Reports ActiveX Designer
Dettagli:
The table '##FORNITO_PDD_ROSSINI' could not be found.
No comments:
Post a Comment