GARANTIR DESCONTO

Fórum Importação de Arquivo *txt e Relatório (Ponto Eletronico) #506091

03/01/2015

0

Srs. Boa noite...

Tenho o segunte arquivo de ponto que me é gerado do relogio em *txt:

0004599883220520141328013084887674,
0004599893220520141710012337840060,
0004599903220520141720012439568688,


onde :


0004599883 22052014 1328    0 13084887674
    NADA       DATA     HORA        PIS




Tenho duas tabelas 1 = pessoa e a outra 1 = ponto...que seguem assim:


pessoa(
codigo,
matricula,
pis,
)


ponto(
id,
matricula,
pis,
hora,
dia,
)




Eu faço a importação do arquivo txt para o banco de dados, e necessito gerar o relatorio. A importação faço normalmente, mas na hora de gerar o relatorio, não me traz as informações corretas, um exemplo é se o individuo registrar duas vezes o ponto na mesma hora, ele duplica, outra é se o individuo registrar só uma vez, ele não me traz nenhum registro.

Aos que puderem me ajudar, Agradeço...
Brunno Sena

Brunno Sena

Responder

Posts

03/01/2015

William

Bs um relatório nada mais é que o resultado de uma pesquisa ou cálculos muitas vezes executados em SQL, então pergunto para você!

As 2 tabelas que recebem os dados da importação estão com registros consistentes?

Essas discrepâncias que você cita, aparecem se você executar uma pesquisa SQL simples?
Responder

Gostei + 0

03/01/2015

Brunno Sena

Bs um relatório nada mais é que o resultado de uma pesquisa ou cálculos muitas vezes executados em SQL, então pergunto para você!

As 2 tabelas que recebem os dados da importação estão com registros consistentes?

Essas discrepâncias que você cita, aparecem se você executar uma pesquisa SQL simples?




Willian, faço da seguinte forma...

TABELAS:

CREATE TABLE PESSOA (
    MATRICULA     INTEGER,
    CC            VARCHAR(8),
    MAODEOBRA     VARCHAR(2),
    NOME          VARCHAR(300),
    PIS           VARCHAR(15),
    CIDADE        VARCHAR(25),
    UF            VARCHAR(2),
    DESC_FUNCAO   VARCHAR(100),
    COD_FUNCAO    INTEGER,
    COD_LOCAL     INTEGER,
    ALOJAMENTO    VARCHAR(100),
    DATA_ENTRADA  DATE,
    DATA_SAIDA    VARCHAR(11),
    SITUACAO      CHAR(1),
    ADM           DATE,
    COD_CIDADE    INTEGER,
    PICTURE       BLOB SUB_TYPE 0 SEGMENT SIZE 80,
    COD_FOTO      INTEGER,
    NASCIMENTO    DATE,
    VENC_EXP1     DATE,
    VENC_EXP2     DATE,
    CATEGORIA     CHAR(1),
    AGENCIA       VARCHAR(9),
    CONTA         VARCHAR(10),
    BANCO         VARCHAR(3),
    NUCLEO        CHAR(1),
    TURNO         INTEGER
);


CREATE TABLE PONTO (
    PIS        VARCHAR(11),
    DATA       VARCHAR(12),
    HORA      VARCHAR(5),
    ID         INTEGER,
    NUM_REP    CHAR(2),
    ID_PESSOA  INTEGER
);





E faço o select dessa forma:



select P1.PIS, P1.DATA, P1.HORA1 as ENTRA, P2.HORA1 as SAI, 
P.MATRICULA, P.NOME as NOME_PESSOA, P.PIS, P.DESC_FUNCAO, 
P.CC, P.DATA_ENTRADA, P.MAODEOBRA, P.situacao, P.turno 
FROM PONTO P1,PONTO P2,PESSOA P 
where P1.DATA = '03012014' AND P2.DATA = P1.DATA AND P2.PIS = P1.PIS 
AND P2.ID > P1.ID AND P.PIS = P1.PIS 
and p.situacao <> 'D' 
group by p1.id, P1.PIS, P1.DATA, P1.HORA1, P2.HORA1, 
P.MATRICULA, P.NOME, P.PIS, P.DESC_FUNCAO, 
P.CC, P.DATA_ENTRADA, P.MAODEOBRA, P.situacao,P.turno 
ORDER BY P.MATRICULA





ele me traz o resultado, e sobre a duplicação te trago o exemplo...

ID	ID1	PIS   DATA	ENTRA	SAI	   MATRICULA	NOME_PESSOA
369	370	20430280194	20122014	17:02	17:02	3998	EDERSON FINKS
369	1114	20430280194	20122014	17:02	07:32	3998	EDERSON FINKS
370	1114	20430280194	20122014	17:02	07:32	3998	EDERSON FINKS


