Friday, February 24, 2012

Help with: "TSLV Record Not Found."

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