Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Frage zur Entwicklung einer Komponente Feiertagsberechnung (https://www.delphipraxis.net/80619-frage-zur-entwicklung-einer-komponente-feiertagsberechnung.html)

JonnyGuitar 12. Nov 2006 16:49


Frage zur Entwicklung einer Komponente Feiertagsberechnung
 
servus,

ich bin totaler neuling was die komponentenentwicklung angeht und bin nun dabei zur übung eine komponente zu schreiben welche die feiertage berechnet. der code steht soweit, ich habe jetzt nur noch ein problem, und zwar möchte ich, dass wenn ich als property ein datum eingebe schon im object inspector zur entwurfszeit in anderen properties ein true oder false zurückkommt ob es sich um einen feiertag handelt und ggfs den feiertagsnamen. wie muss ich das machen, dass auf eine neueingabe des datums im object inpector reagiert wird?


mfg Jonny

Hansa 12. Nov 2006 16:52

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
Zitat:

Zitat von JonnyGuitar
..der code steht soweit..

Dann zeige den mal.

JonnyGuitar 12. Nov 2006 16:56

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
lol, ich depp :)

der code basiert auf folgender quelle: delphi-fundgrube


Delphi-Quellcode:
unit Feiertage;

interface

uses
  SysUtils, Classes;

const
  Feiertage : array [1..19] of string[25] =
   ('Neujahr','Maifeiertag','Tag der deutschen Einheit','Allerheiligen',
    'Totensonntag','Volkstrauertag','1. Weihnachtstag','2. Weihnachtstag',
    'Karfreitag','Ostersonntag','Ostermontag','Christi Himmelfahrt',
    'Pfingstsonntag','Pfingstmontag','Fronleichnam','Heilige 3 Könige',
    'Mariä Himmelfahrt','Reformationstag','Buß- und Bettag');
  Sondertage : array [1..24] of string[25] =
   ('Mariä Lichtmeß','Valentinstag','Weiberfastnacht','Rosenmontag','Fastnacht',
    'Aschermittwoch','Mariä Verkündigung','Palmsonntag','Gründonnerstag','Muttertag',
    'Peter und Paul','Mariä Geburt','Erntedankfest','Mariä Empfängnis','Silvester',
    '1. Advent','2. Advent','3. Advent','4. Advent','Heiligabend','Frühlingsanfang',
    'Sommmeranfang','Herbstanfang','Winteranfang');

type
  TFeiertage = class(TComponent)
  private
    { Private-Deklarationen }
    FFeiertag     : array [1..365] of ShortInt;
    FFeiertag: Boolean;
    FFeiertagName: String;
    FDatum: TDateTime;
    FBundesland: String;
    function OsterSonntag(Y:word):TDateTime;
    function TagImJahr(Datum:TDateTime):word;
    procedure FeiertageBerechnen(Y:word);
  protected
    { Protected-Deklarationen }
  public
    constructor Create(Year:Word) override;
    destructor destroy; override;
    { Public-Deklarationen }
  published
    property Datum: TDateTime read FDatum;
    property Feiertag: Boolean read FFeiertag;
    property Feiertagname: String read FFeiertagName;
    property Bundesland: String write FBundesland;
    { Published-Deklarationen }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Beispiele', [TFeiertage]);
end;

constructor TFeiertage.Create(Year:Word);
begin
  inherited;
  FeiertageBerechnen(Year);
  //
end;

destructor TFeiertage.destroy;
begin
  //
  inherited;
end;

function TFeiertage.TagImJahr(Datum:TDateTime):word;
var T,M,J : word;
    Erster : TDateTime;
begin
  try
    DecodeDate(Datum,J,M,T);
    Erster:=EncodeDate(J,1,1);
    Result:=trunc(Datum-Erster+1);
  except
    Result:=0;
  end;
end;

