Stringgrid objects class: Wann ist der richtige Zeitpunkt für create? Wie Speicher freigeben?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Benutzeravatar
KoBraSoft
Beiträge: 125
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: die zu Zeit aktuellen Versionen, überwiegend Linux
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Stringgrid objects class: Wann ist der richtige Zeitpunkt für create? Wie Speicher freigeben?

Beitrag von KoBraSoft »

Hallo,
ich habe ein Stringgrid in dem in Zeilen die Tage eines Monats stehen und in Spalten die Mitarbeiter. In den Zellen steht die Arbeitszeit bzw der Abwesenheitsgrund (Urlaub, Krank,..) als Text. Die Spalten werden dynamisch erzeugt mit

Code: Alles auswählen

StringGrid1.Columns.Add;  
.
Nun will ich in jeder Zelle Informationen hinterlegen. Bisher habe ich so was immer dadurch gelöst, dass ich den Zeiger in der Zelle

Code: Alles auswählen

StringGrid1.Objects[x, y]
mit

Code: Alles auswählen

StringGrid1.Objects[x, v] := TObject(z);  
und

Code: Alles auswählen

z  := PtrUInt(StringGrid1.Objects[x,y])
missbraucht habe. Hat immer prima geklappt.
Nun will ich aber mehr Informationen in den Zellen zwischenspeichern, nämlich Arbeitszeit in Minuten (UINT16) und Arbeitstyp(UINT8). Ich könnte zwar den Zeiger der 64 bit hat aufteilen, aber da ich flexibel sein will, teste ich die Verwendung einer Klasse. Ich habe mir folgendes zusammen gesucht/gereimt:
Deklaration der Klasse:

Code: Alles auswählen

type
   TArbeitsTag = class
      Bezahlte_Minuten : Uint16;
      Arbeitstyp : Uint8;
   end;       

Dekalration der Variable:

Code: Alles auswählen

var
ArbeitsTag : TArbeitsTag;   
Erzeugen den Variable:

Code: Alles auswählen

ArbeitsTag := TArbeitsTag.Create;  
Zuweisen der Variable:

Code: Alles auswählen

StringGrid1.Objects[x, y] := ArbeitsTag;  
Zugriff auf die Variable:

Code: Alles auswählen

TArbeitsTag(StringGrid1.Objects[x, y]).Bezahlte_Minuten) 
Hier meine Fragen dazu:
  • Wie oft muss ich die Variable erzeugen? Einmalig oder vor jeder Zuweisung?
  • Wann muss ich den Speicher freigeben?
  • Gibt es eine einfachere Alternative zur Verwendung einer Klasse?
Konrad

www.KoBraSoft.de

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Re: Stringgrid objects class: Wann ist der richtige Zeitpunkt für create? Wie Speicher freigeben?

Beitrag von theo »

Die extra Variable brauchst du überhaupt nicht, wenn ich die Frage richtig verstehe.

Code: Alles auswählen

StringGrid1.Objects[x, y] := TArbeitsTag.Create; 
Du könntest einen Konstruktor machen, der es erlaubt, die Daten gleich mitzugeben.

Code: Alles auswählen

StringGrid1.Objects[x, y] := TArbeitsTag.Create(Minuten, Typ);

Benutzeravatar
KoBraSoft
Beiträge: 125
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: die zu Zeit aktuellen Versionen, überwiegend Linux
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Re: Stringgrid objects class: Wann ist der richtige Zeitpunkt für create? Wie Speicher freigeben?

Beitrag von KoBraSoft »

theo hat geschrieben: So 25. Aug 2024, 09:20 Die Variable brauchst du überhaupt nicht, wenn ich die Frage richtig verstehe.

Code: Alles auswählen

StringGrid1.Objects[x, y] := TArbeitsTag.Create; 
Sehr gut, funktioniert.
theo hat geschrieben: So 25. Aug 2024, 09:20 Du könntest einen Konstruktor machen, der es erlaubt, die Daten gleich mitzugeben.

Code: Alles auswählen

StringGrid1.Objects[x, y] := TArbeitsTag.Create(Minuten, Typ);
Ich habe mir auf die Schnelle zusammengegoogled wie man einen Konstruktor macht.

Code: Alles auswählen

type
   TArbeitsTag = class
      FBezahlte_Minuten : Uint16;
      FArbeitstyp : Uint8;
      constructor Create(Bezahlte_Minuten : Uint16; Arbeitstyp : Uint8);
   end;
Ich habe folgendes nach implementation eingefügt:

Code: Alles auswählen

constructor TArbeitsTag.Create(Bezahlte_Minuten : Uint16; Arbeitstyp : Uint8);
begin
  inherited Create;
  FBezahlte_Minuten := Bezahlte_Minuten;
  FArbeitstyp := Arbeitstyp;
end;


funktioniert
Konrad

www.KoBraSoft.de

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Re: Stringgrid objects class: Wann ist der richtige Zeitpunkt für create? Wie Speicher freigeben?

