Autor |
Beitrag |
sebastian1234 
      
Beiträge: 46
|
Verfasst: Sa 11.01.14 14:01
Dadurch das ich den String in der Schleife ausgebe wird der natürlich, je nach Auswahl 4 mal angezeigt!
Wie schaffe ich es das in den String Wert lediglich nur einmal die Auswahl gespeichert wird, damit ich den String an die SQL Abfrage weitergeben kann?
EDIT: Habe es mit einer übergeordneten Variable gelöst!!!
|
|
sebastian1234 
      
Beiträge: 46
|
Verfasst: Mo 13.01.14 12:12
Also mein Programm ist jetzt eigentlich soweit fertig! Das gesamte Projekt geht allerdings noch weiter =)
Es gibt nur noch eine Sache die im Programm gemacht werden muss! Und zwar handelt es sich um folgende Methode...
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| public 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) { int p = 1; int q = 2; int t = 3; 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); } } } |
In dieser Methode sind aktuell 3 Variablen (q,p,t) angegeben! Wenn ich über die Auswahl im Programm 3 Variablen auswähle wird die Methode ohne Probleme ausgeführt. Wähl ich allerdings nur 2 Variablen aus kommt es zu einem Fehler! Außerdem kann es in Zukunft sein das nicht nur 3 sondern bis zu 9 Variablen verwendet werden, von denen man unterschiedliche viele auswählen kann. Das Excel File besteht aus den Spaltenwerten ID / Kennzahl1 / Kennzahl2 / Kennzahl 3 usw...
Wie muss ich die Methode umbauen, damit ich beliebig viele Spalten bzw. Variablen auswählen kann und die Berechnung ohne einen Fehler korrekt durchläuft und dies nach der oben angegebenen Formel?
Ich würde mich über eine Tipp oder eine Idee sehr freuen mit der ich mich dann heute auseinandersetzten kann um eine Lösung zu bauen!
Viele Grüße...
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 13.01.14 12:53
Deine Formel ist für 3 Dimensionen hart kodiert. Also must du die für beliebige Dimensionen umschreiben.
Du wirst also eine Schleife über die Anzahl Dimensionen brauchen der den Teil der jetzt explizit für p,q,t erfolgt einmal in der Schleife für die dann aktuelle Dimension berechnet und zu den bisherigen in der Schleife berechneten Werten hinzuaddiert. Nach der Schleife dann noch die Quadratwurzel aus diesem Wert ziehen.
|
|
sebastian1234 
      
Beiträge: 46
|
Verfasst: Mo 13.01.14 15:23
Okay also ich habe folgendes gebaut...
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:
| public static void distanzBerechnung(double[][] kunde) { double Ergebnis = 0; double Formel = 0; for (int a = 0; a < kunde.Length; ++a) { Console.WriteLine(kunde[a][0]);
for (int b = 0; b < kunde.Length; ++b) { for (int i = 1; i < kunde.Length; ++i) { Formel = (Math.Pow(kunde[a][i] - kunde[b][i],2)); Ergebnis += Formel; } double Endergebnis = 0; Endergebnis = Math.Sqrt(Ergebnis); Console.WriteLine(Endergebnis);
} } } |
Ich denke von der Grundidee sollte es richtig sein. Aber ich erhalte im Gegensatz zu vorher bei der Berechnung irgendwie falsche Werte. Kann mir das bisher nicht genau erklären!
Liegt das vielleicht daran das die Berechnung und Ausgabe in der falschen Schleife sind?!
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 13.01.14 15:24
Warum fängt die Schleife bei 1 an?
|
|
sebastian1234 
      
Beiträge: 46
|
Verfasst: Mo 13.01.14 15:37
Das Excel File hat die Spalten ID / Kennzahl1 / Kennzahl2 / Kennzahl3 usw
Die ID steht für einen bestimmten Fall und für die Berechnung der Distanzen benötigt man ja lediglich die Kennzahlenwerte.
i = 0; wäre ja dann ID aber die soll nicht mit in die Berechnung rein!
Also ist i = 1 doch eigentlich korrekt oder?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 13.01.14 15:43
Nein in dem Array sind nur noch die relevanten Daten. Zumindest wenn du das so programmiert hast wie hier besprochen. Nur die ausgewählten Spalten werden in das Array kopiert. Die Spaltenpositionen im Excelsheet haben also nix mehr zu tun mit denen im Array. Also wo sollte plötzlich in der ersten Dimension des Array die ID da reinkommen wenn du die da nicht hinkopiert hast?
|
|
sebastian1234 
      