function TFeiertage.OsterSonntag(Y:word):TDateTime;
var a,b,c,d,e,tag,monat : integer;
begin
  a:=y MOD 19 ;
  b:=y MOD 4;
  c:=y MOD 7;
  d:=(19*a+24) MOD 30;
  e:=(2*b+4*c+6*d+5) MOD 7;
  Tag:=22+d+e;
  monat:=3;
  IF Tag>31 then begin
    tag:=d+e-9;
    monat:=4;
  end;
  IF (tag=26) AND (monat=4) then
    tag:=19;
  IF (tag=25) AND (monat=4) AND (d=28) AND (e=6) AND (a>10) then
    tag:=18;
  try
    Result:= EncodeDate(y,monat,tag);
  except
    Result:=0;
  end;
end;

procedure TFeiertage.FeiertageBerechnen(Y:word);
var D,dw,OM,aw : word;
    Dat       : TDateTime;
    Ostern    : TDateTime;
    Weihnacht : TDateTime;
begin
  for D:=1 to 365 do
    Feiertag[D]:=0;
  Ostern:=OsterSonntag(Y);
  try
    DecodeDate(Ostern,Y,OM,D);
  except
    OM:=4;
  end;
  try
    Weihnacht:=EncodeDate(Y,12,25);
    if (DayOfWeek(Weihnacht)-1)=0 then
      dw:=7
    else
      dw:=DayOfWeek(Weihnacht)-1;
  except
    Weihnacht:=-1;
    dw:=0;
  end;
  {Mariä Lichtmeß}                     {Sondertage}
  Dat:=Encodedate(Y,2,2);
  Feiertag[TagImJahr(Dat)]:=-1;
  {Valentinstag}
  Dat:=Encodedate(Y,2,14);
  Feiertag[TagImJahr(Dat)]:=-2;
  {Weiberfastnacht}
  Dat:=Ostern-45;
  while DayOfWeek(Dat)<>2 do
    Dat:=Dat-1;
  Feiertag[TagImJahr(Dat)-4]:=-3;
  {Rosenmontag}
  Feiertag[TagImJahr(Dat)]:=-4;
  {Fastnacht}
  Feiertag[TagImJahr(Dat)+1]:=-5;
  {Aschermittwoch}
  Feiertag[TagImJahr(Dat)+2]:=-6;
  {Mariä Verkündigung}
  Dat:=Encodedate(Y,3,25);
  Feiertag[TagImJahr(Dat)]:=-7;
  {Palmsonntag}
  Feiertag[TagImJahr(Ostern)-7]:=-8;
  {Gründonnerstag}
  Feiertag[TagImJahr(Ostern)-3]:=-9;
  {Muttertag}
  Dat:=EncodeDate(y,4,30);
  aw:=DayOfWeek(Dat)-1;
  Dat:=Dat-aw+14;
  if Dat=(Ostern+49) then
    Dat:=Dat-7;
  Feiertag[TagImJahr(Dat)]:=-10;
  {Peter und Paul}
  Dat:=Encodedate(Y,6,29);
  Feiertag[TagImJahr(Dat)]:=-11;
  {Mariä Geburt}
  Dat:=Encodedate(Y,9,8);
  Feiertag[TagImJahr(Dat)]:=-12;
  {Erntedankfest}
  Dat:=Encodedate(Y,10,1);
  while DayOfWeek(Dat)<>1 do
    Dat:=Dat+1;
  Feiertag[TagImJahr(Dat)]:=-13;
  {Mariä Empfängnis}
  Dat:=Encodedate(Y,12,8);
  Feiertag[TagImJahr(Dat)]:=-14;
  {Silvester}
  Dat:=Encodedate(Y,12,31);
  Feiertag[TagImJahr(Dat)]:=-15;
  {1. Advent}
  Dat:=Weihnacht;
  while DayOfWeek(Dat)<>1 do
    Dat:=Dat-1;
  Feiertag[TagImJahr(Dat)-21]:=-16;
  {2. Advent}
  Feiertag[TagImJahr(Dat)-14]:=-17;
  {3. Advent}
  Feiertag[TagImJahr(Dat)-7]:=-18;
  {4. Advent}
  Feiertag[TagImJahr(Dat)]:=-19;
  {Heiligabend}
  Feiertag[TagImJahr(Weihnacht)-1]:=-20;
  {Frühlingsanfang}
  Dat:=Encodedate(Y,3,21);
  Feiertag[TagImJahr(Dat)]:=-21;
  {Sommmeranfang}
  Dat:=Encodedate(Y,6,21);
  Feiertag[TagImJahr(Dat)]:=-22;
  {Herbstanfang}
  Dat:=Encodedate(Y,9,23);
  Feiertag[TagImJahr(Dat)]:=-23;
  {Winteranfang}
  Dat:=Encodedate(Y,12,22);
  Feiertag[TagImJahr(Dat)]:=-24;
  {Neujahr}                         {Feiertage}
  Feiertag[1]:=1;
  {Maifeiertag}
  Dat:=Encodedate(Y,5,1);
  Feiertag[TagImJahr(Dat)]:=2;
  {Tag der deutschen Einheit}
  Dat:=Encodedate(Y,10,3);
  Feiertag[TagImJahr(Dat)]:=3;
  {Allerheiligen}
  Dat:=Encodedate(Y,11,1);
  Feiertag[TagImJahr(Dat)]:=4;
  {Totensonntag}
  if Weihnacht>=0 then
    Feiertag[TagImJahr(Weihnacht-dw-28)]:=5;
  {Buß- und Bettag}
  if Config.Land=12 then
    Feiertag[TagImJahr(Weihnacht-dw-32)]:=19;
  {Volkstrauertag}
  if Weihnacht>=0 then
    Feiertag[TagImJahr(Weihnacht-dw-35)]:=6;
  {1. Weihnachtstag}
  if Weihnacht>=0 then
    Feiertag[TagImJahr(Weihnacht)]:=7;
  {2. Weihnachtstag}
  if Weihnacht>=0 then
    Feiertag[TagImJahr(Weihnacht)+1]:=8;
  {Karfreitag}
  Feiertag[TagImJahr(Ostern)-2]:=9;
  {Ostersonntag}
  Feiertag[TagImJahr(Ostern)]:=10;
  {Ostermontag}
  Feiertag[TagImJahr(Ostern)+1]:=11;
  {Christi Himmelfahrt}
  Feiertag[TagImJahr(Ostern)+39]:=12;
  {Pfingstsonntag}
  Feiertag[TagImJahr(Ostern)+49]:=13;
  {Pfingstmontag}
  Feiertag[TagImJahr(Ostern)+50]:=14;
  {Fronleichnam}
  if (Config.Land<2) or ((Config.Land>=9) and (Config.Land<=12)) or (Config.Land=15) then
    Feiertag[TagImJahr(Ostern)+60]:=15;
  {Heilige 3 Könige}
  if (Config.Land=0) or (Config.Land=1) or (Config.Land=13) then
    Feiertag[6]:=16;
  {Mariä Himmelfahrt}
  if (Config.Land=1) or (Config.Land=11) then begin
    Dat:=Encodedate(Y,8,15);
    Feiertag[TagImJahr(Dat)]:=17;
  end;
  {Reformationstag}
  if (Config.Land=3) or (Config.Land=7) or (Config.Land=12) or (Config.Land=13) or (Config.Land=15) then begin
    Dat:=Encodedate(Y,10,31);
    Feiertag[TagImJahr(Dat)]:=18;
  end;
