Subversion Repositories delphiutils

Rev

Rev 79 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit ZeiterfassungMain;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, DB, ADODB, Grids, Wwdbigrd, Wwdbgrid, ExtCtrls, DBCtrls, StdCtrls;
  8.  
  9. type
  10.   TForm1 = class(TForm)
  11.     ADOConnection1: TADOConnection;
  12.     wwDBGrid1: TwwDBGrid;
  13.     ADOTable1: TADOTable;
  14.     DataSource1: TDataSource;
  15.     ADOTable1TAG: TWideStringField;
  16.     ADOTable1KOMMEN: TWideStringField;
  17.     ADOTable1PAUSE_START: TWideStringField;
  18.     ADOTable1PAUSE_ENDE: TWideStringField;
  19.     ADOTable1GEHEN: TWideStringField;
  20.     ADOTable1SONSTIGER_ABZUG: TWideStringField;
  21.     ADOTable1ZUHAUSE: TWideStringField;
  22.     ADOTable1BERSTUNDEN_SALDO: TIntegerField;
  23.     ADOTable1BERSTUNDEN: TIntegerField;
  24.     ADOTable1FREIER_TAG: TBooleanField;
  25.     Panel1: TPanel;
  26.     Button1: TButton;
  27.     DBNavigator1: TDBNavigator;
  28.     ADOTable1WOCHENTAG: TStringField;
  29.     ADOTable1USERNAME: TStringField;
  30.     ComboBox1: TComboBox;
  31.     Label1: TLabel;
  32.     Label2: TLabel;
  33.     procedure ADOTable1NewRecord(DataSet: TDataSet);
  34.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  35.     procedure ADOTable1BeforePost(DataSet: TDataSet);
  36.     procedure ADOTable1BERSTUNDEN_SALDOGetText(Sender: TField; var Text: string;
  37.       DisplayText: Boolean);
  38.     procedure ADOTable1BERSTUNDENGetText(Sender: TField; var Text: string;
  39.       DisplayText: Boolean);
  40.     procedure wwDBGrid1CalcCellColors(Sender: TObject; Field: TField;
  41.       State: TGridDrawState; Highlight: Boolean; AFont: TFont; ABrush: TBrush);
  42.     procedure ADOTable1AfterPost(DataSet: TDataSet);
  43.     procedure Button1Click(Sender: TObject);
  44.     procedure ADOTable1TAGChange(Sender: TField);
  45.     procedure ADOTable1SONSTIGER_ABZUGSetText(Sender: TField;
  46.       const Text: string);
  47.     procedure ADOTable1ZUHAUSESetText(Sender: TField; const Text: string);
  48.     procedure ADOTable1GEHENSetText(Sender: TField; const Text: string);
  49.     procedure ADOTable1PAUSE_ENDESetText(Sender: TField; const Text: string);
  50.     procedure ADOTable1PAUSE_STARTSetText(Sender: TField; const Text: string);
  51.     procedure ADOTable1KOMMENSetText(Sender: TField; const Text: string);
  52.     procedure FormShow(Sender: TObject);
  53.     procedure ADOTable1WOCHENTAGGetText(Sender: TField; var Text: string;
  54.       DisplayText: Boolean);
  55.     procedure ComboBox1Change(Sender: TObject);
  56.     procedure ADOTable1TAGSetText(Sender: TField; const Text: string);
  57.     procedure ADOTable1AfterDelete(DataSet: TDataSet);
  58.     procedure ADOTable1TAGGetText(Sender: TField; var Text: string;
  59.       DisplayText: Boolean);
  60.     procedure ADOTable1KOMMENGetText(Sender: TField; var Text: string;
  61.       DisplayText: Boolean);
  62.     procedure ADOTable1PAUSE_STARTGetText(Sender: TField; var Text: string;
  63.       DisplayText: Boolean);
  64.     procedure ADOTable1PAUSE_ENDEGetText(Sender: TField; var Text: string;
  65.       DisplayText: Boolean);
  66.     procedure ADOTable1GEHENGetText(Sender: TField; var Text: string;
  67.       DisplayText: Boolean);
  68.     procedure ADOTable1SONSTIGER_ABZUGGetText(Sender: TField; var Text: string;
  69.       DisplayText: Boolean);
  70.     procedure ADOTable1ZUHAUSEGetText(Sender: TField; var Text: string;
  71.       DisplayText: Boolean);
  72.   private
  73.     function GueltigeZeile: boolean;
  74.   protected
  75.     procedure ReorgDataSet;
  76.     procedure ReorgAll;
  77.     function RegelArbeitszeit: integer;
  78.   end;
  79.  
  80. var
  81.   Form1: TForm1;
  82.  
  83. implementation
  84.  
  85. {$R *.dfm}
  86.  
  87. // TODO: Trennstriche zwischen Wochen oder zwischen Urlauben
  88. // TODO: Anmerkungen
  89.  
  90. uses
  91.   DateUtils, StrUtils, IniFiles;
  92.  
  93. {$REGION 'Hilfsfunktionen'}
  94.  
  95. function SQL_Escape(const s: string): string;
  96. begin
  97.   result := StringReplace(s, '''', '\''', [rfReplaceAll]);
  98. end;
  99.  
  100. function IstLeer(f: TField): boolean;
  101. begin
  102.   result := f.IsNull or (f.AsString = '') or (f.AsString = '00:00:00');
  103. end;
  104.  
  105. function Minuten(f: TField): integer;
  106. begin
  107.   if IstLeer(f) then
  108.   begin
  109.     result := 0;
  110.   end
  111.   else
  112.   begin
  113.     result := MinuteOfTheDay(f.AsDateTime);
  114.   end;
  115. end;
  116.  
  117. function MinutenZuHF(f: TField): string;
  118. var
  119.   d: integer;
  120. begin
  121.   if IstLeer(f) then
  122.   begin
  123.     result := '';
  124.   end
  125.   else
  126.   begin
  127.     d := f.AsInteger;
  128.     if d < 0 then
  129.     begin
  130.       result := '-';
  131.       d := -d;
  132.     end
  133.     else
  134.     begin
  135.       result := '';
  136.     end;
  137.     result := result + Format('%.2d:%.2d', [d div 60, d mod 60]);
  138.   end;
  139. end;
  140.  
  141. function EchtesDatum(f: TField): TDate;
  142. begin
  143.   if Copy(f.AsString, 5, 1) = '-' then
  144.   begin
  145.     result := EncodeDate(
  146.     StrtoInt(Copy(f.AsString, 1, 4)),
  147.     StrtoInt(Copy(f.AsString, 6, 2)),
  148.     StrtoInt(Copy(f.AsString, 9, 2))
  149.     );
  150.   end
  151.   else
  152.     result := StrToDate(f.AsString);
  153. end;
  154.  
  155. function WUserName: String;
  156. var
  157.   nSize: DWord;
  158. begin
  159.   nSize := 1024;
  160.   SetLength(Result, nSize);
  161.   if GetUserName(PChar(Result), nSize) then
  162.     SetLength(Result, nSize-1)
  163.   else
  164.     RaiseLastOSError;
  165. end;
  166.  
  167. {$ENDREGION}
  168.  
  169. function TForm1.RegelArbeitszeit: integer;
  170. var
  171.   test: TADOQuery;
  172. begin
  173.   test := TADOQuery.Create(nil);
  174.   try
  175.     test.Connection := ADOConnection1;
  176.     test.Close;
  177.     test.SQL.Text := 'select MINUTEN from REGELARBEITSZEIT where USERNAME = ''' + SQL_Escape(ComboBox1.Text) + '''';
  178.     test.Open;
  179.     if test.RecordCount = 0 then
  180.     begin
  181.       result := 8 * 60;
  182.     end
  183.     else
  184.     begin
  185.       result := test.FieldByName('MINUTEN').AsInteger;
  186.     end;
  187.   finally
  188.     test.Free;
  189.   end;
  190. end;
  191.  
  192. procedure TForm1.ReorgAll;
  193. var
  194.   saldo: integer;
  195.   baks: string;
  196.   bakEv: TDataSetNotifyEvent;
  197.   dead: boolean;
  198. begin
  199.   if ADOTable1.ReadOnly then exit;
  200.  
  201.   if ADOTable1TAG.IsNull then
  202.   begin
  203.     baks := '';
  204.   end
  205.   else
  206.   begin
  207.     if Copy(ADOTable1TAG.AsString, 5, 1) = '-' then
  208.       baks := ADOTable1TAG.AsString
  209.     else
  210.       DateTimeToString(baks, 'YYYY-MM-DD', ADOTable1TAG.AsDateTime);
  211.   end;
  212.   bakEv := ADOTable1.AfterPost;
  213.   ADOTable1.AfterPost := nil;
  214.   ADOTable1.Requery();
  215.   try
  216.     ADOTable1.First;
  217.     saldo := 0;
  218.     dead := false;
  219.     while not ADOTable1.Eof do
  220.     begin
  221.       ADOTable1.Edit;
  222.       if not dead then ReorgDataSet;
  223.       dead := dead or ADOTable1BERSTUNDEN.IsNull;
  224.       if dead then
  225.       begin
  226.         ADOTable1BERSTUNDEN_SALDO.Clear;
  227.       end
  228.       else
  229.       begin
  230.         saldo := saldo + ADOTable1BERSTUNDEN.AsInteger;
  231.         ADOTable1BERSTUNDEN_SALDO.AsInteger := saldo;
  232.         saldo := ADOTable1BERSTUNDEN_SALDO.AsInteger;
  233.       end;
  234.       ADOTable1.Post;
  235.       ADOTable1.Next;
  236.     end;
  237.   finally
  238.     if baks <> '' then ADOTable1.Locate('USERNAME;TAG', VarArrayOf([WUserName, baks]), []);
  239.     ADOTable1.AfterPost := bakEv;
  240.   end;
  241. end;
  242.  
  243. procedure TForm1.ADOTable1AfterDelete(DataSet: TDataSet);
  244. begin
  245.   ReorgAll;
  246. end;
  247.  
  248. procedure TForm1.ADOTable1AfterPost(DataSet: TDataSet);
  249. begin
  250.   ReorgAll;
  251. end;
  252.  
  253. function TForm1.GueltigeZeile: boolean;
  254. begin
  255.   result := false;
  256.  
  257.   if IstLeer(ADOTable1KOMMEN) <> IstLeer(ADOTable1GEHEN) then exit;
  258.   if IstLeer(ADOTable1PAUSE_START) <> IstLeer(ADOTable1PAUSE_ENDE) then exit;
  259.   if not IstLeer(ADOTable1PAUSE_START) and (ADOTable1PAUSE_START.AsDateTime < ADOTable1KOMMEN.AsDateTime) then exit;
  260.   if not IstLeer(ADOTable1PAUSE_ENDE) and (ADOTable1PAUSE_ENDE.AsDateTime < ADOTable1PAUSE_START.AsDateTime) then exit;
  261.   if not IstLeer(ADOTable1GEHEN) and (ADOTable1GEHEN.AsDateTime < ADOTable1KOMMEN.AsDateTime) then exit;
  262.   if not IstLeer(ADOTable1GEHEN) and not IstLeer(ADOTable1PAUSE_START) and (ADOTable1GEHEN.AsDateTime < ADOTable1PAUSE_START.AsDateTime) then exit;
  263.   if not IstLeer(ADOTable1GEHEN) and not IstLeer(ADOTable1PAUSE_ENDE) and (ADOTable1GEHEN.AsDateTime < ADOTable1PAUSE_ENDE.AsDateTime) then exit;
  264.  
  265.   result := true;
  266. end;
  267.  
  268. procedure TForm1.ReorgDataSet;
  269. var
  270.   m: integer;
  271. begin
  272.   if GueltigeZeile then
  273.   begin
  274.     m :=   (Minuten(ADOTable1GEHEN) - Minuten(ADOTable1KOMMEN))
  275.          - (Minuten(ADOTable1PAUSE_ENDE) - Minuten(ADOTable1PAUSE_START))
  276.          - Minuten(ADOTable1SONSTIGER_ABZUG)
  277.          + Minuten(ADOTable1ZUHAUSE);
  278.  
  279.     if not ADOTable1FREIER_TAG.AsBoolean then
  280.     begin
  281.       m := m - RegelArbeitszeit;
  282.     end;
  283.  
  284.     ADOTable1BERSTUNDEN.AsInteger := m;
  285.   end
  286.   else
  287.   begin
  288.     ADOTable1BERSTUNDEN.Clear;
  289.   end;
  290. end;
  291.  
  292. procedure TForm1.ADOTable1BeforePost(DataSet: TDataSet);
  293. begin
  294.   if (ADOTable1.State = dsInsert) and ADOTable1TAG.IsNull then
  295.   begin
  296.     AdoTable1.Cancel;
  297.     Abort;
  298.   end;
  299.  
  300.   ReorgDataSet;
  301. end;
  302.  
  303. procedure TForm1.ADOTable1BERSTUNDENGetText(Sender: TField; var Text: string;
  304.   DisplayText: Boolean);
  305. begin
  306.   Text := MinutenZuHF(ADOTable1BERSTUNDEN);
  307. end;
  308.  
  309. procedure TForm1.ADOTable1BERSTUNDEN_SALDOGetText(Sender: TField;
  310.   var Text: string; DisplayText: Boolean);
  311. begin
  312.   Text := MinutenZuHF(ADOTable1BERSTUNDEN_SALDO);
  313. end;
  314.  
  315. procedure TForm1.ADOTable1GEHENGetText(Sender: TField; var Text: string;
  316.   DisplayText: Boolean);
  317. begin
  318.   Text := Copy(Sender.AsString, 1, 5);
  319. end;
  320.  
  321. procedure TForm1.ADOTable1GEHENSetText(Sender: TField; const Text: string);
  322. begin
  323.   if Text = '' then
  324.   begin
  325.     ADOTable1GEHEN.Clear;
  326.   end
  327.   else
  328.   begin
  329.     ADOTable1GEHEN.AsString := Text;
  330.   end;
  331. end;
  332.  
  333. procedure TForm1.ADOTable1KOMMENGetText(Sender: TField; var Text: string;
  334.   DisplayText: Boolean);
  335. begin
  336.   Text := Copy(Sender.AsString, 1, 5);
  337. end;
  338.  
  339. procedure TForm1.ADOTable1KOMMENSetText(Sender: TField; const Text: string);
  340. begin
  341.   if Text = '' then
  342.   begin
  343.     ADOTable1KOMMEN.Clear;
  344.   end
  345.   else
  346.   begin
  347.     ADOTable1KOMMEN.AsString := Text;
  348.   end;
  349. end;
  350.  
  351. procedure TForm1.ADOTable1NewRecord(DataSet: TDataSet);
  352. var
  353.   test: TADOQuery;
  354. begin
  355.   ADOTable1FREIER_TAG.AsBoolean := false;
  356.   ADOTable1USERNAME.AsString := WUserName;
  357.   test := TADOQuery.Create(nil);
  358.   try
  359.     test.Connection := ADOConnection1;
  360.     test.Close;
  361.     test.SQL.Text := 'select * from TAGE where TAG = ''' + DateToStr(Date) + '''';
  362.     test.Open;
  363.     if test.RecordCount = 0 then
  364.     begin
  365.       ADOTable1TAG.AsDateTime := Date;
  366.       ADOTable1KOMMEN.AsString := TimeToStr(Time);
  367.       ADOTable1FREIER_TAG.AsBoolean := (DayOfWeek(Date) = 1{Sunday}) or
  368.                                        (DayOfWeek(Date) = 7{Saturday});
  369.     end;
  370.   finally
  371.     test.Free;
  372.   end;
  373.  
  374.   wwDBGrid1.SelectedField := ADOTable1TAG;
  375. end;
  376.  
  377. procedure TForm1.ADOTable1PAUSE_ENDEGetText(Sender: TField; var Text: string;
  378.   DisplayText: Boolean);
  379. begin
  380.   Text := Copy(Sender.AsString, 1, 5);
  381. end;
  382.  
  383. procedure TForm1.ADOTable1PAUSE_ENDESetText(Sender: TField; const Text: string);
  384. begin
  385.   if Text = '' then
  386.   begin
  387.     ADOTable1PAUSE_ENDE.Clear;
  388.   end
  389.   else
  390.   begin
  391.     ADOTable1PAUSE_ENDE.AsString := Text;
  392.   end;
  393. end;
  394.  
  395. procedure TForm1.ADOTable1PAUSE_STARTGetText(Sender: TField; var Text: string;
  396.   DisplayText: Boolean);
  397. begin
  398.   Text := Copy(Sender.AsString, 1, 5);
  399. end;
  400.  
  401. procedure TForm1.ADOTable1PAUSE_STARTSetText(Sender: TField;
  402.   const Text: string);
  403. begin
  404.   if Text = '' then
  405.   begin
  406.     ADOTable1PAUSE_START.Clear;
  407.   end
  408.   else
  409.   begin
  410.     ADOTable1PAUSE_START.AsString := Text;
  411.   end;
  412. end;
  413.  
  414. procedure TForm1.ADOTable1SONSTIGER_ABZUGGetText(Sender: TField;
  415.   var Text: string; DisplayText: Boolean);
  416. begin
  417.   Text := Copy(Sender.AsString, 1, 5);
  418. end;
  419.  
  420. procedure TForm1.ADOTable1SONSTIGER_ABZUGSetText(Sender: TField;
  421.   const Text: string);
  422. begin
  423.   if Text = '' then
  424.   begin
  425.     ADOTable1SONSTIGER_ABZUG.Clear;
  426.   end
  427.   else
  428.   begin
  429.     ADOTable1SONSTIGER_ABZUG.AsString := Text;
  430.   end;
  431. end;
  432.  
  433. procedure TForm1.ADOTable1TAGChange(Sender: TField);
  434. begin
  435.   ADOTable1FREIER_TAG.AsBoolean := (DayOfWeek(ADOTable1TAG.AsDateTime) = 1{Sunday}) or
  436.                                    (DayOfWeek(ADOTable1TAG.AsDateTime) = 7{Saturday});
  437.   // TODO: "Wochentag" Feld aktualisieren
  438. end;
  439.  
  440. procedure TForm1.ADOTable1TAGGetText(Sender: TField; var Text: string;
  441.   DisplayText: Boolean);
  442. begin
  443.   Text := DateToStr(EchtesDatum(Sender));
  444. end;
  445.  
  446. procedure TForm1.ADOTable1TAGSetText(Sender: TField; const Text: string);
  447. var
  448.   i, punktCount: integer;
  449. begin
  450.   punktCount := 0;
  451.   for i := 1 to Length(Text) do
  452.   begin
  453.     if Text[i] = '.' then inc(punktCount);
  454.   end;
  455.  
  456.   if punktCount = 1 then
  457.   begin
  458.     ADOTable1TAG.AsString := Text + '.' + IntToStr(CurrentYear);
  459.   end
  460.   else if (PunktCount = 2) and EndsStr('.',Text) then
  461.   begin
  462.     ADOTable1TAG.AsString := Text + IntToStr(CurrentYear);
  463.   end
  464.   else
  465.   begin
  466.     ADOTable1TAG.AsString := Text;
  467.   end;
  468. end;
  469.  
  470. procedure TForm1.ADOTable1WOCHENTAGGetText(Sender: TField; var Text: string;
  471.   DisplayText: Boolean);
  472. begin
  473.   try
  474.     if ADOTable1TAG.AsString <> '' then
  475.       Text := ShortDayNames[DayOfWeek(EchtesDatum(ADOTable1TAG))]
  476.     else
  477.       Text := '';
  478.   except
  479.     Text := '??';
  480.   end;
  481. end;
  482.  
  483. procedure TForm1.ADOTable1ZUHAUSEGetText(Sender: TField; var Text: string;
  484.   DisplayText: Boolean);
  485. begin
  486.   Text := Copy(Sender.AsString, 1, 5);
  487. end;
  488.  
  489. procedure TForm1.ADOTable1ZUHAUSESetText(Sender: TField; const Text: string);
  490. begin
  491.   if Text = '' then
  492.   begin
  493.     ADOTable1ZUHAUSE.Clear;
  494.   end
  495.   else
  496.   begin
  497.     ADOTable1ZUHAUSE.AsString := Text;
  498.   end;
  499. end;
  500.  
  501. procedure TForm1.Button1Click(Sender: TObject);
  502. begin
  503.   ReorgAll;
  504. end;
  505.  
  506. procedure TForm1.ComboBox1Change(Sender: TObject);
  507. begin
  508.   ADOTable1.Active := false;
  509.   ADOTable1.ReadOnly := ComboBox1.Text <> WUserName;
  510.   ADOTable1.Filter := 'USERNAME = ''' + SQL_Escape(ComboBox1.Text) + '''';
  511.   ADOTable1.Filtered := true;
  512.   ADOTable1.Active := true;
  513.   ADOTable1.Last;
  514.  
  515.   Button1.Enabled := not ADOTable1.ReadOnly;
  516.  
  517.   Label2.Caption := IntToStr(RegelArbeitszeit);
  518.  
  519.   ReorgAll;
  520. end;
  521.  
  522. procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
  523. begin
  524.   if ADOTable1.State in [dsEdit, dsInsert] then
  525.   begin
  526.     try
  527.       ADOTable1.Post;
  528.     except
  529.       on E: EAbort do
  530.       begin
  531.         exit;
  532.       end;
  533.     end;
  534.   end;
  535. end;
  536.  
  537. procedure TForm1.FormShow(Sender: TObject);
  538. var
  539.   test: TADOQuery;
  540.   ini: TMemIniFile;
  541. resourcestring
  542.   DefaultConnectionString = 'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Zeiterfassung;' +
  543.                             'Data Source=SHS\FiVe,49007;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=MARSCHALL;Use Encryption for Data=False;Tag with column collation when possible=False;';
  544. begin
  545.   ini := TMemIniFile.Create(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + ChangeFileExt(ExtractFileName(ParamStr(0)), '.ini'));
  546.   try
  547.     ADOConnection1.ConnectionString := ini.ReadString('Connection', 'ConnectionString', DefaultConnectionString);
  548.   finally
  549.     ini.Free;
  550.   end;
  551.   ADOConnection1.Connected := true;
  552.  
  553.   {$REGION 'Username Combobox füllen'}
  554.   test := TADOQuery.Create(nil);
  555.   try
  556.     test.Connection := ADOConnection1;
  557.     test.Close;
  558.     test.SQL.Text := 'select distinct USERNAME from TAGE';
  559.     test.Open;
  560.     ComboBox1.Items.Clear;
  561.     while not test.EOF do
  562.     begin
  563.       ComboBox1.Items.Add(test.FieldByName('USERNAME').AsString);
  564.       test.Next;
  565.     end;
  566.   finally
  567.     test.Free;
  568.   end;
  569.  
  570.   if ComboBox1.Items.IndexOf(WUserName) = -1 then
  571.     ComboBox1.Items.Add(WUserName);
  572.  
  573.   ComboBox1.Sorted := true;
  574.  
  575.   ComboBox1.ItemIndex := ComboBox1.Items.IndexOf(WUserName);
  576.  
  577.   ComboBox1Change(ComboBox1);
  578.   {$ENDREGION}
  579.  
  580.   if wwDBGrid1.CanFocus then wwDBGrid1.SetFocus;
  581.   wwDBGrid1.SelectedField := ADOTable1TAG;
  582. end;
  583.  
  584. procedure TForm1.wwDBGrid1CalcCellColors(Sender: TObject; Field: TField;
  585.   State: TGridDrawState; Highlight: Boolean; AFont: TFont; ABrush: TBrush);
  586. begin
  587.   if Highlight then exit;
  588.  
  589.   if (Field.FieldName = ADOTable1BERSTUNDEN.FieldName) or
  590.      (Field.FieldName = ADOTable1BERSTUNDEN_SALDO.FieldName) then
  591.   begin
  592.     ABrush.Color := clBtnFace;
  593.   end;
  594.  
  595.   if (Field.FieldName = ADOTable1BERSTUNDEN.FieldName) then
  596.   begin
  597.     if ADOTable1BERSTUNDEN.AsInteger < 0 then
  598.     begin
  599.       AFont.Color := clRed;
  600.     end;
  601.   end;
  602.  
  603.   if (Field.FieldName = ADOTable1BERSTUNDEN_SALDO.FieldName) then
  604.   begin
  605.     if ADOTable1BERSTUNDEN_SALDO.AsInteger < 0 then
  606.     begin
  607.       AFont.Color := clRed;
  608.     end;
  609.   end;
  610. end;
  611.  
  612. end.
  613.