Autor Beitrag
sebastian1234
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Do 02.01.14 15:46 
Hallo zusammen,

ich muss ein Excel File auslesen und dieses anschließend in meinem Programm in double oder int in einem Array ablegen das weiter verarbeitet wird.

Folgendes habe ich bisher programmiert. Ich kann das Excel File bereits auslesen und in einem Datagrid darstellen.

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:
public partial class Form1 : Form
    {
        
        public Form1()
        {
            InitializeComponent();
        }
  
        private void ChooseFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.textBox1.Text = openFileDialog1.FileName;
            }
        }

        private void AuswahlTabelle_Click(object sender, EventArgs e)
        {
            string PathConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + textBox1.Text + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
            OleDbConnection conn = new OleDbConnection(PathConn);

            OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("Select * from [" + textBox2.Text + "$]", conn);
            DataTable dt = new DataTable();

            myDataAdapter.Fill(dt);
            dataGridView1.DataSource = dt;

            DataSet kt = new DataSet();
            double[][] kunde = new double[2][];
            
            
        }

       
    }
}



Es handelt sich um ein einfaches Excel File mit jeweils 3 Spalten und Zeilen! Allerdings kann möglichweise eine Spalte hinzukommen. Besteht die Möglichkeit das die einzelnen Spalten und Zeilen dann "flexible" in ein Array gespeichert werden?

Darüberhinaus soll nach in der Oberfläche die Möglichkeit einer Spaltenauswahl bestehen. D.h. das der User auswählen kann welche Spalte berücksichtigt werden und somit in das Array übernommen werden sollen. Wie würdet ihr hier vorgehen? Ich würde mich über kleine Tipps sehr freuen...

Vielen Dank und viele grüße

Moderiert von user profile iconChristian S.: Quote- durch C#-Tags ersetzt

Moderiert von user profile iconChristian S.: Beiträge zusammengefasst

Über den OleDb kann ich ja auf jeden Fall schonmal die Daten auslesen. Aber wie werden die Werte jetzt in ein Array (oder vielleicht etwas anderes) gespeichert, damit diese Werte nachher verrechnet werden können...
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: Do 02.01.14 16:30 
Zitat:
Es handelt sich um ein einfaches Excel File mit jeweils 3 Spalten und Zeilen! Allerdings kann möglichweise eine Spalte hinzukommen. Besteht die Möglichkeit das die einzelnen Spalten und Zeilen dann "flexible" in ein Array gespeichert werden?

z.B.
ausblenden C#-Quelltext
1:
double[][] kunde = dt.Rows.OfType<DataRow>().Select(x => x.ItemArray.Cast<double>().ToArray()).ToArray();					



Zitat:
Darüberhinaus soll nach in der Oberfläche die Möglichkeit einer Spaltenauswahl bestehen. D.h. das der User auswählen kann welche Spalte berücksichtigt werden und somit in das Array übernommen werden sollen. Wie würdet ihr hier vorgehen? Ich würde mich über kleine Tipps sehr freuen...


Das Connection Object OleDbConnection hat eine GetSchema Methode da kannst du dir für alle Tabellen die Spalteninfo ranholen durcharbeiten und die möglichen Spalten dann zur Auswahl anbieten.
Mit den dann ausgewählten Spalten kannst du denn Linqausdruck entsprechend anpassen.

ausblenden C#-Quelltext
1:
double[][] kunde  = dt.Rows.OfType<DataRow>().Select(x => new double[] { (double)x["A"], (double)x["B"] }).ToArray();					


Edit: Das letzte was Unsinn. Ich vergaß das es von selbst kein dynamisches Linq gibt.

Was funktioniert ist sich die Indizes der ausgewählten Spalten zu merken. Die kann man leicht vergleichen ohne dynamischen Code zu brauchen.

ausblenden C#-Quelltext
1:
2:
double[] selectedRowIndices = { 02 };
int[][] kunde = dt.Rows.OfType<DataRow>().Select(x => x.ItemArray.Cast<double>().Where((v,i) => selectedRowIndices.Contains(i)).ToArray()).ToArray();


