Database e C#

domenica 15 giugno 2008 - 16.12

mammamia Profilo | Newbie

Salve, scusate se posto in quest'area ma non sapevo dove inserire la mia domanda per C#

Sono nuovo di questo linguaggio e sto facendo una mia prima applicazione per leggere dei dati da un database e riversare determinati campi in un file di
testo, fin qui nessun problema tranne per il fatto che non riesco a capire come gestire questa situazione:

Per ogni riga del database dovrei pescare determinati campi:

NUMERO DOCUMENTO
DATA EMISSIONE
CODICE ARTICOLO

e disporli in questa maniera nel file .txt:

001 12052008 0000001
002 14062008 0000006
003 15062008 0000134
ecc...

Ho utilizzato il ciclo FOREACH per questa cosa, e alla fine tramite lo STREAMWRITER scrivo i dati nel file (Il codice l'ho accorciato per inserirlo qui chiaramente):

***********
foreach (DataRow MMNUMDOC in DocTable.Rows)
{
NumeroDocumento = (decimal)MMNUMDOC["MMNUMDOC"];
}

***********

using (StreamWriter sw = new StreamWriter("TestFile.txt"))
{
sw.Write(NumeroDocumento.ToString().PadRight(15, ' '));
}

***********

L'effetto però è quello che mi viene letta l'ultima riga del DATABASE e vengono tralasciate le atre, quindi la mia domanda è come faccio a far leggere i campi del database che mi servono nel cilco FOREACH e poi trascriverli nel file prima di passare alla riga successiva?


Grazie mille anticipatamente, e scusate se faccio domande che per voi sembreranno banali.

Matteo

freeteo Profilo | Guru

ciao,
ti basta girare per le righe dopo che hai aperto lo stream sul file e scrivere una linea ad ogni ciclo:

using (StreamWriter sw = new StreamWriter("TestFile.txt")) { for (int i = 0; i < DocTable.Rows.Count; i++) { decimal ndoc = (decimal)DocTable.Rows[i]["MMNUMDOC"]; sw.WriteLine("{0:000} {1,15}", i, ndoc); } }

come vedi l'ho adattato al risultato che vuoi ottenere, se non sbaglio hai anche il numero di riga formattato a 3 cifre davanti al numero del cocumento.
Cmq sia, scrive ogni riga, con dentro il numero di riga (dato dalla i) formattato a 3 cifre, e poi il numero documento preso dalla colonna della riga, lungo 15 caratteri.


ps: qualche info sui formati stringa da poter usare dentro al "WriteLine" lo trovi qui:
http://blog.stevex.net/index.php/string-formatting-in-csharp/

ciao.

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

mammamia Profilo | Newbie

Intanto grazie mille per la risposta...

Rettifico la domanda (ora non ho la possibilità di fare delle prove, poi stasera verifico):

Io ho un DATABASE con 50 campi, di questi me ne servono all'incira 5/6 (io nella domanda infatti ho messo sole un pezzo di codice per esempio), come faccio a includere i campi che mi interessano nel ciclo FOR?
O meglio includendo un campo alla volta in ogni ciclo FOR che mi interessa poi lo STREAMWRITER mi fa casino nella scrittura dei valori.

Spero di essere stato chiaro... aspetto risposte

freeteo Profilo | Guru

ciao,
con il metodo WriteLine puoi scrivere quello che vuoi nella linea, concatenando i valori presi dalla table o specificando uno "string format" del tipo:
"{0}{1}{2}...{n}" dove i numeri sono l'indice del parametro che gli passi:
using (StreamWriter sw = new StreamWriter("TestFile.txt")) { for (int i = 0; i < DocTable.Rows.Count; i++) { string altro = Convert.ToString(MMNUMDOC["altro"]); double altroancora = Convert.ToDouble(MMNUMDOC["altroancora"]); sw.WriteLine("{0:000} {1,15} {2} {3}", i, ndoc,altro,altroancora); ...
dove {0} => i , {1} => ndoc , {2} => altro , {3} => altroancora etc...ovviamente tu metti giù tutto quello che ti interessa avere nella riga, e usi il valore che hai preso dalla table e via così...

ciao.

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

mammamia Profilo | Newbie

Era più semplice del previsto

L'uovo di Colombo !!!


Grazie mille sei stato molto gentile e disponibile.

freeteo Profilo | Guru

>Era più semplice del previsto
eh si!


>Grazie mille sei stato molto gentile e disponibile.
di niente, se ti è stata utile, accetta una risposta così chiudiamo il thread come risolto.Grazie.

ciao.

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

mammamia Profilo | Newbie

Ritorno su questo post per complicare un pò le cose e per capire un po meglio come lavorare con i database.

Ho questa situazione:
- Un database che contiene i dati del destinatario di una probabile merce
- Un database che contiene i dettagli delle righe che compongono i singoli articoli acquistati

Per portare questi dati in un file uso il ciclo FOR come visto sopra, ma mi sto accorgendo che dovrei aggiungere un secondo ciclo FOR per far si che una volta prelevati i dati del primo destinatario, prendo ogni singola riga che compone il suo ordine, finchè una volta terminato passo al destinatario successivo e quindi alle righe che comporranno l'altro ordine.

Considerando che il riferimento tra le due tabelle sta nel NUMERO ORDINE, dovrei scrivere su file il cliente con il numero X e poi di seguito tutte le righe che compongono l'ordine numero X, e via di seguito fino alla fine del database.... senza contare che forse avrei bisogno anche di un intervallo di selezione.

Che consigli mi dai per questo nuovo quesito?

Grazie per la pazienza, Matteo

freeteo Profilo | Guru

ciao,
la cosa è abbastanza semplice, ti basta riempire la DataTable con una left-join per il campo numero ordine, cosicchè ti trovi tutte le righe con i campi duplicati, ma poco male, nel ciclo fai il suo relativo "sotto-ciclo" per le righe di dettaglio al cambiare del numero d'ordine:
string ordine = string.Empty; for (int i = 0; i < tabella.Rows.Count; i++) { if (ordine != Convert.ToString(tabella.Rows[i]["nordine"])) { ordine = Convert.ToString(tabella.Rows[i]["nordine"]); //--- dati di testata //... //--- } //--- dati di riga di quell'ordine //... //--- }

una cosa di questo genere...non è corretto, ma è il concetto che volevo farti capire.

ciao.

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

mammamia Profilo | Newbie

Spero che non mi odierai per tutte le domande che ti sto facendo....

Potresti farmi un esempio di codice inerente alla mia situazione usando il metodo DataTable.Filter che credo sia più semplice da implementare nella mia problematica? Ho provato a studiarmi l'esempio di MSDN ma sarà che oggi non connetto più a non farmi trovare la soluzione adatta.

Nel senso logico io la vedo cosi:
1- Con il primo ciclo FOR leggo i dati di TESTATA dal primo Database (Es. NumeroDocumento 1)
2- Tramite la SELECT filtro i soli dati che riguardano il NumeroDocumento 1
3- Creo un secondo ciclo FOR nidificato dentro al primo dove leggo e poi scrivo su file i dati filtrati
4- Ricomincio da capo con il NumeroDocumento2

Per fare una cosa semplice ho letto montagne di guide, ma d'altra parte se non faccio così non credo di sbloccarmi.... ponendosi una problematica vai a cimentarti con la dura realtà.

Grazie

freeteo Profilo | Guru

ciao,
per i filtri io userei la dataview, però a questo punto mi farei dare prima i diversi numeri di protocollo, o con un'altra query, o se hai già tutto nella tabella singola, girando per i valori della datatable, con un codice di questo tipo:

//--- recupero tutti i diversi numeri dalla datatable caricata List<string> listaNumeri = new List<string>(); foreach (DataRow riga in tabella.Rows) { string num = Convert.ToString(riga["ndoc"]); if (!listaNumeri.Contains(num)) listaNumeri.Add(num); } DataView dv = new DataView(tabella); //--- giro in tutti i numeri mettendoli come filtro foreach (string numero in listaNumeri) { dv.RowFilter = "ndoc='" + numero + "'"; foreach (DataRowView riga in dv) { double prezzo = Convert.ToDouble(riga["prezzo"]); string descrizione = Convert.ToString(riga["descrizione"]); .....etc....


come vedi, se hai la stessa tabella fai 2 volte il giro e quindi il tempo aumenta...la soluzione che ti ho dato prima invece girava per una sola volta, discriminando al momento (ovvio che dovevano essere ordinati per quel campo, ma quello lo facevi nella stringa di select...).
Vedi tu, se vai meglio così, e se i tempi sono accettabili...

ciao.

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

pupino84 Profilo | Newbie

Ciao,
ho un problema relativo all'utilizzo di uno StreamWriter Nel senso che provo a scrivere all'interno del file una qualsiasi cosa ma il file rimane vuoto...

Il codice di test che sto utilizzandoè:

StreamWriter sw = new StreamWriter(percorso);
sw.WriteLine("ciao");
sw.Flush();
sw.Close();

Il file Viene creato con il nome impostato e nella posizione corretta ma rimane sempre vuoto a 0 k.
Prima di queste riche di codice c'è altro codice che però non credo influenzi la scrittura del file...
Non riporto tutto l'altro codice perche sono molteplici riche e finirei per far perdere troppo tempo...

mammamia Profilo | Newbie

Ho provato il tuo codice:

private void scrivi() { StreamWriter sw = new StreamWriter(@"C:\test.txt"); sw.WriteLine("ciao"); sw.Flush(); sw.Close(); }

e crea correttamente il file con il testo scritto, ho usato la using System.IO e nient'altro.

freeteo Profilo | Guru

Confermo che il codice è corretto, io di solito uso lo using per invokare automaticamente il dispose, ma non è questo il problema.
Piuttosto a questo punto mi sembra che possa essere qualcosa che sporchi il file, prova a dare un nome temporaneo al file che non usi da nessuna parte e vediamo se il problema persiste.

Oppure potrebbero essere dei problemi di permessi sulla directory, cosa cmq strana visto che mi dici che non ti genera nessuna Exception...

Ciao.

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

pupino84 Profilo | Newbie

I misteri dell'informatica...
Ho creato un nuovo pulsante, all'interno ho messo quel codice e funziona....
Allora ho provato a commentare tutto ciò che sta nel pulsante precedente dove non funzionana lasciando il codice che ho riportato nel post e nemmeno ora scrive sul file...
MAH....
Vorrà dire che farò un altro pulsante solo per scrivere il file...

freeteo Profilo | Guru

Mi sembra impossibile che lo stesso codice vada da una parte e non dall'altra, ma nella vita tutto può essere.
Cmq puoi allegare il codice inserito magari in un progetto di prova che non ti funziona? Grazie, così capiamo se l'errore è da qualche altra parte, tipo magari il path del file viene sporcato ingiro per l'applicazione...

Ciao.

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

pupino84 Profilo | Newbie

ho scoperto l'arcano...
la causa del file vuoto era dovuta all'interruzione del codice dovuta ad un "return" da me inserito all'interno di una condizione.
In caso si verificasse tale condizione e per tanto venisse eseguito il "retun" prima della fine logica del codice da me inserito faceva si che non venisse scritta alcuna riga di codice.
Per scrivere correttamente il file (tutte le righe comprese quelle che in teoria il codice scrive prima dell'uscita forzata ("return")) è necessario che venga eseguito correttamente le riche di codice
sw.Flush();
sw.Close();

o solamente il close....
Riporto un esempio del mio codice:

StreamWriter sw = new StreamWriter(@"D:\Documenti\Visual Studio 2008\Projects\WindowsFormsApplication1\WindowsFormsApplication1\bin\Debug\file\Materieprime_" + meseRicerca + "_" + annoRicerca + ".txt");
sw.WriteLine("prova");


for (int i = 0; i < tab.Rows.Count ; i++)
{
if (i == tab.Rows.Count - 1)
{
MessageBox.Show("qui");
return;
}
}

sw.Flush();
sw.Close();


nel caso durante l'esecuzione del progetto la condizione contenuta nell'if fosse vera il retun faceva si che il file non venisse scritto rimanendo a 0k nonostante ci fossero scritture anche precedentemente la condizione...
Ringrazio tutti comunque per il tempo dedicatomi e se potrò aiuterò nei prossimi quesiti che verrannno inseriti nel forum..
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