Autor Beitrag
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Do 20.09.12 15:07 
Hallo :)

Also ich habe jetzt mal den Code überarbeitet...
Das ist meine ClassLibary :)
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
namespace Projekt_DB_to_SFirmLibary
{
    public class Zeile
    {
        //hier sind die Spalten drinne z.B:
        public string KName { get; set; }
        public int Bank { get; set; }
        public string BName { get; set; }
    }

    public class Zahlungen
    {
        private SqlConnection ZaConn = null;
        public void OpenConnection(string ZaConnStr)
        {
            ZaConn = new SqlConnection();
            ZaConn.ConnectionString = ZaConnStr;
            ZaConn.Open();
        }
        public void CloseConnection()
        {
            ZaConn.Close();
        }
        public void InsertBank(Zeile rows)
        {
            string anweisung = String.Format("INSERT INTO Zahlungsfreigabe" +
                "(Name, Bank, BName, KNummer) Values" +
                "('{0}','{1}','{2}','{3}')", rows.Name, rows.Bank, rows.BName, rows.KNummer);
            using (SqlCommand cmd = new SqlCommand(anweisung, this.ZaConn))
            {
                cmd.ExecuteNonQuery();
            }
        }
    }   
}


Hier ist mein Main-Code von WinFrom:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
    List<Zeile> rows = new List<Zeile>();

    while (ApReader.Read())
    {
        Zeile Zeile = new Zeile();
        Zahlungen zahlungen = new Zahlungen();
        zahlungen.OpenConnection(ZaConStr);

        Zeile.KName = Convert.ToString(ApReader[1]);
        if (!ApReader.IsDBNull(2))
            Zeile.Bank = Convert.ToInt32(ApReader[2]);
        if (!ApReader.IsDBNull(3))
            Zeile.BName = Convert.ToString(ApReader[3]);
        if (!ApReader.IsDBNull(4))
            Zeile.KNummer = Convert.ToInt32(ApReader[4]);

        rows.Add(Zeile);
        zahlungen.InsertBank(Zeile);

        zahlungen.CloseConnection();
    }


Wenn ich diesen Code Ausführe sagt er mir bei:
ausblenden C#-Quelltext
1:
2:
3:
4:
using (SqlCommand cmd = new SqlCommand(anweisung, this.ZaConn))
{
    cmd.ExecuteNonQuery(); // Der Wert NULL kann in die 'ERP Nummer'-Spalte, 'Zahlungen.dbo.Zahlungsfreigabe'-Tabelle nicht eingefügt werden. Die Spalte lässt NULL-Werte nicht zu. Fehler bei INSERT. Die Anweisung wurde beendet.
}

Also die Spalte "ENummer" darf keine Null-Values haben, da es die Primary-Key Spalte ist.
Und in meiner Zeile wird diese noch nicht definiert oder gar hinzugefügt, weil ich diese Spalte/Zeile aus einer anderen Datei holen möchte.

Nun möchte ich euch fragen, ist der HauptCode soweit richtig, dass er jedesmal diese Zeilen aus der SQL-Datenbank holt und in eine andere Datenbank schreibt?

Dann wollte ich euch fragen, wie kann ich DataRelationen zwischen solchen "Verfahren" herstellen?

Mal ein beispiel:
Zitat:
Datenbank A (DB A)
ID Name Nachname
2 AA BA
5 AB BB
8 AC BC

Datenbank B (DB B)
ID Adresse Alter
1 abcstr. 22
2 abdstr. 23
3 abestr. 39

Datenbank C (DB C)
ID Name Nachname Adresse Alter
2 AA BA abcstr. 22
usw.

Nun Speichere ich ja die Zeile ID 2 von Datenbank A in eine Variable und gleichzeitig schreibt er diese in DB C, doch dort fehlt ja zunächst die Adresse und Alter und nun ist in einer weiteren Variable die Zeile ID 2 von DB B gespeichert. Wie schaffe ich es das beide Variablen, mit der selben ID eine GEMEINSAME Zeile bilden?

Ich hoffe ihr versteht mein Anliegen.

LG

Moderiert von user profile iconTh69: Beitragsformatierung überarbeitet.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4795
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Sa 22.09.12 10:25 
Hallo Vegeto,

ich verstehe schon dein Anliegen. Jedoch muß ich zugeben, daß es mir schwer fällt, dir kurz zu antworten, denn mir erscheint, daß du anscheinend selber immer noch nicht den Code so richtig zu verstehen scheinst.

Vom Grundaufbau ist dein Code jetzt richtig, aber es gibt noch einige kleinere Verbesserungsmöglichkeiten (die ich weiter unten aufzeige).

Nun aber ersteinmal zu deiner Hauptfrage bzgl. des Datenbank-Inserts:
es ist doch logisch, daß du erst dann die Zeile komplett in die Datenbank schreiben darfst, wenn du dir alle Daten geholt hast (insb. wenn der PrimaryKey fehlt ;-).

Also mußt du wohl vor dem Einfügen (d.h. vor dem Aufruf von InsertBank) noch die Daten aus deiner zweiten DB lesen.
Jedoch verstehe ich deinen Satz
Vegeto hat folgendes geschrieben:
... und nun ist in einer weiteren Variable die Zeile ID 2 von DB B gespeichert.

nicht. Hast du diese Daten nun schon vorliegen, oder weißt du, daß du sie brauchst, aber nicht wie du sie einlesen kannst? In welcher Form liegt denn deine "DB B" vor (auch als CSV-Datei)?
Laut deinem Beispiel passt die erste Zeile der DB A mit der ersten Zeile der DB B überein (obwohl die ID unterschiedlich ist). Ist dies wirklich so, oder sollen die passenden ID Zeilen zueinandergefügt werden?

Und nun noch die kleinen Verbesserungsvorschläge:
- innerhalb der Leseschleife brauchst du nicht immer wieder die Connection öffnen und schließen (packe Open und Close also außerhalb der Schleife).
- sofern du die Daten direkt in die DB schreibst, brauchst du die List<Zeile> doch gar nicht (außer du willst sie nach der Schleife noch weiterverarbeiten)
- du solltest dir einen besseren Namen als Zeile überlegen, z.B. Bankdaten o.ä.

Für diesen Beitrag haben gedankt: Vegeto
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Do 27.09.12 14:26 
Zunächst einmal Danke für dein Eintrag. :)

Ich versuche mal deine Fragen zu beantworten.

Du hast recht, er kann sie erst dann in die DB wenn die Zeile vollständig ist, deshalb soll er auch nur GANZE Zeilen kopieen. Das habe ich auch in den vorherigen Post beschrieben.

Ohh Sorry ... da ist mir ein Fehler aufgetreten, es sollen Natürlich die selben IDs miteinander verbunden werden.
Also die einen Daten hole ich aus einer Sql-Datenbank(hier werden zwei Tabellen miteinander gejoint), die anderen Daten versuche ich Momentan aus einer Datei mit der Endung .iqy zu bekommen, hierran sitze ich momentan(weiß aber nicht wie ich das machen soll).

Ich hoffe jetzt kannst du mir vielleicht besser Helfen?

Danke für die verbesserungen, ändere ich sofort.

Lg
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4795
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 27.09.12 16:11 
Hallo,

am besten, du liest deine ".iqy"-Datei am Anfang einmal in ein Dictionary<intstring[]> ein, d.h. der erste Parameter ist die Id und das String-Array deine einzelnen Spaltenwerte (am besten per String.Split).
Und dann kannst du per TryGetValue(...) die passende Id heraussuchen und auf die zugehörigen Spalten zugreifen.

Für diesen Beitrag haben gedankt: Vegeto
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Fr 28.09.12 12:32 
Ohh... WoW...
Danke :)

Ich weiß leider nicht wie ich die ".iqy"-Datei in Visual Studio einlesen kann, habe schon so einige seiten gefunden, doch die sind auf Englisch und haben meistens immer VB.Net und nicht C# :(

Aber das was du da geschrieben hast sieht ya ziemlich genial aus :)

Werde versuchen dies einzubauen, doch dazu muss ich die Datei auslesen können... weiß aber nicht ob ich das schaffe :(

Danke zunächst :)
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4795
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 28.09.12 12:51 
Ich dachte, das ist eine normale Textdatei (wie in deinem Beispiel)?!
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Fr 28.09.12 14:48 
Nein ist es nicht :(

Ich habe ein überschaubares Beispiel gemacht damit jeder User versteht, was ich will.

Eine ".iqy"-Datei ist eine Excel Abfrage Datei, also sie arbeitet wie Excel nur das sie halt jedesmal aktualisiert wird.
Also sie holt die Daten aus dem Internet oder Intranet.

Nur schaffe ich leider nicht eine solche ".iqy"-Datei in Visual Studio ein zubinden.
Dachte das würde mir Helfen... Hier

Doch da arbeiten die mit VB in der Excel Datei :/

Ich hoffe jmd kann mir dazu helfen, wie ich eine solche Datei in Visual Studio lesen kann mittels C#... :S
Habe es mit einem OleDb Connection versucht, bringt nichts.

Danke im Voraus.

LG
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 28.09.12 15:23 
Was steht den in der iqy? Guckt da doch einfach mal mit einem Editor rein. Da steht vermutlich einfach nur'ne Url drin die man auch genauso gut direkt aufrufen kann.
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Fr 28.09.12 16:07 
Ja du hast recht :) mit zeichen wie = {} und so weiter...
und man kann sie einfach öffnen, es Öffnet sich eine XML-Seite, also eine Seite die wie XML aufgebaut ist, mit den einzelnen spalten.

wie kann ich den das jetzt mit Visual Studio verbinden?
einfach die URL einfügen oder wie?

Oder ein Connection String mit dieser URL?

Lg
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4795
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 28.09.12 17:09 
Hallo,

mußt du die iqy-Abfrage denn zur Laufzeit deines Programms ausführen oder reicht dir einfach eine aktuelle Version der Daten. Dann lade dir doch die Daten mittels Excel und speichere sie dann z.B. als CSV-Datei (und diese kannst du dann bequem einlesen).
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mo 01.10.12 08:15 
Habe auch schon sowas überlegt, einfach im Hintergrund Excel starten lassen, dann die Daten einlesen.
Doch das Programm was ich gerade programmiere, soll später einfach im hintergrund laufen, er soll also immer die Aktuellen Datensätze von der ".iqy"-Datei holen.

Da ".iqy"-Dateien Web basierte Dateien sind, können sie mal Datensätze beinhalten, mal auch nicht.
Deswegen soll ich mit diesen Datentyp arbeiten, denn wenn jedesmal was neues Hinzugefügt wird, soll mein Programm die fehlende Zeile erweitern. Nachdem dann die Datensätze bearbeitet wurden, ist die ".iqy"-Datei wieder leer und sie wird zu einem späterem Zeitpunkt wieder befüllt.

Ich hoffe ihr versteht was ich meine.

Doch ich überlege gerade er kann das ya auch so machen wie du es mir vorgeschlagen hast, dass heißt er soll jedesmal eine .csv datei erstellen... Doch ich überlege gerade das werden später unviele(sehr viele) .csv datei.
Und man soll das ja nicht alles per Hand als .csv datei speichern...

hmm... irgendwie weiß ich nicht mehr weiter :S

Lg
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mo 01.10.12 12:04 
Also Ich habe mal eine neue Idee :D :D :D

Also ich dachte mir ich starte mittels C# Excel und lasse dann die Datei öffnen :D
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Excel.Application excel = new Excel.Application();
            excel.Visible = true;

            string appPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            string filename = Path.Combine(appPath, @"teeest.iqy");

            Excel.Workbook workbook = excel.Workbooks.Open(filename);
            Excel.Worksheet worksheet = workbook.Worksheets[1];


habe das so gemacht :)

Nur weiß ich jetzt nicht wie ich diese Werte/Datensätze ansprechen soll und wie bei der SQL-Abfrage meine Zeilen in Variablen speichern :/

Lg
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mo 01.10.12 15:44 
So habe nun weiter gearbeitet :)