Edit 2:

Zitat:

Über den OleDb kann ich ja auf jeden Fall schonmal die Daten auslesen. Aber wie werden die Werte jetzt in ein Array (oder vielleicht etwas anderes) gespeichert, damit diese Werte nachher verrechnet werden können...


Wenns kein Array sein muß dann nimm halt die DataTable die du schon hast.
sebastian1234 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Do 02.01.14 18:24 
Vielen Dank Ralf!

Das auslesen der Excel Tabelle klappt, allerdings nimmt er nicht alle Spalten! Damit du auch genau verstehst was ich eigentlich mache kurz noch eine wichtige Info. Ich entwickle zunächst ein Programm das Euklidische Distanzen zwischen verschiedenen Werte berechnet.

Ausgangspunkt war bisher diese Klasse mit folgendem Array. Dieses "Array" bzw die Werte habe ich 1:1 in das Excel File gelegt!

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
 /*double[][] kunde = new double[3][];

            kunde[0] = new double[] { 1, 10, 30 };
            kunde[1] = new double[] { 2, 40, 10 };
            kunde[2] = new double[] { 3, 15, 25 }; */


Dieses Array wurde in folgender Methode zur Berechnung der Distanzmaße angewendet...

ausblenden 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:
static void distanzBerechnung(double[][] kunde)
        {
            for (int a = 0; a < kunde.Length; ++a)
            {
                Console.WriteLine(kunde[a][0]);

                for (int b = 0; b < kunde.Length; ++b)
                {
                    //Console.WriteLine(kunde[b][0]);

                    for (int p = 1; p <= 1; ++p)
                    {
                        for (int q = 2; q <= 2; ++q)
                        {
                            double Formel = 0;
                            //Console.WriteLine(kunde[a][p]);
                            //Console.WriteLine(kunde[b][q]);
                            Formel = Math.Sqrt(Math.Pow(kunde[a][p] - kunde[b][p], 2) + Math.Pow(kunde[a][p] - kunde[b][p], 2));
                            Console.WriteLine(Formel);
                            //Console.ReadLine();
                        }
                        
                    }
                }
            }
        
        }


Wenn ich nun deine Abfrage verwende...

ausblenden C#-Quelltext
1:
double[][] kunde = dt.Rows.OfType<DataRow>().Select(x => x.ItemArray.Cast<double>().ToArray()).ToArray();					


Gibt er mir allerdings nur die Spalte A und B der Excel Tabelle aus. Dadurch ist die Distanzberechnung natürlich unvollständig. Ich bin noch nicht auf die Lösung des Problems gekommen...

Trotzdem vielen vielen Dank! Endlich komme ich mit meinem Programm wieder etwas weiter =)
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 02.01.14 18:42 
Hallo und :welcome:

die Übergabe an das Array wird einwandfrei funktionieren, nur ist deine Auswertung innerhalb deiner Methode distanzBerechnung fehlerbehaftet:
- du greifst bisher nur auf p zu (nicht auf q)!
- die beiden for-Schleifen mit p und p sind überflüssig
sebastian1234 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Fr 03.01.14 16:07 
Okay du hast Recht das hatte ich total übersehen! Ich habe es jetzt so abgeändert...

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
 static void distanzBerechnung(double[][] kunde)
        {
            for (int a = 0; a < kunde.Length; ++a)
            {
                Console.WriteLine(kunde[a][0]);

                for (int b = 0; b < kunde.Length; ++b)
                {
                    //Console.WriteLine(kunde[b][0]);
                    int p = 1;
                    int q = 2;
                    int t = 3;
                    //Console.WriteLine(kunde[a][t]);
                    //Console.WriteLine(kunde[b][t]);
                    double Formel = 0;
                    Formel = Math.Sqrt(Math.Pow(kunde[a][p] - kunde[b][p], 2) + Math.Pow(kunde[a][q] - kunde[b][q], 2) + Math.Pow(kunde[a][t] - kunde[b][t], 2));
                    Console.WriteLine(Formel);     
                }
            }
        }


