Fórum Trabalhando com 3 tabelas #383816

17/08/2010

0

Preciso fazer um processamento envolvendo 3 tabelas, conforme abaixo, e, não sei como fazer.

1) As tebelas são assim:

Tabela1
cod_cli integer not null,
nome varchar(50),
valor numeric(10,2)

Tabela2
cod_cli integer not null,
evento integer not null,
qtde integer

Tabela3
cod_cli integer not null,
evento integer not null,
total numeric(10,2)


Para cada cod_cli da tabela1 existem diversos cod_cli com eventos diferentes na tabela2, coforme abaixo:

Tabela1
cod_cli Nome                 Valor
001     Fulano de Tal   100,00
002     Beltrano de Tal  50,00

Tabela2
Cod_cli Evento qtde
001      01             5
001      02           10
002      01           10
002      05             5


2) Preciso gravar na tabela3 o resultado de valor (tabela1) * qtde (tabela2).

3) Estou usando DBExpress com ClientDataSet e estou tentando fazer o código assim:

// Tabela1
(...)
DM.Tabela1.first;
while not dm.tabela1.Eof do
begin
  mCod_cli := dm.cdsTabela1COD_CLI.AsInteger;
  nQtde    := dm.cdsTabela1QTDE.AsInteger;
  nValor   := dm.cdsTabela1VALOR.AsInteger;

  // Tabela2 - DUVIDAS...
  Como faço para acessar os registros da Tabela2 com cod_cli = mcod_cli?
  Posso fazer um SELECT * Tabela2 WHERE cod_cli = mcod_cli?
  Tenho no DataModule 1 SQLQuery, 1 DataSetProvider e 1 ClientDataSet.
  Com SQLQuery fica bom ou ficaria melhor com SQLTable ou SQLDataSet?
  Como ficaria o código aqui?

  ?
  ?
  ?
  ?
 
  Solucionada a duvida acima, acho que o código continuaria assim...
  DM.Tabela2.first;
  while not DM.cdsTabela2.Eof do
  begin
    mEvento := dm.cdsTabela2EVENTO.AsInteger;
    nQtde   := dm.cdsTabela2QTDE.AsInteger;
    nTotal  := nQtde * nValor

   // Tabela3 - DUVIDAS
    Como faço para gravar aqui?
    Posso fazer INSERT INTO TABELA2 (COD_CLI, EVENTO, TOTAL) VALUES (mcod_cli, mevento, nTotal );
    De novo tenho, tenho no DataModule 1 SQLQuery, 1 DataSetProvider e 1 ClientDataSet.
    Com SQLQuery fica bom ou ficaria melhor com SQLTable ou SQLDataSet?
    Como ficaria o código aqui?
    ?
    ?
    ?
  
    ou..
    dm.cdsTabela3.Append;
    (...)
    dm.cdsTabela3.Post;
  

    dm.cdsTabela2.Next;
   

  end;

  dm.cdsTabela1.Next;
end;
Francisco Rodrigues

Francisco Rodrigues

Responder

Posts

18/08/2010

Wesley Yamazack

Olá amigo,


Estou analisando seu problema, peço que aguarde um pouco.

Obrigado

Um abraço

Wesley Y
Responder

Gostei + 0

19/08/2010

Francisco Rodrigues

Oi, amigo Wesley,

Meu problema tem solução ou, você não entendeu? Na realidade, preciso:
1)  ler uma tabela de funcionarios (tabela 1) e verificar o valor do salario do empregado;
2)  verificar na tabela 2 se o  empregado fez horas extras;
3)  calcular o valor e gravar na tabela 3.

A lógica é assim

Abre Tabela1
Vai para o inicio da tabela1
Enquando o fim do arquivo não for encontrado
  guarda codigo do empregado
  guarda valor do salario
  Abre tabela 2
  Verifica se existe o empregado na tabela2
  Se existir
  Enquanto o codigo do empregado na tabela2 for igual ao codigo do empregado na tabela 1
    Calcula e guarda valor calculado
    Abre tabela 3
    Grava codigo e valor calculado
    Volta para tabela 2
    Avança 1 registro
  fim tabela 2 encontrado
  volta para tabela 1
  avanca 1 registro
fim  tabela 1 encontrado
fim processamento

Estou fazendo assim, mas, a tabela2  fica sempre vazia e, não sei se desta forma fica bom, já que pretendo utilizar o modelo em diversas partes do programa...

procedure TfrmRH3110.btnCalculoFPClick(Sender: TObject);
var
  mChapa : Integer;

  nSal_Atual,
  nHoras_Contratuais,
  nSal_Hora,
  nSal_Dia,
  nSal_Mes : Currency;

  mEvento : Integer;
  nValor  : Currency;


