Fórum Datas Feriados e Final de Semana #286296

28/06/2005

0

iai galera, tudo Blz pura?!
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

Tremonti

Responder

Posts

28/06/2005

Emerson Nascimento

algo assim:

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);


Responder

Gostei + 0

28/06/2005

Tremonti

Ok, mas preciso desta rotina de verifica feriado, nao tenho...

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...


Responder

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;



Responder

Gostei + 0

29/06/2005

Tremonti

Ok, entendi, fiz desta forma...
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


Responder

Gostei + 0

29/06/2005

Emerson Nascimento

eu alteraria um pouco...

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.



Responder

Gostei + 0

29/06/2005

Jairroberto

Olá, pessoal!

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


Responder

Gostei + 0

29/06/2005

Tremonti

Emerson, Obrigado pela ajuda, irei testa-la amanha

Jair, nao entendi sua questão mas eu nao posso sair do BDE neste caso


Abraços Galera


Responder

Gostei + 0

29/06/2005

Jairroberto

Olá, Tremonti!

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


Responder

Gostei + 0

01/07/2005

Tremonti

Jair
Nao estou entendendo


Responder

Gostei + 0

01/07/2005

Jairroberto

Olá, Tremonti!

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


Responder

Gostei + 0

01/07/2005

Jairroberto

Olá, Tremonti!

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


Responder

Gostei + 0

01/07/2005

Jairroberto

Deculpe, Tremonti. Na pressa acabei clicando no botão errado.
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


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar