Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) Calculo de Dados - Dias Uteis - Função Jonas


Eder

Pergunta

Jonas caso for você quem ver este tópico, não sei se fiz o correto postar o probleminha aqui, mas em fim, se puderes me ajudar ou outro colega.

seguinte.

Na função:

function Dias_Uteis(DataI, DataF:TDate):Integer;
var contador, i, n :Integer; DataR : Tdate;
begin
   n := 0;
   if DataI > DataF then
      begin
         result  := 0;
         exit;
      end;

   Contador := 0;
   while (DataI <= DataF) do
   begin
      if ((DayOfWeek(DataI) <> 1) and (DayOfWeek(DataI) <> 7)) then
         Inc(Contador);

      for i := 0 to Form1.ComboBox1.Items.Count-1 do
         begin
            DataR := strtodate(Form1.ComboBox1.Items.Strings[i]);
            if DataR = int(DataI) then
               n := n + 1;
         end;

      DataI := DataI + 1;
   end;
   result := Contador-n;
end;


procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
begin
   i := Dias_Uteis(DateTimePicker1.Date ,DateTimePicker2.Date);
   showmessage('Total de dias úteis no período : ' + inttostr(i));
end;

Eu estou usando sua função no relatorio, porem como eu tenho que contar sempre diminuindo o primeiro dia util então inseri um -1 na linha:
   result := Contador-n-1;

Neste caso ele sempre diminue 1.

O problema é quando o primeiro dia cai num sabado ou domingo, neste caso ele faz a conta incorretamente.

Exemplo: se a primeira data for sabado dia 06-02 e a ultima data for 08-02 segunda ele deveria contar 1 dia util, porem ta contando 0.

Pela seu codigo original ele conta correto pois eu to diminuindo 1 na função.

tentei fazer um if mas não deu certo. pois se não for final de semana tem que ser assim:

result := Contador-n-1;
mas se for final de semana tem que ser assim:
result := Contador-n;

Como eu poderia contornar este problema?

Muito Obrigado

Link para o comentário
Compartilhar em outros sites

14 respostass a esta questão

Posts Recomendados

  • 0
O problema é quando o primeiro dia cai num sabado ou domingo, neste caso ele faz a conta incorretamente.

Exemplo: se a primeira data for sabado dia 06-02 e a ultima data for 08-02 segunda ele deveria contar 1 dia util, porem ta contando 0.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    DateTimePicker1: TDateTimePicker;
    DateTimePicker2: TDateTimePicker;
    Button1: TButton;
    ComboBox1: TComboBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function Dias_Uteis(DataI, DataF:TDate):Integer;
var contador, i, n :Integer; DataR : Tdate;
begin
   n := 0;
   if DataI > DataF then
      begin
         result  := 0;
         exit;
      end;

   Contador := 0;
   while (DataI <= DataF) do
   begin
      if ((DayOfWeek(DataI) <> 1) and (DayOfWeek(DataI) <> 7)) then
         Inc(Contador);

      for i := 0 to Form1.ComboBox1.Items.Count-1 do
         begin
            DataR := strtodate(Form1.ComboBox1.Items.Strings[i]);
            if DataR = int(DataI) then
               n := n + 1;
         end;

      DataI := DataI + 1;
   end;
   result := Contador-n;
end;


procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
begin
   i := Dias_Uteis(DateTimePicker1.Date ,DateTimePicker2.Date);
   showmessage('Total de dias úteis no período : ' + inttostr(i));
end;


end.

Eder ... a função funciona corretamente

exemplo:

DateTimePicker1 = 06/03/2010

DateTimePicker2 = 08/03/2010

Total de dias úteis no período : 1

DateTimePicker1 = 07/03/2010

DateTimePicker2 = 08/03/2010

Total de dias úteis no período : 1

abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Bom Dia!

Sim Jonas, a função é show de bola.

você não entendeu a minha dúvida.

Eu estou usando a sua função para contar quantos dias eu levo para entregar uma mercadoria(transportadora).

então eu coleto a mercadoria num dia e entrego em outro dia.

O problema é que eu não posso contar o dia da coleta da mercadoria então na sua função em fiz assim nesta linha:

result := Contador-n-1;//note que inclui um -1 ai funciona menos um dia certinho.

Só que ai esbarrei num problema quando a coleta acontece num sabado ou domingo e a entrega ocorre na segunda ele não conta 1 dia e sim 0zero dia.

Como eu poderia contornar este problema....

Acredito que um IF resolveria o problema> tipo SE SABADO OU DOMINGO USA result := Contador-n; SENÃO result := Contador-n-1;

mas não to conseguindo montar este if, fiz alguns mas não obedece.

O que você acha?

Agradecido, Abraço.

Link para o comentário
Compartilhar em outros sites

  • 0
Acredito que um IF resolveria o problema> tipo SE SABADO OU DOMINGO USA result := Contador-n; SENÃO result := Contador-n-1;
E é isso mesmo ....

mas não to conseguindo montar este if

Eder ... é muito facil fazer isso ...

