Fórum Datas Feriados e Final de Semana #286296
28/06/2005
0
Bom, estou com o seguinte problema,
Tenho que mudar as datas de alguns cheques para os dias uteis.
Entao o sistema tem que ver se não é sabado ou domingo, se for sabado joga pra segunda, se for domingo pra segunda tb.
Bom, tem os feriados, que são cadastrados numa tabela chamada Feriados, onde armazeno a data do feriado...
Entao o sistema tem que fazer a verificação, se nao for final de semana e nem feriado, joga pra outra data, que consequentemente não poderá ser nem final de semana nem feriado...
Agradeço
Abraços...
Tremonti
Curtir tópico
+ 0Posts
28/06/2005
Emerson Nascimento
if DayOfWeek(Data)=1 then // domingo
Data := Data + 1; // joga pra segunda
else
if DayOfWeek(Data)=7 then // sábado
Data := Data + 2; // joga pra segunda
VerificaFeriado(Data);
Gostei + 0
28/06/2005
Tremonti
vamos dizer que caiu de domingo e ele jogou pra segunda...Ok
e segunda é feriado e ele jogou pra terça que também eh feriado,,,,iai?!
Abraços...
Gostei + 0
28/06/2005
Emerson Nascimento
DataOk := False; Data := aqui vai a data do vencimento while not DataOk do begin if DayOfWeek(Data)=1 then // domingo Data := Data + 1; // joga pra segunda else if DayOfWeek(Data)=7 then // sábado Data := Data + 2; // joga pra segunda DataOk := not EhFeriado(Data); if not DataOk then Data := Data + 1; end; procedure EhFeriado(Data: TDateTime): boolean; begin // vc decide se terá um componente de pesquisa sql instanciado // ou se vai criá-lo em tempo de execução query.close; query.sql := ´select data from feriado where data = :data´; query.parambyname(´data´).asdatetime := data; query.open; result := not query.isempty; query.close; // se o objeto foi criado em tempo de execução, // é hora de liberá-lo da memória end;
Gostei + 0
29/06/2005
Tremonti
mas ficou um pouco lento,. mas funcionou....
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Grids, DBGrids, DBTables, Buttons, StdCtrls, ExtCtrls,
WinSkinData, ComCtrls;
type
TForm1 = class(TForm)
DbBrasil: TDatabase;
sesBrasil: TSession;
qryBrasil: TQuery;
upsBrasil: TUpdateSQL;
dsBrasil: TDataSource;
DBGrid1: TDBGrid;
Panel1: TPanel;
Label1: TLabel;
Edit1: TEdit;
SpeedButton1: TSpeedButton;
qryBrasilnumeroCheque: TIntegerField;
qryBrasilvalor: TFloatField;
qryBrasildataBomPara: TDateTimeField;
qryBrasilcodigoBanco: TStringField;
qryBrasilcodigoPrefixoAgencia: TStringField;
qryBrasilnumeroContaCorrente: TStringField;
qryBrasilseuNumero: TStringField;
qryBrasilnumeroImpressoCheque: TStringField;
Label2: TLabel;
Panel2: TPanel;
Label3: TLabel;
rbBomPara: TRadioButton;
rbBanco: TRadioButton;
SkinData1: TSkinData;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
StatusBar1: TStatusBar;
Panel3: TPanel;
Label4: TLabel;
lbltot: TLabel;
TlMark: TSession;
Principal: TDatabase;
Panel4: TPanel;
Label5: TLabel;
Label6: TLabel;
lblReg: TLabel;
lblRegAtual: TLabel;
Label7: TLabel;
ProgressBar1: TProgressBar;
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormShow(Sender: TObject);
procedure qryBrasilAfterOpen(DataSet: TDataSet);
function VerFeriado(prData: TDateTime): TDateTime;
function ProxDiaUtil(prData: TDateTime): TDateTime;
procedure SpeedButton3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
with qryBrasil do
Begin
Close;
SQL.Clear;
if Edit1.Text = ´´ then
Begin
SQL.Add(´Select numeroCheque, Valor, dataBomPara, codigoBanco, codigoPrefixoAgencia, ´);
SQL.Add(´NumeroContaCorrente, seuNumero, NumeroImpressoCheque´);
SQL.Add(´From Cheque´);
End
else
begin
SQL.Add(´Select *´);
SQL.Add(´From Cheque´);
SQL.Add(´Where seuNumero = :num´);
ParamByName(´num´).Value := Edit1.Text;
end;
if rbBanco.Checked then
SQL.Add(´Order by CodigoBanco´)
else
SQL.Add(´Order by DataBomPara´);
Open;
End; //With
end;
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
Application.Terminate;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.Hint := StatusBar1.SimpleText;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
CASE key of
VK_RETURN : SpeedButton1.Click;
end; //Case
end;
procedure TForm1.FormShow(Sender: TObject);
begin
SpeedButton1.Click;
end;
procedure TForm1.qryBrasilAfterOpen(DataSet: TDataSet);
begin
lbltot.Caption := inttostr(qryBrasil.RecordCount);
end;
function TForm1.ProxDiaUtil(prData: TDateTime): TDateTime;
var
mDay, mDias: Integer;
begin
mDay := DayOfWeek(prData);
if mDay = 1 then // Sunday
mDias := 1
else if mDay = 7 then // Saturday
mDias := 2
else // week day
mDias := 0;
//
Result := prData + mDias;
end;
function TForm1.VerFeriado(prData: TDateTime): TDateTime;
var
i: Integer;
mTabela: TTable;
begin
mTabela := TTable.Create( Application );
with mTabela do
begin
DatabaseName := ´DbPrincipal´;
SessionName := ´MainSession´;
TableName := ´Feriados´;
Open;
for i :=0 to 10 Do
Begin
if Locate(´DtFeriado´, prData, []) Then
prData := prData + 1;
prData :=ProxDiaUtil(prData);
end; //For
Close;
end; //With
mTabela.Free;
Result := prData;
end;
procedure TForm1.SpeedButton3Click(Sender: TObject);
var
matual : integer;
begin
if MessageBox(Handle, ´Este Processo é irreversível.´ + #13 + ´Atualizar as Datas?!´, ´**** ATENÇÃO *****´, MB_ICONWARNING or MB_YESNO or MB_DEFBUTTON2) = idYes then
Begin
Panel1.Enabled := False;
SpeedButton3.Enabled := False;
SpeedButton2.Enabled := False;
qryBrasil.DisableControls;
matual := 0;
Panel4.Visible := true;
lblRegAtual.Caption := IntToStr(matual);
ProgressBar1.Position := 0;
ProgressBar1.Max := qryBrasil.RecordCount;
lblReg.Caption := InttoStr(qryBrasil.RecordCount);
qryBrasil.First;
while not qryBrasil.Eof Do
Begin
qryBrasil.Edit;
qryBrasildataBomPara.Value := VerFeriado(qryBrasildataBomPara.Value);
qryBrasil.ApplyUpdates;
qryBrasil.Next;
ProgressBar1.Position := ProgressBar1.Position + 1;
Inc(matual);
lblRegAtual.Caption := IntToStr(matual);
lblReg.Update;
End; //While
qryBrasil.EnableControls;
qryBrasil.First;
Panel4.Visible := False;
Panel1.Enabled := True;
SpeedButton3.Enabled := True;
SpeedButton2.Enabled := True;
End; //If MessageBox
end;
end.
Abraços, e se tiver alguma dica pra me dar, a vontade e eu agradeço
Gostei + 0
29/06/2005
Emerson Nascimento
exclua a função VerFeriado e altere a ProxDiaUtil. segue o código completo com as alterações propostas:
[i:a37fcbf669]obs.: veja se não há algum erro. eu não testei o código[/i:a37fcbf669]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Grids, DBGrids, DBTables, Buttons, StdCtrls, ExtCtrls,
WinSkinData, ComCtrls;
type
TForm1 = class(TForm)
DbBrasil: TDatabase;
sesBrasil: TSession;
qryBrasil: TQuery;
upsBrasil: TUpdateSQL;
dsBrasil: TDataSource;
DBGrid1: TDBGrid;
Panel1: TPanel;
Label1: TLabel;
Edit1: TEdit;
SpeedButton1: TSpeedButton;
qryBrasilnumeroCheque: TIntegerField;
qryBrasilvalor: TFloatField;
qryBrasildataBomPara: TDateTimeField;
qryBrasilcodigoBanco: TStringField;
qryBrasilcodigoPrefixoAgencia: TStringField;
qryBrasilnumeroContaCorrente: TStringField;
qryBrasilseuNumero: TStringField;
qryBrasilnumeroImpressoCheque: TStringField;
Label2: TLabel;
Panel2: TPanel;
Label3: TLabel;
rbBomPara: TRadioButton;
rbBanco: TRadioButton;
SkinData1: TSkinData;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
StatusBar1: TStatusBar;
Panel3: TPanel;
Label4: TLabel;
lbltot: TLabel;
TlMark: TSession;
Principal: TDatabase;
Panel4: TPanel;
Label5: TLabel;
Label6: TLabel;
lblReg: TLabel;
lblRegAtual: TLabel;
Label7: TLabel;
ProgressBar1: TProgressBar;
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormShow(Sender: TObject);
procedure qryBrasilAfterOpen(DataSet: TDataSet);
function VerFeriado(prData: TDateTime): TDateTime;
function ProxDiaUtil(prData: TDateTime): TDateTime;
procedure SpeedButton3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
with qryBrasil do
Begin
Close;
SQL.Clear;
if Edit1.Text = ´´ then
Begin
SQL.Add(´Select numeroCheque, Valor, dataBomPara, codigoBanco, codigoPrefixoAgencia, ´);
SQL.Add(´NumeroContaCorrente, seuNumero, NumeroImpressoCheque´);
SQL.Add(´From Cheque´);
End
else
begin
SQL.Add(´Select *´);
SQL.Add(´From Cheque´);
SQL.Add(´Where seuNumero = :num´);
ParamByName(´num´).Value := Edit1.Text;
end;
if rbBanco.Checked then
SQL.Add(´Order by CodigoBanco´)
else
SQL.Add(´Order by DataBomPara´);
Open;
End; //With
end;
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
Application.Terminate;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.Hint := StatusBar1.SimpleText;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
CASE key of
VK_RETURN : SpeedButton1.Click;
end; //Case
end;
procedure TForm1.FormShow(Sender: TObject);
begin
SpeedButton1.Click;
end;
procedure TForm1.qryBrasilAfterOpen(DataSet: TDataSet);
begin
lbltot.Caption := inttostr(qryBrasil.RecordCount);
end;
function TForm1.ProxDiaUtil(prData: TDateTime): TDateTime;
var
mDay: Integer;
mTabela: TQuery; // note que agora é TQuery
EhFeriado: boolean;
begin
mDay := DayOfWeek(prData);
// vejo se cai num fim de semana
if mDay = 1 then // Sunday
Result := prData + 1
else
if mDay = 7 then // Saturday
Result := prData + 2;
mTabela := TQuery.Create( Application );
// feita a análise sobre o fim de semana,
// verifico se não é um feriado.
with mTabela do
begin
DatabaseName := ´DbPrincipal´;
SQL.Text := ´Select DtFeriado from Feriado where DtFeriado=:Data´;
ParamByName(´Data´).AsDateTime := prData;
Open;
EhFeriado := not IsEmpty;
Close;
end;
mTabela.Free;
// usando recursividade (caso haja necessidade)
if EhFeriado then
prData := ProxDiaUtil(prData+1);
Result := prData;
end;
procedure TForm1.SpeedButton3Click(Sender: TObject);
var
matual: integer;
begin
if MessageBox(Handle, ´Este Processo é irreversível.´ + #13 +
´Atualizar as Datas?!´, ´**** ATENÇÃO *****´,
MB_ICONWARNING or MB_YESNO or MB_DEFBUTTON2) <> idYes then
exit;
Panel1.Enabled := False;
SpeedButton3.Enabled := False;
SpeedButton2.Enabled := False;
matual := 0;
Panel4.Visible := true;
lblRegAtual.Caption := IntToStr(matual);
ProgressBar1.Position := 0;
ProgressBar1.Max := qryBrasil.RecordCount;
lblReg.Caption := InttoStr(qryBrasil.RecordCount);
qryBrasil.First;
qryBrasil.DisableControls;
while not qryBrasil.Eof Do
Begin
qryBrasil.Edit;
qryBrasildataBomPara.Value := ProxDiaUtil(qryBrasildataBomPara.Value);
qryBrasil.ApplyUpdates;
qryBrasil.Next;
ProgressBar1.Position := ProgressBar1.Position + 1;
Inc(matual);
lblRegAtual.Caption := IntToStr(matual);
lblReg.Update;
End; //While
qryBrasil.EnableControls;
qryBrasil.First;
Panel4.Visible := False;
Panel1.Enabled := True;
SpeedButton3.Enabled := True;
SpeedButton2.Enabled := True;
end;
end.Gostei + 0
29/06/2005
Jairroberto
Eu gostaria de dar uma sugestão: use um ClientDataSet para carregar a tabela de feriados ao criar o formulário e utilize o método Locate para identificar os feriados. Isso deve melhorar a performance.
Um abraço,
Jair
Gostei + 0
29/06/2005
Tremonti
Jair, nao entendi sua questão mas eu nao posso sair do BDE neste caso
Abraços Galera
Gostei + 0
29/06/2005
Jairroberto
Não havia atentado para o fato de que você estava usando BDE. Neste caso é mais fácil ainda melhorar a performance. Se a tabela de feriado está indexada pelo campo ´DtFeriado´ use um objeto TTable em vez de TQuery e utilize o índice para fazer a pesquisa:
EhFeriado := TableFeriado.FindKey([prData]);
Um abraço,
Jair
Gostei + 0
01/07/2005
Tremonti
Nao estou entendendo
Gostei + 0
01/07/2005
Jairroberto
Volte a parte do seu código original onde você usa TTable em vez de TQuery na função ProxDiaUtil, porém, como essa função deve ser executada repetidamente, em vez de criar a ´mTabela´ dentro da função ´ProxDiaUtil´, adicione esta tabela ao ´Form1´, abra ela no evento ´OnCreate´ do ´Form1´ e feche no ´OnDestroy´. Além disso, como todas as pesquisas serão feitas pelo campo ´Data´ da tabela ´Feriado´, esse campo deve ser a chave primária do arquivo, como você já deve ter feito. O resto é mais ou menos como você já fazia, só simplifiquei um pouco:
procedure TForm1.Form1Create(Sender: TObject); begin tbtFeriado.Open; end; procedure TForm1.Form1Destroy(Sender: TObject); begin tblFeriado.Close; end; function TForm1.ProxDiaUtil(prData: TDateTime): TDateTime; var EhFeriado: Boolean; begin function TForm1.ProxDiaUtil(prData: TDateTime): TDateTime; begin Result := prData; while (DayOfWeek(prData) in [1, 7]) or tblFeriado.Locate(´Data´, prData, []) do Inc(Result); end;
Um abraço,
Jair
Gostei + 0
01/07/2005
Jairroberto
Volte a parte do seu código original onde você usa TTable em vez de TQuery na função ProxDiaUtil, porém, como essa função deve ser executada repetidamente, em vez de criar a ´mTabela´ dentro da função ´ProxDiaUtil´, adicione esta tabela ao ´Form1´, abra ela no evento ´OnCreate´ do ´Form1´ e feche no ´OnDestroy´. Além disso, como todas as pesquisas serão feitas pelo campo ´Data´ da tabela ´Feriado´, esse campo deve ser a chave primária do arquivo, como você já deve ter feito. O resto é mais ou menos como você já fazia, só simplifiquei um pouco:
procedure TForm1.Form1Create(Sender: TObject); begin tbtFeriado.Open; end; procedure TForm1.Form1Destroy(Sender: TObject); begin tblFeriado.Close; end; function TForm1.ProxDiaUtil(prData: TDateTime): TDateTime; var EhFeriado: Boolean; begin function TForm1.ProxDiaUtil(prData: TDateTime): TDateTime; begin Result := prData; while (DayOfWeek(Result) in [1, 7]) or tblFeriado.Locate(´Data´, Result, []) do Result := Result + 1; end;
Um abraço,
Jair
Gostei + 0
01/07/2005
Jairroberto
Segue o código correto:
procedure TForm1.Form1Create(Sender: TObject); begin tbtFeriado.Open; end; procedure TForm1.Form1Destroy(Sender: TObject); begin tblFeriado.Close; end; function TForm1.ProxDiaUtil(prData: TDateTime): TDateTime; begin Result := prData; while (DayOfWeek(Result) in [1, 7]) or tblFeriado.Locate(´Data´, Result, []) do Result := Result + 1; end;
Um abraço,
Jair
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)