Aber irgendwie geht das nciht wie ich das will :/
Hier mal mein Code:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
            Excel.Application excel = new Excel.Application();
            Excel.Range range = null;
            excel.Visible = false// wenn ich das hier auf true setze öffnet sich Excel, mehr aber nicht!

            string appPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            string filename = Path.Combine(appPath, @"teeest.iqy");

            Excel.Workbook workbook = excel.Workbooks.Open(filename);
            Excel.Worksheet worksheet = workbook.Worksheets[1];

            range = worksheet.UsedRange;
            int rowCount = 0;

            List<Zeile> rows = new List<Zeile>();

            Zahlungen zahlungen = new Zahlungen();
            zahlungen.OpenConnection(ZaConStr);

            for (rowCount = 1; rowCount <= range.Rows.Count; rowCount++)
            {
                //Hier haben wir Zugriff auf jede Zeile
                if ((range.Cells[rowCount, 1as Excel.Range).Value2 != null)
                {
                    try
                    {
                        Zeile RechnungsDaten = new Zeile();                       

                        RechnungsDaten.Betrag = (Int32)(range.Cells[rowCount, 0as Excel.Range).Value2;
                        RechnungsDaten.Verwendung1 = (string)(range.Cells[rowCount, 1as Excel.Range).Value2;
                        RechnungsDaten.Verwendungs2 = (string)(range.Cells[rowCount, 2as Excel.Range).Value2;
                        RechnungsDaten.Fä = (Int32)(range.Cells[rowCount, 3as Excel.Range).Value2;
                        RechnungsDaten.Fr = (string)(range.Cells[rowCount, 4as Excel.Range).Value2;
                        RechnungsDaten.Bemerk = (string)(range.Cells[rowCount, 5as Excel.Range).Value2;
                        RechnungsDaten.Bdatum = (DateTime)(range.Cells[rowCount, 6as Excel.Range).Value2;
                        RechnungsDaten.Zart = (string)(range.Cells[rowCount, 7as Excel.Range).Value2;
                        RechnungsDaten.ZV = (Boolean)(range.Cells[rowCount, 8as Excel.Range).Value2;
                        RechnungsDaten.Etyp = (string)(range.Cells[rowCount, 9as Excel.Range).Value2;
                        RechnungsDaten.Pfad = (string)(range.Cells[rowCount, 10as Excel.Range).Value2;
                        RechnungsDaten.Belegn = (Int32)(range.Cells[rowCount, 11as Excel.Range).Value2;
                        RechnungsDaten.Kundenn = (Int32)(range.Cells[rowCount, 12as Excel.Range).Value2;
                        RechnungsDaten.DID = (Int32)(range.Cells[rowCount, 13as Excel.Range).Value2;
                        RechnungsDaten.ERP = (Int32)(range.Cells[rowCount, 14as Excel.Range).Value2;

                        rows.Add(RechnungsDaten);
                        zahlungen.InsertRechnung(RechnungsDaten);
                    }
                    catch { }
                }
            }
            zahlungen.CloseConnection();


habe das so gemacht wie oben schon einmal gemacht.
ausblenden C#-Quelltext
1:
 range.Cells[rowCount, 0as Excel.Range).Value2;					

habe ich von einer Internet seite :) Ich weiß aufjedenfall das die zweite zahl die Spalte angibt.
Und das davor und danach habe ich einfach übernommen, doch irgendwie kopiert er garnichts, weder Fehlermeldung noch irgendwas...

Kann mir jemand helfen?

Lg

PS.:
Hilfsklasse:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
 public void InsertRechnung(Zeile rows)
        {
            string anweisung = String.Format("INSERT INTO Zahlungsfreigabe" +
                "(Betrag,Verwendung1,Verwendung2,Fä,Fr,Bemerk,Bdatum,Zart,ZV,Etyp,Pfad,Belegn,Kundenn,DID,ERP) Values" +
                "('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}')", rows.Betrag, rows.Verwendung1, rows.Verwendung2, rows.Fä, rows.Fr, rows.Bemerk, rows.Bdatum, rows.Zart, rows.ZV, rows.Etyp, rows.Pfad, rows.Belegn, rows.Kundenn, rows.DID, rows.ERP);
            using (SqlCommand cmd = new SqlCommand(anweisung, this.ZaConn))
            {
                cmd.ExecuteNonQuery();
            }
        }


Danke schonmal fürs lesen :)