Wie ich oben schon angesprochen habe, muss ich eine Auswahlmöglichkeit bauen die mir ermöglicht, gewisse Spalten auszuwählen, sodass nur die ausgewählten Spalten in die Distanzberechnung mit eingehen.

So sieht die Excel Tabelle bzw. das DataGrid aus:

ID / Kennzahl1 / Kennzahl2 / Kennzahl3
1 / 10 / 20 / 15
2 / 25 / 45 / 35
3 / 45 / 55 / 85

Ich habe gesehen das man im DataGrid die Spalten markieren bzw. auswählen kann. Darüber kann man doch dann bestimmt eine solche Auswahlmöglichkeit realisieren. Also das nur die Makierten Spalten an das Array und dann die Distanzberechnung übergeben werden.

Eine andere Lösung könnte vielleicht das Anlegen einer CheckedListBox sein, die dann die Spaltenüberschriften der Tabelle ausließt und in der man dann jeweils die Spalten auswählen kann (bsp. Kennzahl1 und Kennzahl2)

Welchen Weg würde sich hier am besten anbieten.

Viele Grüße
sebastian1234 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Fr 03.01.14 18:04 
Kurze Ergänzung!

ausblenden 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:
private void AuswahlButton_Click(object sender, EventArgs e)
        {
            string PathConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + textBox1.Text + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
            OleDbConnection conn = new OleDbConnection(PathConn);
            OleDbCommand cmd = new OleDbCommand("Select column_name from [" + "Tabelle1" + "$]", conn);
            OleDbDataReader dr;


            
            
            dr = cmd.ExecuteReader();
            if (dr.HasRows)
            {
                while (dr.Read())
                {
                    checkedListBox1.Items.Add(dr[0].ToString());
                }
            }
            dr.Close();
            conn.Close();
           
            
            
        }


Um die oberste Reihe zur Auswahl der Spalten zu erhalten habe ich column_name genommen! Allerdings bin ich mir nicht sicher ob das wirklich funktioniert!

Die oberste Spaltenname sollen in der checkboxliste ausgegeben werden und darüber ausgewählt werden können.
Aktuelle erhalte ich beim Ausführen den Fehler "INvalidOperationException" bei dr. = cmd.ExecuteReader();
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 03.01.14 18:33 
Ich zitier mich mal selbst.

user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Das Connection Object OleDbConnection hat eine GetSchema Methode da kannst du dir für alle Tabellen die Spalteninfo ranholen durcharbeiten und die möglichen Spalten dann zur Auswahl anbieten.


Das was du vor hattest ist irgendwie merkwürdig. Die Spaltennamen in deiner Tabelle stehen in einer Row und nicht in einer Column. Wo hast du das her mit column_name?
sebastian1234 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Fr 03.01.14 18:39 
Mein Beispiel basiert auf dem SQL Client! Ich dachte ich könnte das irgendwie mit OleDB verbinden bzw. einbauen. Ok das scheint nicht zu gehen.

Dann werde ich mir mal das GetSchema von OleDbConnection anschauen...
sebastian1234 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Mo 06.01.14 13:01 
Ich habe mich am Wochenende mal mit OleDbConnection get Schema auseinander gesetzt und folgendes gebaut (in der Methode AuswahlButton_CLick)...

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:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;

namespace Clusteranalyse
{
    public partial class Form1 : Form
    {
        
        public Form1()
        {
            InitializeComponent();
        }
  
        private void ChooseFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.textBox1.Text = openFileDialog1.FileName;
            }
        }

        private void AuswahlTabelle_Click(object sender, EventArgs e)
        {
            string PathConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + textBox1.Text + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
            OleDbConnection conn = new OleDbConnection(PathConn);

            OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("Select * from [" + "Tabelle1" + "$]", conn);
            DataTable dt = new DataTable();

            myDataAdapter.Fill(dt);
            dataGridView1.DataSource = dt;

            
            double[][] kunde = dt.Rows.OfType<DataRow>().Select(x => x.ItemArray.Cast<double>().ToArray()).ToArray();
            //double[][] kunde = dt.Rows.OfType<DataRow>().Select(x => new double[] { (double)x["A"], (double)x["B"], (double)x["C"] }).ToArray(); 
            distanzBerechnung(kunde);

            
           
            
        }

        static void distanzBerechnung(double[][] kunde)
        {
            for (int a = 0; a < kunde.Length; ++a)
            {
                Console.WriteLine(kunde[a][0]);

                for (int b = 0; b < kunde.Length; ++b)
                {
                    //Console.WriteLine(kunde[b][0]);
                    int p = 1;
                    int q = 2;
                    int t = 3;
                    //Console.WriteLine(kunde[a][t]);
                    //Console.WriteLine(kunde[b][t]);
                    double Formel = 0;
                    Formel = Math.Sqrt(Math.Pow(kunde[a][p] - kunde[b][p], 2) + Math.Pow(kunde[a][q] - kunde[b][q], 2) + Math.Pow(kunde[a][t] - kunde[b][t], 2));
                    Console.WriteLine(Formel);     
                }
            }
        }

        private void AuswahlButton_Click(object sender, EventArgs e)
        {
            //string PathConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + textBox1.Text + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
            OleDbConnection conn = new OleDbConnection();
            OleDbCommand cmd = new OleDbCommand();
            DataTable schemaTable;
            OleDbDataReader myReader;

            conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + textBox1.Text + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
            conn.Open();

            cmd.Connection = conn;
            cmd.CommandText = "Select * from [" + "Tabelle1" + "$]";
            myReader = cmd.ExecuteReader(CommandBehavior.KeyInfo);

            schemaTable = myReader.GetSchemaTable();

            foreach (DataRow myField in schemaTable.Rows)
            {
                foreach (DataColumn myProperty in schemaTable.Columns)
                {
                    Console.WriteLine(myProperty.ColumnName + " = " + myField[myProperty].ToString());
                }
                Console.WriteLine();
                Console.ReadLine();
            }

            myReader.Close();
            conn.Close();
            
        }
    }
}


Ich möchte mir zunächst über die Methode AuswahlButton_Click, die Spaltennamen über die Console ausgeben lassen und damit nachher die Auswahl durchzuführen. Allerdings erhalte ich momentan 2 Fehler!

1.Fehler
Quelldatei: .... /Clusteranalyse/Form1.cs
Modul: .... /bin/debug/Clusteranalyse.exe
Prozess: [2576] Clusteranalyse.vshost.exe

Die Quelldatei ist anders als zum Zeitpunkt der Erstellung des Moduls. Soll der Debugger sie dennoch verwenden? ja/nein

2.Fehler
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + textBox1.Text + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";

InvalidOperationException -> Execute Reader erfordert eine geöffnete und verfügbare Verbindung. Aktueller Status geschlossen!


Mir ist nicht ganz klar weshalb die Verbindung geschlossen ist? Über conn.open(); öffne ich sie doch?!

Mein Programm ist bisher auch sehr provisorisch aufgebaut. So gibt es noch die ursprungs Klasse welche nur noch ein Objekt vom Typ form öffnet

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
namespace Clusteranalyse
{
    class DistanzenBerechnen
    {
        [STAThread]
        static void Main(string[] args)
        {
            /*double[][] kunde = new double[3][];

            kunde[0] = new double[] { 1, 10, 30 };
            kunde[1] = new double[] { 2, 40, 10 };
            kunde[2] = new double[] { 3, 15, 25 }; */


            Form1 dialog = new Form1();
            dialog.ShowDialog();

            //fakult‰t(kunde);
            //distanzBerechnung(kunde)
            //Console.ReadLine(); 


        }


Kann einer erkenne wo ich einen Fehler mache?
Viele Grüße!
sebastian1234 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Do 09.01.14 16:10 
Hallo,

nachdem ich das Programm nochmals neue 1:1 programmiert habe erhalt ich nun eine Ausgabe!
Allerdings werde eine ganz Reihe verschiedener Informationen in der Konsole veröffentlicht.

ColumnName = ID
ColumnOrdinal = 0
ColumnSize = 8
NumericPrecision = 15
NumericScale = 0
DataType = System.double
ProviderType= 5
usw...

Meine Excel Tabelle besteht ja aus den Spalten ID/Kennzahl1/Kennzahl2/Kennzahl3 und nur diese Spalten sollten ausgegeben werden, sodass später eine Auswahl nach diesen Spalten gemacht werden kann.

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:
private void AuswahlButton_Click(object sender, EventArgs e)
        {
            //string PathConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + textBox1.Text + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
            OleDbConnection conn = new OleDbConnection();
            OleDbCommand cmd = new OleDbCommand();
            DataTable schemaTable;
            OleDbDataReader myReader;

            conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + textBox1.Text + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
            conn.Open();

            cmd.Connection = conn;
            cmd.CommandText = "Select * from [" + "Tabelle1" + "$]";
            myReader = cmd.ExecuteReader(CommandBehavior.KeyInfo);

            schemaTable = myReader.GetSchemaTable();

            foreach (DataRow myField in schemaTable.Rows)
            {
                foreach (DataColumn myProperty in schemaTable.Columns)
                {
                    Console.WriteLine(myProperty.ColumnName + " = " + myField[myProperty].ToString());
                }
                Console.WriteLine();
                Console.ReadLine();
            }

            myReader.Close();
            conn.Close();
            
        }
    }


Ich denke das Problem liegt irgendwie in der foreach-Schleife?!
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 09.01.14 16:24 
Hallo,

das ist doch offensichtlich: in der inneren Schleife iterierst du über alle Spalten der Schema-Tabelle.

Wenn du nur den Namen der Spalten haben willst, dann anstatt der inneren Schleife
ausblenden C#-Quelltext
1:
string sColumnName = myField["ColumnName"].ToString(); // oder myField[0].ToString()					

s.a. OleDbDataReader.GetSchemaTable (unter Hinweise)

Für diesen Beitrag haben gedankt: sebastian1234
sebastian1234 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Do 09.01.14 17:32 
Ohja du das stimmt!


Ich habe jetzt diese Lösung gebaut und sie funktioniert!
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
foreach (DataRow myField in schemaTable.Rows)
{
   string sColumnName = myField["ColumnName"].ToString();
   checkedListBox1.Items.Add(sColumnName);
}


Allerdings kommt jetzt der wohl komplizierte Teil.
Wie schaffe ich es das Array so zu beeinflussen das nur die Ausgewählten Felder mit einbezogen werden?
Irgendwie muss die Auswahl ja mit in die OleDbCommand Anweisung. Also das quasi nur die ausgewählten Spalten berücksichtigt werden?! Das * hinter SELECT müsste doch irgendwie angepasst werden?

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("Select * from [" + "Tabelle1" + "$]", conn);
            DataTable dt = new DataTable();