Beiträge: 46
|
Verfasst: Mo 13.01.14 15:46
Ich wähle in der checklistbox immer ID aus damit ich die Kennzahlen_Werte den einzelnen ID_Fällen zuordnen kann...
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 13.01.14 15:49
Dann solltest du noch Formel und Ergebnis vor der inneren Schleife auf 0 zurücksetzen. Im Moment summierst du immer weiter auch wen du schon in der nächsten Zeile bist.
Edit: Falls das das Problem ist. Hätte ddir das beim debuggen des Codes auffallen müssen. Wenn nicht wäre es jetzt an der Zeit sich das Handwerk des Debuggens anzueignen. Ansonsten stehst du dir zu oft selbst im weg wenn du ein Problem durch blosses Ansehen des Codes finden willst. Das klappt üblicherweise nur ganz schlecht beim eigenen Code.
|
|
sebastian1234 
      
Beiträge: 46
|
Verfasst: Mo 13.01.14 17:11
Okay! Ja du hattest auf jeden Fall recht! Das mit dem debuggen schau ich mir jetzt mal an!
Allerdings habe ich die Spaltenwerte nun von 3 auf 7 erhöht und hier ist mir aufgefallen das er bei 3 Schleifendurchgängen abbricht. Er verwendet vermutlich nur die Zeilenwerte die halt 3 sind. (3 Zeilenwerte)
In der for-Schleife müsste i aber 7 Durchläufe haben! Ist die for-Schleife für i falsch? Oder wie kann ich die Spaltenwerte über i auf die Spaltenanzahl erhalten?
|
|
Th69
      

Beiträge: 4798
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mo 13.01.14 17:22
Hallo,
dann verwende kunde[a].Length oder kunde[b].Length (bzw. noch besser, das Minimum aus beiden Werten - falls die Zeilen unterschiedlich lang sind).
Ich hoffe dir ist klar, was da der Unterschied zu kunde.Length ist?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 13.01.14 17:25
kunde.Length ist die Länge der ersten Dimension die enthält die Zeilen (vermutlich hast du im Moment 3 Zeilen) du willst aber die Länge der Zweiten Dimension.
Korrekterweise müßtest du immer die Länge der aktuellen zeile von a oder b nehmen da ja zumindest theoretisch nicht jede Zeile gleich viele Spalten hat.
Da wir es aber besser Wissen könne wir einfach die Länge irgendeiner Zeile nehmen z.B einfach der ersten also kunde[0].Length.
Edit: Ich schwör ich wollt nicht vorsagen 
Für diesen Beitrag haben gedankt: sebastian1234
|
|
sebastian1234 
      
Beiträge: 46
|
Verfasst: So 02.02.14 15:02
Hallo zusammen,
die Anforderungen an mein Programm haben sich wieder etwas verändert! Ich habe auf der Oberfläche einen zusätzliche checkbox eingefügt. Über eine Methode die eine if else Abfrage beinhaltet soll nun über geben werden ob die checkbox gecheckt ist oder nicht! Allerdings kann ich in meiner DistanzBerechnen Klasse nicht darauf zugreifen sondern nur in der Form1 Klasse. Wie kann ich auch in meiner DistanzBerechne klasse darauf zugreifen?
Hier zunächst die Klasse in der ich auf die checkbox1 zugreifen kann...
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:
| 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 { string spalten; DistanzenBerechnen rechnen = new DistanzenBerechnen(); 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; } }
public 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);
spalten = string.Join(",", checkedListBox1.CheckedItems.OfType<string>().ToArray()); Console.WriteLine("Geladene Spaltenwerte: "+spalten); Console.WriteLine("");
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("Select "+spalten+" 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(); DistanzenBerechnen.distanzBerechnung(kunde);
}
public void AuswahlButton_Click_1(object sender, EventArgs e) { 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); } myReader.Close(); conn.Close(); } } } |
Und hier die Klasse in der es bisher nicht geht! Die Frage ist wie ich die Übergabe hinbekomme. ich setzte mich gerade mit Konstrukoren auseinander aber noch keine Lösung gefunden...
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:
| using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace Clusteranalyse { public class DistanzenBerechnen { [STAThread] static void Main(string[] args) { Form1 dialog = new Form1(); dialog.ShowDialog(); }
public static void distanzBerechnung(double[][] kunde) { double Ergebnis = 0; double Formel = 0; for (int a = 0; a < kunde.Length; ++a) { Console.WriteLine(""); Console.WriteLine("Unternehmen: "+kunde[a][0]);
for (int b = 0; b < kunde.Length; ++b) { for (int i = 1; i < kunde[0].Length; ++i) { Formel = (Math.Pow(kunde[a][i] - kunde[b][i],2)); Ergebnis += Formel; }
} } }
public static void distanzBerechnungAuswahl(Ergebnis) { double Endergebnis = 0; if(checkBox1 == checked){ Endergebnis = Math.Sqrt(Ergebnis); Console.WriteLine(Endergebnis); Endergebnis = 0; } else{ Console.WriteLine("Hier wird City Block Metrik definiert!"); } } }
} |
Kleiner Tipp wäre sehr hilfreich! In die DistanzBerechnenAuswahl soll die Abfrage der checkbox hinkommen...
Viele Grüße und danke... Moderiert von Th69: Beiträge zusammengefasstEDIT: PROBLEM gelöst!!!
|
|