Beitrag von theo »

Ja.
Freigeben musst du die Objekte im Grunde nur, wenn du wieder neue erzeugst (besser vermeiden), die Liste leerst etc.
Ob das Object schon erzeugt wurde, kannst du mit Nil oder Assigned() prüfen. Falls schon da, einfach die Felder neu belegen.
So kann nicht viel passieren. Beim Schliessen der Anwendung kann man die Objekte freigeben, aber im Grunde wird der Speicher dabei sowieso frei (Unter der Annahme, dass du nur ein solches StrigGrid auf dem Formular hast und nicht laufend neue erzeugst und freigibst).

wp_xyz
Beiträge: 5193
Registriert: Fr 8. Apr 2011, 09:01

Re: Stringgrid objects class: Wann ist der richtige Zeitpunkt für create? Wie Speicher freigeben?

Beitrag von wp_xyz »

Ich würde etwas anders vorgehen und versuchen, die Daten von der Benutzeroberfläche zu trennen. Vielleicht mit einer kleinen lokalen SQL-Datenbank, in der jeder Grid-Eintrag ein Record wäre (Felder: Datum, Mitarbeiter, Arbeitstyp, Bezahlte_Minuten, usw.). Oder man könnte ein 2D-Array anlegen mit "Datum" in der einen Richtung und "Mitarbeiter" in der anderen, und jedes Array-Element wäre ein Record mit Arbeitstyp, Bezahlte_Minuten usw. Auch kompliziertere Datenstrukturen wie ein AVL-Tree wären denkbar.

Im ersten Fall würde ich für die Anzeige statt eines StringGrid ein DBGrid nehmen, das alles für mich erledigt (allerdings in der Handhabung etwas störrischer ist als ein StringGrid). Im zweiten Fall würde ich ein DrawGrid nehmen, das die darzustellenden Daten aus der übergeordneten Datenstruktur entnimmt (2D-Array, oder AVLTree); als Minimum wäre hier die Textausgabe in den Zellen zu programmieren. Für die Dateneingabe müsste man außerdem noch Handler schreiben für OnGetEditText/OnSetEditText etc. schreiben, die die Eingabe in die Datenstruktur zurückschreiben. Oder, besser, man erstellt sich ein eigenes Eingabeformular.

Benutzeravatar
KoBraSoft
Beiträge: 125
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: die zu Zeit aktuellen Versionen, überwiegend Linux
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Re: Stringgrid objects class: Wann ist der richtige Zeitpunkt für create? Wie Speicher freigeben?

Beitrag von KoBraSoft »

wp_xyz hat geschrieben: So 25. Aug 2024, 12:50 Ich würde etwas anders vorgehen und versuchen, die Daten von der Benutzeroberfläche zu trennen. Vielleicht mit einer kleinen lokalen SQL-Datenbank, in der jeder Grid-Eintrag ein Record wäre (Felder: Datum, Mitarbeiter, Arbeitstyp, Bezahlte_Minuten, usw.).
Die Daten liegen auf einer Datenbank auf einem Server. Viele Daten stammen von einem kleinen Tablet PC mit RFID Leser der auch als DB Server (Firebird) dient. Meine Routine prüft die Gültigkeit der Zeiterfassungen und trägt sie in das Stringgrid wo sie als Kreuztabelle angezeigt werden und darin bearbeitet werden können. zB Urlaub, Krankeit, .. eingetragen werden.
Zeilen sind Tage, Spalten sind Mitarbeiter. Das ließe sich mit einen DBGrid noch realisieren. In der ersten Spalte ist außerdem Datum auch noch der Wochentag und Feiertage hinterlegt und farblich gekennzeichnet.

Der Kunde soll per Maus in einer Mitarbeiterspalte mehrere Tage gleichzeitig markieren können und für die markierten Tage zB Urlaub eintragen können. Ich habe keinen Weg gefunden, wie ich dies mit einem DBGrid realisieren könnte.

Die Daten werden anschließend wieder in die DB geschrieben.
Konrad

www.KoBraSoft.de

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6855
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Stringgrid objects class: Wann ist der richtige Zeitpunkt für create? Wie Speicher freigeben?

Beitrag von af0815 »

Ich würde es sowieso nicht mit DB sentisiven visuellen Komponenten lösen. Dazu sind die zu generisch und man hat zuwenig Kontrolle. Ich versorge ein Formular mit Daten und nach der Bearbeitung, prüfe ich Eingaben und spiele die Daten zurück. Damit kannst du auch die ganze Validierung kontrollieren, auch Transaktionen sauber verwenden und es ist egal wenn mal ein Formular mit offenen Daten "vergessen" wird. Da bleibt keine Transaktion offen und kein Lock in der DB. Und wenn es kracht beim Einbuchen, so kann man den Benutzer führen. Kann ja sein, das der Kollege/in halt schneller war, oder es doch keine gute Idee war, in einer Buchung mal Mittag zu feiern :D
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten