Evento oncalfields X Internalcalc
Pessoal do portal, li uma matéria do Guinter Pauli na revista clube delphi edição número 54 no artigo dicas sobre dbexpress, datasnap e clientdataset pergunta número 13 pagina 44 sobre internlcalc. Diz o artigo que usar o evento oncalcfields para fazer pesquisa no banco de dados é um suícidio é o meu caso, faço uma pesquisa na tabela
de produtos no momento que o usuario digita o código do produto para trazer o nome do produto,isto numa grid tela de digitação de pedidos. Fiz uma alteração e coloquei esta pesquisa no evento onvalidate da query, resultado não mostra o nome do produto.
A minha pergunta é a seguinte em qual evento da query é o ideal para se fazer esta
pesquisa?
Segue abaixo um exemplo da minha query
with TSQLQuery.Create(nil) do
begin
try
SQLConnection := FrmPrincipalSGCAdm.SQLConnection1;
Sql.Add(´SELECT PROD_DESCRICAOPRODUTO FROM PRODUTO´);
Sql.Add(´WHERE EMP_CODIGO =´ +IntToStr(FrmPrincipalSGCAdm.CodEmpresa));
Sql.Add(´AND PROD_CODIGO = ´+IntToStr(cdsDetalhePROD_CODIGO.AsInteger));
Open;
cdsDetalheDescProd.AsString := Fields[0].AsString;
finally
Free;
end;
end;
Obs. O campo DescrProd é um campo calculado na query
Grato pela atenção.
´Com Cristo no barco da nossa vida, tudo vai muito bem´
de produtos no momento que o usuario digita o código do produto para trazer o nome do produto,isto numa grid tela de digitação de pedidos. Fiz uma alteração e coloquei esta pesquisa no evento onvalidate da query, resultado não mostra o nome do produto.
A minha pergunta é a seguinte em qual evento da query é o ideal para se fazer esta
pesquisa?
Segue abaixo um exemplo da minha query
with TSQLQuery.Create(nil) do
begin
try
SQLConnection := FrmPrincipalSGCAdm.SQLConnection1;
Sql.Add(´SELECT PROD_DESCRICAOPRODUTO FROM PRODUTO´);
Sql.Add(´WHERE EMP_CODIGO =´ +IntToStr(FrmPrincipalSGCAdm.CodEmpresa));
Sql.Add(´AND PROD_CODIGO = ´+IntToStr(cdsDetalhePROD_CODIGO.AsInteger));
Open;
cdsDetalheDescProd.AsString := Fields[0].AsString;
finally
Free;
end;
end;
Obs. O campo DescrProd é um campo calculado na query
Grato pela atenção.
´Com Cristo no barco da nossa vida, tudo vai muito bem´
Placido
Curtidas 0
Respostas
Bruno_fantin
16/11/2004
Esquece o que o fulano lá disse...
Deixa no OnCalcField mesmo...
É só você saber controlar certinho as buscas no banco que funciona 10 e rapidinho...
Deixa no OnCalcField mesmo...
É só você saber controlar certinho as buscas no banco que funciona 10 e rapidinho...
GOSTEI 0
Placido
16/11/2004
Bruno obrigado pela dica, mas você poderia me ajudar a fazer este controle? rodo a aplicação no passo a passo qualquer alteração que o cliente faça o evento oncalcfields é acionado e consequentemente os
dentro dele tambem. Como que eu faria este controle??
Grato
dentro dele tambem. Como que eu faria este controle??
Grato
GOSTEI 0
Bruno_fantin
16/11/2004
É a segunda pessoa que me pergunta isso... Para a primeira eu respondi assim... Se tiver alguma coisa que não faz sentindo não se preocupe... O texto foi copiado e colado...
Teoricamente a técnica é assim...
Você tem um campo chamado idcliente... e clica um calcfield (usando o editor
de campos do dataset) chamado nomecliente...
No evento oncalfields você dar um select no banco buscando o nome do cliente
usando o campo idlciente e salva o resultado no campo nomecliente....
Na grid você manda exibir o campo nomecliente...
Só tem um problema... Como oncalcfield é chamado sempre que um campo é
alterado você pode acabar fazendo muitos acessos ao banco tornando lento a
aplicação...
Em muito casos (aonde a descrição nunca muda) você pode verificar o conteúdo
do calcfields e só consultar o banco quando o mesmo for vazio...
Se esse não for o seu caso (caso aonde pode acontecer de a descrição
mudar)... O ideal é criar uma tabela de memória com os resultados já obtidos
e antes de consultar o banco você consulta essa tabela...
Em casos extremos (caso aonde a descrição muda a casa instante) você vai ter
que consultar toda hora... Não tem muito o que fazer.... Apesar que nesse
caso os lookup sofrem do mesmo problema...
Falou....
Teoricamente a técnica é assim...
Você tem um campo chamado idcliente... e clica um calcfield (usando o editor
de campos do dataset) chamado nomecliente...
No evento oncalfields você dar um select no banco buscando o nome do cliente
usando o campo idlciente e salva o resultado no campo nomecliente....
Na grid você manda exibir o campo nomecliente...
Só tem um problema... Como oncalcfield é chamado sempre que um campo é
alterado você pode acabar fazendo muitos acessos ao banco tornando lento a
aplicação...
Em muito casos (aonde a descrição nunca muda) você pode verificar o conteúdo
do calcfields e só consultar o banco quando o mesmo for vazio...
Se esse não for o seu caso (caso aonde pode acontecer de a descrição
mudar)... O ideal é criar uma tabela de memória com os resultados já obtidos
e antes de consultar o banco você consulta essa tabela...
Em casos extremos (caso aonde a descrição muda a casa instante) você vai ter
que consultar toda hora... Não tem muito o que fazer.... Apesar que nesse
caso os lookup sofrem do mesmo problema...
Falou....
GOSTEI 0
Placido
16/11/2004
Bruno obrigado pela dedicação em tentar a resolver este problema, mas percebi que o assunto é muito polêminco, no meu caso o nome do produto
não muda realmente, o usuário digita o código do produto, pesquiso na tabela produto e mostro a descrição do produto.
Mas considerei uma observação dele fiz o teste e fuiniona ex.
O usuário digita o campo qtde e valor unitario, calculo o valor total
e mostro este total para o usuario, fiz o exemplo que ele deu na revista criando o campo total como internalcal e não como calculado e funcionou direitinho, e o calculo do valor total foi feito somente uma vez e não várias vezes como no evento oncalcfields.
Grato
não muda realmente, o usuário digita o código do produto, pesquiso na tabela produto e mostro a descrição do produto.
Mas considerei uma observação dele fiz o teste e fuiniona ex.
O usuário digita o campo qtde e valor unitario, calculo o valor total
e mostro este total para o usuario, fiz o exemplo que ele deu na revista criando o campo total como internalcal e não como calculado e funcionou direitinho, e o calculo do valor total foi feito somente uma vez e não várias vezes como no evento oncalcfields.
Grato
GOSTEI 0
Placido
16/11/2004
Bruno obrigado pela dedicação em tentar a resolver este problema, mas percebi que o assunto é muito polêminco, no meu caso o nome do produto
não muda realmente, o usuário digita o código do produto, pesquiso na tabela produto e mostro a descrição do produto.
Mas considerei uma observação dele fiz o teste e fuiniona ex.
O usuário digita o campo qtde e valor unitario, calculo o valor total
e mostro este total para o usuario, fiz o exemplo que ele deu na revista criando o campo total como internalcal e não como calculado e funcionou direitinho, e o calculo do valor total foi feito somente uma vez e não várias vezes como no evento oncalcfields. Sendo assim procede a observação dele que fazer pesquisa numa tabela neste evento não é o mais adequado.
Grato
GOSTEI 0
Gurc
16/11/2004
Placido,
Tive muitos problemas com programadores usando campos calculados e, indubitavelmente, é preferível não usá-los, neste ponto concordo com o Guinther. Não li a reportagem, mas, devemos tomar muito cuidado com campos calculados internamente. Certamente ele deve ter mencionado a função dos campos calculados internamente. Eles são calculados apenas uma vez e quando o DataSet é aberto, todos de uma vez.
Existem situações em que somos ´obrigados´ a usar o campo calculado, pois, não podemos colocar tudo em um simples SELECT. Nestes casos o SELECT ficaria extremamente lento, mas devemos tentar conseguir o máximo de resultado com eles. Quando isto não é possível, sim, devemos usar o campo calculado do delphi e, se a pesquisa não for retornar muitos regístros, usamos o internalcalc. Tudo deve ser medido. Em projetos muito grandes com uma massa muito volumosa de dados você aprende a tratar diversas situações desse tipo de performance. Preocupe-se sempre com isso e você não irá se arrepender. Campos calculados podem deixar uma pesquisa MUITO lenta. Tome cuidado.
Abraços,
Gustavo Royer Chaurais
Tive muitos problemas com programadores usando campos calculados e, indubitavelmente, é preferível não usá-los, neste ponto concordo com o Guinther. Não li a reportagem, mas, devemos tomar muito cuidado com campos calculados internamente. Certamente ele deve ter mencionado a função dos campos calculados internamente. Eles são calculados apenas uma vez e quando o DataSet é aberto, todos de uma vez.
Existem situações em que somos ´obrigados´ a usar o campo calculado, pois, não podemos colocar tudo em um simples SELECT. Nestes casos o SELECT ficaria extremamente lento, mas devemos tentar conseguir o máximo de resultado com eles. Quando isto não é possível, sim, devemos usar o campo calculado do delphi e, se a pesquisa não for retornar muitos regístros, usamos o internalcalc. Tudo deve ser medido. Em projetos muito grandes com uma massa muito volumosa de dados você aprende a tratar diversas situações desse tipo de performance. Preocupe-se sempre com isso e você não irá se arrepender. Campos calculados podem deixar uma pesquisa MUITO lenta. Tome cuidado.
Abraços,
Gustavo Royer Chaurais
GOSTEI 0
Placido
16/11/2004
Gustavo bom dia.
Gostei muito das sua observações, todas elas tem nexo, vou rever minha
programção.
Um abraço, fique com Deus.
Gostei muito das sua observações, todas elas tem nexo, vou rever minha
programção.
Um abraço, fique com Deus.
GOSTEI 0
Placido
16/11/2004
Segue abaixo um exemplo da minha query, a minha duvida está em que evento eu devo fazer a pesquisa para mostrar a descrição do produto.
Obs. na consulta o usuario digita o pedido e o sistema mostra a descrição do produto numa boa, mas quando estou fazendo uma inserção, não mostra a descrição do produto. Esta tela contem dados de uma tabela mestre detalhe, a tabela de itens do pedido esta numa grid.
SELECT PI.PED_NUMEROOPERACAO,
PI.PIT_QTDEVENDIDA,
PI.PIT_VALORUNITARIO,
PI.PIT_PERCENTUALDESCONTO,
PI.EMP_CODIGO,
PI.PIT_PERCENTUALIPI,
PI.PROD_CODIGO,
PI.PIT_QTDEMTS,
PI.QTDETOTAL,
PI.PROD_CODIGOBARRA,
PI.PIT_SEQUENCIA,
PRO.PROD_DESCRICAOPRODUTO
FROM PEDITENS PI
JOIN PRODUTO PRO ON (PI.EMP_CODIGO = PRO.EMP_CODIGO AND
PI.PROD_CODIGO = PRO.PROD_CODIGO)
WHERE PI.EMP_CODIGO= :EMP_CODIGO AND
PI.PED_NUMEROOPERACAO= :PED_NUMEROOPERACAO
:?: :?: :?: :!:
Grato
Plácido
Obs. na consulta o usuario digita o pedido e o sistema mostra a descrição do produto numa boa, mas quando estou fazendo uma inserção, não mostra a descrição do produto. Esta tela contem dados de uma tabela mestre detalhe, a tabela de itens do pedido esta numa grid.
SELECT PI.PED_NUMEROOPERACAO,
PI.PIT_QTDEVENDIDA,
PI.PIT_VALORUNITARIO,
PI.PIT_PERCENTUALDESCONTO,
PI.EMP_CODIGO,
PI.PIT_PERCENTUALIPI,
PI.PROD_CODIGO,
PI.PIT_QTDEMTS,
PI.QTDETOTAL,
PI.PROD_CODIGOBARRA,
PI.PIT_SEQUENCIA,
PRO.PROD_DESCRICAOPRODUTO
FROM PEDITENS PI
JOIN PRODUTO PRO ON (PI.EMP_CODIGO = PRO.EMP_CODIGO AND
PI.PROD_CODIGO = PRO.PROD_CODIGO)
WHERE PI.EMP_CODIGO= :EMP_CODIGO AND
PI.PED_NUMEROOPERACAO= :PED_NUMEROOPERACAO
:?: :?: :?: :!:
Grato
Plácido
GOSTEI 0
Placido
16/11/2004
Estou aguardando discas para resolver este meu problema.
Grato
Grato
GOSTEI 0