Autor |
Beitrag |
chip777
      
Beiträge: 127
Win 7 Prof
C# VS 2008
|
Verfasst: Mi 21.04.10 13:26
Hi,
ich habe folgendes Problem: Ich habe Daten in ein DataGridView geladen. Aus diesen Daten will ich Objekte erstellen, sodass die Daten wie von mir vorgesehen verwendet werden können. Unter anderem will ich die Daten später in einem TreeView darstellen. Ich hab es auch soweit hinbekommen das ich Objekte erzeuge die die Daten aufnehmen. Jetzt hab ich allerdings keine Ahnung wie ich auf diese zugreifen kann.
Höchstwahrscheinlich gibt es für dieses Problem eine viel bessere Lösung, wenn ihr eine Idee hättet wäre ich sehr dankbar. Hier mal der Code um hoffentlich etwas zu verdeutlichen was ich erreichen will.
In diesem Abschnitt stelle ich fest welche Zeilen als Objekt erstellt werden sollen:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| for (int i = 0; i != j; i++) { string Name = Convert.ToString(dataGridView1[0, i].Value); if ((Name != "") && (Name != @"W/R/St.") && (Name != "Kategorie")) { RoboterManager Roboter = new RoboterManager(i,dataGridView1); } } |
Hier wird jeweils ein neues Objekt erzeugt, leider hab ich das Gefühl, wenn ich das so mache wie hier, dass ich später nicht darauf zugreifen kann, aber ich bin noch Anfänger und hab keine Ahnung wie es anders geht, deshalb frag ich.
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:
| public class RoboterManager { public RoboterManager(int i,DataGridView dataGridView1) { bool vorhanden = false; if (vorhanden == false) { Roboter Rob = new Roboter(); } Vorgang Vor = new Vorgang(); Vor.NameVorgang = Convert.ToString(dataGridView1[1, i].Value); Vor.Description = Convert.ToString(dataGridView1[2, i].Value); Vor.Bemerkung = Convert.ToString(dataGridView1[3, i].Value); string test = Convert.ToString(dataGridView1[6, i].Value); if (test == "") Vor.StartPlan = 0.0; else Vor.StartPlan = Convert.ToDouble(dataGridView1[6, i].Value); test = Convert.ToString(dataGridView1[8, i].Value); if (test == "") Vor.EndePlan = 0.0; else Vor.EndePlan = Convert.ToDouble(dataGridView1[8, i].Value); test = Convert.ToString(dataGridView1[7, i].Value); if (test == "") Vor.LaengePlan = 0.0; else Vor.LaengePlan = Convert.ToDouble(dataGridView1[7, i].Value); test = Convert.ToString(dataGridView1[4, i].Value); if (test == "") Vor.SchaltdauerVorPlan = 0.0; else Vor.SchaltdauerVorPlan = Convert.ToDouble(dataGridView1[4, i].Value); test = Convert.ToString(dataGridView1[5, i].Value); if (test == "") Vor.SchaltdauerRueckPlan = 0.0; else Vor.SchaltdauerRueckPlan = Convert.ToDouble(dataGridView1[5, i].Value); } } |
Und hier mal noch die beiden Klassen, zum einem Roboter, zum anderen Vorgang.
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:
| public class Roboter { public string NameRoboter { get; set; } public string VorgaengerRoboter { get; set; } public int PositionRoboter { get; set; } public int IdRoboter { get; set; } } public class Vorgang { public string NameVorgang { get; set; } public string Description { get; set; } public string Bemerkung { get; set; } public double StartPlan { get; set; } public double EndePlan { get; set; } public double LaengePlan { get; set; } public double SchaltdauerVorPlan { get; set; } public double SchaltdauerRueckPlan { get; set; } public double StartProz { get; set; } public double EndeProz { get; set; } public double LaengeProz { get; set; } public double SchaltdauerVorProz { get; set; } public double SchaltdauerRueckProz { get; set; } public string VorgaengerVorgang { get; set; } public string VorgaengerRoboter { get; set; } public int PositionVorgang { get; set; } public int IdVorgang { get; set; } } |
Ich hoffe mal das ich mein Problem zumindest ein wenig verdeutlichen konnte, und vielleicht hat einer von euch eine Idee wie er mir helfen kann.
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Mi 21.04.10 13:49
Hallo,
im Ansatz ist dies gar nicht sooo verkehrt. Dennoch funktioniert es so natürlich ja nicht. Du frägst dich, wie du auf die Objekte zugreifen kannst - mit dem Code soweit gar nicht. Du erzeugst zwar in deiner RoboterManager-Klasse einen Roboter und einen Vorgang, merkst dir aber diese erzeugte Objekte gar nicht. Sprich deine RoboterKlasse benötigt eigentliche eine Funktion wie: public void CreateRoboter(DataRow row); mit der du aus einer Zeile (nicht das ganze DataGridView + Zeilennr. übergeben) ein Robert Objekt erstellen kannst.
Naja, ich könnte nun so weiter machen mit Dingen die du noch alle anpassen muss, dass es läuft. Am Ende hättest du dann einen spezifischen (für die Klasse Robotor und Vorgang) Objekt zu Relational Mapper - kurz und allgemein als O/R-Mapper bekannt.
Diese Aufgabe haben bereits viele mehr oder weniger Erfolgreich umgesetzt. Dabei kamen auch viele generische (Klassen unabhängige) Lösungen heraus. Diese Lösungen kannst du verwenden um genau dein Problem zu lösen. Die Frage ist nur, wo du ansetzten kannst. So wie es für mich aussieht, existiert die DB bereits.
Frage: Was für ein Typ von Datenbank verwendest du ? (MS Sql, MySQl, Oracale, DB2, Firebird, ...)
Frage: Ist die Struktur der Datenbank schon fest?
ADO.NET bzw. nun Linq bietet dir die Möglichkeit aus SQL DB Objekte mittels eines Designer zu erzeugen. Ich denke das wäre das was du benötigst.
Bitte lief noch ein paar Informationen damit wir dir einen konkreteren Lösungshinweis geben können.
Gruß
|
|
chip777 
      
