Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Aus Geburtsdatum automatisch das Alter berechnen


GiuStyler - Mo 24.11.14 14:17
Titel: Aus Geburtsdatum automatisch das Alter berechnen
Hallo Leute,

stehe mal wieder vor einem Problem. Ich habe in meinem Formular zwei Felder.

EditGeburtsdatum.Text = Manuelle eingabe des Geburtstages & EditAlter.Text = Hier soll das Automatische Alter angegeben werden.

----

Hier im Forum habe ich folgendes gefunden


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
uses ...DateUtils;
....

var Geburtstag : TDate; 
    Alter : Integer;

begin 
  Geburtstag := '12.07.1987';
  Alter := YearsBetween(Geburtstag,now);
  Showmessage(Inttostr(Alter));
end;


Habe das versucht umzusetzen, aber irgendwie funktioniert es nicht. Entweder für meine Lösung das Falsche oder mein Umbau ist verkehrt was ich eher vermute.

Mein Umbau sieht so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TFormKundenverwaltung.EditAlterChange(Sender: TObject);
var
  Geburtsdatum : TDate;
  Alter : Integer;
begin
  Geburtsdatum := StrToDate(EditGeburtsdatum.Text);
  EditAlter.Text := IntToStr(YearsBetween(StrToDate(EditGeburtsdatum.Text), now));
end;


Bitte um Hilfe. Wie kriege ich im EditAlter.Text automatisch das Alter, wenn ich im EditGeburtsdatum.Text das Datum eingebe?

Mit freundlichen Grüßen


Nersgatt - Mo 24.11.14 14:38

user profile iconGiuStyler hat folgendes geschrieben Zum zitierten Posting springen:
aber irgendwie funktioniert es nicht. Entweder für meine Lösung das Falsche oder mein Umbau ist verkehrt was ich eher vermute.


Solche Sätze sind immer ganz schlechte Fehlerbeschreibungen. Bitte sagt etwas genauer, was nicht funktioniert.

Bekommst Du eine Fehlermeldung?
Wenn ja welche?
Und wann kommt die Meldung?
Schon beim kompilieren oder wenn Du das Programm ausführst?
Oder bekommst Du ein falsches Ergebnis?
Welches Ergebnis bekommst Du und welches Ergebnis erwartest Du?


GiuStyler - Mo 24.11.14 14:46

Es kommt kein Fehler.

Alles läuft. Nur wenn ich im EditGeburtsdatum.Text das Datum eingeben XX.XX.XXXX sollte bei anderem Fenster EditAlter.Text automatisch dann eben das Alter kommen. Es bleibt aber leer.

Mit freundlichen Grüßen


Nersgatt - Mo 24.11.14 14:51

Ist bei Deinem Editfeld, wo Du das Datum eingibst das Ereignis "OnChange" auch mit dem Code verbunden? Also im Propertyeditor?


GiuStyler - Mo 24.11.14 15:06

Oh hm ne, da ist nichts eingetargen.

Da muss ich wohl den Wert dem EditAlter.Text zuweisen oder?

Also alles was mit dem Alter zu tun hat ist folgedes.
----

In der uses habe ich das hinzugefügt


Delphi-Quelltext
1:
DateUtils;                    


In der type Klasse ist das vorhanden


Delphi-Quelltext
1:
procedure EditAlterChange(Sender: TObject);                    


und dann der Code


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TFormKundenverwaltung.EditAlterChange(Sender: TObject);
var
  Geburtsdatum : TDate;
  Alter : Integer;
begin
  Geburtsdatum := StrToDate(EditGeburtsdatum.Text);
  EditAlter.Text := IntToStr(YearsBetween(StrToDate(EditGeburtsdatum.Text), now));
  ShowMessage(IntTostr(Alter));
end;


Das hier ist leer bzw. nicht vorhanden bei mir


Delphi-Quelltext
1:
2:
3:
4:
procedure TFormKundenverwaltung.EditGeburtsdatumChange(Sender: TObject);
begin

end;


Mit freundlichen Grüßen


Nersgatt - Mo 24.11.14 15:09

Du musst ja festlegen, wann Dein Code ausgeführt wird.
Sinnvoll ist es hier, das zu machen, wenn sich der Text im Eingabefeld ändert. Dies wird durch das Ereignis "onChange" repräsentiert.
Also mache einen Doppelklick im Propertyeditor bei dem Ereignis. Delphi legt Dir dann einen leeren Procedurerumpf an. Dort kannst Du nun den Code einfügen, der Dir das Alter berechnet und das Ergebnis der Rechnung im Ausgabefeld anzeigt.


GiuStyler - Mo 24.11.14 15:34

Hm. Irgendwie funktioniert es nicht so wirklich. So wie ich es jetzt programmiert habe kommt sobald ich nur eine Zahl drücke automatisch im Feld 30.12.1899

Bei mir sehen nun beide so aus. Ist zu 100% Falsch. Aber habe gerade keine IDee welchen von beiden wenn überhaupt richtig ist


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TFormKundenverwaltung.EditGeburtsdatumChange(Sender: TObject);
var
  lg_geburtsdatum : TDate;
  Alter : Integer;
begin
  EditGeburtsdatum.Text := DateToStr(lg_geburtsdatum);
  EditAlter.Text := IntToStr(YearsBetween(StrToDate(EditGeburtsdatum.Text), now));
end;

procedure TFormKundenverwaltung.EditAlterChange(Sender: TObject);
var
  lg_eburtsdatum : TDate;
  Alter : Integer;