function Dias_Uteis(DataI, DataF:TDate):Integer;
var contador, i, n, d :Integer; DataR : Tdate;
begin
   n := 0;
   d := 0;
   if DataI > DataF then
      begin
         result  := 0;
         exit;
      end;

   Contador := 0;
   while (DataI <= DataF) do
   begin
      if ((DayOfWeek(DataI) <> 1) and (DayOfWeek(DataI) <> 7)) then
         Inc(Contador);

      if contador > 1 then d := 1;

      for i := 0 to Form1.ComboBox1.Items.Count-1 do
         begin
            DataR := strtodate(Form1.ComboBox1.Items.Strings[i]);
            if DataR = int(DataI) then
               n := n + 1;
         end;

      DataI := DataI + 1;
   end;
   result := Contador-n-d;
end;

OBS: Precisa melhorar seu raciocínio lógico .rs

abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Eder, só pra deixar claro, se você quiser saber qual dia da semana você está, você usa a função DayOfWeek, segue um exemplo:

if (DayOfWeek(Date) = 7) or (DayOfWeek(Date) = 1) then

ShowMessage('HOJE É SABADO OU DOMINGO')

else

ShowMessage('HOJE É UM DIA DE SEMANA');

Date é a data do PC, você pode por qualquer componente de data ali...

caso não sabia...

1 = Domingo

2 = Segunda-Feira

3 = Terça-Feira

4 = Quarta-Feira

5 = Quinta-Feira

6 = Sexta-Feira

7 = Sabado

hehe

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Jonas, testei a sua idéia porem não ta dando certo:

06-02 a 08-02 = 1 deveria ser 1 este esta correto

06-02 a 09-02 = 1 deveria ser 2 segunda e terça

06-02 a 10-02 = 2 deveria ser 3 segunda, terça e quarta

06-02 a 11-02 = 3 deveria ser 4 segunda, terça, quarta e quinta

Ontem também fiz alguns if´s diferente do seu e também dava algo distorcido.

Será porque eu to chamando a função no OnPrint de um QrLabel?

i := Dias_Uteis(Query1DATA_EMISSAO.AsDateTime ,Query1ULT_OCORR_DATA.AsDateTime);
   VALUE:= inttostr(i);

Grato

Link para o comentário
Compartilhar em outros sites

  • 0

Eder... aqui esta correto de acordo com o seu racicinio

DateTimePicker1 = 06/03/2010

DateTimePicker2 = 08/03/2010

Total de dias úteis no período : 1

DateTimePicker1 = 06/03/2010

DateTimePicker2 = 09/03/2010

Total de dias úteis no período : 1

DateTimePicker1 = 06/03/2010

DateTimePicker2 = 10/03/2010

Total de dias úteis no período : 2

DateTimePicker1 = 06/03/2010

DateTimePicker2 = 11/03/2010

Total de dias úteis no período : 3

Experimente sem o Time

i := Dias_Uteis(Query1DATA_EMISSAO.AsDate ,Query1ULT_OCORR_DATA.AsDate);
   VALUE:= inttostr(i);

abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Jonas, eu fiz este teste abaixo na sua função alterada e não funciona da o mesmo resultado:

Function Dias_Uteis(DataI, DataF:TDate):Integer;
var contador, i, n, d :Integer; DataR : Tdate;
begin
   n := 0;
   d := 0;
   if DataI > DataF then
      begin
         result  := 0;
         exit;
      end;

   Contador := 0;
   while (DataI <= DataF) do
   begin
      if ((DayOfWeek(DataI) <> 1) and (DayOfWeek(DataI) <> 7)) then
         Inc(Contador);

      if contador > 1 then d := 1;

      for i := 0 to Form1.ComboBox1.Items.Count-1 do
         begin
            DataR := strtodate(Form1.ComboBox1.Items.Strings[i]);
            if DataR = int(DataI) then
               n := n + 1;
         end;

      DataI := DataI + 1;
   end;
   result := Contador-n-d;
end;



procedure TForm1.BitBtn1Click(Sender: TObject);
var i : integer;
begin
   i := Dias_Uteis(DateTimePicker1.Date ,DateTimePicker2.Date);
   showmessage('Total de dias úteis no período : ' + inttostr(i));
end;
end. Da este resultado igual ao relatorio no quick, ou seja, tirar o TIME não resolveria :wacko: Douglas, SIM EU fi mas ai a função também não responde, ela diz que é SEMANA mas o if aponta FINAL DE SEMANA :wacko: VEJA A FUNÇÃO:
function Dias_Uteis(DataI, DataF:TDate):Integer;
var contador, i, n :Integer; DataR : Tdate;
Var Tipo:string;
begin
   n := 0;
   if DataI > DataF then
      begin
         result  := 0;
         exit;
      end;

   Contador := 0;
   while (DataI <= DataF) do
   begin
         Tipo:='';
      if ((DayOfWeek(DataI) <> 1) and (DayOfWeek(DataI) <> 7)) then
         Inc(Contador);
      if ((DayOfWeek(DataI) = 1) or (DayOfWeek(DataI) = 7)) then
         Tipo:='FSEMANA';

      for i := 0 to Form1.ComboBox1.Items.Count-1 do
         begin
            DataR := strtodate(Form1.ComboBox1.Items.Strings[i]);
            if DataR = int(DataI) then
               n := n + 1;
         end;

      DataI := DataI + 1;
   end;
   if Tipo = 'FSEMANA' Then
   begin
   result := Contador-n; //aqui tira um dia
   showmessage('FINAL DE SEMANA');
   end
   else
   begin
   result := Contador-n-1;  //aqui não
   showmessage('SEMANA');
   end;

   end;

Obrigado pessoal. :wacko:

Link para o comentário
Compartilhar em outros sites

  • 0

Eder... não sei o que voce esta fazendo de errado, mas os testes que fiz aqui estão corretos.

Mas Jonas eu estou fazendo igual ao seu, nem estou jogando no meu relatorio montei o esqueminha aqui no delphi, ou seja, peguei a sua função + o codigo do botão + os datetimer´s e mais nada.

Note que estou sempre pegando o dia 06-02 um sabado.

seu eu pegar qualquer dia da semana diferente do sabado e domingo ai da certo, tipo:

10-02 a 12-02 = 2

10-02 a 13-02 = 3

agora faz o teste do dia 13-02 sabado a dia 16-02(terça) o resultado da 1 dia, porem o correto é 2 dias

Pode ver que ta dando incorreto.

Abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Veja que fiz o código baseado nisso:

06-02 a 08-02 = 1 deveria ser 1 este esta correto

06-02 a 09-02 = 1 deveria ser 2 segunda e terça

06-02 a 10-02 = 2 deveria ser 3 segunda, terça e quarta

06-02 a 11-02 = 3 deveria ser 4 segunda, terça, quarta e quinta

depois voce coloca isso

agora faz o teste do dia 13-02 sabado a dia 16-02(terça) o resultado da 1 dia, porem o correto é 2 dias

Se tivesse colocado isso no inicio já tinha sido solucionado

veja como fica o codigo

Function Dias_Uteis(DataI, DataF:TDate):Integer;
var contador, i, n, d :Integer; DataR : Tdate;
begin
   n := 0;
   d := 0;
   if DataI > DataF then
      begin
         result  := 0;
         exit;
      end;

   Contador := 0;
   while (DataI <= DataF) do
   begin
      if ((DayOfWeek(DataI) <> 1) and (DayOfWeek(DataI) <> 7)) then
         Inc(Contador)
      else
         d := d + 1;

      for i := 0 to Form1.ComboBox1.Items.Count-1 do
         begin
            DataR := strtodate(Form1.ComboBox1.Items.Strings[i]);
            if DataR = int(DataI) then
               n := n + 1;
         end;

      DataI := DataI + 1;
   end;
   if d = 0 then
      result := Contador-n-1
   else
      result := (Contador-n-d)+d;
end;



procedure TForm1.BitBtn1Click(Sender: TObject);
var i : integer;
begin
   i := Dias_Uteis(DateTimePicker1.Date ,DateTimePicker2.Date);
   showmessage('Total de dias úteis no período : ' + inttostr(i));
end;

abraço

Link para o comentário
Compartilhar em outros sites

  • 0
Perfeito Jonas, Calculou certinho.

Achei que tava tudo certinho, no exemplo que citei realmente ta calculando correto, mas agora fiz outros testes com outras datas e deu resultado incorreto:

08-02 A 13-02 = 5 CORRETO É 4
08-02 A 23-02 =11 CORRETO É 10
15-02 A 24-02 = 8 CORRETO É 7

Ta dando um a mais.

Achei que tava resolvido, :blush:

Se meche num lugar acaba afetando o outro, não ta facil, não

Grato

Link para o comentário
Compartilhar em outros sites

  • 0

Acho que agora resolve

Function Dias_Uteis(DataI, DataF:TDate):Integer;
var contador, i, n :Integer; DataR : Tdate;
begin
   n := 0;

   if DataI > DataF then
      begin
         result  := 0;
         exit;
      end;

   Contador := 0;
   while (DataI <= DataF) do
   begin
      if ((DayOfWeek(DataI) <> 1) and (DayOfWeek(DataI) <> 7)) then
         Inc(Contador);

      for i := 0 to Form1.ComboBox1.Items.Count-1 do
         begin
            DataR := strtodate(Form1.ComboBox1.Items.Strings[i]);
            if DataR = int(DataI) then
               n := n + 1;
         end;

      DataI := DataI + 1;
   end;

   case DayOfWeek(Form1.DateTimePicker1.Date) of
     1: result := (Contador-n);
     7: result := (Contador-n);
   else
     result := (Contador-n-1);
   end;

end;

abraço

Link para o comentário
Compartilhar em outros sites

  • 0
Acho que agora resolve

Sim, agora sim, fiz um monte de testes e realmente rodou certinho o relatório, ficou muito Bom e completo.

Espero não achar mais nenhum promeminha :blush: .

Jonas, valeu a Força.

Abraços. :D

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,2k
×
×
  • Criar Novo...