end;

end.

mfg Jonny

Robert Marquardt 13. Nov 2006 05:40

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
Klassischer Fehler. Das sollte nie eine Komponente sein. Solche Berechnungen sind beser als Funktionssammlung aufgehoben.

Hansa 13. Nov 2006 08:08

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
Schaltjahre wurden auch vergessen. Wann ist eigentlich "Maria Verkündigung" :shock: oder ist das etwa schon rum ? :lol:

JonnyGuitar 13. Nov 2006 09:15

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
das heisst, ich sollte daraus keine komponente machen?

dataspider 13. Nov 2006 09:24

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
Hi Jonny,

um auf die Anfangsfrage einzugehen.
Du musst das Property Datum mit einem Setter versehen:
Delphi-Quellcode:
private
  FDatum: TDateTime;
  procedure SetDatum(const Value: TDateTime);
  { Private-Deklarationen }
  ...
published
  property Datum: TDateTime read FDatum write SetDatum;
end;
  ...
procedure TFeiertage.SetDatum(const Value: TDateTime);
begin
  if FDatum <> Value then
  begin
    FDatum := Value;
    // und hier die Änderungen an den anderen Props
  end;
end;
Es ist wirklich nicht gerade ein Anwendungsfall für eine Komponente, aber zum Üben ist es OK.

