Vsual C++ - MFC App and Crystal Report

domenica 11 marzo 2007 - 23.38

dancur21 Profilo | Newbie

Salve,
premesso che ho una buona esperienza in applicazioni MFC ma è la prima volta che mi trovo a dover utilizare Crystal Report, e in quetso ambito non posso passare a linguaggi (es. C# o VB).

Ho problemi nell'utilizzare i controlli ActiveX di CR, ho cercato qualche tutorial o informazioni utili ma non ne ho trovate.. qualcuno ha qualche progetto d'esempio o può guidarmi nei passi base necessari per utilizzare nel migliore dei modi questi componenti?

Finora sono riuscito a visualizzare il report nel Viewer (creando una classe Wrapper per il Viewer), ma non riesco:
- ad impostare il filtro sui dati tramite il metodo "put_SelectionFormula" (non da errore ma non funziona);
- cambiare la datasource del report e far utilizzare un Recordset diverso (es. come un Dataset creato a Runtime).

P.S. Sottolineo ancora la necessità di implementare il tutto all'interno di una Applicazione MFC in Visual C++ (Visual Studio 2005).

Vi prego ho un grande bisogno di trovare una soluzione al più presto possibile!!
Ringrazio in anticipo per la disponibilità e per gli aiuti.

freeteo Profilo | Guru

ciao,
sinceramente in c++ non ci lavoro quindi non saprei aiutarti, pero' ho fatto qualcosa in vb6 che usa l'ocx di crystal e i riferimenti alla "craxdrt.dll" che è il cuore del motore di report.

Quindi ti do il codice che usavo io al tempo:
Dim mioReport As CRAXDRT.report Dim miaApp As CRAXDRT.Application Dim mioRs As New RecordSet Set miaApp = New CRAXDRT.Application Set mioReport = miaApp.OpenReport("c:\..\report.rpt") Set CaricaReport = mioReport ...riempi il recordset... mioReport.Database.SetDataSource mioRs CRViewer1.ReportSource = mioReport CRViewer1.ViewReport

Ma probabilmente fin qua ci sei gia' arrivato.
Per quanto riguarda la selecionFormula, devi ricordarti di costruirla come stringa pari a quella che vedi nell'editor della formula a design time, compreso di parentesi "{" prima del campo ed eventuali funzioni di conversioni tra i tipi come "CDate(...".
Ad esempio qualcosa del tipo:
{camponumero} < 100 and {campodata} < Cdate("23/12/2077")
ciao.

Matteo Raumer
[MCAD .net]
http://blogs.dotnethell.it/freeteo

dancur21 Profilo | Newbie

Ciao,
e grazie per la risposta. Come hai intuito sono già arrivato al punto in cui visualizzo un report, ma il mio problema è in primo luogo poter impostare una Selection_Formula sui dati del report stesso e in secondo luogo poter cambiare il DataSource del report.

- ho già provato ad impostare una Selection_Formula con la sintassi da te descritta e il pgm viene compilqato, l'esecuzione non genera errori ma è come se non fosse settata nessuna Selection_formula (visualizza tutti i dati);

- per quanto riguarda la possibilità di cambiare il DataSource del report non ho ancora provato, ma riuscendo a crearmi un ADORecordset penso che si sufficente passare questo come sorgente dati (no?!?!).

Valutando il primo problema, mi è sorto il dubbio di utilizzare male il componente ActiveX di Crystal report, e quindi sarei grato se qualcuno mi indicasse i passi principali per utilizzare nel migliore dei modi il componente.

Ti ringrazio per la grande disponibilità, considerando che non sei un programmatore c++ e hai provato comunque ad aiutarmi.

freeteo Profilo | Guru

>- ho già provato ad impostare una Selection_Formula con la sintassi
>da te descritta e il pgm viene compilqato, l'esecuzione non genera
>errori ma è come se non fosse settata nessuna Selection_formula
>(visualizza tutti i dati);
si ok ma la stringa magari non è corretta come tipi di dati, sei sicuro che non dipenda dal fatto che non fai i giusti Cdate, Cstr etc... (funzioni delle formule di Crystal)


>- per quanto riguarda la possibilità di cambiare il DataSource
>del report non ho ancora provato, ma riuscendo a crearmi un ADORecordset
>penso che si sufficente passare questo come sorgente dati (no?!?!).
si esatto


>Ti ringrazio per la grande disponibilità, considerando che non
>sei un programmatore c++ e hai provato comunque ad aiutarmi.
di niente, spero di averti dato magari qualche buono spunto...
ciao.

Matteo Raumer
[MCAD .net]
http://blogs.dotnethell.it/freeteo

dancur21 Profilo | Newbie

Avevo pensato a questa opportunità e ho provato ad utilizzare tali funzioni (Cdate,Cstr,ecc...) senza risultati soddisfacenti, il codice da me usato in partenza era:

//-------------- REPORT -------------------------------------- //Imposta il report da visualizzare m_Report = m_Application->OpenReport("Dipendenti.rpt",vtMissing); //Imposta il Visualizzatore m_Viewer.put_ReportSource(m_Report); m_Viewer.put_SelectionFormula(_T("{Dipendenti.Cognome} = \"King\"")); m_Viewer.ViewReport();

Il mio intento in questo caso è di visualizzare solo il dipendente con cognome "King",
ma in fase di esecuzione vengono visualizzati tutti i dipendenti.

Ho anche provato con:

CString str; str = "King"; m_Viewer.put_SelectionFormula(_T("{Dipendenti.Cognome} = Cstr(str)"));

Ma ottenendo anche qui risultati pessimi.. sapresti suggerirmi la sintassi corretta per impostare un filtro di questo tipo?

Grazie ancora.


freeteo Profilo | Guru

ciao,
si mi smbra proprio strano come problema, la sintassi sembra giusta...
Pero' potresti lavorare al contrario (reverse engineering ) impostandola nel report e poi andandotela a leggere a debug...

Mi sembra veramente strana come cosa, che non sia un problema di singolo apice invece del doppio...mah sincereamente non saprei...


ciao.

Matteo Raumer
[MCAD .net]
http://blogs.dotnethell.it/freeteo

dancur21 Profilo | Newbie

Grande... siamo arrivati insieme alla stessa conlusione e questo non fa altro che aumentare le stranezze!!

Ho impostato il filtro da report e tutto funziona correttamente e riesco anche a impostare una nuova query di estrazione dati!
Forse il problema è dovuto al fatto che per il Viewer utilizzo la classe Wrapper creata da VS per il controllo ActiveX, mentre per il report uso il IReportPtr. Bho...!!!

Comunque il problema è risolto... aggirandolo!!

- Avrei un'altra domanda.. sei io volessi impostare come sorgente dati per il report un ADORecordset che creo runtime, come devo fare?
Ho usato il seguente codice:

//....Creo il mio Recordset m_RS m_Report->Database->SetDataSource(m_RS);

ma in fase di esecuzione mi appare un dialog che dice:
"Le funzioni avanzate di Crystal Report non sono disponibili nella versione integrata in Visual Studio"
Devo acquistare la licenza Crystal Report?

Anche qui potrei passare la query che genera il report ma mi sarebbe utile velocizzare l'esecuzione evitando di rigenerare il RecordSet (cosa che in pratica farebbe CR).

- Per cambiare il Databse di riferimento del report utilizzo i metodi in report->Database->... vero?


Grazie mille per la pazienza.

freeteo Profilo | Guru

>Grande... siamo arrivati insieme alla stessa conlusione e questo
>non fa altro che aumentare le stranezze!!
>
>Ho impostato il filtro da report e tutto funziona correttamente
>e riesco anche a impostare una nuova query di estrazione dati!
>Forse il problema è dovuto al fatto che per il Viewer utilizzo
>la classe Wrapper creata da VS per il controllo ActiveX, mentre
>per il report uso il IReportPtr. Bho...!!!
>
>Comunque il problema è risolto... aggirandolo!!
>
>- Avrei un'altra domanda.. sei io volessi impostare come sorgente
>dati per il report un ADORecordset che creo runtime, come devo
>fare?
>Ho usato il seguente codice:
>
>//....Creo il mio Recordset m_RS
>m_Report->Database->SetDataSource(m_RS);
>
>ma in fase di esecuzione mi appare un dialog che dice:
>"Le funzioni avanzate di Crystal Report non sono disponibili
>nella versione integrata in Visual Studio"
>Devo acquistare la licenza Crystal Report?
dal messaggio credo tu abbia aggiunto una sorgente dati ad un report nuovo, o cmq tu stia modificando le impostazioni di un report, cosa che appunto non si puo' fare.
Per fare queste cose, effettivamente dovresti comprare la versione avanzata che ti permette di creare anche tutto un report da codice, senza averne fatto uno in precedenza.
Ma per settare solo dei dati mi sembra assurdo quindi io opererei in questo modo:
- creo un db access, con la struttura che gli passero' da codice
- creo un report che a design punta su quel db temporaneo
- da codice apri il report e gli passi i dati con quel metodo, anche se il rs ce l'hai in memoria a lui non fa differenza, tanto si aspetta una struttura di quel tipo (attento appunto a passare la stessa struttura con cui hai creato il report, cmpreso l'ordine dei campi)


>Anche qui potrei passare la query che genera il report ma mi
>sarebbe utile velocizzare l'esecuzione evitando di rigenerare
>il RecordSet (cosa che in pratica farebbe CR).
si esatto lui punta ai dati se vuoi, non occorre che glieli passi tu per forza (dipende dalle casistiche in cui ti troverai, ma diciamo che è indifferente).
Per farlo puntare lui,devi impostare le "logonInfo" qualcosa tipo qeullo che è spiegato qui:
http://www.dotnethell.it/forum/messages.aspx?ThreadID=8681

il codice è in vb.net ma fai presto a rimapparlo su c++...


>- Per cambiare il Databse di riferimento del report utilizzo
>i metodi in report->Database->... vero?
forse è proprio la logoninfo di cui stai parlando, prova a cercare anche nel forum altri messaggi che parlano di questo ce ne sono tanti...


>Grazie mille per la pazienza.
figurati!spero solo di esserti stato utile
ciao.

Matteo Raumer
[MCAD .net]
http://blogs.dotnethell.it/freeteo
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5