Laden...

Daten aus Datenbank ausdrucken - Welche Form ist am Besten geeignet?

Erstellt von Lakustus vor 7 Jahren Letzter Beitrag vor 7 Jahren 2.883 Views
L
Lakustus Themenstarter:in
25 Beiträge seit 2016
vor 7 Jahren
Daten aus Datenbank ausdrucken - Welche Form ist am Besten geeignet?

verwendetes Datenbanksystem: SQL CE 3.5
WPF

Hallo allerseids,

ich möchte gerne Daten aus einer .sdf auslesen und diese Daten an den Drucker senden (geht aber jetzt rein um das Auslesen der Daten).
Bin mir nicht sicher wie bzw. wohin ich auslesen soll - vieleicht hat jemand einen guten Rat im Hinblick auf das Drucken (was ist geeigneter: datagridview, listbox, variablen, list<>..?)

Hier mein Code:


SqlCeConnection ceconn;
SqlCeResultSet cers;
ceconn = new SqlCeConnection(@"DataSource = C:\Users\sysadmin\Desktop\datenbank.sdf; Password ='passwort'");
using (SqlCeCommand cmd = new SqlCeCommand())
            {
                object acc1 = 0, drawer = 0;
                List<string> belegt = new List<string>();
                try
                {
                    cmd.Connection = ceconn;
                    ceconn.Open();
                    cmd.CommandText = "SELECT * FROM ProcessMenge";
                    cers = cmd.ExecuteResultSet(ResultSetOptions.Updatable | ResultSetOptions.Scrollable);
                    dataGridView1.DataContext = cers;
                    while (cers.Read())
                    {
                        cmd.CommandText = "SELECT * FROM ProcessMenge WHERE ID=1";
                        belegt.Add(cers["Account1"].ToString());
                        belegt.Add(cers["Drawer"].ToString());
                        cmd.CommandText = "SELECT * FROM ProcessMenge WHERE ID=2";
                        belegt.Add(cers["Account1"].ToString());
                        belegt.Add(cers["Drawer"].ToString());
                    }
                    MessageBox.Show(belegt.ToString());
                }
                finally
                {
                    cers.Close();
                }
                ceconn.Close();
            }

Habe schon verschiedene Ansätze versucht, schaffe es aber nicht die Daten ausgelesen in einen neuen "Topf" rein zu schreiben um diesen dann ausdrucken zu können. Einmal heisst es "von jenem Typ kann nicht in diesen konvertiert werden", mal "keine Zeilen/Spalten vorhanden" und sonstige.

Der Code selbst ist noch ein Versuchsfeld also nicht wundern wenn ich da momentan Variablen habe die nicht genutzt werden oder eine MessageBox etwas ausgeben will was so nicht geht 😉

Wäre schön wenn mir jemand ein Lämpchen aufgehen lassen könnte 😃

Grüße

2.207 Beiträge seit 2011
vor 7 Jahren

Hallo Lakustus,

(geht aber jetzt rein um das Auslesen der Daten).
[...]
vieleicht hat jemand einen guten Rat im Hinblick auf das Drucken

Wo genau ist dein Problem? Beim Auslesen? Oder beim Drucken? Oder bei der Form des Druckens?

du wirfst hier mMn drei Probleme in einen Topf. Erstens willst du die Daten auslesen können. Zweitens willst du die Daten in eine Form giessen, mit der man sie lesen kann und drittens willst du das dann auch ausdrucken. Ich hoffe ich habe dich richtig verstanden.

Meine Empfehlung ist, dass du dich mit den Problemen nach und nach beschäftigst. Sorge erstmal dafür, dass du die Daten zuverlässig bekommst: Keine Fehler bei der Abfrage, Null-Values beachten etc.

[Artikelserie] SQL: Parameter von Befehlen

Danach kümmerst du dich um die Anzeige zum Ausdrucken. Du kannst mit iTextSharp beispielswiese im Code Tabellen erstellen, das als PDF rauslassen. Dann brauchst dus nur noch normal ausdrucken. Manuell oder, was ein anderes Problem wäre, automatisch via C#.

Für alle diese Probleme gibt es sehr sehr viele Quellen und Beispiele im Netz.

Gruss

Coffeebean

16.834 Beiträge seit 2008
vor 7 Jahren

Hilfreich wäre auch eine saubere Trennung...
[Artikel] Drei-Schichten-Architektur

