Thema: Delphi überfordert ~.~

Einzelnen Beitrag anzeigen

nahpets
(Gast)

n/a Beiträge
 
#6

AW: überfordert ~.~

  Alt 9. Apr 2013, 12:34
Hallo,

habe gerade mal ein bisserl nix zu tuen, deshalb schau ich kurz in den Quelltext

warum
Delphi-Quellcode:
anreise:=(DatetoStr(bu_anreise.Date));
abreise:=(DatetoStr(bu_abreise.Date));

if (anreise >= abreise) then
  begin
    Showmessage('Buchung nich möglich. Bitte überprüfen Sie das Datum.');
  end
else
  begin
Datumswerte kann man miteinander vergleichen (auch unter Delphi 6)
if (bu_anreise.Date >= bu_abreise.Date) then dürfte die gleiche Wirkung haben, wobei ein Vergleich von z. B. 25.05.2013 mit 01.08.2013 als Datumswerte durchaus zu einem "besseren" Ergebnis führen kann als als Zeichenfolge. Als Zeichenfolge ist 01.08.2013 kleiner als 25.05.2013, bei einem Datumsvergleich nicht.

Bitte mal in der Hilfe die Beschreibungen zu den Datumsfunktionen der Unit DateUtils anschauen. Dort sollte es sowas wie DayOf, MonthOf, YearOf geben, die Funktionen benötigen alle als Eingabeparameter einen TDateTime, der mit bu_anreise.Date... ja vorhanden ist. Dadurch läßt sich die gesamte Zeichenfolgenverarbeitung vermeiden und die Ergebnisse werden sicherlich einfacher und korrekt ermittelt.

Die gesamte Datumsumformatierungsorgie mit DD, MM und JJ wird dadurch hinfällig.

Da es sich bei den Buchungsdaten für Anreise und Abreise um Datumswerte handelt, sollten hier in der Datenbank auch Datumswerte gespeichert werden und keine Timestamps. Der Datentyp Date ist der genutzten Datenbank bekannt.

Die Datenbankabfragen sollten parametrisiert werden, damit das Zusammenbauen der SQL-Statements vereinfacht wird.
Das könnte dann z. B. so oder so ähnlich aussehen:
Delphi-Quellcode:
ADOQuery_Buchen2.sql.text:=('SELECT Buchung.Zimmer_Nr FROM Buchung WHERE Buchung.Anreise >= :anreise AND Buchung.Abreise <= :abreise ');
ADOQuery_Buchen2.Parameters.ParamByName('anreise').Value := bu_anreise.Date;
ADOQuery_Buchen2.Parameters.ParamByName('abreise').Value := bu_abreise.Date;
ADOQuery_Buchen2.Active:=true;
Dashier erschließt sich mir überhaupt nicht:
Delphi-Quellcode:
    For zeile := 1 to 20 DO //Zeilen im DBGrid hochzaehlen
      begin
       with DBGrid1.DataSource.DataSet do
         begin
          RecNo := Zeile;
          s:= Fields[spalte-1].AsString;
         end;
         b:=strtoint(s);
      end;
DBGrid1 ist mit ADOQuery_Buchen2 verbunden, es dürfte also auch mit
Delphi-Quellcode:
    For zeile := 1 to 20 DO //Zeilen im DBGrid hochzaehlen
      begin
       with ADOQuery_Buchen2 do
         begin
          RecNo := Zeile;
          s:= Fields[spalte-1].AsString;
         end;
         b:=strtoint(s);
      end;
gehen. Spalte wird am Anfang auf 1 gesetzt und dann immer mit Spalte-1 genutzt, warum? Spalte könnte dann auch direkt 0 sein oder direkt Fields[0].AsString. Da das Feld Zimmer_Nr gelesen wird, wäre FieldByName('Zimmer_Nr').AsString aber eleganter.
Aber sinnvoll ist das Ganze nicht, was ist, wenn die Abfrage weniger als 20 Zeilen hat?
Die Logik geht hier davon aus, dass die Ergebnismenge immer über 20 Zeilen verfügt, das dürfte eher unwahrscheinlich sein. Zimmer_Nr ist in der Datenbank numerisch, warum dann ein derartiges Konstrukt?
Delphi-Quellcode:
s:= Fields[spalte-1].AsString;
b:=strtoint(s);
Wir lesen also einen Integerwert der Datenbank als String, um diesen dann in einen Integer zu verwandeln?b := FieldByName('Zimmer_Nr').AsInteger liefert das gleiche Ergebnis. Interessant ist, dass bei dieser Logik am Ende b immer den Wert der 20. Zimmmer_Nr aus der Ergebnismenge hat. Man könnte dann auch sowas programmieren:
Delphi-Quellcode:
ADOQuery_Buchen2.Active:=true;
ADOQuery_Buchen2.MoveBy(20);
b := FieldByName('Zimmer_Nr').AsInteger;
Hier gibt es, wie mir scheint, mehrere Probleme: Einige, für die Aufgabenstellung erforderliche, Grundlagen sind nicht (hinreichend?) bekannt. Die Aufgabenstellung ist nicht bekannt oder verstanden worden bzw. die Aufgabe wurde nicht in hinreichend kleine Teilstücke zerlegt, um diese dann sinnvoll in Quelltext umsetzen zu können.
  Mit Zitat antworten Zitat