Problema com data me tirando do sério
Possuo um sistema q dentre outras funções gera parcelas de pagamento, sendo permitido ao operador modificar essa data caso não seja uma data ideal para o cliente naquele mês (é feita uma ligação antes pra confirmar), a operadora escolhe a nova data em um DateTimePeacker, no closeup, tenho a seguinte rotina:
e a função Data_util, q verifica se é uma data válida e faz uma consulta a uma tabela de feriados pra saber se é feriados ou não.
e o problema é o seguinte:
quando se entra no sistema, tudo funciona perfeitamente, escolhe uma data, se for feriado ele decrementa um dia, se for domingo, decrementa um dia, se for um dia normal, fica na data escolhida; só que no decorrer da operação do sistema a coisa começa a desandar, toda data q é escolhida, independente de ser válida ou não, o sistema decrementa um dia, ai tem q fechar o sistema e abrí-lo quando tudo funciona normal de novo e assim fica o dia todo, deu problema, fecha e abre.
Será q estou esquecendo de retirar algo da memória?[/code]
procedure TFrm_Recibos_Impressao.Cbo_DataCloseUp(Sender: TObject); var Q_Qr:TSqlquery; dt: TDate; diautil,diadomes,diadasemana:boolean; begin diautil := False; diadomes := False; diadasemana := false; dt:= cbo_data.Date; diautil := Data_util(datetostr(dt)) = ´N´; diadomes := DayOfTheMonth(dt) = 1; diadasemana := DayOfWeek(dt) = 1; if (diautil) and (diadomes) then dt := IncDay(dt,1) else if diautil then dt := IncDay(dt,-1) else if (diadomes) and (diadasemana) then dt := IncDay(dt,1) else If diadasemana then dt := IncDay(dt,-1) else dt := Cbo_Data.Date; if Q_Doacoes_Impressao.RecordCount > 0 then begin Q_Qr := TSQLQuery.Create(nil); Q_Qr.SQLConnection := dm.Conexao; Q_Qr.SQL.Add(´UPDATE TAB_DOACOES SET DOC_DATA_OPERACAO = :data WHERE DOC_ID =´+Q_Doacoes_ImpressaoDOC_ID.AsString); Q_Qr.Params.ParamByName(´data´).AsDate := dt; Q_Qr.ExecSQL; Q_Qr.Free; end; end;
e a função Data_util, q verifica se é uma data válida e faz uma consulta a uma tabela de feriados pra saber se é feriados ou não.
function TFrm_Recibos_Impressao.Data_util(data: string): string; begin If Not dm.F_Data_Valida(data) Then Begin Exit; End; Try dm.dsQ_Query2.Close; dm.dsQ_Query2.Params.ParamByName(´DATA´).AsDate := strtodate(data); dm.dsQ_Query2.Open; Except MessageDlg(´Aconteceu um erro no momento da obtenção dos dados! Contacte o administrador do sistema!´,mtError,[mbOK],0); Exit; End; if dm.dsQ_Query2.RecordCount = 0 then Result := ´S´ else Result := ´N´; end;
e o problema é o seguinte:
quando se entra no sistema, tudo funciona perfeitamente, escolhe uma data, se for feriado ele decrementa um dia, se for domingo, decrementa um dia, se for um dia normal, fica na data escolhida; só que no decorrer da operação do sistema a coisa começa a desandar, toda data q é escolhida, independente de ser válida ou não, o sistema decrementa um dia, ai tem q fechar o sistema e abrí-lo quando tudo funciona normal de novo e assim fica o dia todo, deu problema, fecha e abre.
Será q estou esquecendo de retirar algo da memória?[/code]
Fajo
Curtidas 0
Respostas
Emerson Nascimento
12/07/2009
acho é preciso fazer mais algumas análises:
- não há pagamento no dia 1o. do mês???
- se a data escolhida for uma segunda-feira e essa segunda feira for feriado, o sistema deixará como data de pagamento o domingo. é isso mesmo?
- o correto, ao cair num domingo ou feriado, não seria INcrementar ao invés de decrementar?
- e quanto ao sábado???? se o dia escolhido for domingo o sistema muda pra sábado???
- não há pagamento no dia 1o. do mês???
- se a data escolhida for uma segunda-feira e essa segunda feira for feriado, o sistema deixará como data de pagamento o domingo. é isso mesmo?
- o correto, ao cair num domingo ou feriado, não seria INcrementar ao invés de decrementar?
- e quanto ao sábado???? se o dia escolhido for domingo o sistema muda pra sábado???
GOSTEI 0
Emerson Nascimento
12/07/2009
eu incrementaria a data, como é o comum no caso de parcelamentos:
e faria minha função de avaliação de ´dia útil´ da seguinte forma:
nota 1: não utilize Recordcount, a menos que você queira saber exatamente qual foi o número de registros retornados, o que não é o caso nas suas rotinas.
nota 2: só pra constar, todas as suas datas vinham decrementadas em 1 devido ao código
procedure TFrm_Recibos_Impressao.cbo_dataCloseUp(Sender: TObject); var Q_Qr:TSqlquery; dt: TDate; diautil, diaprimeiro, domingo: boolean; begin dt := cbo_data.Date; // enquanto a data for um fim-de-semana ou feriado, // joga a data 1 dia "pra frente"... while not Data_util(dt) do dt := IncDay(dt, 1); if Q_Doacoes_Impressao.Active and not Q_Doacoes_Impressao.IsEmpty then begin Q_Qr := TSQLQuery.Create(nil); Q_Qr.SQLConnection := dm.Conexao; Q_Qr.SQL.Add(´UPDATE TAB_DOACOES SET DOC_DATA_OPERACAO = :data WHERE DOC_ID =´+Q_Doacoes_ImpressaoDOC_ID.AsString); Q_Qr.Params.ParamByName(´data´).AsDate := dt; Q_Qr.ExecSQL; Q_Qr.Free; end; end;
e faria minha função de avaliação de ´dia útil´ da seguinte forma:
function TFrm_Recibos_Impressao.Data_util(datainformada: TDate): boolean; begin Result := not (DayOfWeek(datainformada) in [1, 7]); // sábado ou domingo // se não é um fim de semana, verifico se é um feriado if Result then begin try dm.dsQ_Query2.Close; dm.dsQ_Query2.Params.ParamByName(´DATA´).AsDate := datainformada; dm.dsQ_Query2.Open; except MessageDlg(´Aconteceu um erro no momento da obtenção dos dados! Contacte o administrador do sistema!´,mtError,[mbOK],0); Exit; end; // se o resultset estiver vazio, é uma data válida Result := dm.dsQ_Query2.IsEmpty; end; end;
nota 1: não utilize Recordcount, a menos que você queira saber exatamente qual foi o número de registros retornados, o que não é o caso nas suas rotinas.
nota 2: só pra constar, todas as suas datas vinham decrementadas em 1 devido ao código
if diautil then dt := IncDay(dt,-1)
GOSTEI 0
Fajo
12/07/2009
Vamos lá emerson,
há sim:
só q se for no dia 1º, ele incrementa para o dia 2 e não para o mês anterior.
na verdade não, se cair num domingo tem q ser decrementada pra sábado.
realmente já tinha percebido essa falha, obrigado.
obrigado, pela sugestão, irei implementá-la.
mas somente se a função diautil retornar true, senão, vai pro próximo if.
agora, o q me deixa perdido é exatamento pq funciona bem por um perido de tempo e depois, começa a decrementar pra toda data.[/code]
- não há pagamento no dia 1o. do mês???
há sim:
só q se for no dia 1º, ele incrementa para o dia 2 e não para o mês anterior.
- se a data escolhida for uma segunda-feira e essa segunda feira for feriado, o sistema deixará como data de pagamento o domingo. é isso mesmo?
na verdade não, se cair num domingo tem q ser decrementada pra sábado.
realmente já tinha percebido essa falha, obrigado.
- o correto, ao cair num domingo ou feriado, não seria INcrementar ao invés de decrementar?
. . diadasemana := DayOfWeek(dt) = 1; . . If diadasemana then dt := IncDay(dt,-1)
não utilize Recordcount, a menos que você queira saber exatamente qual foi o número de registros retornados, o que não é o caso nas suas rotinas.
obrigado, pela sugestão, irei implementá-la.
só pra constar, todas as suas datas vinham decrementadas em 1 devido ao código
mas somente se a função diautil retornar true, senão, vai pro próximo if.
agora, o q me deixa perdido é exatamento pq funciona bem por um perido de tempo e depois, começa a decrementar pra toda data.[/code]
GOSTEI 0
Emerson Nascimento
12/07/2009
Vamos lá emerson,
[quote:551123a5ad=´emerson.en´]- não há pagamento no dia 1o. do mês???
há sim:
só q se for no dia 1º, ele incrementa para o dia 2 e não para o mês anterior.[/quote:551123a5ad]
ENTÃO NÃO HÁ PAGAMENTO NO DIA 1o.
agora, o q me deixa perdido é exatamento pq funciona bem por um perido de tempo e depois, começa a decrementar pra toda data.
um dos fatores é justamente pelo código mostrado:
if diautil then dt := IncDay(dt,-1)
vejamos seu código (troquei o nome de algumas variáveis pra ficar mais amigável):
procedure TFrm_Recibos_Impressao.Cbo_DataCloseUp(Sender: TObject); var Q_Qr:TSqlquery; dt: TDate; diautil,diaprimeiro,domingo:boolean; begin diautil := False; diaprimeiro := False; domingo := false; dt:= cbo_data.Date; diautil := Data_util(datetostr(dt)) = ´N´; diaprimeiro := DayOfTheMonth(dt) = 1; domingo := DayOfWeek(dt) = 1; if (diautil) and (diaprimeiro) then dt := IncDay(dt,1) else if diautil then dt := IncDay(dt,-1) else if (diaprimeiro) and (domingo) then dt := IncDay(dt,1) else If domingo then dt := IncDay(dt,-1) else dt := Cbo_Data.Date; if Q_Doacoes_Impressao.RecordCount > 0 then begin Q_Qr := TSQLQuery.Create(nil); Q_Qr.SQLConnection := dm.Conexao; Q_Qr.SQL.Add(´UPDATE TAB_DOACOES SET DOC_DATA_OPERACAO = :data WHERE DOC_ID =´+Q_Doacoes_ImpressaoDOC_ID.AsString); Q_Qr.Params.ParamByName(´data´).AsDate := dt; Q_Qr.ExecSQL; Q_Qr.Free; end; end;
tomemos o calendário abaixo como exemplo:
D S T Q Q S S 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
eis o trecho que controla a mudança do dia
if (diautil) and (diaprimeiro) then dt := IncDay(dt,1) else if diautil then dt := IncDay(dt,-1) else if (diaprimeiro) and (domingo) then dt := IncDay(dt,1) else If domingo then dt := IncDay(dt,-1) else dt := Cbo_Data.Date;
- se for escolhido dia 1o, seu código mudará para dia 2, porque é um dia útil e é dia primeiro.
if (diautil) and (diaprimeiro) then dt := IncDay(dt,1)
- se for escolhido dia 6, seu código mudará para dia 5, pois é um domingo
If domingo then dt := IncDay(dt,-1)
- agora, se for escolhido qualquer outro dia que não seja domingo nem seja dia 1o, seu código irá mudar para o dia anterior, devido ao trecho
if diautil then dt := IncDay(dt,-1)
porque o if segue o fluxo, não vai chegar no else porque a segunda condição será válida antes de chegar lá. ao que parece a data só permanecerá aquela escolhida se for selecionado um sábado que não seja dia 1o.
Aliás, o que você considera como dia útil? Para essa sua necessidade, sábado é um dia útil?
GOSTEI 0
Fajo
12/07/2009
Mas emerson, o código:
da função Date_util diz q, se retornar ´S´, a variável diautil recebera False, onde dessa forma ele não deveria cair entrar no:
e sim, continuar o fluxo até chegar no
o q vc acha?
if dm.dsQ_Query2.RecordCount = 0 then Result := ´S´ else Result := ´N´;
da função Date_util diz q, se retornar ´S´, a variável diautil recebera False, onde dessa forma ele não deveria cair entrar no:
if diautil then dt := IncDay(dt,-1)
e sim, continuar o fluxo até chegar no
else dt := Cbo_Data.Date;
o q vc acha?
GOSTEI 0
Emerson Nascimento
12/07/2009
não dá pra dizer com certeza, porque algumas coisas estão ocultas...
o que faz a função [i:7408b54057]F_Data_Valida[/i:7408b54057]?
qual a instrução da [i:7408b54057]dm.dsQ_Query2[/i:7408b54057]?
e, pra te falar a verdade eu nunca vi uma avaliação dessas, em que se retrocede o dia de vencimento.
e você não me respondeu como é considerado o sábado. é um dia útil?
o que faz a função [i:7408b54057]F_Data_Valida[/i:7408b54057]?
qual a instrução da [i:7408b54057]dm.dsQ_Query2[/i:7408b54057]?
e, pra te falar a verdade eu nunca vi uma avaliação dessas, em que se retrocede o dia de vencimento.
e você não me respondeu como é considerado o sábado. é um dia útil?
GOSTEI 0