PS: iTextSharp hat mittlerweile ne unvorteilhafte Lizenzierung.
Alte Versionen sind da offener.

6.911 Beiträge seit 2009
vor 7 Jahren

Hallo Lakustus,

BTW: has du dir schon Reporting Tools (z.B. ReportViewer) angeschaut? Diese wäre für solche Aufgabe gedacht und können in deiner Anwendung verwendet werden.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

L
Lakustus Themenstarter:in
25 Beiträge seit 2016
vor 7 Jahren

Hallo alle,

vielen Dank für eure Antworten! Werde mir alles anschauen und versuchen damit meine Aufgabe zu lösen.

@was genau gefragt ist: Daten auslesen und sie ausdrucken 😃
herangehensweise: Neulingsmäßig ausgedacht "die ausgelesenen Daten müssen wohl erstmal irgendwo zwischengespeichert und danach an den Drucker geschickt werden" (?)

Sobald ich eine fertige Lösung habe (oder wieder fragen), poste ich sie.

Grüße

3.825 Beiträge seit 2006
vor 7 Jahren

Für das Drucken gibt es mehrere Möglichkeiten :

  • PrintDocument : Du musst alles selber machen

  • PrintForm : Ein Form wird gedruckt

  • Reportbuilder : Komfortabel und hübsch

  • Andere Reportgeneratoren (SAP Crystal Reports, FIY Reporting bzw. der Nachfolger NReports etc.)

Jede Methode hat so ihre Vor- und Nachteile.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

C
2.121 Beiträge seit 2010
vor 7 Jahren

Eine Ergänzung noch, visuelle Komponenten zum zwischenspeichern sind sehr ungeeignet. Das ist Overkill, denn du willst die Daten ja nur irgendwo halten und nicht anzeigen.

L
Lakustus Themenstarter:in
25 Beiträge seit 2016
vor 7 Jahren

phuu, also aller Anfang ist echt schwer 😃

Zum Auslesen der gewünschten Daten aus einer DB habe ich nun folgendes Konstrukt gebastelt:


SqlCeConnection ceconn = new SqlCeConnection(@"DataSource = C:\Users\lakustus\Desktop\datenbank.sdf; Password ='dbpasswort'");
            try
            {
                string SQL = "SELECT * FROM ProcessMenge";
                SqlCeCommand cmd = new SqlCeCommand(SQL, ceconn);
                SqlCeDataReader dr;
                ceconn.Open();
                dr = cmd.ExecuteReader();
                for (int i = 0; i < 20; i++)
                {
                    while (dr.Read())
                    {
                        acc1.Text += dr["Account1"].ToString() + "\n";
                        draw.Text += dr["Drawer"].ToString() + "\n";
                        if (acc1.Text.Length > 1)
                        {
                            drucken.Text = "Fach: " + draw.Text + " ist belegt";
                        }
                    }
                }
                dr.Close();        
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ein Fehler ist aufgetreten");
            }
            ceconn.Close();

Ist ganz sicher nicht eine super Lösung aber immerhin erhalte ich die Daten die ich brauch. Die for-Schleife ist irgendwie pfui weil die DB zwar maximal rund 20 Zeilen lang wäre aber der Großteil doch um die 9 hat.

a) Kann man die Zeilenanzahl an Einträge herauslesen und diese der for-Schleife als "bis"Kriterium mitgeben?

b) wieso muss das mit dem Drucken so kompliziert sein 😄 habe etwa 5 verschiedene Ansätze versucht von heute Morgen 9 bis jetzt noch immer am rummachen- jedesmal ist der Ausdruck leer hrhr.

Achso, "drucken" ist eine TextBox (von datagrid bis listbox und List<string> alles mal versucht) die ich ausdrucken möchte.

16.834 Beiträge seit 2008
vor 7 Jahren

Tu Dir selbst einen Gefallen....

  • trenne Daten von Business-Logik und von UI (nochmals Hinweis auf [Artikel] Drei-Schichten-Architektur )
  • arbeite mit using(), wenn eine Klasse - die eine Datenbankverbindung oder der Reader - IDisposable implementiert
  • fange immer spezifische Exceptions, und nicht planlos einfach "Exception"

Warum Du das for mit einer fixen Zahl von 20 laufen lässt ist mir schleierhaft.
das while ist doch dafür da um zu prüfen, ob es noch was zu lesen gibt.