begin
  lg_eburtsdatum := StrToDate(EditGeburtsdatum.Text);
  EditAlter.Text := IntToStr(YearsBetween(StrToDate(EditGeburtsdatum.Text), now));
end;



Aber wie im ersten Satz beschrieben ist, sobald ich auf dem Geburtsdatum gehe und eine Zahl drücke kommt sofort 30.12.1899 und im Altersfeld was nicht beschrieben werden kann 114. Das geht schon mal, aber wieso kommt nun automatisch dieses Datum?

EDIT: Das EditAlterChange ist überflüssig. Habe ich gerade mal entfernt und es geht trotzdem mit dem beschriebenen Fehler.

Mit freundlichen Grüßen


WasWeißDennIch - Mo 24.11.14 15:44

Ich habe mal einen DateTimePicker und ein Label zur Anzeige statt zweier Edits genommen. Im OnChange des DateTimePickers steht:

Delphi-Quelltext
1:
lblAge.Caption := IntToStr(YearsBetween(now, dtpBirthday.Date));                    

Sieht bei kurzen Tests gut aus.


GiuStyler - Mo 24.11.14 15:49

Das mit dem DareTimePicker hatte ich mal auch getestet, aber da zeigt er mir ja das aktuelle Datum und ich muss mich durchklicken bich ich dann das Geburtsdatum der jeweiligen Person eintragen kann. Das ist umständlicher als wenn ich die 8 Zahlen und zwei (.) direkt manuell eingeben oder?


WasWeißDennIch - Mo 24.11.14 15:52

Du kannst das Datum doch auch im DateTimePicker direkt eingeben, man muss ja nicht zwingend den Kalender benutzen.


GiuStyler - Mo 24.11.14 15:56

Ja, habe ich gerade bemerkt, aber das Alter kommt nicht direkt.

Habe das im Label getestet, da kommt nichts und bei einem EditFeld muss ich im Editfeld erst rein und dann Leertaste drücken, damit das Alter kommt. Sieht beim Test gerade so aus.


Delphi-Quelltext
1:
2:
3:
4:
procedure TFormKundenverwaltung.Edit1Change(Sender: TObject);
begin
  Label1.Caption := IntToStr(YearsBetween(now, DateTimePicker1.Date));
end;


WasWeißDennIch - Mo 24.11.14 15:59

Zitat:

Delphi-Quelltext
1:
2:
3:
4:
procedure TFormKundenverwaltung.Edit1Change(Sender: TObject);
begin
  Label1.Caption := IntToStr(YearsBetween(now, DateTimePicker1.Date));
end;

Den Sinn dahinter verstehe ich nicht. Wieso nimmst Du nicht das OnChange des DateTimePickers, das Edit brauchst Du doch überhaupt nicht?


GiuStyler - Mo 24.11.14 16:06

OK. Danke. Funktioniert nun. Aber wie kriege ich nun das ausgewählte Datum ins StringGrid? Das war ja der Grund wieso ich es als EditFeld ausgegeben habe.

Welche Funktion muss ich nun nehmen statt


Delphi-Quelltext
1:
lg_geburtdatum := EditGeburtsdatum.Text                    


???


WasWeißDennIch - Mo 24.11.14 16:18

In DateTimePicker1.Date steht das ausgewählte Datum als TDate. Das kannst Du mit DateToStr ganz einfach in einen String umwandeln und z.B. in einem StringGrid anzeigen.


GiuStyler - Mo 24.11.14 16:21

Danke. Habs gerade rausgefunden :-).

So, dann wäre das nächste Problem gelöst. Danke euch beiden für die Hilfe.


baka0815 - Mo 24.11.14 17:59

Um noch ein bisschen für Aufklärung zu sorgen:

Das "OnChange"-Ereignis eines Textfelds wird jedes mal gefeuert, wenn man eine Taste drück - eben mit jeder Änderung.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TFormKundenverwaltung.EditAlterChange(Sender: TObject);
var
  Geburtsdatum : TDate;
  Alter : Integer;
begin
  { Sorgt für eine Zugriffsverletzung, wenn in EditGeburtsdatum.Text kein gültiges Datum steht.
    Du könntest StrToDateDef(EditGeburtsdatum.Text, 0) verwenden.
    Bedeutet - Wandle den Text aus EditGeburtsdatum.Text in ein Datum um, klappt dies nicht, verwende 0 (30.12.1899).
    Du kannst dann im weiteren Verlauf prüfen ob Geburtsdatum <= 0 und abbrechen.
  }

  Geburtsdatum := StrToDate(EditGeburtsdatum.Text);

  { Du benutzt hier zweimal denselben Code (StrToDate(...))
    Da du das Geburtsdatum bereits in der Variable "Geburtsdatum" als TDate hast,
    solltest du dieses hier auch verwenden:

    YearsBetween(Geburtsdatum, Now)
  }

  EditAlter.Text := IntToStr(YearsBetween(StrToDate(EditGeburtsdatum.Text), now));

  ShowMessage(IntTostr(Alter));
end;


YearsBetween funktioniert übrigens nicht 100%ig, da immer ein Annäherungswert von 365,25 Tagen pro Jahr verwendet wird. Dadurch gibt es leichte Abweichungen.

Ein guter Beitrag dazu in der Delphi Praxis [http://www.delphipraxis.net/146593-alter-fehlerfrei-errechnen.html].