Beiträge: 127
Win 7 Prof
C# VS 2008
|
Verfasst: Mi 21.04.10 13:58
Hi Daniel,
erstmal Danke für deine schnelle Antwort. Eine richtige Datenbank habe ich nicht, sondern eine Excel Datei(*.xls).
Diese Datei lese ich dann per OLEDB in ein DataGridView ein, welches 2 Gründe hat:
1. der Zugriff über Excel ist mir zulangsam.
2. ich weiß nicht wie ich üebr OLEDB direkt an Werte komme, indem ich Zeilen und Spaltennummer übergebe
Von daher lese ich die Datei in ein DataGridView, da kann ich dann nach belieben durchsuchen, da ich weiß welche Informationen in welcher Spalte zu finden sind.
Für weitere Infos wäre ich wie sehr dankbar.
Edit: eine möglichst einfache Variante wäre mir am liebsten, eine Optimierung das alles besser und schneller geht, kann später erfolgen, erstmal soll mein Programm überhaupt laufen
Martin
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Mi 21.04.10 14:18
Ein DataGrid View solltest du nicht verwenden um Daten abzuspeichern, sondern - wie der Name sagt - zum Anzeigen.
Ich weiß war nicht wie genau du die Daten vorliegen hast,aber soweit ich das verstehe, denke ich, dass du die Daten auch in ein DataTable packen kannst. Des weiterem weiß ich nicht, dass es Möglich wäre mithilfe eines Designer aus einer Excel-Datei Objekte zu erstellen. Deshalb musst du an dieser Stelle wohl Handarbeit machen.
Die Frage ist, was du später mit den Objekten machen willst. Aktuell ist es ja nur ein Datenspeicher, dann würde ein DataRow ausreichen.
Ich habe die bedenken, dass du das selber noch nicht so genau weißt und auch nicht was die Objekte später machen???
Deshalb gebe ich dir mal blind (ohne das ich dafür ein Verständnis hätte) dir ein paar Ratschläge wie du deinen Ansatz umsetzten kannst:
In der Schleife:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7:
| List<Roboter> robotics = new List<Robotoer>(); DataGridViewRoboterFactory robotFactory = new DataGridViewRoboterFactory();
foreach (DataGridViewRow row in dataGridView1.Rows) { robotics .Add(robotFactory.CreateRobot(row)); } |
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| class DataGridViewRobotoerFactory : IRobotFactory { public Robot CreateRobot(DataGridViewRow row) { return new Robot{ NameVorgang = row.Cells["NameVorgang"].Value, Description = row.Cells["Description"].Value, Bemerkung = row.Cells["Bemerkung "].Value, ... }; } } |
Analog für die Vorgang-Klasse ...
|
|
chip777 
      