begin
  with dmProcessamento do
  begin
    cdsFuncionario.DisableControls;
    cdsFuncionario.First;
    while not cdsFuncionario.Eof do
    begin
      mChapa             := cdsFuncionarioCHAPA.AsInteger;
      nSal_Atual         := cdsFuncionarioSAL_ATUAL.AsCurrency;
      nHoras_Contratuais := cdsFuncionarioHORAS_CONTRATUAIS.AsCurrency;

      nSal_hora          := nSal_Atual/nHoras_Contratuais;
      nSal_dia            := nSal_Atual/30;


      cdsEve.FetchParams;
      cdsEve.Params.ParamByName('CHAPA').Value := mChapa;
      cdsEve.Open;
      if not cdsEve.IsEmpty then  {Erro: Aqui fica sempre vazio}
      begin
        cdsEve.First;
        while not cdsEve.Eof do
        begin
          mEvento := cdsEve.FieldByName('EVENTO').AsInteger;
          if cdsEve.FieldByName('VALOR').AsCurrency <> 0 then
             nValor := cdsEve.FieldByName('VALOR').AsCurrency
          else
             nValor := cdsEve.FieldByName('VALOR').AsCurrency * nSal_Hora;

          cdsEvn.Append;
          cdsEvn.FieldByName('CHAPA').AsInteger  := mChapa;
          cdsEvn.FieldByName('EVENTO').AsInteger  := mEvento;
          cdsEvn.FieldByName('VALOR').AsCurrency := nValor;

          cdsEvn.Post;
          if cdsEvn.ApplyUpdates(0) <> 0 then
            cdsEvn.CancelUpdates;

          cdsEve.Next;

        end;
      end;
      cdsFuncionario.Next;

    end;
    cdsFuncionario.EnableControls;

  end;

end;






Responder

Gostei + 0

20/08/2010

Wesley Yamazack

Olá amigo,

Seguinte você havia me dito que eram 3 tabelas

cdsFuncionario
cdsEve
Onde esta a outra tabela ?

Segundo ponto :

      cdsEve.Close; //Adicione o Close para ver se resolve
      cdsEve.FetchParams;
      cdsEve.Params.ParamByName('CHAPA').AsInteger := mChapa;
      cdsEve.Open;
      ShowMessage('Valor cdsEve : ' + IntToStr(cdsEve.Params.ParamByName('CHAPA').AsInteger) +#13 +
                  'Valor mChapa : ' + IntToStr(mChapa)); {Adicione este ShowMessage para poder ver os valores que estão sendo armazenados}
      if not cdsEve.IsEmpty then  {Erro: Aqui fica sempre vazio}

A única explicação é que o Parametro Chapa, na hora de filtrar não existe o valor mCHapa, para ele estar sempre IsEmpty.

Um abraço,

Wesley Y
Responder

Gostei + 0

20/08/2010

Francisco Rodrigues

Olá, amigo.

Adicionando o cdsEve.Close, como você sugeriu, resolveu.

Quanto a 3ª tabela, é cdsEvn, onde gravo o resultado do processamento. Então,

cdsFuncionario - Tabela 1
cdsEve - Tabela 2
cdsEvn - Tabela 3

Fiz esta rotina enquanto aguardava a sua resposta. Não sei se como estou fazendo está correto ou, se de outra forma ficaria melhor. De certa forma estou fazendo como fazia no bom e velho clipper. Desculpe-me, pelas minhas dúvidas de iniciante, mas,  as suas dicas são muito importantes para ver se estou fazendo certo, já que vou aplicar isso em outros programas.

Um abraço,

Francisco Rodrigues

Responder

Gostei + 0

20/08/2010

Wesley Yamazack

Francisco,

O que é mais gratificante neste ramo, ou em qualquer outra, é ajudar pessoas, sejam iniciantes, intermediários, ou avançados, afinal ninguém sabe tudo. Não me peça desculpas por suas dúvidas iniciantes, estamos aqui para lhe ajudar em qualquer situação.

Qualquer dúvida estamos aqui.

Dica : Veja também se consegue assistir algumas vídeo aulas de Delphi, veja os padrões e as formas com que o pessoal trabalha nas vídeos, isso é muito importante para conhecimento. Particularmente, quando estava iniciando, comecei com umas vídeos do Rodrigo Carreiro, muito boas por sinal.

Um abraço

Wesley Y
Responder

Gostei + 0

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

Aceitar