Cu, Frank

Hansa 13. Nov 2006 09:38

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
Welchen Sinn soll eine "Komponente" denn da haben ? Bzw. wo ist der Zusatznutzen gegenüber einer function ? Du willst lediglich etwas berechnen.

Das geht auch so :

Delphi-Quellcode:
DayString : array[1..7] of string[15] = (
    'Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag');

function Wochentag (d : Tdate) : string;
begin
  Wochentag := DayString [DayOfWeek (d)];
end;
Baue in Dein Array eben statt der Wochentage die Feiertage ein und fertig. Die Rechenvorschrift ändert sich dann natürlich auch. Maria Empfängnis ? :gruebel: :mrgreen:

P.S.: Das Daystring ist eine Konstante !!

[edit=SirThornberry]Quelltext korrigiert - Mfg, SirThornberry[/edit]

JonnyGuitar 13. Nov 2006 11:10

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
ok, ich denke auch das hier bei diesem thema eine komponente keine erleichterung bringt.

mich würde jetzt nur noch interessieren wie ich die geschichte mit den schaltjahren da unterbringe,
an den aspekt habe ich gar nciht gedacht


mfg Jonny

Hansa 13. Nov 2006 11:18

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
Gibts nicht
Delphi-Quellcode:
IsLeapYear
? :gruebel:

Touchdown 13. Nov 2006 11:22

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
Dazu muss man genau wissen, wie ein Schaltjahr das Result beeinflussen kann. Das ist eher eine fachliche Frage und keine technische.

Mit etwas googeln kann man sich diese Frage leicht beantworten.

Hansa 13. Nov 2006 12:05

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
Fachlich ? Welches Fach ? :shock: Die festen Feiertage (24.12. usw.) sind ja wohl kein Problem. Ostern ist ein Hauptproblem. Warum ist das jedes Jahr an einem anderen Wochenende (vom Datum her gesehen) ? 4 Wochen vorher beginnt die Fastenzeit und 6 Wochen danach ist auch was. Selbst die recht umfangreiche DateUtils gibt da nichts mehr her. Aber er wird ja wohl wissen, dass solche Fragen quasi auf dem Mond zu lösen sind :mrgreen:

JonnyGuitar 13. Nov 2006 12:43

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
hier hat schon vor einiger zeit ein programmierer das gemacht was ich vorhatte.
Delphi-Forum

die komponente funktioniert auch soweit nur verstehe ich nicht warum

Delphi-Quellcode:
  published
    property Date: TDate read FDate write SetDate;
    property HolidayName: String read FHolidayName;
    property SpecialdayName: String read FSpecialdayName;
    property Region: TRegion read FRegion write SetRegion;
    property OnHoliday: THolidayEvent read FOnHoliday write FOnHoliday;
    property OnSpecialday: TSpecialdayEvent read FOnSpecialday write FOnSpecialday;
    property OnInvalidDate: TNotifyEvent read FOnInvalidDate write FOnInvalidDate;
  end;
holidayname oder specialdayname nicht im objectinspector auftauchen, um nochmal auf meine ausgangsfrage zurückzukommen.

SirThornberry 13. Nov 2006 12:58

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
Das kommt daher das er für "Date" eine SetMethode geschrieben hat. Dadurch wird nicht direkt auf die Variable geschrieben sondern eine Methode aufgerufen welcher der neue Wert übergeben wird.

JonnyGuitar 13. Nov 2006 14:50

Re: Frage zur Entwicklung einer Komponente Feiertagsberechnu
 
es hat lange gedauert, aber ich habe verstanden :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:13 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