agora acho que pode me dizer que select melhor fazer pra isso, acredito que o problema seja no select, porque se ele me trouxer o select funcionando, pra o espelho de ponto, vai ser moleza...

Abraço...
Responder

Gostei + 0

03/01/2015

Marisiana Battistella

Considerando que vc precisa retornar os dados da pessoa independente de ela ter registro de ponto ou não, você precisa usar um LEFT JOIN da tabela pessoa com a tabel ponto para atender essa necessidade. Veja um exemplo:
SELECT P1.PIS,
         P1.DATA,
         P1.HORA1 AS ENTRA,
         P2.HORA1 AS SAI, 
         P.MATRICULA,
         P.NOME as NOME_PESSOA,
         P.PIS, P.DESC_FUNCAO, 
         P.CC, P.DATA_ENTRADA,
         P.MAODEOBRA,
         P.situacao,
         P.turno 
FROM PESSOA P
LEFT JOIN PONTO P1
ON  P.PIS = P1.PIS 
LEFT JOIN PONTO P2
ON  P.PIS = P2.PIS
AND P2.DATA = P1.DATA 
WHERE P1.DATA = '03012014' 
--- AND P2.ID > P1.ID 
AND p.situacao <> 'D'
GROUP BY p1.id,
               P1.PIS,
               P1.DATA,
               P1.HORA1,
               P2.HORA1, 
               P.MATRICULA,
               P.NOME, P.PIS,
               P.DESC_FUNCAO, 
               P.CC, P.DATA_ENTRADA,
               P.MAODEOBRA,
               P.situacao,
               P.turno 
ORDER BY P.MATRICULA


Não entendi o porque de utilizar o JOIN " AND P2.ID > P1.ID "...

Não cheguei a fazer testes, mas logicamente é essa idéia q deve ser seguida.
Responder

Gostei + 0

05/01/2015

Brunno Sena

Considerando que vc precisa retornar os dados da pessoa independente de ela ter registro de ponto ou não, você precisa usar um LEFT JOIN da tabela pessoa com a tabel ponto para atender essa necessidade. Veja um exemplo:
SELECT P1.PIS,
         P1.DATA,
         P1.HORA1 AS ENTRA,
         P2.HORA1 AS SAI, 
         P.MATRICULA,
         P.NOME as NOME_PESSOA,
         P.PIS, P.DESC_FUNCAO, 
         P.CC, P.DATA_ENTRADA,
         P.MAODEOBRA,
         P.situacao,
         P.turno 
FROM PESSOA P
LEFT JOIN PONTO P1
ON  P.PIS = P1.PIS 
LEFT JOIN PONTO P2
ON  P.PIS = P2.PIS
AND P2.DATA = P1.DATA 
WHERE P1.DATA = '03012014' 
--- AND P2.ID > P1.ID 
AND p.situacao <> 'D'
GROUP BY p1.id,
               P1.PIS,
               P1.DATA,
               P1.HORA1,
               P2.HORA1, 
               P.MATRICULA,
               P.NOME, P.PIS,
               P.DESC_FUNCAO, 
               P.CC, P.DATA_ENTRADA,
               P.MAODEOBRA,
               P.situacao,
               P.turno 
ORDER BY P.MATRICULA


Não entendi o porque de utilizar o JOIN " AND P2.ID > P1.ID "...

Não cheguei a fazer testes, mas logicamente é essa idéia q deve ser seguida.





Obrigado Marisiana, mas a utilidade do "AND P2.ID > P1.ID", é pra que não duplique, pois do modo que você me passou, me apresentou da seguinte forma:



ID	ID1	PIS	DATA	ENTRA	SAI	MATRICULA	NOME_PESSOA
402	402	12961397709	20122014	08:13	08:13	3963	DANIELE ROCHA PEREIRA
402	407	12961397709	20122014	08:13	11:53	3963	DANIELE ROCHA PEREIRA
407	402	12961397709	20122014	11:53	08:13	3963	DANIELE ROCHA PEREIRA
407	407	12961397709	20122014	11:53	11:53	3963	DANIELE ROCHA PEREIRA
424	424	12580868684	20122014	07:17	07:17	3969	JOSE VADERLI DA SILVA SUTELLO
424	434	12580868684	20122014	07:17	12:40	3969	JOSE VADERLI DA SILVA SUTELLO
434	424	12580868684	20122014	12:40	07:17	3969	JOSE VADERLI DA SILVA SUTELLO
434	434	12580868684	20122014	12:40	12:40	3969	JOSE VADERLI DA SILVA SUTELLO





O que na verdade preciso, é que não duplique, e que se o individuo registra 1 batida, me traga ainda sim.