Kann das sein, dass Du irgendwoher einfach Code kopierst, versuchst ihn anzuwenden, ohne ihn zu verstehen?
Und wir sollens richten, oder wie? Finde ich nicht nett 😃

Warum er leer ist:
[Artikel] Debugger: Wie verwende ich den von Visual Studio?

L
Lakustus Themenstarter:in
25 Beiträge seit 2016
vor 7 Jahren

Huhu Abt,

ja hast recht 😃 bin erst einpaar Monate am Programmieren lernen durch meine Ausbildung und wirklich verstehen tu ich nicht vieles. Das meiste wird ergöoegelt und durch rumbasteln und rumprobieren versucht zu erlernen.

Ja los richtet es! 😛 ne quatsch, aber bissi helfen das man auf den richtigen Weg kommt erhofft man sich von jedem Forum.

Deshalb nochmals danke für alle Antworten!

3.825 Beiträge seit 2006
vor 7 Jahren

Lass diese Schleife weg, sie hat keine Funktion :

for (int i = 0; i < 20; i++)

Ergänze deine Fehlermeldung um den genauen Grund des Fehlers :

 MessageBox.Show("Ein Fehler ist aufgetreten : " + ex.Message);

Unter Windows statt \n besser \r\n oder Environment.NewLine.

Jetzt das Ergebnis nur noch drucken !

Du kannst das Ergebnis auch in ein DataSet laden, hier siehst Du wie Du ein DataSet als Tabelle ausdruckst :

http://www.gotreportviewer.com/

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

L
Lakustus Themenstarter:in
25 Beiträge seit 2016
vor 7 Jahren

Hallo Bernd, hallo alle,

vielen Dank für eure Denkanstöße. Wie versprochen hier die fertige Version wie ich das ganze letztendlich gelöst habe.


List<string> ausdruck = new List<string>();

        private void DruckButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            string acc1 = null;
            string acc2 = null;
            using (SqlCeConnection ceconn = new SqlCeConnection(@"DataSource = C:\Users\db.sdf; Password ='db_passwort'"))
            {
                try
                {
                    string SQL = "SELECT Account1, Account2, Drawer FROM tabelle1";
                    SqlCeCommand cmd = new SqlCeCommand(SQL, ceconn);
                    SqlCeDataReader dr;
                    ceconn.Open();
                    dr = cmd.ExecuteReader();
                    while (dr.Read())
                    {
                            acc1 += dr["Account1"].ToString() + Environment.NewLine;
                            acc2 += dr["Account2"].ToString() + Environment.NewLine;
                            ausdruck.Add(dr["Drawer"].ToString());
                    }
                    dr.Close();
                    if (acc1 != null  || acc2 != null)
                    {
                        Print(1);
                    }
                    else
                        Print(0);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Ein Fehler ist aufgetreten" + ex.ToString());
                }
                ceconn.Close();
            }
        }

Zunächst wird die DB gezielt ausgelesen und die Spalten "aufgeteilt" gespeichert und in der Druckfunktion die List<string>'s verwendet. Klappt alles wie gewollt. Der Lerneffekt ist akzeptabel 😃

Grüße

3.003 Beiträge seit 2006
vor 7 Jahren

Bitte nicht in Schleifen strings mit += verketten -> Schlemiel the Painter's algorithm

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

16.834 Beiträge seit 2008
vor 7 Jahren

Viel schlimmer als += is die Mischung von UI, BL und DAL.
[Artikel] Drei-Schichten-Architektur

L
Lakustus Themenstarter:in
25 Beiträge seit 2016
vor 7 Jahren

ach herrje, und das bei meinem Englisch 😄 @LaTino

aber danke für den Hinweis!

ja das muss ich mir noch unbedingt angewöhnen/lernen mit dem "Schichten". Und wenn nicht hin und wieder jemand euch AugenkrebsCode hinklatscht, würdet ihr ja vergessen das hier auch Anfänger am werkeln sind, hihi.

Wäre dashier besser? (statt += und string):


StringBuilder acc1 = new StringBuilder();
StringBuilder acc2 = new StringBuilder();

while (dr.Read())
{
       acc1.AppendLine(dr["Account1"].ToString());
       acc2.AppendLine(dr["Account2"].ToString());
}

Geht es hierbei um performance oder was ist schlecht an einer "Verkettung in Schleifen"?

Grüße