Laden...

Tabellen auf Uneinstimmigkeiten vergleichen

Erstellt von myworld vor 7 Jahren Letzter Beitrag vor 7 Jahren 3.645 Views
M
myworld Themenstarter:in
41 Beiträge seit 2013
vor 7 Jahren
Tabellen auf Uneinstimmigkeiten vergleichen

Hallo,
Ich habe hier ein Problem mit dem ich seit einiger Zeit kämpfen muss und zwar habe ich eine Tabelle vom SQL Server und eine Excel Tabelle in zwei verschiedenen DataTables eingefügt, dass läuft schon mal ohne Probleme. Aber jetzt will ich die zwei verschiedenen Tabellen vergleichen, umso die fehlenden Datensätze die in Tabelle 2 vorhanden sind aber nicht in der Tabelle 1 und nicht übereinstimmende Datensätze (Tabelle 1 und 2) in einem Datagridview angezeigt bekommen. Darüber gibt es viel Code im Internet aber bis jetzt hat keines von denen funktioniert. Meine Vermutung ist das die Codes aus dem Internet nur mit Tabellen die das gleiche Schema haben also gleiche Reihenanzahl, gleiche Spaltennamen, gleiche Spaltenanzahl etc. funktionieren. Bei mir ist eher nicht der Fall die Daten sind zwar dieselben aber kleine Unterschiede gibt es:

(Siehe Bild): Die erste Tabelle hat ca. 7000 Zeilen die zweite um die 36000. Bei Tabelle 2 ist das so, dass die Spalte LST nicht nur eine sondern einige Fallnummern und Stückanzahl enthält das geht so weiter wäre das ein Problem wenn es um die Implementierung geht müsste man da etwas beachten?

(siehe Bild) : Und so ca. sollte die Ergebnis Tabelle ausschauen wie oben schon erwähnt sollen die fehlenden Einträge aus der ersten Tabelle dort eingetragen werden und eventuelle unterschiede zwischen den beiden Tabellen (Fehleinträge zum Beispiel), wäre sehr hilfreich wenn irgendjemand eine Lösung oder ein Code Teil für mein Problem hat. Weiter unten findet Ihr meinen derzeitigen Code was ich bisher alles versucht habe.

Danke!


using Microsoft.Win32; 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Linq;
using System.Data.OleDb;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;