Agradecido.
Responder

Gostei + 0

05/01/2015

Marisiana Battistella

Na verdade ele não está duplicando, está fazendo certo pois ele está listando por ID. Observe que as combinações de ID são diferentes, talvez você deva filtrar e agrupar sem esses IDs. Tenta remover o campo p1.id da cláusula GROUP BY...

Qual é o campo identificador (foreig key) da pessoa na tabela Ponto?
Responder

Gostei + 0

05/01/2015

Brunno Sena

Na verdade ele não está duplicando, está fazendo certo pois ele está listando por ID. Observe que as combinações de ID são diferentes, talvez você deva filtrar e agrupar sem esses IDs. Tenta remover o campo p1.id da cláusula GROUP BY...

Qual é o campo identificador (foreig key) da pessoa na tabela Ponto?



Marisiana, São IDs diferentes porque vou salvando assim, pra ter ids diferente, à não ser que o modo em que eu esteja puxando do txt para o BD, esteja errada.

Faço desta forma:


for I := 0 to lbArquivos.Items.Count - 1 do
  begin
  try
//    lbArquivos.Selected[i];
    AssignFile(Txt,(eArquivo.Text+'\'+lbArquivos.Items[i]));{ NOME do arquivo texto}
    Reset(Txt);

  if not SQLDataSet1.Active then
      SQLDataSet1.Open;
    cdsDados.EmptyDataSet; //... zera o arquivo
  cdsDados.Open;

  While not Eoln(Txt) do
  begin
    Readln(Txt,Entrada);
//    Readln(Txt,Entrada);

    cdsDados.Insert;

    consultaID;
    novo_ID := dmDados.cdsID.FieldByName('MAX').AsInteger;
    novo_ID := novo_ID + 1;

    cdsDados.FieldByName('ID').AsInteger := novo_ID;
    cdsDados.FieldByName('PIS').Value:= Copy(Entrada,24,11);
    cdsDados.FieldByName('DATA').Value:= Copy(Entrada,11,08);
    cdsDados.FieldByName('HORA1').Value:= Copy(Entrada,19,02)+':'+Copy(Entrada,21,02);
    cdsDados.FieldByName('NUM_REP').Value:= Copy(lbArquivos.Items[i],14,2);

    cdsDados.Post;
    cdsDados.ApplyUpdates(0);
    end;
  CloseFile(Txt);
    MessageDlg('Arquivo importado com sucesso !',mtInformation,[mbOK]);
  except
    MessageDlg('Erro na importação !',mtError,[mbOK]);
  end;



Mas de qualquer forma, o indentificador é o pis. Mas ela não é Integer, é varchar!
Responder

Gostei + 0

07/01/2015

Marisiana Battistella

Mas, pelo q entendi, o armazenamento da informação está correto...
A questão é q na consulta (SELECT) q vc está fazendo não precisa pedir para listar e agrupar pelo ID, senão vc não vai conseguir visualizar os dados como você precisa.
Responder

Gostei + 0

07/01/2015

Brunno Sena

Mas, pelo q entendi, o armazenamento da informação está correto...
A questão é q na consulta (SELECT) q vc está fazendo não precisa pedir para listar e agrupar pelo ID, senão vc não vai conseguir visualizar os dados como você precisa.



Eu testei retirando o id, mas não funcionou, continuou a duplicar... alguma sugestão ?
Responder

Gostei + 0

07/01/2015

Marisiana Battistella

Mais uma alteração... Não sei se vai resolver..
Se não der certo é em função da definição na cláusula WHERE...
SELECT P.MATRICULA,
       P.NOME as NOME_PESSOA,
       P.PIS,
       P.DESC_FUNCAO,
       P.DATA_ENTRADA,
       P.MAODEOBRA,
       P.SITUACAO,
       P.CC,
       P1.DATA,
       P.TURNO,
       P1.HORA1 AS ENTRA,
       P2.HORA1 AS SAI 
FROM PESSOA P
LEFT JOIN PONTO P1
ON  P1.PIS = P.PIS 
LEFT JOIN PONTO P2
ON  P2.PIS = P.PIS
WHERE P1.DATA = '03012014'
AND P2.DATA = P1.DATA 
AND P2.ID > P1.ID 
AND P.SITUACAO <> 'D'
GROUP BY P.MATRICULA,
       P.NOME,
       P.PIS,
       P.DESC_FUNCAO,
       P.DATA_ENTRADA,
       P.MAODEOBRA,
       P.SITUACAO,
       P.CC,
       P1.DATA,
       P.TURNO,
       P1.HORA1,
       P2.HORA1 
ORDER BY P.MATRICULA
Responder

Gostei + 0

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

Aceitar