Autor Beitrag
chip777
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 127

Win 7 Prof
C# VS 2008
BeitragVerfasst: 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:
ausblenden 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.
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:
public class RoboterManager 
    {
        public RoboterManager(int i,DataGridView dataGridView1)
        {
            bool vorhanden = false;
            //Code der überprüft ob Roboter mit diesem Namen bereits vorhanden
            if (vorhanden == false)
            {
            Roboter Rob = new Roboter();
            //Rob.IDRoboter = ID des vorherigen Robs+1;
            //Rob.PositionRoboter = Pos letzter Rob+1;
            }
            //Anlegen eines neuen Vorgangs
            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.
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:
    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; } //im BFW Beschreibung genannt
        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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 127

Win 7 Prof
C# VS 2008
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Mi 21.04.10 14:18 
Ein DataGridView 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:
ausblenden 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));
            }


ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 127

Win 7 Prof
C# VS 2008
BeitragVerfasst: Mi 21.04.10 14:37 
user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:

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.

user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
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
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 127

Win 7 Prof
C# VS 2008
BeitragVerfasst: 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:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
                    dataGridView1.Visible = true;   //dataGridView einblenden
                    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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 127

Win 7 Prof
C# VS 2008
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
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
BeitragVerfasst: Do 22.04.10 09:14 
user profile iconchip777 hat folgendes geschrieben Zum zitierten Posting springen:
Wie kann ich jetzt Daten an bestimmte Positionen einfügen?

Siehe das Beispiel zu DataTable.NewRow.

Gruß Jürgen
chip777 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 127

Win 7 Prof
C# VS 2008
BeitragVerfasst: Do 22.04.10 09:34 
Hi Jürgen,

user profile iconchip777 hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
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
BeitragVerfasst: Do 22.04.10 11:39 
user profile iconchip777 hat folgendes geschrieben Zum zitierten Posting springen:

user profile iconchip777 hat folgendes geschrieben Zum zitierten Posting springen:
Wie kann ich jetzt Daten an bestimmte Positionen einfügen?

ich meinte nicht wie man Daten anfügt, dass habe ich gefunden, sondern wie man auf Daten anhand des Indexes zugreifen kann.

Ausreichend korrekte Informationen helfen ungemein. "Daten einfügen" ist für mich so etwas wie das Gegenteil von "auf Daten zugreifen". Und "Index" gibt es sowohl für die Zeilen als auch für die Spalten. :?!?:

Jürgen
chip777 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 127

Win 7 Prof
C# VS 2008
BeitragVerfasst: 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:

ausblenden 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
ausblenden C#-Quelltext
1:
public DataColumn column;					

definiert.
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
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
BeitragVerfasst: Do 22.04.10 14:42 
Du musst genau auf die Datentypen achten. Zum einen:
ausblenden C#-Quelltext
1:
2:
3:
myTable.Rows[7][2] = "Robot1";
// oder auch:
myTable.Rows[7]["Spaltenname"] = "Robot1";

Und zum Vergleich musst du den Wert in den passenden Typ konvertieren:
ausblenden C#-Quelltext
1:
if ( (string)myTable.Rows[7]["Spaltenname"] == myRobotName )					

Jürgen
chip777 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 127

Win 7 Prof
C# VS 2008
BeitragVerfasst: 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