Delphi-PRAXiS
Seite 2 von 6     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   Übungsprogramm "Kinokarten" (https://www.delphipraxis.net/191102-uebungsprogramm-kinokarten.html)

EdAdvokat 12. Dez 2016 13:05

AW: Übungsprogramm "Kinokarten"
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier nun mein zweiter Versuch "Kinokarten" mit Karten für den 1. bis 3. Rang und Bedingungen für die Platzanzahl in Bezug auf die verkauften Karten.
Ich hoffe den Hinweis Arrays zu verwenden habe ich richtig verstanden und einige weitere Veränderungen haben das kleine Übungsprogramm etwas aufgewertet.

EdAdvokat 14. Dez 2016 13:07

AW: Übungsprogramm "Kinokarten"
 
Liste der Anhänge anzeigen (Anzahl: 1)
So perfekt kann das Programm doch nicht gewesen sein, dass bislang keine Kritik folgte. Hier nun meine vorerst letzte Version mit einigen zusätzlichen Funktionen wie Kontextmenü und Preise für ermäßigte Karten.

Luckie 14. Dez 2016 14:23

AW: Übungsprogramm "Kinokarten"
 
Ich habe es noch nicht angeguckt. :mrgreen:

Delphi-Quellcode:
procedure TForm1.CloseExecute(Sender: TObject);
begin
  Application.Terminate;
end;
Was ist denn das? Warum kein einfaches Close? Klar, kann ich beim Auto einfach den Zündschlüssel abziehen. Aber normalerweise bremst man, hält an, leg den ersten Gang ein, zieht die Handbremse, macht dann den Motor aus und zieht den Zündschlüssel ab.

Delphi-Quellcode:
procedure TForm1.EdRang1KeyPress(Sender: TObject; var Key: Char);
begin
   if not (Key in ['0'..'9', FormatSettings.DecimalSeparator, FormatSettings.ThousandSeparator, Char(VK_BACK)]) then
    Key := #0;
end;
Die Prozedur kommt neunmal vor und ist immer identisch. Einmal schreiben und allen Komponenten diese eine Ereignissprozedur zu weisen.

Delphi-Quellcode:
procedure TForm1.PreisExecute(Sender: TObject);
var anz : array[1..3] of integer;
    Rang : array[1..3] of integer;
    zwSu, Steuer, Endpreis : real;
begin
   try
      Anz[1]:=0;
      Anz[2]:=0;
      Anz[3]:=0;
      ZwSu:=0.0;
      Steuer:=0.0;
      Endpreis:=0.0;

//Eingabe der Kartenanzahl zum Kauf
      EdRang1.SetFocus;
      Anz[1]:=strtoint(EdRang1.Text);
      Rang[1]:=Anz[1]*15;
        if ckbxR1.Checked then Rang[1]:=Rang[1]-(Rang[1]div 10)
          else if not ckbxR1.checked then
            Rang[1]:=Anz[1]*15;
        if frKaR[1]<Anz[1] then
          begin
            Showmessage('Sie wollen mehr Karten 1. Rang verkaufen als Plätze vorhanden sind!');
             exit;
          end;

      Anz[2]:=strtoint(EdRang2.Text);
      Rang[2]:=Anz[2]*13;
        if ckbxR2.Checked then Rang[2]:=Rang[2]-(Rang[2]div 10)
          else if not ckbxR2.checked then
            Rang[2]:=Anz[2]*13;
        if frKaR[2]<Anz[2] then
          begin
            Showmessage('Sie wollen mehr Karten 2. Rang verkaufen als Plätze vorhanden sind!');
             exit;
          end;

      Anz[3]:=strtoint(EdRang3.Text);
      Rang[3]:=Anz[3]*10;
        if ckbxR3.Checked then Rang[3]:=Rang[3]-(Rang[3]div 10)
          else if not ckbxR3.checked then
            Rang[3]:=Anz[3]*10;
         if frKaR[3]<Anz[3] then
          begin
            Showmessage('Sie wollen mehr Karten 3. Rang verkaufen als Plätze vorhanden sind!');
             exit;
          end;

       if frPl<Anz[1]+Anz[2]+Anz[3] then
       begin
          Showmessage('Sie wollen mehr Karten verkaufen als Plätze vorhanden sind!');
           exit;
       end;
//Preisberechnung für erworbene Karten
      ZwSu:=ZwSu+Rang[1]+Rang[2]+Rang[3];
      Steuer:=ZwSu*0.19;
      Endpreis:=ZwSu+Steuer;
      AusgEndpreis.Text:=floattostrF(Endpreis, ffCurrency, 8,2);

//Ausgabe der Preisinformation
    MessageDlg('Der Preis '+floattostrF(Endpreis,ffCurrency, 8,2)+' setzt sich zusammen aus '+floattostrF(zwSu,ffCurrency, 8,2)+' Netto plus '#10#13+floattostrF(Steuer, ffCurrency, 8,2)+' MWSt' , mtInformation, [mbOK], 0);

//Berechnung der verkauften Karten und der freien Plätze
      KartR[1]:=KartR[1]+Anz[1];
      frKaR[1]:=FrKaR[1]-Anz[1];
      gek1Rang.Text:=inttostr(KartR[1]);
      frKaR1.Text:=inttostr(frKaR[1]);

      KartR[2]:=KartR[2]+Anz[2];
      frKaR[2]:=FrKaR[2]-Anz[2];
      gek2Rang.Text:=inttostr(KartR[2]);
      frKaR2.Text:=inttostr(frKaR[2]);

      KartR[3]:=KartR[3]+Anz[3];
      frKaR[3]:=FrKaR[3]-Anz[3];
      gek3Rang.Text:=inttostr(KartR[3]);
      frKaR3.Text:=inttostr(frKaR[3]);

      GesamtPl:=GesamtPl+ Anz[1]+Anz[2]+Anz[3];
      FrPl:=FrPl-(Anz[1]+Anz[2]+Anz[3]);
      AusgKartenGes.Text:=inttostr(GesamtPl);
      AusgFreiePl.Text:=inttostr(FrPl);

//Hinweise für verkaufte Karten
   if KartR[1]>20 then
    begin
      ShowMessage('Es wurden 20 Karten 1. Rang verkauft!');
    end;

   if KartR[2]>30 then
    begin
      ShowMessage('Es wurden 30 Karten 2. Rang verkauft!');
    end;

    if KartR[3]>50 then
    begin
      ShowMessage('Es wurden 50 Karten 3. Rang verkauft!');
    end;

//Gesamtplätze berechnen
   if GesamtPl>=100 then
     begin
       ShowMessage('Es sind bereits 100 Karten verkauft');
          EdRang1.Enabled:=false;
        EdRang2.Enabled:=False;
        EdRang3.Enabled:=False;
        Button1.Enabled:=false;
     end;
          zwSu:=0.0;
        Steuer:=0.0;
        Endpreis:=0.0;
  except
    on EConvertError do showMessage(Fehler);
  end;
end;
Ich habe mal den ganzen Code reinkopiert. 113 Zeilen. Für mich viel zu lang für ein Prozedur. Du hast es ja schon die Abschnitte kommentiert, was da gemacht wird:
Delphi-Quellcode:
//Preisberechnung für erworbene Karten
      ZwSu:=ZwSu+Rang[1]+Rang[2]+Rang[3];
      Steuer:=ZwSu*0.19;
      Endpreis:=ZwSu+Steuer;
      AusgEndpreis.Text:=floattostrF(Endpreis, ffCurrency, 8,2);

//Ausgabe der Preisinformation
    MessageDlg('Der Preis '+floattostrF(Endpreis,ffCurrency, 8,2)+' setzt sich zusammen aus '+floattostrF(zwSu,ffCurrency, 8,2)+' Netto plus '#10#13+floattostrF(Steuer, ffCurrency, 8,2)+' MWSt' , mtInformation, [mbOK], 0);

//Berechnung der verkauften Karten und der freien Plätze
      KartR[1]:=KartR[1]+Anz[1];
      frKaR[1]:=FrKaR[1]-Anz[1];
      gek1Rang.Text:=inttostr(KartR[1]);
      frKaR1.Text:=inttostr(frKaR[1]);

      KartR[2]:=KartR[2]+Anz[2];
      frKaR[2]:=FrKaR[2]-Anz[2];
      gek2Rang.Text:=inttostr(KartR[2]);
      frKaR2.Text:=inttostr(frKaR[2]);

      KartR[3]:=KartR[3]+Anz[3];
      frKaR[3]:=FrKaR[3]-Anz[3];
      gek3Rang.Text:=inttostr(KartR[3]);
      frKaR3.Text:=inttostr(frKaR[3]);

      GesamtPl:=GesamtPl+ Anz[1]+Anz[2]+Anz[3];
      FrPl:=FrPl-(Anz[1]+Anz[2]+Anz[3]);
      AusgKartenGes.Text:=inttostr(GesamtPl);
      AusgFreiePl.Text:=inttostr(FrPl);
Ich würde jeden Abschnitt in ein eigene Prozedur auslagern. Das macht den Code übersichtlicher und die Kommentare werden überflüssig. Zudem: Was für eine Exception erwartest du in dem Codeblock?

Und immer wieder die selben Meldungen:
Delphi-Quellcode:
//Hinweise für verkaufte Karten
   if KartR[1]>20 then
    begin
      ShowMessage('Es wurden 20 Karten 1. Rang verkauft!');
    end;

   if KartR[2]>30 then
    begin
      ShowMessage('Es wurden 30 Karten 2. Rang verkauft!');
    end;

    if KartR[3]>50 then
    begin
      ShowMessage('Es wurden 50 Karten 3. Rang verkauft!');
    end;
Besser:
Delphi-Quellcode:
TForm1.ShowSoldTickets(CntTickets: Integer; Rang: Integer)
begin
  ShowMessage(Format(..., [CntTickets, Rang]));
end;
Genauso mit den Fehlermeldungen.

Und wenn du das alle sin eien Klasse TKinokasse verpackst, hast du eine Trennung von Datenverarbeitung und Benutzeroberfläche, das ganze wird leichter erweiterbar und übersichtlicher, weil die ganzen Steuerelemnte im Code verschwinden.

Aviator 14. Dez 2016 14:26

AW: Übungsprogramm "Kinokarten"
 
Zitat:

Zitat von Luckie (Beitrag 1356120)
Was ist denn das? Warum kein einfaches Close? Klar, kann ich beim Auto einfach den Zündschlüssel abziehen. Aber normalerweise bremst man, hält an, leg den ersten Gang ein, zieht die Handbremse, macht dann den Motor aus und zieht den Zündschlüssel ab.

Du hast das Lenkradschloss vergessen. :mrgreen:

Luckie 14. Dez 2016 14:32

AW: Übungsprogramm "Kinokarten"
 
Zitat:

Zitat von Aviator (Beitrag 1356121)
Zitat:

Zitat von Luckie (Beitrag 1356120)
Was ist denn das? Warum kein einfaches Close? Klar, kann ich beim Auto einfach den Zündschlüssel abziehen. Aber normalerweise bremst man, hält an, leg den ersten Gang ein, zieht die Handbremse, macht dann den Motor aus und zieht den Zündschlüssel ab.

Du hast das Lenkradschloss vergessen. :mrgreen:

Das lasse ich vom Autodieb selber einrasten. :mrgreen:

EdAdvokat 14. Dez 2016 15:36

AW: Übungsprogramm "Kinokarten"
 
Ich will aus der Anweisung Application.terminate keine Ideologie machen, oder gar ein "Autounfall" provozieren. Bislang habe ich auch immer "close" für das Schließen des Programmes benutzt und mußte u.a. auch hier in der DP und in anderen Foren lernen, dass "close" lediglich zum Schließen eines Formulars eingesetzt werden sollte, jedoch nicht zum Schließen des Programms selbst. Dies wurde wie eine Todsünde behandelt. Nun kommt die Rolle rückwärts? Da habe ich doch brav all die Hinweise der Foren berücksichtigt und soll nun also wieder vom Glauben abfallen? Ist es denn so schlimm mit Application.terminate?
Über die anderen Fakten werde ich nachdenken.
Wie ich die Exception besser lösen könnte ist mir nicht klar. Ich weis da nicht so richtig weiter. Einfach nur frei lassen (also den Quatsch mit "on EConvertError do showMessage(Fehler)" weglassen?) und erwarten was für eine Exception-Meldung kommt oder was? Da könnte ich eine Anregung gebrauchen. Danke

haentschman 14. Dez 2016 15:47

AW: Übungsprogramm "Kinokarten"
 
Moin...8-)
Zitat:

und mußte u.a. auch hier in der DP und in anderen Foren lernen, dass "close" lediglich zum Schließen eines Formulars eingesetzt werden sollte
Das hast du nicht von hier... :zwinker: Auch deine Anwendung ist auch ein Formular. :P ...allerdings das Letzte.
Mit Terminate brichst du das Programm HART ab. (sinngemäß) Beispiel: Datenbanken werden u.u. nicht richtig geschlossen. Das kann zu Problemen führen.

..also immer CLOSE :thumb:

Luckie 14. Dez 2016 16:11

AW: Übungsprogramm "Kinokarten"
 
Wenn du die eine große Prozedur, wie schon vorgeschlagen, in einzelne zerlegst, kannst du gezielt mögliche Exceptions abfangen.

Und zum Close: Ein Aufruf von Close im Hauptformular bewirkt genau das, dass die Anwendung beendet wird. Und bitte zeig mir den Thread hier im Forum, wo gesagt wird, dass Apüplication.Terminate zum Beendne einer Anwendung vor zu ziehen ist. Klar auch wenn man eine Anwendung/Prozess hart beendet gibt Windows alle Systemressourcen frei, DLls werden entladen, alle offenen Handles werden geschlossen usw. Aber Close ist einfach sauberer.

@haentschman: Sockets und DBs sollte man wohl extra behandeln zu Sicherheit, sprich explizit selber schließen, da würde ich mich nicht auf Windows verlassen.

EdAdvokat 15. Dez 2016 13:57

AW: Übungsprogramm "Kinokarten"
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich gebe zu, mit den Hinweisen war ich gefordert und das Ergebnis (Datei anbei) ist sicher nicht so, wie erwaret. Ich komme nicht weiter mit einer effektiveren Verkleinerung der großen Prozedur "Kartenbestellung". Bei jeder versuchten Neuaufteilung kommt die Zählerei der noch freien Plätze durcheinander. Wenn diese Berechnung ordentlich durchführt wird, gibt er trotz nicht freier Kinoplätze eine Rechnungssumme aus. Ich habe mehrere Varianten ausprobiert, doch meine bescheidenen Kenntnisse...
In der jetzigen Form sollte alles so wie vorgesehen funktionieren.
Noch eine kleine Frage habe ich zum Compilerhinweis besser charlnset zu verwenden bei der Abfrage der Editfelder (Key in...)

Luckie 15. Dez 2016 14:56

AW: Übungsprogramm "Kinokarten"
 
Deswegen das ganze in eine Klasse kapseln.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:04 Uhr.
Seite 2 von 6     12 34     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz