![]() |
Record im Array nutzen? - Sinnvollere Wege?
Guten Tag,
zurzeit benutze ich ein Array, welches ein Element eines Records ist. Nur habe ich gerade bei meinen Recherchen erfahren, dass dies keine schöne Methode ist. Also mein Record sieht so aus:
Delphi-Quellcode:
Das Array besteht aus 40 Feldern, die jeweils ja diese Record Anordnung haben.
TEmployee = Record
CardID : Integer; Prename, Surname, Workstation, Position : String[100]; Birthdate : TDate; AvailAbility : Array[1..7] of String; End; Nun Frage ich mich, ist dieser Weg, wie ich ihn gewählt habe, in Ordnung, oder gibt es bessere Methoden dies umzusetzen? MfG Asura |
AW: Record im Array nutzen? - Sinnvollere Wege?
Wie wäre es mit Objekten in einer TObjectList?
Also TEmployee = class und die Liste je nach Delphiversion deklariert als TObjectList oder wenn möglich besser TObjectList<TEmployee>. Vorteile sind, dass du Teile der Objekte anders als bei Records auch direkt setzen kannst über die Liste und dass du eine beliebige Anzahl an Elementen hast ohne das Array manuell in der Größe verändern zu müssen. |
AW: Record im Array nutzen? - Sinnvollere Wege?
Eine Liste ist zunächst einmal eine gute Alternative.
Ich würde aber erst einmal tiefer ansetzen und die Elemente des Records kritisch hinterfragen. a) ist die CardId wirklich numerisch? oder sieht sie nur so aus? b) was verbirgt sich hinter Position? wenn dies festgelegte Inhalte sind, dann wäre es nicht schlecht z.B. mit ENUM-Typen zu arbeiten. sonst läuft die Suche nach "Hausmeister" ins Leere weil da jetzt der "Facility Manager" steht. c) Wenn Du
Delphi-Quellcode:
nutzt dann wenigstens auch
Position : String[100];
Delphi-Quellcode:
oder
AvailAbility : Array[1..7] of AnsiString;
Delphi-Quellcode:
Sonst ist das Character-Chaos vorprogrammiert.
AvailAbility : Array[1..7] of String[255];
Gruß K-H |
AW: Record im Array nutzen? - Sinnvollere Wege?
Ich habe die schreckliche Vermutung dass sich hinter Availability die Verfügbarkeit an einem bestimmten Wochentag verbirgt. Hier wäre ja dann wohl eher so etwas sinnvoll (abgesehen dass es dann in 8 Bit statt in 8 Byte gespeichert werden kann):
Delphi-Quellcode:
TWeekDays = (wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday, wdSaturday, wdSunday);
TAvailability = set of TWeekDays; |
AW: Record im Array nutzen? - Sinnvollere Wege?
Hallo,
Dankeschön erstmal für die Antworten. Ich habe mal im Anhang das ganze Projekt angehängt, sodass ihr euch mal ein Bild machen könnt (Im Source Ordner zu finden). Ich habe es zurzeit über meine Methode gelöst - zwar mit mehreren Stunden Ärgernissen, aber schlussendlich gelöst. Aber auch nur die Mitarbeiterverwaltung zum großteil. Zu den Availability: Ja das sind Tage. Ich habe das so gelöst, dass der Index 1 Beispielsweise für Montag steht und der hintergelegte Text "17:00-23:00" beispielsweise gesplittet und aufgeteilt wird. Alle Werte sollten Variabel gehalten werden, sprich in meiner aktuellen Version lassen sich alle bearbeiten. Auch Position. Und Card ID benutze ich zum Teil dafür um meine Items im Array zu finden, sie dient aber auch für den Anwender Informationsgrundlage, die bei der Eintragung wichtig ist. Ich würde mich auch sehr freuen, wenn ihr generell paar Kritik Äußerungen zu den Programmcode mir schreiben könntet und was ich da verbessern kann oder komplett verändern muss. Würde mich sehr freuen! MfG Asura |
AW: Record im Array nutzen? - Sinnvollere Wege?
Ich hätte das mit Klassen so aufgebaut
Delphi-Quellcode:
unit Unit1;
interface uses System.Classes, System.DateUtils, System.Generics.Collections, System.TimeSpan; type {$SCOPEDENUMS ON} TWeekDay = ( Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday ); {$SCOPEDENUMS OFF} TAvailibility = class( TPersistent ) private FFrom: TTime; FDuration: TTimeSpan; FIsAvailable: Boolean; procedure SetFrom( const Value: TTime ); procedure AssignToAvailibility( Dest: TAvailibility ); procedure SetIsAvailable( const Value: Boolean ); protected procedure AssignTo( Dest: TPersistent ); override; public function Equals( Obj: TObject ): Boolean; override; property IsAvailable: Boolean read FIsAvailable write SetIsAvailable; property From: TTime read FFrom write SetFrom; property Duration: TTimeSpan read FDuration write FDuration; end; TEmployee = class( TPersistent ) private FAvailibility: TObjectDictionary<TWeekDay, TAvailibility>; FCardID: Integer; FPrename: string; FSurname: string; FWorkstation: string; FPosition: string; FBirthday: TDate; function GetAvailibility( Weekday: TWeekDay ): TAvailibility; procedure SetBirthday( const Value: TDate ); procedure AssignToEmployee( Dest: TEmployee ); procedure SetAvailibility( Weekday: TWeekDay; const Value: TAvailibility ); protected procedure AssignTo( Dest: TPersistent ); override; public constructor Create; destructor Destroy; override; function Equals( Obj: TObject ): Boolean; override; property CardID: Integer read FCardID write FCardID; property Prename: string read FPrename write FPrename; property Surname: string read FSurname write FSurname; property Workstation: string read FWorkstation write FWorkstation; property Position: string read FPosition write FPosition; property Birthday: TDate read FBirthday write SetBirthday; property Availibility[ Weekday: TWeekDay ]: TAvailibility read GetAvailibility write SetAvailibility; end; implementation { TEmployee } procedure TEmployee.AssignTo( Dest: TPersistent ); begin if ( Dest is TEmployee ) then AssignToEmployee( Dest as TEmployee ) else inherited; end; procedure TEmployee.AssignToEmployee( Dest: TEmployee ); var LWeekDay: TWeekDay; begin Dest.FCardID := Self.FCardID; Dest.FPrename := Self.FPrename; Dest.FSurname := Self.FSurname; Dest.FWorkstation := Self.FWorkstation; Dest.FPosition := Self.FPosition; Dest.FBirthday := Self.FBirthday; for LWeekDay := low( TWeekDay ) to high( TWeekDay ) do Dest.SetAvailibility( LWeekDay, Self.GetAvailibility( LWeekDay ) ); end; constructor TEmployee.Create; var LWeekDay: TWeekDay; begin inherited Create; FAvailibility := TObjectDictionary<TWeekDay, TAvailibility>.Create( [ doOwnsValues ] ); for LWeekDay := low( TWeekDay ) to high( TWeekDay ) do begin FAvailibility.Add( LWeekDay, TAvailibility.Create ); end; end; destructor TEmployee.Destroy; begin FAvailibility.Free; inherited; end; function TEmployee.Equals( Obj: TObject ): Boolean; begin Result := ( Self = Obj ) or Assigned( Obj ) and ( Obj is TEmployee ) and ( TEmployee( Obj ).FCardID = Self.FCardID ); end; function TEmployee.GetAvailibility( Weekday: TWeekDay ): TAvailibility; begin Result := FAvailibility[ Weekday ]; end; procedure TEmployee.SetAvailibility( Weekday: TWeekDay; const Value: TAvailibility ); begin FAvailibility[ Weekday ].Assign( Value ); end; procedure TEmployee.SetBirthday( const Value: TDate ); begin FBirthday := DateOf( Value ); end; { TAvailibility } procedure TAvailibility.AssignTo( Dest: TPersistent ); begin if ( Dest is TAvailibility ) then AssignToAvailibility( Dest as TAvailibility ) else inherited; end; procedure TAvailibility.AssignToAvailibility( Dest: TAvailibility ); begin Dest.FFrom := Self.FFrom; Dest.FDuration := Self.FDuration; end; function TAvailibility.Equals( Obj: TObject ): Boolean; begin Result := ( Self = Obj ) or Assigned( Obj ) and ( Obj is TAvailibility ) and ( {} ( TAvailibility( Obj ).FIsAvailable = Self.FIsAvailable ) or {} ( ( TAvailibility( Obj ).FFrom = Self.FFrom ) and ( TAvailibility( Obj ).FDuration = Self.FDuration ) ) ); end; procedure TAvailibility.SetFrom( const Value: TTime ); begin FFrom := TimeOf( Value ); end; procedure TAvailibility.SetIsAvailable( const Value: Boolean ); begin FIsAvailable := Value; end; end. |
AW: Record im Array nutzen? - Sinnvollere Wege?
Also zunächst mal ist zu sagen, dass es in Delphi seit Version 4 bereits dynamische Arrays gibt. Es gibt also keinen Grund, eine Maximalgröße wie „1000“ fest vorzugeben. Feste Größen sind schlecht, weil sie erstens beliebig sind (warum gerade 1000? Was ist, wenn es 1001 Mitarbeiter gibt?) und zweitens, weil sie Platz verschwenden. Schreibe statt
Delphi-Quellcode:
also besser
Employees: array[1..1000] of TEmployee
Delphi-Quellcode:
. Die Größe kannst du mit SetLength zur Laufzeit verändern.
Employees: array of TEmployee
Da es aber mühsam ist, jedes mal beim Hinzufügen eines Elements (vom Löschen fangen wir gar nicht erst an) folgendes zu schreiben
Delphi-Quellcode:
verwendet man besser eine TObjectList oder TList.
SetLength(Employees, length(Employees)+1);
Employees[length(Employees)-1] := NewEmployee; Das mit der festen Höchstlänge gilt auch für Strings. Wenn es nicht wirklich einen guten Grund gibt, dann sollte man nicht
Delphi-Quellcode:
schreiben, sondern einfach
String[100]
Delphi-Quellcode:
.
String
Als Grundproblem sehe ich bei dir die aber die mangelnde Modellierung an. Zunächst mal solltest du die Geschäftslogik strikt von der Darstellung trennen. Du solltest also Termine, Uhrzeiten etc. z.B. intern niemals als String speichern. Statt einen einzelnen Termin ("15:00-17:30") als String zu repräsentieren, der immer wieder geparst werden muss, bastel dir einen speziellen Typen, der genau die Information abbildet:
Delphi-Quellcode:
Dann der nächste Punkt:
TAppointment = record
StartTime: TTime; EndTime: TTime; end; [...] Availability : Array[1..7] of TAppointment;
Delphi-Quellcode:
. Zunächst mal fangen Arrays normalerweise bei 0 an und nicht bei 1. Davon abzuweichen führt eher zu Verwirrungen und Fehlern. Noch wichtiger: Die Zahlen sagen mir nichts über die Bedeutung. Ich kann nur mutmaßen, dass es sich hier um Wochentage handelt. Aber dann ist immer noch die Frage, welche Zahl welchem Tag entspricht. Entspricht die 1 z.B. dem Montag oder dem Sonntag?
Array[1..7]
Besser wäre:
Delphi-Quellcode:
Das sieht schon besser aus.
TWeekday = (wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday, wdSaturday, wdSunday);
Availability: Array[TWeekday] of TAppointment; Allerdings ist diese Modellierung jetzt natürlich immer noch darauf eingeschränkt, dass es pro Wochentag nur einen Termin gibt. Da kann ich jetzt ohne nähere Informationen zu deinem Anwendungsfall nicht sagen, ob das zu deinem Anwendungsfall passt oder nicht. Aber selbst dann wäre es eventuell besser, einfach eine flache Liste von Terminen zu speichern, die nicht nach Wochentagen gruppiert ist:
Delphi-Quellcode:
So ist man, falls sich die Anforderungen später doch mal ändern, flexibler mit der Art von Terminen, die möglich sind. Man könnte z.B. mehrere Termine an einem Tag haben. Durch hinzufügen eines zusätzlichen Feldes zu TAppointment könnte man sogar unterscheiden zwischen einmaligen Terminen und solchen, die sich jede Woche wiederholen.
TAppointment = record
StartTime: TDateTime; // Beachte: Nun DateTime EndTime: TDateTime; end; [...] Availability: array of TAppointment; // οder bei neueren Delphis Availability: TList<TAppointment>; |
AW: Record im Array nutzen? - Sinnvollere Wege?
Erstmal vielen Dank für die bis jetzt aufgebrachte Mühe!
Ich muss vorab sagen, ich mach das alles nur als Hobby, bin nebenbei noch Schüler und interessiere mich in den Bereich und würde auch gerne in der Richtung studieren wollen und will mir bereits fürs Studium mal schon ein gewisses Basiswissen schaffen. Nun wo fange ich erstmal an. Ich habe mir mal den Programmaufbau von Sir Rufo angeschaut. Ich muss sagen, dass ist für mein Anfängerwissen echt zu hoch. Also da fallen mir viele Fragen ein, wobei ich das mal nur auf das allgemeinste begrenze:
Ich muss sagen, dass dieses Codebeispiel, nochmals danke für diese Mühe extra auf mein Fallbeispiel angepasst eine Unit zu verfassen, für mich eine zu Hohe Hausnummer ist, man vergleiche mal meine Version (Um mal auf Deutsch zu sagen "ein Scheiß dagegen" ist.) Ich habe mich mal desweiteren informiert und muss sagen, dass TObjects sich auf jedenfall besser eignet als meine Method, die wie von euch genannt, zu stark auf die Darstellung ausrichtet ist. Nun zu Namenloser: Bezüglich dem Array, ich gebe dir absolut Recht bezüglich dem Dynamischen Array und würde auch hier lieber TObjectlist nutzen. Also an meinem Anwendungsfall, wird pro Wochentag nur ein Termin genutzt. Denn später werde ich mit der Zeit schauen, ob die betroffene Person an dem Wochentag in einem bestimmten Zeitraum verfügbar ist und dabei wird nur dieser Zeitwert für den einen Wochentag genutzt. Bezüglich 0 und 1 im Array. Ich habe das eig benutzt, damit ich später noch weiß, dass damit von Montag bis Sonntag gemeint ist (7 Tage). Aber die vorgeschlagene Methode ist um einiges besser. Aber ich muss auch später Urlaubstage einfügen, also ich habe mir einfach gedacht, dass ich diese Tage in eine TStringlist reinschreibe und das Programm einfach die Liste durchgeht und wenn der Tag mit dem Tag der Überprüfung übereinstimmt, wird dieser als nicht verfügbar angezeigt. Eine schlussendliche Frage habe ich noch: Als Grundproblem soll meine mangelnde Modellierung schuld sein, kann ich dies irgendwo nachlesen bzw. lernen? Eventuell habt ihr dazu passendes Informationsmaterial zur Hand? Würde gerne daran arbeiten wollen. MfG Asura |
AW: Record im Array nutzen? - Sinnvollere Wege?
Zitat:
Wenn du Objektorientierung verinnerlicht hast, schau dir als nächstes Design Patterns an. |
AW: Record im Array nutzen? - Sinnvollere Wege?
Zur Not kannst du auch erst mal beim Record bleiben, dann mußt du dein Programm nicht komplett neu machen. Records sind aus mehren Gründen allerdings nicht zu empfehlen. Der String[100] kann auch irgendwann mal ein string werden, wenn du satt typisierte Dateien (Annahme) z.B. einen FileStream oder zur Not auch eine MemIniFile verwendest.
Delphi-Quellcode:
TEmployees = class
private function GetCount: integer; procedure SetCount(const Value: integer); public Items: array of TEmployee; property Count: integer read GetCount write SetCount; function Add(const Value: TEmployee): integer; procedure Delete(const Index: integer); procedure Assign(Value: TEmployees); procedure Clear; procedure LoadFromFile(const FileName: string); procedure SaveToFile(const FileName: string); destructor Destroy; override; end; { TEmployees } destructor TEmployees.Destroy; begin Clear; inherited; end; function TEmployees.GetCount: integer; begin Result := Length(Items); end; procedure TEmployees.SetCount(const Value: integer); begin SetLength(Items, Value); end; procedure TEmployees.Clear; begin SetCount(0); end; function TEmployees.Add(const Value: TEmployee): integer; begin Result := Count; SetCount(Result + 1); Items[Result] := Value; end; procedure TEmployees.Delete(const Index: integer); var I: integer; begin for I := Index to Count - 2 do Items[I] := Items[I + 1]; SetCount(Count - 1); end; procedure TEmployees.Assign(Value: TEmployees); var I: integer; begin SetCount(Value.Count); for I := 0 to Count - 1 do Items[I] := Value.Items[I]; end; procedure TEmployees.LoadFromFile(const FileName: string); begin end; procedure TEmployees.SaveToFile(const FileName: string); begin end; |
AW: Record im Array nutzen? - Sinnvollere Wege?
Die Persistenz-Schicht sollte aber nicht im Objekt selber sein.
Das gibt nachher einfach nur Kuddelmuddel, wenn man das Datenformat ändert/ändern muss (Umstieg von Dateien auf eine Datenbank). Der Anwendung selber sollte es egal sein, wo die Daten abgelegt werden. Es gibt einfach einen Service, dem die Anwendung mitteilt, was mit dem Objekt passieren soll (CRUD). Der Service kümmert sich dann darum, wo diese Daten konkret abgelegt werden. Der Aufwand ist nicht wirklich mehr als diese Verquickung, aber ungemein flexibel. |
AW: Record im Array nutzen? - Sinnvollere Wege?
Wie könnte ich dann diese Persistenz-Schicht nach außen verlagern?
Und wie stelle ich da diese Informationen so bereit, dass dieser Service egal ist, ob diese in einer Datenbank oder File gespeichert werden? Also wäre es ratsamer, wenn ich das Programm komplett neu überarbeite und nicht unbedingt nun ein Record nehme? Oder kann ich für meine Dimension des Programmes ruhig beim Record bleiben? |
AW: Record im Array nutzen? - Sinnvollere Wege?
@Sir Rufo: Das ist ja alles schön und gut, aber lass doch erst mal die Kirche im Dorf. Es macht keinen Sinn, jemandem, dem noch die Grundlagen der Objektorientierung fehlen, solche Konstrukte hinzuklatschen. Das führt nur zu Verwirrung. Von 0 auf 100 geht nun mal nicht sofort.
@Asura: Beim record lassen – kannst du zwar zur Not, bringt dich aber auch nicht weiter. Ich würde dir eher raten, dich einfach mal mit den Grundlagen objektorientierter Programmierung (Was ist eine Klasse? Was ist ein Objekt? Wann muss ich ein Objekt erzeugen und freigeben? Was ist Kapselung, Vererbung, Polymorphie?) zu befassen. Dann nutze dieses Wissen, um aus dem record eine Klasse und aus dem Array eine ObjectList zu machen. Dabei würde ich es dann auch erst mal belassen. In ein paar Jahren kannst du dich dann mit dem beschäftigen, was Sir Rufo geschrieben hat ;) |
AW: Record im Array nutzen? - Sinnvollere Wege?
Guten Tag,
und zwar habe ich mich nun an der Klasse und an der Objectlist versucht: Meine Klasse "Employee" hat die Properties, wie von Sir Rufo bereits vorgeschlagen. Ich habe dann die Objectliste erstellt "OLEmployees". Meine vorgehensweise sieht wie folgt aus: Ich speichere in die Properties die Inhalte der Textfelder. Danach adde ich der Objectliste die Klasse Employee als neues Item dazu. Die Initialisierungen und das Freigeben lasse ich hiermal weg, die finden in der Haupt-Unit im OnCreate und OnClose Event statt.
Delphi-Quellcode:
procedure TF_AddEditEmployee.btn_AddEditClick(Sender: TObject);
var EmployeeData: TStringlist; begin EmployeeData := TStringlist.Create; EmployeeData.Add(edt_CardID.Text); EmployeeData.Add(edt_PreName.Text); EmployeeData.Add(edt_SurName.Text); EmployeeData.Add(DatetoStr(dt_Birthday.Date)); EmployeeData.Add(edt_WorkStation.Text); EmployeeData.Add(edt_Position.Text); F_Employees.SelCardID := StrtoInt(edt_CardID.Text); try AddEmployeeData(F_Main.OLEmployees.Count, EmployeeData); except Messagebox(Self.Handle, 'Mitarbeiter konnte nicht hinzugefügt werden', 'Fehler', MB_ICONWARNING or MB_OK); end; close; EmployeeData.Free; end;
Delphi-Quellcode:
Meine Frage ist nun, ist das so richtig und wie kann ich nun wieder aus der Objectliste heraus das richtige Item finden? Ich kann ja schlecht IndexOf benutzen, da ja alle Items das gleiche Object (Employee) haben nur mit anderen Properties.
// *************************** Mitarbeiterhinzufügen ***************************
procedure AddEmployeeData(Index: Integer; EmployeeData: TStringlist); begin F_Main.Employee.CardID := StrtoInt(EmployeeData[0]); F_Main.Employee.Prename := EmployeeData[1]; F_Main.Employee.Surname := EmployeeData[2]; F_Main.Employee.Birthday := StrtoDate(EmployeeData[3]); F_Main.Employee.Workstation := EmployeeData[4]; F_Main.Employee.Position := EmployeeData[5]; F_Main.OLEmployees.Add(F_Main.Employee); // Employee Daten werden als neuer Eintrag gespeichert end; Zurzeit wäre ja jedes neue Item der Objectlist ein neuer Mitarbeiter mit den Eigenschaften von Employee. |
AW: Record im Array nutzen? - Sinnvollere Wege?
@Asura: Warum dieser Umweg über die Stringliste?
MfG Dalai |
AW: Record im Array nutzen? - Sinnvollere Wege?
Zitat:
Alternativ kann man auch entsprechende Indizes erstellen und über die dann den Zugriff steuern. Gruß K-H |
AW: Record im Array nutzen? - Sinnvollere Wege?
@Dalai:
Ich dachte mir für jede Property ein Parameter zu nehmen, wo ich den Inhalt eines Editfeldes übermittle ist unschön. Oder gibt es eine andere Methode? @p80286: Muss ich mir dafür eine Funktion schreiben, oder wie kann ich nach der Property suchen? |
AW: Record im Array nutzen? - Sinnvollere Wege?
Zitat:
1x suchen: Linear durchsuchen. öfter suchen: Dictionary. Sortieren und dann suchen? Ich jedenfalls nie. |
AW: Record im Array nutzen? - Sinnvollere Wege?
Zitat:
MfG Dalai |
AW: Record im Array nutzen? - Sinnvollere Wege?
@Dalai:
Ich habe es glaube ich aber trotzdem verstanden. Im Prinzip überspringst du einfach die Parameterübergabe von der einen Unit zur anderen und fügst gleich die Inhalte den Eigenschaften von dem Objekt Employee und fügst das dann der Objektliste zu. Ich frage mich aber wie ich die Funktion Equals der Klasse TEmployee von Sir Rufo nutzen kann, könnte man mir da eventuell ein Beispiel geben? |
AW: Record im Array nutzen? - Sinnvollere Wege?
Mit
Delphi-Quellcode:
kann man Instanzen auf Gleichheit prüfen.
function TObject.Equals( Obj: TObject ): Boolean;
Und zwar im Sinne von "stellen das Gleiche dar". Zwei unterschiedliche Instanzen von
Delphi-Quellcode:
können ja die gleiche ID haben und stellen somit das Gleiche dar.
TEmployee
Delphi-Quellcode:
var e1, e2: TEmployee;
if e1 = e2 then ShowMessage( 'Gleiche Instanzen' ); if e1.Equals( e2 ) then ShowMessage( 'Gleiche Bedeutung' ); |
AW: Record im Array nutzen? - Sinnvollere Wege?
Dankeschön!
Ich habe noch eine weitere Frage: Wenn ich einen Mitarbeiter hinzufüge über den Button erfolgt nun folgendes: Ich erstelle ein neues Objekt mit
Delphi-Quellcode:
speichere dann die Inhalte in die Property von Employee und füge das dann der Liste hinzu.
Employee.Create();
Nun meine Frage ist jz, muss ich mit dem Objekt von TEmployee arbeiten oder muss ich pro Mitarbeiter ein neues Objekt von
Delphi-Quellcode:
erstellen mit einer Index-Nummer (Beispielsweise Employee1, Employee2 usw.) und dieses dann über
TEmployee
Delphi-Quellcode:
initialisieren?
Employee1.Create();
Weil in meiner Methode hätte TObjectlist ja jedes Object in der Liste mit dem Namen "Employee", nur mit verschiedenen Properties oder kann ich das so machen? |
AW: Record im Array nutzen? - Sinnvollere Wege?
Eine Instanzvariable ist eine Referenz (Zeiger) auf eine Instanz (Objekt). Du kannt die selbe wiederverwenden oder sogar ganz auf sie verzichten.
|
AW: Record im Array nutzen? - Sinnvollere Wege?
Eine Instanz erzeugt man mit
Delphi-Quellcode:
.
Employee := TEmployee.Create();
Delphi-Quellcode:
ruft nur den Konstruktor der Instanz auf, erzeugt aber keine Instanz!
Employee.Create();
|
AW: Record im Array nutzen? - Sinnvollere Wege?
Zitat:
Neu erstellen geht nur mit
Delphi-Quellcode:
.
TEmployee.Create();
|
AW: Record im Array nutzen? - Sinnvollere Wege?
Ohh stimmt, mein Fehler.
Die Frage bleibt aber, ob ich nun die Instanz mit dem gleichen Namen "Employee" nur neu erstellen oder jeweils der neuen Instanz eine Indexnummer angefügt werden soll, weil sonst kann ich doch in der FUnktion Equals keinen Unterschied festlegen, da er nicht weiß, welche Instanz nun überprüft werden soll. Aber dann frage ich mich, ich muss diese Instanzen ja initialisieren in var:
Delphi-Quellcode:
. Wie soll ich da mit einer variablen Indexnummer arbeiten?
var
Employee1, Employee2: TEmployee |
AW: Record im Array nutzen? - Sinnvollere Wege?
Die Frage verstehe ich nun gar nicht.
Es sei denn, du würdest die ID fälschlicherweise als Indexnummer bezeichnen. Die ID ist aber ein Identifizierer und kein Index. In einer Datenbank würde man es als Primary Index bezeichnen (eindeutiger Hauptindex) oder auch mal als Identity oder Unique Index (eindeutiger Index). Ein einfacher Index kann mehrfach vorkommen und eignet sich nicht als Identifizierer. Hier sind also die exakten Begrifflichkeiten wichtig, weil die Frage ansonsten von niemandem verstanden wird. |
AW: Record im Array nutzen? - Sinnvollere Wege?
Nun, ich habe ja zwei Möglichkeiten eingetragene Daten in die Objectliste zu speichern:
Entweder ich nutze nur die Instanz Employee von der Klasse TEmployee und lasse sie mir vor dem speichern der Eigenschaften neu erzeugen. Wie in meinem aktuellen Fall: Methode 1
Delphi-Quellcode:
Methode 2:procedure AddEmployeeData(Index: Integer; EmployeeData: TStringlist); begin F_Main.Employee := TEmployee.Create(); F_Main.Employee.CardID := StrtoInt(EmployeeData[0]); F_Main.Employee.Prename := EmployeeData[1]; F_Main.Employee.Surname := EmployeeData[2]; F_Main.Employee.Birthday := StrtoDate(EmployeeData[3]); F_Main.Employee.Workstation := EmployeeData[4]; F_Main.Employee.Position := EmployeeData[5]; F_Main.OLEmployees.Add(F_Main.Employee); // Employee Daten werden als neuer Eintrag gespeichert showmessage(TEmployee(F_Main.OLEmployees.Items[0]).Prename); // dient als test showmessage(TEmployee(F_Main.OLEmployees.Items[1]).Prename); // dient als Test end; Oder ich müsste für jeden eingetragenen Mitarbeiter beispielsweise eine neue Instanz mit Indexnummer versehen. Beispiel:
Delphi-Quellcode:
F_Main.Employee1 := TEmployee.Create(); // Für Mitarbeiter 1 der eingetragen wurde
Delphi-Quellcode:
Weil bei Equals könnte ich ja dann im Prinzip im zweiten Fall einfach:
F_Main.Employee2 := TEmployee.Create(); // Für Mitarbeiter 2 der eingetragen wurde
Delphi-Quellcode:
machen, welches im ersten Fall ja nicht so einfach geht, da ich ja nur eine Instanz habe, nämlich Employee.
if Employee1.Equals( Employee2 ) then
ShowMessage( 'blablabla' ); Ich hoffe nun ist das verständlicher. EDIT: Mit der Index nummer meine ich eig nur die Zahl hinter Employee, also Employee1, Employee2 usw. Für mich ist Methode 1 einfacher und sie funktioniert auch insoweit, nur Frage ich mich, ob man doch Methode 2 anwenden soll. |
AW: Record im Array nutzen? - Sinnvollere Wege?
Du kannst die StringList-Orgie komplett weg lassen. Anstatt die Werte aus den Edit-Feldern in eine String-Liste zu schreiben um diese dann von der String-Liste in eine neue
Delphi-Quellcode:
zu schreiben und diese Instanz dann in die Liste,
TEmployee
warum dann nicht gleich die Instanz mit den Werten aus den Edit-Feldern bestücken? Machst du doch eh schon, nur mit dem Umweg über die String-Liste. |
AW: Record im Array nutzen? - Sinnvollere Wege?
Das mit der TStringliste mache ich nur, weil ich sämtliche Methoden, die zu der Verarbeitung der Instanz Employee zuständig sind, in einer anderen Unit haben wollte. Ich rufe aus der Unit, mit einem Formular, nur die Funktionen auf, die zu der Verarbeitung zuständig sind und es werden hier nur Formatierungsangelegenheiten hinterlegt. Also die Verwaltung der Objektlist findet praktisch nur in der anderen Unit statt.
Ich wollte hier nur die wichtigen "Main-Funktionen" von Formatierung (Wie: Was passiert wenn Edit feld 1 geändert wurde) trennen. Edit: Achso, ich glaube ich weiß worauf ihr hinaus wollt, das ich selbst in der anderen Unit einfach diese ansprechen kann, oder? |
AW: Record im Array nutzen? - Sinnvollere Wege?
Zitat:
Du kannst aber auch einfach einen Konstruktor erstellen, der die Parameter bekommt. In beiden Fällen musst du aber nicht erst in Strings umwandeln. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:14 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz