Jump to content
Fórum Script Brasil
  • 0

[resolvido] Somar Campo Timer (horas Extras) Paradox


Eder
 Share

Question

Ola...pessoal

Eu preciso montar um relatorio de horas extras.....sintetico, ou seja, totalizar quantos horas extras o camarada fez num periodo.

Eu sei fazer o layout pra este tipo de relatorio, só não to conseguindo somar estas horas.

Se eu fosse somar digamos ou campo numerico eu apenas utilizaria assim:

SUM(query1.SALARIO)
e pronto....já me traria o SALARIO acumulado por funcionario(COMO exemplo). Mas como na tabela eu to trabalhando com campo Timer(HORAS EXTRAS)...ai ele não me traz nada coloquei assim:
SUM(query1.hora_extra)

alguém poderia me dizer como é que eu mostraria a soma das horas no quick??

Grato

Link to comment
Share on other sites

18 answers to this question

Recommended Posts

  • 0
(...)

coloquei assim:

SUM(query1.hora_extra)

alguém poderia me dizer como é que eu mostraria a soma das horas no quick??

Eder, realmente não dá para fazer assim. Mas...

Supondo que você grave apenas hh:mm (não grava os segundos), poderia ser feita uma continha fácil no seu select. Siga o meu exemplo:

select sum(extract(hour from Hora)+(extract(minute from Hora)/24)) as Total_Horas

from Teste.db

Estamos transformando o Time em um Float que possui na parte inteira a quantidade de horas e na fracionária, os minutos. Ou seja, você poderá obter na parte inteira as "n" horas e multiplicando a parte fracionária por 60, terá os "n" minutos.

Se preferir transformar este campo para um equivalente ao TDateTime (ou TTime) no Delphi, divida o valor do campo por 24 que é o número de horas de um dia.

Se você leu o que rolou semana passada sobre esta questão de TDateTime, você deve ter lido o post que fiz há algum tempo sobre o formato deste tipo (TDateTime).

Se tiver que formatar horas além de 23:59:59, dê uma olhada em Tutoriais & Dicas, procurando pela função que lá já postei há algum tempo.

Abraços

Link to comment
Share on other sites

  • 0
Supondo que você grave apenas hh:mm (não grava os segundos), poderia ser feita uma continha fácil no seu select. Siga o meu exemplo:
R.:Carinha eu já to gravando hh:mm:ss

Eu Não consigue montar o relatorio...conforme sua dica.

Ai Pesquisando na Net e em foruns...achei uma função que seria ideal:

//Função converter Hora para Segundos

function Hora_Seg( Horas:string ):LongInt;
Var Hor,Min,Seg:LongInt;
begin
 Horas[Pos(':',Horas)]:= '[';
 Horas[Pos(':',Horas)]:= ']';
 Hor := StrToInt(Copy(Horas,1,Pos('[',Horas)-1));
 Min := StrToInt(Copy(Horas,Pos('[',Horas)+1,(Pos(']',Horas)-Pos('[',Horas)-1)));
 if Pos(':',Horas) > 0 then
    Seg := StrToInt(Copy(Horas,Pos(']',Horas)+1,(Pos(':',Horas)-Pos(']',Horas)-1)))
 else
    Seg := StrToInt(Copy(Horas,Pos(']',Horas)+1,2));
 Result := Seg + (Hor*3600) + (Min*60);
end;
//Função converter Segundos para Horas
function Seg_Hora( Seg:LongInt ):string;
Var Hora,Min:LongInt;
  Tmp : Double;
begin
 Tmp := Seg / 3600;
 Hora := Round(Int(Tmp));
 Seg :=  Round(Seg - (Hora*3600));
 Tmp := Seg / 60;
 Min := Round(Int(Tmp));
 Seg :=  Round(Seg - (Min*60));
 Result := FormatFloat( '00', Hora )+ ':' + FormatFloat( '00', Min ) + ':' + FormatFloat( '00', Seg );
end;
Codigo Usado no belorePrint do Quickrep1:
procedure TForm2.QuickRep1BeforePrint(Sender: TCustomQuickRep;
  var PrintReport: Boolean);
var
HEPAG: Integer;
begin
HEPAG := 0;
Query1.Open;
   while ( not Query1.EOF ) do
    begin
   HEPAG := HEPAG + Hora_Seg( TimeToStr( Query1.FieldByName('HE_DIURNA').AsDateTime ) );
   Query1.Next;
   QRLABEL4.CAPTION:=(seg_hora(HEPAG));
   end;
end;
O codigo acima funciona legal no caso se eu mandar listar as horas de um periodo.. Mas no meu caso eu preciso mostra por funcionario acumulado tipo assim:
Mario 10:00:00 Jose 15:30:00 Total...........25:30:00
e ai não to conseguindo mostrar os totais de cada hum. tentei fazer assim o relatorio:
mario    he
            02:00:00
            08:00:00
total.....10:00:00

Jose      he
            10:30:00
            05:30:00
total......15:30:00
mas o resultado sai assim:
mario    he
            02:00:00
            08:00:00
total......25:30:00

Jose      he
            10:30:00
            05:30:00
total......25:30:00
note que o resultado(total) é igual, pois o codigo me mostra o total de horas de todos...não de cada um. Algo devo estar fazendo incorredo. estou usando assim as Bandas:
1-banda QRGroup
Expression=QUERY1.funcionario
Footerband=a bandaGroupFooter

1-Detail=com o campo de funcionario e o campo de Horas

1-RbGroupFooter
Nela o QrLabel4 mostrando os totais de horas de cada funcionario

Um relatorio muito simples...mas como é com horas...to me quebrando...e não to conseguindo resolver.

Amigão...se puder me dar uma forcinha te agradeço.

Grato :(

Edited by Eder
Link to comment
Share on other sites

  • 0
Codigo Usado no belorePrint do Quickrep1:

procedure TForm2.QuickRep1BeforePrint(Sender: TCustomQuickRep;
  var PrintReport: Boolean);
var
HEPAG: Integer;
begin
  HEPAG := 0;
  Query1.Open;
  while ( not Query1.EOF ) do
    begin
    HEPAG := HEPAG + Hora_Seg( TimeToStr( Query1.FieldByName('HE_DIURNA').AsDateTime ) );
    Query1.Next;
    QRLABEL4.CAPTION:=(seg_hora(HEPAG));
  end;
end;
note que o resultado(total) é igual, pois o codigo me mostra o total de horas de todos...não de cada um. Algo devo estar fazendo incorredo. estou usando assim as Bandas:
1-banda QRGroup
Expression=QUERY1.funcionario
Footerband=a bandaGroupFooter

1-Detail=com o campo de funcionario e o campo de Horas

1-RbGroupFooter
Nela o QrLabel4 mostrando os totais de horas de cada funcionario

Eder, veja que você mesmo já colocou a origem de seu problema.

Você totaliza as horas antes da impressão do relatório (QuickRep1.BeforePrint) e inicializa o QrLabel4 que mostrará este total, logo, para cada usuário o total só poderá ser o mesmo!

Voce precisará é definir esta sua variável HEPAG na sessão private do seu form, de modo que você possa utilizá-lo nos seguintes pontos:

- no GroupHeade, você inicializa (zera) ela;

- no BeforePrint da banda detalhe, você soma a hora sendo impressa ao valor já armazenado em HEPAG;

- no BeforePrint da banda GroupFooter, você converte o total de horas do empregado e atribui a QrLabel4.

Só para constar, naquela sua rotina no BeforePrint, a atribuição ao QrLabel4 deve ficar fora do WHILE para que não seja constantemente atribuído. ;)

Na verdade, este procedimento não seria mais utilizado, pela forma como mencionei acima.

Link to comment
Share on other sites

  • 0

Amigão..fiz o que me indicou...mas não deu certo NÃO..Acho que esta variavel HEPAG não ta zerando ....favor dar uma reparadinha abaixo e ver se fiz algo de errado:

Haaa...depois destas mudanças o relatorio ficou faltando funcionario...agora só aparece o primeiro ...mas como o total de horas de todos juntos.

Eder, veja que você mesmo já colocou a origem de seu problema.

Você totaliza as horas antes da impressão do relatório (QuickRep1.BeforePrint) e inicializa o QrLabel4 que mostrará este total, logo, para cada usuário o total só poderá ser o mesmo!

R. OK.

Voce precisará é definir esta sua variável HEPAG na sessão private do seu form,

Ok.: já colocado como abaixo:

private
  HEPAG: Integer;  //variavel que armazena a hora
    { Private declarations }
de modo que você possa utilizá-lo nos seguintes pontos:
- no GroupHeade, você inicializa (zera) ela;
  public
    { Public declarations }
  end;
Resposta:
procedure TForm2.QRGroup1BeforePrint(Sender: TQRCustomBand;
  var PrintBand: Boolean);
begin
HEPAG := 0;
end;
- no BeforePrint da banda detalhe, você soma a hora sendo impressa ao valor já armazenado em HEPAG;
procedure TForm2.QRBand5BeforePrint(Sender: TQRCustomBand;
  var PrintBand: Boolean);
begin
Query1.Open;
   while ( not Query1.EOF ) do
    begin
   HEPAG := HEPAG + Hora_Seg( TimeToStr( Query1.FieldByName('HE_DIURNA').AsDateTime ) );
   Query1.Next;
   end;
end;
-no BeforePrint da banda GroupFooter, você converte o total de horas do empregado e atribui a QrLabel4.
procedure TForm2.QRBand7BeforePrint(Sender: TQRCustomBand;
  var PrintBand: Boolean);
begin
   QRLABEL4.CAPTION:=(seg_hora(HEPAG));
end;
Só para constar, naquela sua rotina no BeforePrint, a atribuição ao QrLabel4 deve ficar fora do WHILE para que não seja constantemente atribuído.
R. Ok. foi erro meu mesmo.
Na verdade, este procedimento não seria mais utilizado, pela forma como mencionei acima.
R. Achei este mais facil o entendimento. A unit completa segue abaixo:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Qrctrls, QuickRpt, ExtCtrls, Db, DBTables, StdCtrls;

type
  TForm2 = class(TForm)
    Query1: TQuery;
    Query1CODIGO: TIntegerField;
    Query1DATA: TDateField;
    Query1CODVEI: TIntegerField;
    Query1CODMOT: TIntegerField;
    Query1DTSAIDA: TDateField;
    Query1DTCHEGADA: TDateField;
    Query1KMINICIAL: TFloatField;
    Query1KMFINAL: TFloatField;
    Query1KMPER: TFloatField;
    Query1OBSERVACAO: TStringField;
    Query1LUSUARIO: TStringField;
    Query1ADIANTAMENTO: TFloatField;
    Query1LDATA: TStringField;
    Query1LHORA: TStringField;
    Query1CODIGO_1: TIntegerField;
    Query1DATA_SAIDA: TDateField;
    Query1HR_SAIDA: TTimeField;
    Query1DATA_CHEGADA: TDateField;
    Query1HR_CHEGADA: TTimeField;
    Query1PESO: TFloatField;
    Query1HE_PAGADORA: TTimeField;
    Query1HE_NOTURNA: TTimeField;
    Query1HE_DIURNA: TTimeField;
    Query1CODLAN: TIntegerField;
    Query1CODROT: TIntegerField;
    Query1TIPO_HORA: TStringField;
    Query1CONTADOR: TIntegerField;
    Query1TOTAL_HORAS: TTimeField;
    Query1CODMOT_1: TIntegerField;
    Query1NOME: TStringField;
    Query1CARGO: TStringField;
    Query1SALARIO: TFloatField;
    QuickRep1: TQuickRep;
    QRGroup1: TQRGroup;
    QRDBText8: TQRDBText;
    QRLabel28: TQRLabel;
    QRBand7: TQRBand;
    QRLabel58: TQRLabel;
    QRExpr3: TQRExpr;
    QRExpr6: TQRExpr;
    QRExpr7: TQRExpr;
    QRExpr8: TQRExpr;
    QRExpr9: TQRExpr;
    QRBand9: TQRBand;
    QRImage1: TQRImage;
    QRLabel15: TQRLabel;
    QRSysData4: TQRSysData;
    QRSysData5: TQRSysData;
    QRLabel16: TQRLabel;
    QRLabel65: TQRLabel;
    QRLabel20: TQRLabel;
    QRLabel67: TQRLabel;
    QRLabel22: TQRLabel;
    QRLabel1: TQRLabel;
    QRLabel26: TQRLabel;
    QRBand5: TQRBand;
    QRDBText10: TQRDBText;
    QRDBText27: TQRDBText;
    QRDBText29: TQRDBText;
    QRDBText32: TQRDBText;
    QRDBText33: TQRDBText;
    QRDBText34: TQRDBText;
    QRDBText35: TQRDBText;
    QRDBText36: TQRDBText;
    QRDBText37: TQRDBText;
    QRDBText38: TQRDBText;
    QRDBText39: TQRDBText;
    Button1: TButton;
    QRLabel4: TQRLabel;
    procedure Button1Click(Sender: TObject);
    procedure QRGroup1BeforePrint(Sender: TQRCustomBand;
      var PrintBand: Boolean);
    procedure QRBand5BeforePrint(Sender: TQRCustomBand;
      var PrintBand: Boolean);
    procedure QRBand7BeforePrint(Sender: TQRCustomBand;
      var PrintBand: Boolean);
  private
  HEPAG: Integer;  //variavel que armazena a hora
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.DFM}

//Função converter Hora para Segundos

function Hora_Seg( Horas:string ):LongInt;
Var Hor,Min,Seg:LongInt;
begin
 Horas[Pos(':',Horas)]:= '[';
 Horas[Pos(':',Horas)]:= ']';
 Hor := StrToInt(Copy(Horas,1,Pos('[',Horas)-1));
 Min := StrToInt(Copy(Horas,Pos('[',Horas)+1,(Pos(']',Horas)-Pos('[',Horas)-1)));
 if Pos(':',Horas) > 0 then
    Seg := StrToInt(Copy(Horas,Pos(']',Horas)+1,(Pos(':',Horas)-Pos(']',Horas)-1)))
 else
    Seg := StrToInt(Copy(Horas,Pos(']',Horas)+1,2));
 Result := Seg + (Hor*3600) + (Min*60);
end;



//Função converter Segundos para Horas

function Seg_Hora( Seg:LongInt ):string;
Var Hora,Min:LongInt;
  Tmp : Double;
begin
 Tmp := Seg / 3600;
 Hora := Round(Int(Tmp));
 Seg :=  Round(Seg - (Hora*3600));
 Tmp := Seg / 60;
 Min := Round(Int(Tmp));
 Seg :=  Round(Seg - (Min*60));
 Result := FormatFloat( '00', Hora )+ ':' + FormatFloat( '00', Min ) + ':' + FormatFloat( '00', Seg );
end;

procedure TForm2.Button1Click(Sender: TObject);
  begin
  QUERY1.ACTIVE:=TRUE;
  QuickRep1.Preview;
  end;

procedure TForm2.QRGroup1BeforePrint(Sender: TQRCustomBand;
  var PrintBand: Boolean);
begin
HEPAG := 0;
end;

procedure TForm2.QRBand5BeforePrint(Sender: TQRCustomBand;
  var PrintBand: Boolean);
begin
Query1.Open;
   while ( not Query1.EOF ) do
    begin
   HEPAG := HEPAG + Hora_Seg( TimeToStr( Query1.FieldByName('HE_DIURNA').AsDateTime ) );
   Query1.Next;
   end;
end;

procedure TForm2.QRBand7BeforePrint(Sender: TQRCustomBand;
  var PrintBand: Boolean);
begin
   QRLABEL4.CAPTION:=(seg_hora(HEPAG));
end;

end.

muito Grato :)

Edited by Eder
Link to comment
Share on other sites

  • 0
Amigão..fiz o que me indicou...mas não deu certo NÃO..Acho que esta variavel HEPAG não ta zerando ....favor dar uma reparadinha abaixo e ver se fiz algo de errado:

Haaa...depois destas mudanças o relatorio ficou faltando funcionario...agora só aparece o primeiro ...mas como o total de horas de todos juntos.

Agora que você pôs o código, isto está bem claro.

Você tem apenas um dataset (Query1) no seu relatório, certo?! Então, só para lembrar, você nunca deve manipular ele em qualquer parte do código quando ele estiver vinculado ao QuickRep - captou?!

É assim: o quick report obtém os dados do dataset para imprimir as informações do groupheader e em seguida banda detalhe, então, ele mostrar os dados do primeiro registro. Após imprimir este registro, no groupheader ele executará o procedimento BeforePrint da banda detail e aí vem o problema: você move o dataset até seu final. Na sequência, ele imprime o groupfooter e verifica se o final do arquivo chegou, e como isto é verdade, encerra o relatório com apenas um registro e o somatório total.

O que você tem que fazer é mudar o BeforePrint da banda detalhe para:

procedure TForm2.QRBand5BeforePrint(Sender: TQRCustomBand;
  var PrintBand: Boolean);
begin
  HEPAG := HEPAG + Hora_Seg( TimeToStr( Query1.FieldByName('HE_DIURNA').AsDateTime ) );
end;

Abraços

Link to comment
Share on other sites

  • 0

Amigão...Bingo

Ótima explicação, nunca ninguém havia me explicado este processo sobre o quick

muito Agradecido.

Funcionou direitinho...

Carinha...só pra fechar....este relatorio devido ao layout eu costuma chama-lo de analitico, acredito que você também..pois ele abre o nome do funcionario, logo apos lista na banda detail as horas e na Groufooter ele totaliza..beleza..show.

Mas pra fazer ele ficar Sintetico, ou seja uma lista exemplo:

funcionario------hora extra
=================
jose......................10:00:00
maria....................20:30:00
carla.....................10:15:00
---------------------------------
total......................40:45:00
bem simples....ele abre o relatorio com o nome do funcionario e ao lado lista as horas...bem simples no formato..pra economizar papel, senão vai sair analitico e vai um monte de folhas...e o cara do RH vai enxer o saco....rs......só precisaria mesmo do total de horas extras. Tentei adaptar aqui...até achei uma solução pra quebrar um galho, nem precisa mexer muito no form do quick..apenas peguei a bandDetail e coloquei a propriedade Height=0 e deletei todos os qrdbtext dela....ficou legalzinho.....mais ainda não seria o ideal como mostrei o layout acima. ficou assim:
--------------------------------------
FUNCIONARIO: JOSE
QT DE HE.....................10:00:00
FUNCIONARIO: MARIA
QT DE HE.....................20:30:00
FUNCIONARIO: CARLA:
QT DE HE.....................10:15:00
--------------------------------------
total............................40:45:00

Mas ...beleza....já ta de bom tamanho a força que você me deu..

muito Grato.....

Abraço ;) :D

Link to comment
Share on other sites

  • 0

Eder, você quer utilizar o mesmo relatório para imprimir o Analítilo e o Resumo?

Quanto a mexer com a altura da banda, até não seria necessária - você poderia apenas definir a banda detalhe com Enabled=False

Link to comment
Share on other sites

  • 0
Eder, você quer utilizar o mesmo relatório para imprimir o Analítilo e o Resumo?
R.: Sim.

Quanto a mexer com a altura da banda, até não seria necessária - você poderia apenas definir a banda detalhe com Enabled=False

R.: Sim.....também funciona...beleza.

Carinha...tentei inserir Na bandSumary...UM TOTALIZADOR FINAL no relatório, mas não to conseguindo fazer com que pegue o valor total de HORAS EXTRAS num QrLabel. Qual o segredo??

muito Grato

Link to comment
Share on other sites

  • 0
Eder, você quer utilizar o mesmo relatório para imprimir o Analítilo e o Resumo?
R.: Sim.

Faça o seguinte, então, na sua banda groupfooter, coloque um QRDBEdit igualzinho o que está no groupheader (com o nome do funcionário)

daí, conforme opção:

1) Sintético:

- marque sua propriedade Enabled=True deste último QRDBEdit (na groupfooter)

- defina a propriedade Enabled=False da banda groupheader;

- defina a propriedade Enabled=False da banda detail;

2) Analítico:

- marque sua propriedade Enabled=False deste último QRDBEdit (na groupfooter)

- defina a propriedade Enabled=True da banda groupheader;

- defina a propriedade Enabled=True da banda detail;

Testa aí. Depois que funcionar você pode fazer algum tipo de ajuste estético.

Se não funcionar deste jeito (não somar direito), ao invés de desbilitar as bandas, você deixa habilitadas e no beforeprint delas, você continua fazendo o cálculo e altera o valor do parâmetro PrintBand para False (no caso do sintético). Para isto, provavelmente você vai ter que criar uma variável no private do form para armazenar a opção: se analítico ou sintético.

Link to comment
Share on other sites

  • 0

carinha.....não deu certo não...

defina a propriedade Enabled=False da banda detail;
se você desabilitar esta band ele...não mostra as horas..fica zerado. Outra coisinha...a questão de colocar o QrDbtext na GroupFooter também não deu certo. Mas beleza...eu fiz com aquele jeitinho que te falei e funcionou...
FormRel_HE2.QRBand5.Height:=0;//bandDetail

isto faz com que a bandDetail seja reduzida a zero e funcionando, apenas não aparece. ;)

Eu só queria ver com você...é um totalizador na BandSumary..que não to conseguindo fazer.

Lembra que fomos até a rbGroupFooter??

muito Grato... :D

Edited by Eder
Link to comment
Share on other sites

  • 0
Eu só queria ver com você...é um totalizador na BandSumary..que não to conseguindo fazer.

Lembra que fomos até a rbGroupFooter??

então, a totalização na sumary vai cair na mesma situação da groupfooter. Para ter esta totalização, como a contabilização é feita na mão, você vai ter que ter outra variável em que acumulará os totais de cada funcionário e mover na mão para um QRLabel.

Quanto aos outros itens que você não conseguiu implementar, vou ver o que posso fazer para que você entenda o que quiz dizer. ;)

Quanto aos outros itens que você não conseguiu implementar, vou ver o que posso fazer para que você entenda o que quiz dizer. ;)
Eder, tente baixar o arquivo exemplo Relatorio Horas.zip, que fiz utilizando das sugestões que havia citado.

- Realmente aquela consulta SQL para somar horas (post#2) não estava 100% certa, a quantidade retornada não estava na unidade adequada. Ajustei ela e temos um double como resultado, onde na parte inteira está o nº de Horas e na fracionária os minutos no formato 1/n horas (décimos de hora). Ex. 0,25 horas equivale a 15minutos.

- Também não dá para utilizar a alternativa de desabilitar as bandas (post#10) mas, a outra, a de definir PrintBand=False ou True conforme caso funciona sem problemas.

- O relatório é bem simples, mas implementa o recurso 2 em 1 (Analítico ou Sintético).

Achei que assim ficaria mais fácil de explicar. Espero que ajude.

Edited by Micheus
Retirado anexo (arquivo ZIP) e hospedado no 4share.
Link to comment
Share on other sites

  • 0

Carinha...desculpe a demora em responder...meu delphi na empresa deu pau......e agora tenho que reinstalar tudo de novo..componentes..etc....echiiiii...

Mas tentei baixar e ver o seu exemplo aqui em casa..porem ao baixar...tinha dentro do zip um arquivo desconhecido..e não consegui ver..

Poderias dar uma olhadinha neste seu zip?

Fico no aguardo...abraço e muito grato

:D

Link to comment
Share on other sites

  • 0

Carinha...consegui abrir sim o zip.....tentei montar um exemplo conforme os meus dados..e me perdi......hehehe...achei um pouquinho dificil....hehehe.....mas prometo que vou dar uma olhada mais com tempo na semana que vem....mas quanto ao modelo de relatório que você montou..é isto mesmo....ficou show...basta agora eu pegar e tentar entender...com tempo vou pegando o esquema..pois você colocou em cada linha de codigo o que estava fazendo.

valeu ..Carinha...muito grato pelo esforço.

Com certeza a sua dica vai ser muito útil, pois o tipo de relatorio é muito usado.

Abraço

:D

CARINHA.....tava também vendo este seu comentário sobre a ideia que a gente tava discutindo antiga.

De eu totalizar a banda sumary....com todas as horas do relatorio...você diz que:

então, a totalização na sumary vai cair na mesma situação da groupfooter. Para ter esta totalização, como a contabilização é feita na mão, você vai ter que ter outra variável em que acumulará os totais de cada funcionário e mover na mão para um QRLabel.

Então resolvi tentar também fazer...só que o resultado na bandaSumary da o valor total do ultimo funcionario...e NÃO DA O VALOR TOTAL DE HORAS DO RELATORIO.

fiz como você mencionou coloquei uma outra variavel......e fiz igualzinho ao Total de cada funcionario..só que ao invés de colocar este codigo abaixo na GroupFooter coloquei na QRBand1BeforePrint da SUMARY...

QRLABEL2.CAPTION:=(seg_hora(HESUMARY));

se não der......vou ter que abandonar este modelo e caminhar para o seu.......só que eu queria terminar este pra não ficar no meio do caminho entende....?? ai na semana quem vem vou entrar de cara no seu modelo..achei também interessante pois ele é dois em um.

t+..Abraço..agora vou ver um Dvd..da uma relaxada.....hehehe..

Link to comment
Share on other sites

  • 0
CARINHA.....tava também vendo este seu comentário sobre a ideia que a gente tava discutindo antiga.

De eu totalizar a banda sumary....com todas as horas do relatorio...você diz que:

então, a totalização na sumary vai cair na mesma situação da groupfooter. Para ter esta totalização, como a contabilização é feita na mão, você vai ter que ter outra variável em que acumulará os totais de cada funcionário e mover na mão para um QRLabel.

Então resolvi tentar também fazer...só que o resultado na bandaSumary da o valor total do ultimo funcionario...e NÃO DA O VALOR TOTAL DE HORAS DO RELATORIO.

fiz como você mencionou coloquei uma outra variavel......e fiz igualzinho ao Total de cada funcionario..só que ao invés de colocar este codigo abaixo na GroupFooter coloquei na QRBand1BeforePrint da SUMARY...

QRLABEL2.CAPTION:=(seg_hora(HESUMARY));

se não der......vou ter que abandonar este modelo e caminhar para o seu.......só que eu queria terminar este pra não ficar no meio do caminho entende....?? ai na semana quem vem vou entrar de cara no seu modelo..achei também interessante pois ele é dois em um.

Eder, diante deste questionamento eu só tenho uma pergunta: Voce já olhou o exemplo que eu lhe passei? Acho que sei a resposta: Não!

Tá lá é só olhar, assim vou achar que perdi meu tempo à toa <_<

Link to comment
Share on other sites

  • 0
se não der......vou ter que abandonar este modelo e caminhar para o seu.......só que eu queria terminar este pra não ficar no meio do caminho entende....?? ai na semana quem vem vou entrar de cara no seu modelo..achei também interessante pois ele é dois em um.

Eder, diante deste questionamento eu só tenho uma pergunta: Voce já olhou o exemplo que eu lhe passei? Acho que sei a resposta: Não!

R. Sim...olhei, estudei e tentei fazer o seu exemplo ontem a noite e hoje de manhã....no seu exemplo encalhei no codigo da query, deu erro:

SELECT MOTORIS.NOME, 
MOTORIS.CODMOT, 
VIAGEM.HE_DIURNA, 
VIAGEM.DATA_SAIDA,
VIAGEM.CODLAN,
AJUSTE.CODIGO,  
AJUSTE.CODMOT,
sum(extract(hour from HE_DIURNA)+(extract(minute from HE_DIURNA)/60)+(extract(second from HE_DIURNA)/3600)) as Total_Horas
FROM MOTORIS, VIAGEM,  AJUSTE where
(ajuste.codigo = viagem.codlan) and 
(ajuste.codmot = motoris.codmot)
group by motoris.nome, viagem.data_saida
order by motoris.nome
da erro: whem gruup by exists, every simple field in projetour must be un Group by **Agora no Modelo Antigo que eu já estava usando eu consegui totalizar as horas na BandSumary....estudei o seu exemplo e ai deu certo Segue abaixo a minha unit do relatorio para caso alguém necessite de um modelo:Sendo assim este tópico vai ficar completo, vai ter dois modelos pra calcular horas. ;) vai ajudar bastante usuários do forum. Segue abaixo Unit:
unit UnitRelHE2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Qrctrls, QuickRpt, ExtCtrls, Db, DBTables, StdCtrls, ComCtrls;

type
  TFormRel_HE2 = class(TForm)
    Query1: TQuery;
    QuickRep1: TQuickRep;
    QRGroup1: TQRGroup;
    QRDBText8: TQRDBText;
    QRLabel28: TQRLabel;
    QRBand7: TQRBand;
    QRLabel58: TQRLabel;
    QRExpr3: TQRExpr;
    QRBand9: TQRBand;
    QRImage1: TQRImage;
    QRLabel15: TQRLabel;
    QRSysData4: TQRSysData;
    QRSysData5: TQRSysData;
    QRLabel1: TQRLabel;
    QRLabel26: TQRLabel;
    QRBand5: TQRBand;
    QRDBText10: TQRDBText;
    QRDBText27: TQRDBText;
    QRDBText29: TQRDBText;
    QRDBText32: TQRDBText;
    QrLDiurna: TQRLabel;
    QRBand1: TQRBand;
    QRLabel2: TQRLabel;
    QRLabel3: TQRLabel;
    QRLabel20: TQRLabel;
    QRLabel6: TQRLabel;
    QRLabel22: TQRLabel;
    QRLabel5: TQRLabel;
    QRLabel7: TQRLabel;
    QRLabel8: TQRLabel;
    QRLabel9: TQRLabel;
    QrLNoturna: TQRLabel;
    QrLPagadora: TQRLabel;
    QRDBText1: TQRDBText;
    QRLabel4: TQRLabel;
    QRBand2: TQRBand;
    Button1: TButton;
    QRLabel10: TQRLabel;
    QRLabel11: TQRLabel;
    QRLabel12: TQRLabel;
    Query1Codigo: TIntegerField;
    Query1Codlan: TIntegerField;
    Query1CodMot: TIntegerField;
    Query1CodMot_1: TIntegerField;
    Query1Nome: TStringField;
    Query1He_Diurna: TTimeField;
    Query1He_Noturna: TTimeField;
    Query1He_Pagadora: TTimeField;
    procedure QRBand5BeforePrint(Sender: TQRCustomBand;
      var PrintBand: Boolean);
    procedure QRBand7BeforePrint(Sender: TQRCustomBand;
      var PrintBand: Boolean);
    procedure QRBand2BeforePrint(Sender: TQRCustomBand;
      var PrintBand: Boolean);
    procedure Button1Click(Sender: TObject);
    procedure QuickRep1BeforePrint(Sender: TCustomQuickRep;
      var PrintReport: Boolean);
    procedure QRGroup1BeforePrint(Sender: TQRCustomBand;
      var PrintBand: Boolean);
  private

  {VARIAVEIS QUE ARMAZENA AS HORAS
  horas diurnas, noturnas e pagadora que seria a soma da diruna + noturna}
  DIURNA, NOTURNA, PAGADORA : Integer;
  {abaixo as totalizadoras da bandaSumary}
  DIURNA_SUMARY, NOTURNA_SUMARY, PAGADORA_SUMARY : Integer;

    { Private declarations }

  public
    { Public declarations }
  end;

var
  FormRel_HE2: TFormRel_HE2;

implementation

uses UnitRelMedia;

{$R *.DFM}

//Função converter Hora para Segundos

function Hora_Seg( Horas:string ):LongInt;
Var Hor,Min,Seg:LongInt;
begin
Horas[Pos(':',Horas)]:= '[';
Horas[Pos(':',Horas)]:= ']';
Hor := StrToInt(Copy(Horas,1,Pos('[',Horas)-1));
Min := StrToInt(Copy(Horas,Pos('[',Horas)+1,(Pos(']',Horas)-Pos('[',Horas)-1)));
if Pos(':',Horas) > 0 then
    Seg := StrToInt(Copy(Horas,Pos(']',Horas)+1,(Pos(':',Horas)-Pos(']',Horas)-1)))
else
    Seg := StrToInt(Copy(Horas,Pos(']',Horas)+1,2));
Result := Seg + (Hor*3600) + (Min*60);
end;



//Função converter Segundos para Horas

function Seg_Hora( Seg:LongInt ):string;
Var Hora,Min:LongInt;
  Tmp : Double;
begin
Tmp := Seg / 3600;
Hora := Round(Int(Tmp));
Seg :=  Round(Seg - (Hora*3600));
Tmp := Seg / 60;
Min := Round(Int(Tmp));
Seg :=  Round(Seg - (Min*60));
Result := FormatFloat( '00', Hora )+ ':' + FormatFloat( '00', Min ) + ':' + FormatFloat( '00', Seg );
end;


{Banda Detail}
procedure TFormRel_HE2.QRBand5BeforePrint(Sender: TQRCustomBand;
  var PrintBand: Boolean);
begin
{Abaixo recebe os valores da tabela}
 DIURNA := DIURNA + Hora_Seg( TimeToStr( Query1.FieldByName('HE_DIURNA').AsDateTime ) );
 NOTURNA := NOTURNA + Hora_Seg( TimeToStr( Query1.FieldByName('HE_NOTURNA').AsDateTime ) );
 PAGADORA := PAGADORA + Hora_Seg( TimeToStr( Query1.FieldByName('HE_PAGADORA').AsDateTime ) );
end;


{Abaixo é a RbGroupFooter}
procedure TFormRel_HE2.QRBand7BeforePrint(Sender: TQRCustomBand;
  var PrintBand: Boolean);
begin
{abaixo totaliza a bandSumary}
Diurna_Sumary := Diurna_Sumary + DIURNA;
   Noturna_Sumary := Noturna_Sumary + Noturna;
     Pagadora_Sumary := Pagadora_Sumary + Pagadora;
{Abaixo Totaliza a Banda GRoupFooter de Cada Funcionario.}
   QRLDiurna.CAPTION:=(seg_hora(DIURNA));
      QRLNoturna.CAPTION:=(seg_hora(NOTURNA));
         QRLPagadora.CAPTION:=(seg_hora(PAGADORA));
   end;

{banda Sumary}
procedure TFormRel_HE2.QRBand2BeforePrint(Sender: TQRCustomBand;
  var PrintBand: Boolean);
begin
{Abaixo os totalizadores da BandSumary}
QRLABEL10.CAPTION:=(SEG_HORA(DIURNA_SUMARY));
QRLABEL11.CAPTION:=(SEG_HORA(NOTURNA_SUMARY));
QRLABEL12.CAPTION:=(SEG_HORA(PAGADORA_SUMARY));
end;

procedure TFormRel_HE2.Button1Click(Sender: TObject);
begin
{codigo sql da Query:

SELECT Ajuste.Codigo, Viagem.Codlan,
Ajuste.CodMot, Motoris.CodMot, Motoris.Nome,
Viagem.He_Diurna, Viagem.He_Noturna, Viagem.He_Pagadora
FROM AJUSTE, VIAGEM, MOTORIS where
(ajuste.codigo = viagem.codlan) and
(ajuste.codmot = Motoris.codmot)
order by motoris.nome

}
{ativa aquery e manda o Preview}
QUERY1.Active:=TRUE;
QUICKREP1.PREVIEW;
end;

procedure TFormRel_HE2.QuickRep1BeforePrint(Sender: TCustomQuickRep;
  var PrintReport: Boolean);
begin
//Limpa as Variaveis totalizadoras da BandSumary
DIURNA_SUMARY := 0;
NOTURNA_SUMARY := 0;
PAGADORA_SUMARY := 0;
end;

{Abaixo é a QRGroup1}
procedure TFormRel_HE2.QRGroup1BeforePrint(Sender: TQRCustomBand;
  var PrintBand: Boolean);
begin
//Limpa as Variaveis totalizadoras da GroupFooter
DIURNA := 0;
NOTURNA := 0;
PAGADORA := 0;
end;

end.

Valeu....Abraço. ;)

Edited by Eder
Link to comment
Share on other sites

  • 0
SELECT MOTORIS.NOME, 
MOTORIS.CODMOT, 
VIAGEM.HE_DIURNA, 
VIAGEM.DATA_SAIDA,
VIAGEM.CODLAN,
AJUSTE.CODIGO,  
AJUSTE.CODMOT,
sum(extract(hour from HE_DIURNA)+(extract(minute from HE_DIURNA)/60)+(extract(second from HE_DIURNA)/3600)) as Total_Horas
FROM MOTORIS, VIAGEM,  AJUSTE where
(ajuste.codigo = viagem.codlan) and 
(ajuste.codmot = motoris.codmot)
group by motoris.nome, viagem.data_saida
order by motoris.nome
da erro: whem gruup by exists, every simple field in projetour must be un Group by
Nem me refiria a mudar a query porque isto dependeria de ser ou não viável ao seu caso - coloquei mais a título de demonstrar que seria possível. O erro a que você se refere é decorrente do fato de que, ao utilizar GROUP BY, todas as colunas que não seja função de agregação devem ser repetidas nesta cláusula. Assim, você teria que utilizar deste modo:
SELECT M.NOME, M.CODMOT, V.HE_DIURNA, V.DATA_SAIDA, V.CODLAN, A.CODIGO, A.CODMOT,
sum(extract(hour from HE_DIURNA)+(extract(minute from HE_DIURNA)/60)+(extract(second from HE_DIURNA)/3600)) as Total_Horas
FROM MOTORIS M, VIAGEM V,  AJUSTE A
where (A.codigo = V.codlan) and 
      (A.codmot = M.codmot)
group by  M.NOME, M.CODMOT, V.HE_DIURNA, V.DATA_SAIDA, V.CODLAN, A.CODIGO, A.CODMOT
order by motoris.nome
Agora no modelo antigo que eu já estava usando e só preciso do totalizador na sumary......aqui eu fiz em cima deste modelo que você passou...e o total sempre da o do ultimo funcionario...ele não guarda na variavel o total dos funcionarios anteriores e soma....sei lá..já verifiquei e não acho o erro...
Voce diria que a banda QRGroup1 é justamente a que faz a quebra de funcionário? Se for, parece razoável que você obtenha apenas o total do último funcionário já que no BeforePrint deste group você zera a variável DIURNA_SUMARY!!! Vamos repassar qual deveria ser o conceito envolvido nesta questão (controlar totalização "na mão"): - variável para controlar total por grupo (Funcionario) e total geral (sumario); - o sumário representa uma total geral, então você inicializa a variável antes de começar a impressão, ou seja, no beforeprint do relatório(quickrep); - o total por grupo, deve ser inicializado ao iniciar cada grupo, ou seja, ao imprimir o cabeçalho do grupo (groupheader); - ao ser impresso cada item (detail), acumulamos o valor na variável do grupo (eventualmente na do sumario - questão de opção); - ao ser impresso o rodapé do grupo (footergroup) apresentamos o total do grupo e somamos seu valor ao totalizador geral (sumario - e esta é a opção que prefiro); - ao ser impresso o sumário (sumary) apresentamos o valor no tatalizador geral. Itens que estão bem explícitos no exemplo:
TRelHoras = class(TForm)
    :
  private
    InRelAnalitico :Boolean;
    QtdHorasGroup,
    QtdHorasSumary :Double;
   ...
 :