namespace Compare
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        DataTable ds;
        DataTable dt;

        public void btn_Click(object sender, EventArgs e)
        {
            SqlDataAdapter adapter = new SqlDataAdapter("select a.test1, m.test2, m.test3, m.test4 From testg m with (nolock) inner join dsd with (nolock) on a.ax = m.aid where m.ML_datum>= '2016-01-01' and m.ort= '9523' order by a.fallzahl", "Server = dsdas; Database = dsd;Trusted_Connection = True");
            ds = new DataTable(" ");
            adapter.Fill(ds);
            dataGridView1.DataSource = ds;



        }

        private void Excelsheet_Click(object sender, EventArgs e)
        {
          
            openFileDialog1.ShowDialog();




        }
      
        private void choose_Click(object sender, EventArgs e)
        {
            OpenFileDialog OpenFileDialog = new OpenFileDialog();

            /* if (OpenFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
             {
                 this.tb_file.Text = OpenFileDialog.FileName;
             }
             */


        }
        private string Excel03ConString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR={1}'";

        private string Excel07ConString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 8.0;HDR={0}'";







        public void openFileDialog1_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
        {
            string filePath = openFileDialog1.FileName;

            string extension = Path.GetExtension(filePath);

            string header = radioButton1.Checked ? "YES" : "NO";

            string conStr, sheetName, cells;




            conStr = string.Empty;

            switch (extension)
            {
                    


                case ".xls": //Excel 97-03

                    conStr = string.Format(Excel03ConString, filePath, header);

                    break;



                case ".xlsx": //Excel 07

                    conStr = string.Format(Excel07ConString, filePath, header);

                    break;
            }




            using (OleDbConnection con = new OleDbConnection(conStr))
            {

                using (OleDbCommand cmd = new OleDbCommand())
                {

                    cmd.Connection = con;
                    con.Open();

                    System.Data.DataTable dtExcelSchema = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

                    sheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();



                    // cells = filePath.Cells[1, 1].Value.ToString();
                    //string sValue = (filePath.Cells[i + 36377, 1] as Microsoft.Office.Interop.Excel.Range).Value2.ToString();
                    //_row,_column your column & row number 
                    //eg: string sValue = (sheet.Cells[i + 9, 12] as Microsoft.Office.Interop.Excel.Range).Value2.ToString();
                    //sValue has your value
                    con.Close();







                }

            }

            using (OleDbConnection con = new OleDbConnection(conStr))
            {

                using (OleDbCommand cmd = new OleDbCommand())
                {

                    using (OleDbDataAdapter oda = new OleDbDataAdapter())
                    {

                        dt = new DataTable();

                        cmd.CommandText = "SELECT * From [" + sheetName + "]";

                        cmd.Connection = con;

                        con.Open();

                        oda.SelectCommand = cmd;

                        oda.Fill(dt);

                        con.Close();


                        dataGridView2.DataSource = dt; 


                    }

                }

            }
        }
        

        /*public static DataTable CompareTwoDataTable(DataTable ds, DataTable dt)
        {

            ds.Merge(dt);

            DataTable d3 = dt.GetChanges();


            return d3;
      
        }
        */

        private void dataGridView3_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            DataTable d3 = new DataTable(" ");

        }


        private void Form1_Load(object sender, EventArgs e)
        {
            /* dataGridView3.DataSource = from table1 in ds.AsEnumerable()
                          join table2 in dt.AsEnumerable() on table1.Field<int>("ColumnA") equals table2.Field<int>("ColumnA")
                          where table1.Field<int>("ColumnB") == table2.Field<int>("ColumnB") || table1.Field<string>("ColumnC") == table2.Field<string>("ColumnC") || table1.Field<object>("ColumnD") == table2.Field<object>("ColumnD")
                          select table1;
             dataGridView3.DataSource = from table1 in ds.AsEnumerable()
                          where !dataGridView3.Contains(table1)
                          select table1;
             */
        }

        public void CompareData()
        {
            //If you have primary keys:
            //var results = from table1 in dt1.AsEnumerable()
            //            join table2 in dt2.AsEnumerable() on table1.Field<int>("id") equals table2.Field<int>("id")
            //          where table1.Field<int>("ColumnA") != table2.Field<int>("ColumnA") || table1.Field<int>("ColumnB") != table2.Field<int>("ColumnB") || table1.Field<String>("ColumnC") != table2.Field<String>("ColumnC")
            //        select table1;
            //This will give you the rows in dt1 which do not match the rows in dt2.  You will need to expand the where clause to include all your columns.


            //If you do not have primarry keys then you will need to match up each column and then find the missing.

            //var matched = from table1 in ds.AsEnumerable()
            //           join table2 in dt.AsEnumerable() on table1.Field<int>("ColumnA") equals table2.Field<int>("ColumnA")
            //          where table1.Field<int>("ColumnB") == table2.Field<int>("ColumnB") || table1.Field<string>("ColumnC") == table2.Field<string>("ColumnC") || table1.Field<object>("ColumnD") == table2.Field<object>("ColumnD")
            //        select table1;
            // var missing = from table1 in ds.AsEnumerable()
            //            where !matched.Contains(table1)
            //          select table1;
            // This should give you the rows which do not have a match.  You will need to expand the where clause to include all your columns.
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Ausgabe!!!! 
            //DataTable dtmismatch = ds.AsEnumerable().Except(dt.AsEnumerable(), DataRowComparer.Default).CopyToDataTable<DataRow>();

            // Get rows those are present in table2 but not in table1
            //IEnumerable<DataRow> rowsNotInTableA = dt.AsEnumerable().Except(ds.AsEnumerable());

           // dataGridView3.DataSource = CompareTables();

            /*
                 var matched = from table1 in ds.AsEnumerable()
                               join table2 in dt.AsEnumerable() on table1.Field<string>("ColumnA") equals table2.Field<string>("ColumnC")
                               where table1.Field<string>("ColumnB") == table2.Field<string>("ColumnA") || table1.Field<int>("ColumnC") == table2.Field<int>("ColumnD")
                               select table1; 
                 var missing = from table1 in ds.AsEnumerable()
                               where !matched.Contains(table1)
                               select table1;
           
                

                      
             }
                ! */

           // dataGridView3.DataSource = CompareTables();
            

        }

        /*        public bool DatatablesAreSame()
                {



                    if (ds.Rows.Count == dt.Rows.Count)

                        return true;

                    foreach (DataColumn dc in ds.Columns)
                    {
                        for (int i = 0; i < dt.Rows.Count; i++)
                        {
                            if (ds.Rows[i][dc.ColumnName = "test"] != dt.Rows[i][dc.ColumnName = "test1"])
                            {
                    

                            }
                        }
                    }
            
                    return true;
                }
     
           */


        private void CompareTables()
        {

            try
            {

              

                var dt1Records = ds.AsEnumerable().Select(e1 => new { Id = e1["ISH_FALLZAHL"].ToString(), Name = e1["FAL"].ToString() });

                var dt2Records = dt.AsEnumerable().Select(e2 => new { Id = e2["ISH_FALLZAHL"].ToString(), Name = e2["FAL"].ToString() });



                var extraRecords = dt1Records.Except(dt2Records);




                dataGridView3.DataSource = extraRecords;
           



            }

            catch (Exception ex)

            { }

        }

       



        

    }
}

        



      