            myDataAdapter.Fill(dt);
            dataGridView1.DataSource = dt;

            
            double[][] kunde = dt.Rows.OfType<DataRow>().Select(x => x.ItemArray.Cast<double>().ToArray()).ToArray();
            distanzBerechnung(kunde);


Vielen Dank
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: Do 09.01.14 18:23 
Nimm dir die selektierten Einträge aus deiner CheckListBox und schreib die kommasepariert anstelle des * in die Abfrage.

Für diesen Beitrag haben gedankt: sebastian1234
sebastian1234 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Do 09.01.14 18:47 
Ich möchte das dynamisch machen. Also das ich in meiner Oberfläche die einzelnen Spalten auswählen kann. Wenn ich die Spaltennamen jetzt einfach in die Abfrage schreibe ist das ja nicht möglich. Oder habe ich das falsch verstanden?

...


Kann man die ausgewählten Spalten nicht durch drücken eines Buttons in ein Array schreiben und dieses dann in die Abfrage anstelle von * integrieren?
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: Do 09.01.14 18:52 
Ja? Zur Laufzeit liest du die gerade selektierten Einträge aus der Listbox und schreibst die Liste an die Stelle wo im Moment noch der * steht. Was in einen string einfügen solltest du hinbekommen hast du ja mit dem Sheet-Namen auch geschafft.
sebastian1234 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Do 09.01.14 20:24 
Ich habe mal was probiert allerdings bin ich langsam mit meinem Latein am Ende.

Hiermit wollte ich mir die ausgewählten Spalten ausgeben lassen aber irgendwie gibt er mir die nciht wirklich zurück.
ausblenden C#-Quelltext
1:
checkedListBox1.getitemText(CheckedListBox1.CheckedItems);					


Button1 = Ließt die Spalten aus dem Excel File und zeigt sie mir in der Checkedlist box an.
Über Button2 = Sollen nun die ausgewählten Spalten in das Array gespeichert werden....

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
private void AuswahlTabelle_Click(object sender, EventArgs e)
        {
            string PathConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + textBox1.Text + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
            OleDbConnection conn = new OleDbConnection(PathConn);


            //Hier müssen die gecheckten Listbox ausgelesen werden und dann in einem String gespeichert werden... der dann in die myDbDataAdapter Abfrage kommt...

            OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("Select * from [" + "Tabelle1" + "$]", conn);
            DataTable dt = new DataTable();

            myDataAdapter.Fill(dt);
            dataGridView1.DataSource = dt;

            
            double[][] kunde = dt.Rows.OfType<DataRow>().Select(x => x.ItemArray.Cast<double>().ToArray()).ToArray();
             
            distanzBerechnung(kunde);


Kennst du vielleicht ein ähnliches Beispiel an dem ich mich orientierten kann?
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: Do 09.01.14 21:29 
Das mit getitemText wird dir nicht weiterhelfen. Du hast ja die Texte vermutlich direkt in die CheckedListBox geschrieben damit enthält die CheckedItems einfach eine Liste von strings. Das muß man dem Compiler nur klar machen. Das geht zum Beispiel mit der Extension Method OfType<T>. Wenn du dann eine Liste von strings hast kannst du die mit string.Join und einem Trennzeichen zusammenfügen.

Also etwa

ausblenden C#-Quelltext
1:
string meineLiebenColumns = string.Join(",", checkedListBox1.CheckedItems.OfType<string>());					


und dann das eben als Spaltenliste in deinen SQL String einbauen. Etwa

ausblenden C#-Quelltext
1:
2:
string meinLiebesSQLStatement = string.Format("select {0} from [{1}$]", meineLiebenColumns , meinLieberSheetName);
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter(meinLiebesSQLStatement , conn);
sebastian1234 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Sa 11.01.14 13:30 
Hallo Ralf,

ich verstehe jetzt wie das funktioniert aber ich habe mich vorher etwas ungenau ausgedrückt.
Hier jetzt nochmal das vollständige Programm!

Ich geh mal schnell die Methoden durch:

1.choose_File Click: wählt die Datei aus!
2.Auswahl_tabelle Click: Holt die Daten aus dem Excel File, stellte diese im DataGrid an der oberfläche dar und Berechnet dann die Distanzen
3.distanz_Berechnung: Berechnet die Distanzen
4.Auswahl_button Click: ließt die Spaltendaten aus dem Excel File und läd sie in das checklistbox feld!

Ich möchte nun die Methode 2 und 4 quasi zu einer machen! Die Spaltenname werden zur Laufzeit über den Auswahl_Button Click in das checkedlistbox Feld geladen und stehen nciht vorher schon drin! auf Basis der Auswahl soll dann so weitergerechnet werden wie in methode 1!

ich habe
ausblenden C#-Quelltext
1:
string meineLiebenColumns = string.Join(",", checkedListBox1.CheckedItems.OfType<string>());					


irgendwie versucht mal in die 4.methode einzubauen um damit die ausgewählten spalten werte aus der checkedlistbox zu erhalten aber irgendwie wird immer ein fehler angezeigt...

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:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;

namespace Clusteranalyse
{
    public partial class Form1 : Form
    {
        
        public Form1()
        {
            InitializeComponent();
        }
  
        private void ChooseFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.textBox1.Text = openFileDialog1.FileName;
            }
        }

        private void AuswahlTabelle_Click(object sender, EventArgs e)
        {
            string PathConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + textBox1.Text + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
            OleDbConnection conn = new OleDbConnection(PathConn);

            OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("Select * from [" + "Tabelle1" + "$]", conn);
            DataTable dt = new DataTable();

            myDataAdapter.Fill(dt);
            dataGridView1.DataSource = dt;

            
            double[][] kunde = dt.Rows.OfType<DataRow>().Select(x => x.ItemArray.Cast<double>().ToArray()).ToArray();
            distanzBerechnung(kunde);     
            
        }

        static void distanzBerechnung(double[][] kunde)
        {
            for (int a = 0; a < kunde.Length; ++a)
            {
                Console.WriteLine(kunde[a][0]);

                for (int b = 0; b < kunde.Length; ++b)
                {
                    //Console.WriteLine(kunde[b][0]);
                    int p = 1;
                    int q = 2;
                    int t = 3;
                    //Console.WriteLine(kunde[a][t]);
                    //Console.WriteLine(kunde[b][t]);
                    double Formel = 0;
                    Formel = Math.Sqrt(Math.Pow(kunde[a][p] - kunde[b][p], 2) + Math.Pow(kunde[a][q] - kunde[b][q], 2) + Math.Pow(kunde[a][t] - kunde[b][t], 2));
                    Console.WriteLine(Formel);     
                }
            }
        }


       private void AuswahlButton_Click_1(object sender, EventArgs e)
       {
           //string PathConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + textBox1.Text + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
           OleDbConnection conn = new OleDbConnection();
           OleDbCommand cmd = new OleDbCommand();
           DataTable schemaTable;
           OleDbDataReader myReader;

           conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + textBox1.Text + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
           conn.Open();

           cmd.Connection = conn;
           cmd.CommandText = "Select * from [" + "Tabelle1" + "$]";
           myReader = cmd.ExecuteReader(CommandBehavior.KeyInfo);

           schemaTable = myReader.GetSchemaTable();

           foreach (DataRow myField in schemaTable.Rows)
           {
               string sColumnName = myField["ColumnName"].ToString();
               checkedListBox1.Items.Add(sColumnName);
               //string test = checkedListBox1.GetItemText(checkedListBox1.CheckedItems);
               //string meineLiebenColumns = string.Join(",", checkedListBox1.CheckedItems.OfType<string>());
               
               //Console.WriteLine(test);
           }
           

           myReader.Close();
           conn.Close();
            
       } 
    }
}