procedure TRelHoras.QuickRep1BeforePrint(Sender: TQuickRep; var PrintReport: Boolean);
begin
 // zera para todo o início de relatório
  QtdHorasSumary := 0;
end;

procedure TRelHoras.QRGroupHeaderBeforePrint(Sender: TQRCustomBand; var PrintBand: Boolean);
begin
  PrintBand := InRelAnalitico;     // só imprime no modo analítico, mas faz o cálculo
  ChildBand1.Enabled := PrintBand; // Child do GroupFooter - cabeçalho "Data e H. Extra"
 // zera para cada grupo de empregados
  QtdHorasGroup := 0;
end;

procedure TRelHoras.QRBand1BeforePrint(Sender: TQRCustomBand; var PrintBand: Boolean);
begin
  PrintBand := InRelAnalitico;     // só imprime no modo analítico, mas faz o cálculo
 // totaliza por grupo funcionário
  QtdHorasGroup := QtdHorasGroup +QryTotalHorasTotal_Horas.Value;
  QRLabel2.Caption := FullTimeToStr(QryTotalHorasTotal_Horas.Value/24); // divide por 24 p/ converter em TTime
end;

procedure TRelHoras.QRGroupFooterBeforePrint(Sender: TQRCustomBand; var PrintBand: Boolean);
begin
 // acrescenta qtd do usuário a qtd do sumário (geral)
  QtdHorasSumary := QtdHorasSumary +QtdHorasGroup;
  QRLabel4.Caption := FullTimeToStr(QtdHorasGroup/24); // divide por 24 p/ converter em TTime
end;

procedure TRelHoras.QRBand3BeforePrint(Sender: TQRCustomBand; var PrintBand: Boolean);
begin
  QRLabel5.Caption := FullTimeToStr(QtdHorasSumary/24); // divide por 24 p/ converter em TTime
end;

Abraços

Link to comment
Share on other sites

  • 0

Carinha...deu certo.....alias eu tinha respondido no anterior...quanto ao modelo antigo até disponibilizei a unit pra caso alguém viesse a pricisar....só faltava esta parte do seu modelo(query sql)mas também deu certo.......parece que eu e você estavamos editando junto e você largou primeiro a resposta...pois isto....e eu tava editando a resposta de manhã pois achei o totalizador da Banda sumary agora a tarde.

O Importante é que deu certo.....nos dois exemplos

valeu...mais uma vez...

Grato

Fechamos o tópico...t+

:D

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Forum Statistics

    • Total Topics
      149.8k
    • Total Posts
      646.6k
×
×
  • Create New...