Beiträge: 127
Win 7 Prof
C# VS 2008
|
Verfasst: Mi 21.04.10 14:37
danielf hat folgendes geschrieben : |
Ich weiß war nicht wie genau du die Daten vorliegen hast,aber soweit ich das verstehe, denke ich, dass du die Daten auch in ein DataTable packen kannst.
|
Ich werd mal schauen ob ich dir eine Beispieldatei zukommen lassen kann, ich denke das sollte kein Problem sein. Allerdings wird das wohl erst gegen heute Abend zeitlich möglich sein.
danielf hat folgendes geschrieben : |
Die Frage ist, was du später mit den Objekten machen willst. Aktuell ist es ja nur ein Datenspeicher, dann würde ein DataRow ausreichen.
|
Ich versuche mal zu erklären was ich später mit den Objekten machen möchte: Zum einen soll ein TreeView erzeugt werden, dafür brauche ich den Namen des Roboters udn den Namen der Vorgänge, das ganze soll dann so ungefähr aussehen:
+Roboter 1
- Vorgang1 Rob1
- Vorgang2 Rob1
+Roboter 2
- Vorgang1 Rob2
- Vorgang2 Rob2
Ich hoffe mal das man bisschen erkennt was ich meine. Desweiteren werden die Zeiten benötigt um daraus Balkendiagrammobjekte zu erzeugen, damit man visuell die Prozess und die Planungszeiten vergleichen kann.
Außerdem sollte es eine Möglichkeit geben die Objekte zu speichern(Beispielsweise in einer Datei) damit diese nach einem Programmneustart wieder so zur Verfügung stehen, aber ich denke das ist ein anderes Thema.
Und wie gesagt das DataGridView hab ich nur verwendet um die Daten anzuzeigen, speichern wollte ich diese dann mit hilfe der Objekte. Das mit dem DataRow schau ich mir jetzt mal an.
edit: Außerdem muss ich auch über ein zweites Form eine Verbindung zu den Objekten aufnehmen können. Denn ich habe noch einen modalen Dialog, welcher auf die Daten zugreifen können muss.
|
|
JüTho
      
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Mi 21.04.10 14:52
Hallo Martin,
Daniels Hinweise möchte ich noch etwas konkretisieren, damit du gleich in die richtige Richtung läufst und nicht in die Irre.
Du sagst, dass du die Daten per OleDb in das DataGridView holst. Das glaube ich nicht; du wirst sie vermutlich wirklich in eine DataTable packen und diese als DataSource an das DataGridView hänge. Damit hast du schon eine Daten-Klasse, die du weiter verwenden kannst. Wenn alle Informationen, die du für den Roboter brauchst, schon darin enthalten sind, dann kannst du die DataRow für einen einzelnen Roboter und die DataTable anstelle der List<Roboter> verwenden.
Wenn das wegen der Informationen und der weiteren Bearbeitung (noch) nicht genügt, dann kannst du (ähnlich wie Daniels Vorschlag für CreateRobot) aus der DataRow ein Element erzeugen. Der Ablauf ist praktisch identisch zu Daniels Vorschlag: Ersetze DataGridView durch DataTable.Rows und DataGridViewRow durch DataRow; der Zugriff geht analog.
Wichtig für deine weitere Arbeit ist der Hinweis (den Daniel mehrfach gegeben hat, ich weiß nur nicht, ob auf deine oder auf andere Fragen hin): Trenne die Daten von der GUI. Wenn du die Daten behandeln willst, dann tu das und denke nicht mit GUI-Inhalten.
Gruß Jürgen
/Edit
Die Übergabe an andere Formulare erfolgt dann durch ein einzelnes DataRow- oder Robot-Objekt.
|
|
chip777 
      
Beiträge: 127
Win 7 Prof
C# VS 2008
|
Verfasst: Mi 21.04.10 15:09
Hi Jürgen,
ich glaub du hast recht das ich das schon in einem DataTable habe. Hier mal der Code der die Datei in das DataGridView einliest:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| dataGridView1.Visible = true; System.Data.OleDb.OleDbConnection MyConnection; System.Data.DataSet DtSet; System.Data.OleDb.OleDbDataAdapter MyCommand; MyConnection = new System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + fullPathname + "';Extended Properties=Excel 8.0;"); MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [Funktionsdiagramm$A:Y]", MyConnection); MyCommand.TableMappings.Add("Table", "TestTable"); DtSet = new System.Data.DataSet(); MyCommand.Fill(DtSet); dataGridView1.DataSource = DtSet.Tables[0]; MyConnection.Close(); |
Ich werd auf jeden Fall mal versuchen Daniels Hinweise umzusetzen, mit deiner Anmerkung natürlich, indem ich nciht übers DataGridView sondern direkt über den Table gehe. Mal schauen ob ich es hinbekommen 
|
|
chip777 
      
Beiträge: 127
Win 7 Prof
C# VS 2008
|
Verfasst: Do 22.04.10 07:40
Ich hatte jetzt die Idee, aus jedem dieser Objekte eine Zeile eines DataTable zu machen, um die Daten so zu speichern wie ich sie später benötige.
Jetzt ist mein Problem das ich keine Ahnung habe wie ich ein DataTable initialisiere und wie ich dann auf einzelne Zellen zugreifen kann, da wäre ein Beispiel nett. Ich schau auch nochmal bei MSDN vorbei, vielleicht hilft das ja schon.
eidt: MSDN hat geholfen, ich hab ein DataTable erstellt und hab auch die Titelleiste erstellt. Wie kann ich jetzt Daten an bestimmte Positionen einfügen?
|
|
JüTho
      
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Do 22.04.10 09:14
chip777 hat folgendes geschrieben : | Wie kann ich jetzt Daten an bestimmte Positionen einfügen? |
Siehe das Beispiel zu DataTable.NewRow.
Gruß Jürgen
|
|
chip777 
      
Beiträge: 127
Win 7 Prof
C# VS 2008
|
Verfasst: Do 22.04.10 09:34
Hi Jürgen,
chip777 hat folgendes geschrieben : | Wie kann ich jetzt Daten an bestimmte Positionen einfügen? |
Danke für die Info, allerdings habe ich vorhin gepostet ohne den Text nochmal zu lesen, ich meinte nicht wie man Daten anfügt, dass habe ich gefunden, sondern wie man auf Daten anhand des Indexes zugreifen kann.
|
|
JüTho
      
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Do 22.04.10 11:39
|
|
chip777 
      
Beiträge: 127
Win 7 Prof
C# VS 2008
|
Verfasst: Do 22.04.10 11:43
Ich will beispielsweise den Inhalt von Zelle x ändern, ich weiß das Zelle x, in Reihe 7 und in Spalte 2 ist.
Wie kann ich jetzt beispielsweise "Rob1" in Zelle x schreiben?
Das gleiche Problem habe ich dann auch beim Vergleich von Inhalten:
C#-Quelltext 1:
| if (column[j].Value == NameRoboter) |
Diese Zeile funktioniert so nicht , da der Zugriff aufgrund einer Sicherheitsebene nicht möglich ist.
NameRoboter ist hier eine Variable vom Typ string. j ist eine Variable vom Typ int. column ist als
C#-Quelltext 1:
| public DataColumn column; |
definiert.
|
|
JüTho
      
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Do 22.04.10 14:42
Du musst genau auf die Datentypen achten. Zum einen:
C#-Quelltext 1: 2: 3:
| myTable.Rows[7][2] = "Robot1"; myTable.Rows[7]["Spaltenname"] = "Robot1"; |
Und zum Vergleich musst du den Wert in den passenden Typ konvertieren:
C#-Quelltext 1:
| if ( (string)myTable.Rows[7]["Spaltenname"] == myRobotName ) |
Jürgen
|
|
chip777 
      
Beiträge: 127
Win 7 Prof
C# VS 2008
|
Verfasst: Do 22.04.10 15:40
Danke Jürgen,
jetzt komm ich erstmal ein großes Stück weiter.
Falls ich wieder irgendwo stecken bleibe meld ich mich wieder^^
Dann aber in einem neuen Thread.
Martin
|
|
|