Wie würdest du die Methoden 2 und 4 zusammenlegen sodass mein Problem gelöst wird? Bzw. was verstehe ich nicht oder mache ich falsch, dass ich die ausgewählten Items der checkedlistbox nicht erhalte?

EDIT:

In der foreach Mehtoden müsste irgendwie etwas rein das quasi bei jedem Durchlauf die Spaltenname speichert ... ?
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 11.01.14 13:45 
Hallo sebastian1234,

sebastian1234 hat folgendes geschrieben:
aber irgendwie wird immer ein fehler angezeigt...

Welchen genauen Fehler erhältst du denn?
Arbeitest du noch mit .NET 3.5 (oder tiefer)? Dann fehlt noch ein .ToArray() beim 2. Parameter von String.Join (da die Überladung mit IEnumerable<T> noch nicht existiert).

Du solltest - in deinem eigenen Interesse - lernen, Fehlermeldungen interpretieren zu können, um diese selbständig zu lösen (d.h. evtl. im Internet danach zu suchen oder in der MSDN nachzuschlagen etc.).
sebastian1234 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46



BeitragVerfasst: Sa 11.01.14 13:53 
Wahrscheinlich tiefer denn jetzt geht es! Allerdings gibt er mir immer noch nicht die Spalten aus sondern nur <Auflistung> <Auflistung> <Auflistung> <Auflistung>!

Ich versuche schon im Internet Lösung zu finden aber ich komme da momentan immer sehr schnell an meine Grenzen!

Aber wieso mir immer nur <Auflistung> ausgegeben wird verstehe ich nicht???

Moment jetzt scheint es zu klappen!!!!