H
523 Beiträge seit 2008
vor 7 Jahren

Hilft Dir vielleicht diese Erklärung?

M
myworld Themenstarter:in
41 Beiträge seit 2013
vor 7 Jahren

Leider nicht, mein Problem ist das ich nach eine Methode/Lösung für das obige Problem suche aber gar nichts gescheites finde bzw. keine Ahnung habe wie ich an das rangehen soll.

Danke!

T
314 Beiträge seit 2013
vor 7 Jahren

Wo genau liegt denn dein Problem? Das die Tabellen ein unterschiedliches Schema haben ist erstmal egal.

Du musst jedoch ein Kriterium haben, welches einen Datensatz in beiden Tabellen als zusammengehörig/gleich definiert.

Danach sollte es für dich problemlos möglich sein die Tabelle 3 zu erstellen. Dort sollte es dann ja reichen über beide Tabellen zu iterieren und prüfen ob der Datensatz bereits in Tabelle 3 vorhanden ist. Falls nicht hinzufügen, falls schon ggf. Datensatz anreichern oder eben einfach ignorieren.

M
myworld Themenstarter:in
41 Beiträge seit 2013
vor 7 Jahren

Naja das Problem ist das die Codes die ich alle probiert habe nicht funktionieren entweder er gibt null aus oder er gibt eine unlogische Lösung aus. Tabelle 1 hat 2 Primary keys genauso wie Tabelle 2, zwar heißen die Spalten anders aber trotzdem ist der gleiche Datentyp und der Inhalt gleich. Ich würde gerne wisse ob es irgend ein Code im Internet gibt der bei meinen Anforderungen funktionieren würde.

Danke!

3.170 Beiträge seit 2006
vor 7 Jahren

Hallo,

wenn Du meint ob es einen Code gibt der ohne Anpassungen genau für Dein roblem passt - eher nicht. Zumindest die Logik, welche Datensätze als gleich interpretiert werden, musst Du sicher selbst schreiben.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

M
myworld Themenstarter:in
41 Beiträge seit 2013
vor 7 Jahren

Tut mir leid habe mich falsch ausgedrückt. Natürlich muss ich einiges anpassen. Das was ich brauche ist ein Code der mir als Ansatz dient da ich bisher nur falsche Codes gefunden habe selbst ausbauen werde ich den schon selber.

Danke!

J
251 Beiträge seit 2012
vor 7 Jahren

Wurde schon versucht via SQL die Schemen zu analysieren?

M
myworld Themenstarter:in
41 Beiträge seit 2013
vor 7 Jahren

Nein noch nicht aber wie soll das gehen wenn die Daten in Datatables sind kann man damit per SQL zugreifen? Falls ja wäre es nett von dir ein Mustercode bzw. Link zu senden.

Danke!

H
523 Beiträge seit 2008
vor 7 Jahren

Warum nicht so wie t0ms3n es vorgeschlagen hat? Ist doch ein sehr einfacher Weg:

Danach sollte es für dich problemlos möglich sein die Tabelle 3 zu erstellen. Dort sollte es dann ja reichen über beide Tabellen zu iterieren und prüfen ob der Datensatz bereits in Tabelle 3 vorhanden ist. Falls nicht hinzufügen, falls schon ggf. Datensatz anreichern oder eben einfach ignorieren.

M
myworld Themenstarter:in
41 Beiträge seit 2013
vor 7 Jahren

ohne Code Ansatz schaffe ich es leider nicht.

H
523 Beiträge seit 2008
vor 7 Jahren

Woran hapert es denn genau?

P
1.090 Beiträge seit 2011
vor 7 Jahren

Nimm doch mal den leeren Catch Block in der CompareTables() Methode weg. Ich denke dann solltest du eine Exception bekommen da "ISH_FALLZAH" nach deiner Angabe in keinen der Tabellen ist. Sondern IST_FALLNUMMER. Und dann auch nur in einer der Tabellen. Genau wie FAL.

Beides mal als ID nehmen und Name weg lassen. Dann sollte Except auch funktionieren.

p.s. Poste bitte nur relevanten Code. Wer hat den schon Lust deinen ganzen Code (teils auch noch Auskommentierten) zu lesen. 😉

Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern