Report

martedì 02 settembre 2008 - 15.19

dupperelko Profilo | Junior Member

Ciao ragazzi,
chiedo gentilmente aiuto se q.no sa,
ne ho bisogno per un lavoro urgente.

Non riesco a capire come mai lanciando il Form (uso VB2005), in cui ho un ReportViewer,
mi visualizza tutti i record che deve tranne l'ultimo!

Il problema è che questa strana mancanza di record
lo fa 1 volta ogni 3-4 volte... non capisco!

quindi non e' problema di codice o altro, ma problema
di qualche refresh da parte del ReportViewer..

ma poi perchè una volta si e 3-4 no?

Vi ringrazio


ciao
a tutti




********************************************************
Se a q.no puo' essere utile,
ho scoperto che questo scherzo me lo fa solo
con i report composti da piu' di una pagina.

Perchè ho provato a lanciare il report
con una decina di dettagli (quindi mezza pagina)
e per 50 volte mi ha sempre visualizzato tutti e dieci i record.

Poi ho lanciato il report composto da 3 pagine
e alla 4 volta mi mancava l'ultima riga nell'ultima pagina...

misteri del Framework!

freeteo Profilo | Guru

ciao e scusami del ritardo nella risposta.
Volevo chiederti, il fatto che ti manca l'ultimo recordo ce l'hai anche quando vai in visualizzazione "Print Layout" ovvero nella toolbar clicchi il pulsante relativo all'impaginazione "come verrà stampato"?

Perchè potrebbe essere che non vedi il record, ma poi se lo stampi lo vedi correttamente, allora questo è un problema di zoom o cmq di visualizzazione...


ps: la prossima volta per problemi relativi alle stampe in generale, posta nella stanza Reportistica (l'ultima della lista delle stanze) che così riesco a vederla prima
ciao.

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

dupperelko Profilo | Junior Member

Ciao Matteo,
non ti ho più scritto perché
ho cercato di risolvere il problema cambiando il codice, ma è come prima, quindi è un problema di report.

Riassumo visto che è passato un po' di tempo, ti ringrazio per l'attenzione.

Ho realizzato un applicativo con VB2005, ado.net e un reportviewer,
che semplicemente stampa fatture e bolle.

Nell'applicazione utilizzo un db Access in cui vengono memorizzati i dati.

Nel db c'è una tabella temporanea dove la riempio con i dati da stampare al momento e poi la svuoto.

Il problema nasce quando il mio reportviewer carica i dati dal db!

Cioè:
- nel prog. tutto funziona
- il db si riempie con i dati esatti
- il report va a leggere sul db i dati esatti e li butta nella sezione "corpo" del report in una tabella.


Tutti felici e contenti.

Ma perchè ogni 3-4 volte (quindi non stabile e non uguale di volta in volta) che lancio il mio report manca l'ultimo record sulla tabella nel corpo del report?


Esempio:
se io ho 10 record da stampare, ogni 3-4 volte mi trovo 9 record,
poi rimando in stampa e trovo 10 record...

Questo è un problema perché nella fattura manca l’ultimo record!

Chissà se puoi aiutarmi?
E’ un problema di refresh in qualche punto?
Ti ringrazio per l'attenzione



M avevi chiesto alcune cose:
ti dico che il report (ogni 3-4 volte) non lo vede proprio l'ultimo record (anche se sul db c'è), sia in print layout che normalmente
e poi questo problema c'è sia che abbia 1000 record sia che ne abbia 3.

Ciao

grazie


Andrea

freeteo Profilo | Guru

Ciao,
sinceramente non mi è mai capitato....puoi postare il codice che hai scritto? (solo il caricamento e la visualizzazione del report)

Effettivamente potrebbe essere anche un problema di refresh (chaima il metodo reportViewer.RefreshReport() per sicurezza, che non si tenga qualcosa in cache.



Ciao.

Matteo Raumer
[MVP Visual C#]
http://blogs.dotnethell.it/freeteo

dupperelko Profilo | Junior Member

Ciao Matteo,
ti invio il codice del Form che contiene il ReportViewer (che a sua volta punta ad un Report),
eccolo:



***************************************************************************************************

Public Class frmStampaFattImm

Private Sub frmStampaFattImm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Me.TmpStampaTableAdapter.Fill(Me.dbFattureDataSet.TmpStampa)

Dim param As List(Of Microsoft.Reporting.WinForms.ReportParameter) = New List(Of Microsoft.Reporting.WinForms.ReportParameter)
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_RagioneSociale", var_RagioneSociale))
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_Indirizzo", var_Indirizzo))
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_Citta", var_Citta))
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_NumeroFattura", var_NumeroFattura))
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_DataFattura", var_DataFattura))
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_PIva", var_PIva))
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_CF", var_CF))
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_Pagamento", var_Pagamento))
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_Scadenza", var_Scadenza))
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_Imponibile", var_Imponibile))
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_Imposta", var_Imposta))
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_TotaleFattura", var_TotaleFattura))

ReportViewer1.LocalReport.SetParameters(param)

Me.ReportViewer1.RefreshReport()

End Sub
End Class

****************************************************************************************************


Queste variabili (che finiscono nell'head e nel footer del report) le setto nel programma e devo dire che loro non hanno mai dato problemi...

quello che da problemi è la Tabella nel body del Report, che perde l'ultimo record della coda (quella letta dal DB) per strada...

Illuminami... ciao e grazie









freeteo Profilo | Guru

ciao,
dal tuo codice vedo che lasci fare al designer il report, il quale ha generato il codice per te.
Forse il runtime ogni tanto sbaglia qualcosa, io ti consiglio di caricarlo sempre, così sei sicuro che quello che visualizzi è cmq quello che viene eleborato in quel momento, controllando tu cosa succede esattamente.

Perciò io ti consiglierei di passare tu i dati innanzi tutto:

Me.TmpStampaTableAdapter.Fill(Me.dbFattureDataSet.TmpStampa) '--- gli passi il datasource Dim dataSource As New ReportDataSource("#NOME#",Me.dbFattureDataSet.TmpStampa) Me.ReportViewer1.LocalReport.DataSources(0) = dataSource '...parametri... Me.ReportViewer1.RefreshReport()

come vedi viene ricaricato il report, passati i dati, e poi visualizzato.
Anche quello che fai tu è corretto, e sicuramente farà più o meno lo stesso codice, solo che magari tiene qualcosa in cache o cmq fa qualcosa del genere.
Prova con questo codice.


Ciao.

Matteo Raumer
[MVP Visual C#]
http://blogs.dotnethell.it/freeteo

dupperelko Profilo | Junior Member

ok... adesso provo


grazie

dupperelko Profilo | Junior Member

Ciao Matteo,
ho provato ad inserire i tuoi suggerimenti (modificati così), ma non va lo stesso.

Dim dataSource As New Microsoft.Reporting.WinForms.ReportDataSource("dbFattureDataSet_TmpStampa", Me.dbFattureDataSet.TmpStampa)
Me.ReportViewer1.LocalReport.DataSources(0) = dataSource


Però ho scoperto una cosa.
Se metto un break alla variabile dataSource, ho un record in meno, quindi il problema nasce prima.

Allora sono andato a vedere il codice che mi carica i dati, eccolo:


' stringaSQL e Cn sono dichiarati qua, fuori dall'each

For Each riga As DataRow In tblDettaglio.Rows
Dim objCom As New OleDbCommand(stringaSQL, Cn)

objCom.Parameters.AddWithValue("@um", riga("UM").ToString)
objCom.Parameters.AddWithValue("@qta", riga("Qta").ToString)
objCom.Parameters.AddWithValue("@cod", riga("Cod").ToString)
objCom.Parameters.AddWithValue("@description", riga("Descrizione").ToString)
objCom.Parameters.AddWithValue("@prezzo", FormatNumber(riga("Prezzo"), 2))
objCom.Parameters.AddWithValue("@importo", FormatNumber((riga("Prezzo") * riga("Qta")), 2))
objCom.Parameters.AddWithValue("@ali", var_Aliquota)

TOT_IMP += FormatNumber((riga("Prezzo") * riga("Qta")), 2)

objCom.ExecuteNonQuery()

' ho provato ad inserire anche un doevents, ma niente da fare
Application.DoEvents()

objCom.Parameters.Clear()

Next






Supponiamo che i record siano 30.
In pratica in tblDettaglio ho tutti e 30 i record (che sarebbero i dettagli della fattura).
Quindi li leggo ad uno ad uno e li metto (con ExecuteNonQuery) in una tabella temp del DB in modo che il report li peschi da li.

Il problema salta fuori quando arriva l'ultimo record (infatti il problema è dato sempre dall'ultimo
record e mai da uno centrale).

Secondo me non riesce ad eseguire l'istruzione "objCom.ExecuteNonQuery()" per l'ultimo record,
objCom cade (perché cade il "for each") e quindi l'ultimo record si perde!

Ho provato a mettere un Application.DoEvents() ma niente da fare.

Il tutto funziona se io vado step by step con il breakpoint e quindi mi vedo l'ExecuteNonQuery
che viene fatto a tutti e 30 correttamente, poi se tolgo il breakpoint e lascio fare al runtime,
mi trovo un record in meno.


Secondo te devo cambiare qualcosa nel codice? Ho provato a tirar fuori dall'each
"Dim objCom As New OleDbCommand(stringaSQL, Cn)" ma non va lo stesso!





Grazie


ciao

freeteo Profilo | Guru

>Però ho scoperto una cosa.
>Se metto un break alla variabile dataSource, ho un record in
>meno, quindi il problema nasce prima.
ah, vedi allora non è il report, è qualcosa del tableAdapter.
Io sinceramente non li uso mai, non mi piacciono perchè non sono molto puliti, preferisco scrivermi il codice (praticamente standard) per accedere al db e farmi la query, e magari farmi tornare un datatable (o meglio ancora una collection tipizzata con i miei oggi, ma anche datatable ogni tanto torna comoda).

Per cui, qualcosa del tipo:
Public Function GetDati() As DataTable Dim table As DataTable = New DataTable Dim con As OleDbConnection = New OleDbConnection("...") con.Open() Dim cmd As OleDbCommand = con.CreateCommand() cmd.CommandText = "SELECT ..." '--- eventuali parametri se la query ne ha bisogno table.Load(cmd.ExecuteReader) Return table End Function
e sono sempre sicuro che i dati vengono caricati in quel momento, e sono quelli che voglio.
Prova ad usare questa strada anche tu, facendoti tornare una datatable, e mettendo quella come datasource, quindi non usando quella del dataset che hai creato a design.
Verifica se anche a questa manca un record.

Ciao.

Matteo Raumer
[MVP Visual C#]
http://blogs.dotnethell.it/freeteo

dupperelko Profilo | Junior Member

Ciao Matteo,
ora provo...

io uso dappertutto daset e datatable creati da codice,
l'unico posto dove ho inserito i tipizzati era il report, questo perché
inizialmente non sapevo come caricare i dati nella Tabella del corpo del Report e quindi
con il tipizzato prendevo il campo da 'Origine dati' e lo trascinavo nello spazio adibito nel report..
era comodo...
adesso provo a far così come dici tu,

l'unica cosa è che non conosco l'istruzione per caricare i dati dal datatable
al campo del report... Conosco solo come caricare da parametri e cioè:

Dim param As List(Of Microsoft.Reporting.WinForms.ReportParameter) = New List(Of Microsoft.Reporting.WinForms.ReportParameter)
param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_RagioneSociale", var_RagioneSociale))
ReportViewer1.LocalReport.SetParameters(param)
Me.ReportViewer1.RefreshReport()

ma sui campi non so... proverò


grazie per la disponibilità
e per le informazioni

Ciao


Saluti




freeteo Profilo | Guru

>l'unica cosa è che non conosco l'istruzione per caricare i dati
>dal datatable
Diciamo che non "carichi" i dati dal datable al report, ma "passi" il datatable come "datasource" del report.
Quest'ultimo sa poi cosa farne,ossia visualizzarli (o meglio renderizzarli) strutturati rispettando il template che hai impostato disegnandolo.

Il codice è semplice, come ti ho scritto prima, si riduce a passare il datasource (e poi il resto dei parametri e il refresh...):
'--- gli passi il datasource Dim dataSource As New ReportDataSource("#NOME#",Me.dbFattureDataSet.TmpStampa) Me.ReportViewer1.LocalReport.DataSources(0) = dataSource ...
dove "#NOME#" è il nome della datasource, che trovi nelle proprietà del report

Ciao.

Matteo Raumer
[MVP Visual C#]
http://blogs.dotnethell.it/freeteo

dupperelko Profilo | Junior Member

ok..
per adesso ho preparato la function:

Public Function GetDati() As DataTable

Dim SQL As String = "Select * From DettaglioFatture" 'poi la where con i parametri la metto successiavmente, adesso provo così
Dim CnDet As New OleDbConnection(strCn) 'connessione definita altrove
Dim Da As New OleDbDataAdapter(SQL, CnDet)
Dim DS As New DataSet
Da.Fill(DS, "Dettaglio")

Dim tblDettaglio As DataTable
tblDettaglio = DS.Tables("Dettaglio")

Return tblDettaglio

End Function





Adesso che ho tblDettaglio tra le mani
provo a fare come dici


grazie
per adesso

PS: per Natale forse finisco ;)

dupperelko Profilo | Junior Member

Ciao Matteo,
scusa ma non riesco.

Ho creato il mio datatable in memoria, e va bene:

Public Function GetDati() As DataTable
Dim SQL As String = "Select * From DettaglioFatture"
Dim CnDet As New OleDbConnection(strCn) 'connessione definita altrove
Dim Da As New OleDbDataAdapter(SQL, CnDet)
Da.Fill(DS, "Dettaglio")
tblDettaglio = DS.Tables("Dettaglio")
Return tblDettaglio
End Function


Ora nel mio report vuoto, composto da head, body e footer
ho trascinato nel body, dalla casella strumenti, una Tabella (di default 3 colonne poi la modifico)

In 'Origini dati report' credo non debba fare niente,
in 'proprietà del report' ho solo la gestione delle misure/altro
e in 'parametri report' andrò poi dopo a mettere i miei report
ma questo so che funziona perché te lo avevo già fatto vedere e cioè:

'Dim param As List(Of Microsoft.Reporting.WinForms.ReportParameter) = New List(Of Microsoft.Reporting.WinForms.ReportParameter)
'param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_RagioneSociale", var_RagioneSociale))
'param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_Indirizzo", var_Indirizzo))
'param.Add(New Microsoft.Reporting.WinForms.ReportParameter("parametro_Citta", var_Citta))
'ReportViewer1.LocalReport.SetParameters(param)


Ho inoltre inserito le righe di codice come suggerite da te e cioè:

Dim dataSource As New Microsoft.Reporting.WinForms.ReportDataSource("#NOME#", Me.tblDettaglio)
Me.ReportViewer1.LocalReport.DataSources(0) = dataSource

Quello che non capisco è come faccio a far uscire i dati del datatable creato con la function,
nelle colonne del Table nel body del Report?

Mi manca q.sa?

E poi non ho capito su #nome# cosa devo mettere!


Grazie per la pazienza e l'aiuto


ciao
A.


freeteo Profilo | Guru

>Ora nel mio report vuoto, composto da head, body e footer
>ho trascinato nel body, dalla casella strumenti, una Tabella
>(di default 3 colonne poi la modifico)
>In 'Origini dati report' credo non debba fare niente,
da quello che mi dici, ti mancano dei concetti base per capire come fare un report e poi visualizzarlo dentro ad un'applicazione
I passi standard sono:

1) creazione del report agganciato ad una sorgente dati (tipicamente database).
questa sorgente dati non è detto che sia la stessa che hai poi in esecuzione, anzi, tipicamente lo costruisci su un db di prova e invece poi sarà utilizzato sul db reale.
Questo aggancio lo fai nel report tramite la finestra "data sources" aganci il report a dei dati, e li trascini in tabelle, list etc...ossia quello che vuoi venga ripetuto per le varie righe.
Disegni il report come vuoi usando questi campi, nell'esempio sono messi tutti in una table, niente di speciale, è solo per capire.
La cosa importante è che la struttura (nomi e tipi dei campi) che gli passi dopo a runtime, sia la stessa che hai usato per crearlo, in modo che quello che cambia siano solamente i valori visualizzati nel report

2) caricamento del report nel viewer, e passaggio dati, sia come sorgente dati, che come parametri.
Il caricamento del report può essere fatto anche a design, (come hai fatto tu mi sembra di capire) ma può anche essere fatto tutto da codice, tanto quello che fa il designer è impostare nel viewer l'oggetto "LocalReport" dandogli il relativo path del file rdlc etc...

Il passaggio dei dati lo abbiamo già spiegato nei post precedenti di questo thread, il codice lo trovi nell'esempio.
Cmq puoi usare il dataset tipizzato o altre sorgenti dati tue come abbiamo detto, io preferisco farmi il codice, perchè non mi piacciono i dataset tipizzati, ma questa è un'opinione personale.

Il passaggio dei parametri mi sembra che lo facessi già correttamente.



Invece di darti il codice qui,ho preferito allegarti un esempio semplice che faccia questi passi, così da farti capire velocemente.
Partendo dall'esempio poi tu, adattalo alla tua situazione.

ps: il codice è in C# perchè lo preferisco come linguaggio, ma è abbastanza facile passare da uno all'altro, dovresti riuscire senza problemi.
Eventualmente aiutati con tool tipo: http://www.carlosag.net/Tools/CodeTranslator/

Ciao.

Matteo Raumer
[MVP Visual C#]
http://blogs.dotnethell.it/freeteo

dupperelko Profilo | Junior Member

Grazie di tutto,

problema risolto!


Ciao

Ciao

P.S. complimenti per il tuo KnowHow

freeteo Profilo | Guru

>Grazie di tutto,
figurati, siamo qui per questo.


>problema risolto!
ottimo, accetta una risposta così marchiamo il thread come risolto


>P.S. complimenti per il tuo KnowHow
grazie, troppo gentile.

Ciao.

Matteo Raumer
[MVP Visual C#]
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-2023
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5