Curso de dbExpress e DataSnap
Parte IX – InternalCalc
Este exemplo mostra como utilizar o recurso de InternalCalc em ClientDataSets, utilizado para otimizar campos calculados em memória. Faremos um exemplo que vai compara campos calculados tradicionais com InternalCalcs.
O evento OnCalcFields de um DataSet é uma “armadilha”. Ele é, obviamente, utilizado para implementar campos calculados. O que poucos sabem é que esse evento é chamado a todo o momento, por exemplo, quando um valor de um campo muda, mesmo que esse campo não afete o valor do cálculo. Se você escrever um código mais complexo nesse evento, como uma consulta ao banco de dados para obter um valor a ser usado no cálculo (o que considero um “suicídio”), verá que a performance da sua aplicação cairá consideravelmente.
A solução é criar o campo como InternalCalc ao invés de Calculated. A seguir, no evento OnCalcFields, testamos se o estado (State) do DataSet é dsInternalCalc antes de fazermos o processamento, como no exemplo:
if ClientDataSet1.State = dsInternalCalc then
ClientDataSet1CAMPO.Value := ...
Com isso, o código será executado uma única vez para cada registro, por exemplo quando há uma navegação ou quando um Post é chamado.
Para ver um exemplo prático, coloque um ClientDataSet no formulário e um DataSource. Dê um duplo clique no componente e clique de direita no editor, escolhendo New Field (vamos criar um DataSet de memória neste exemplo).
Adicione o campo NUM1 como mostrado a seguir:
Figura 1.
Adicione o campo NUM2 como mostrado a seguir:
Figura 2.
Adicione o campo DUMMY como mostrado a seguir:
Figura 3.
Adicione o campo CALCULATED como mostrado a seguir (observe que ele será um campo calculado):
Figura 4.
Adicione o campo INTERNALCALC como mostrado a seguir (observe que ele será um campo InternalCalc):
Figura 5.
Arraste os campos criados para o formulário, para que sejam criados os controles Data-Aware. Coloque também um DBNavigator apontando para o DataSource.
Seu formulário deve estar semelhante ao mostrado a seguir:
Figura 6.
Neste exemplo, vamos processar o cálculo de NUM1 e NUM2 e atribuir a ambos os campos calculados, sem cada um é de um tipo (um internal e outro não). Para isso, no evento OnCalcFields do ClientDataSet, digitamos:
procedure TFrmMain.ClientDataSet1CalcFields(DataSet: TDataSet);
begin
inherited;
{ calculado normal}
ClientDataSet1CALCULATED.AsInteger :=
ClientDataSet1NUM1.AsInteger +
ClientDataSet1NUM2.AsInteger;
{internal calc}
if ClientDataSet1.State = dsInternalCalc then
ClientDataSet1INTERNALCALC.AsInteger :=
ClientDataSet1NUM1.AsInteger +
ClientDataSet1NUM2.AsInteger;
end;
Execute a aplicação e digite dois valores, para NUM1 e NUM2:
Figura 7.
Para ver o campo em ação, coloque dois Brekpoints no código conforme mostrado a seguir:
Figura 8.
Agora digite um valor qualquer no campo DUMMY, observe que ele não afeta o cálculo, pois não serve para nada (não participa da soma). Mesmo assim, note que o código do campo calculado será executado, mesmo que a soma não seja afetada por DUMMY.
O processo não é o mesmo para o campo InternalCalc (no segundo breakpoint), ele será executado somente uma vez para fazer a soma, quando você der o Post no DataSet (mais otimizado).
Figura 9.
Download
dbExpress, DataSnap e ClientDataSet: Técnicas Avançadas
Para mais informações sobre acesso a dados no Delphi e técnicas avançadas, sugiro a leitura do meu livro, “Delphi: Programação para Banco de Dados e Web”, como apoio para o aprendizado das tecnologias. Na obra mostro várias técnicas introdutórios e avançadas de desenvolvimento com ClientDataSet, dbExpress e DataSnap (multicamadas, incluindo SOAP e COM+). Para mais informações, consulte o link http://www.clubedelphi.net/guinther
Leia todos artigos da série
- Curso de dbExpress e DataSnap
- Curso de dbExpress e DataSnap - Parte II
- Curso de dbExpress e DataSnap - Parte III
- Curso de dbExpress e DataSnap - Parte IV
- Curso de dbExpress e DataSnap - Parte V
- Curso de dbExpress e DataSnap - Parte VI
- Curso de dbExpress e DataSnap - Parte VII
- Curso de dbExpress e DataSnap - Parte VIII
- Curso de dbExpress e DataSnap - Parte IX
- Curso de dbExpress e DataSnap - Parte X
- Curso de dbExpress e DataSnap - Parte XI
- Curso de dbExpress e DataSnap - Parte XII
- Curso de dbExpress e DataSnap - Parte XIII
- Curso de dbExpress e DataSnap - Parte XIV
- Curso de dbExpress e DataSnap - Parte XV
- Curso de dbExpress e DataSnap - Parte XVI
- Curso de dbExpress e DataSnap - Parte XVII
- Curso de dbExpress e DataSnap - Parte XVIII
- Curso de dbExpress e DataSnap - Parte XIX
- Curso de dbExpress e DataSnap - Parte XX
- Curso de dbExpress e DataSnap - Parte XXI
- Curso de dbExpress e DataSnap - Parte XXII
- Curso de dbExpress e DataSnap - Parte XXIII
- Curso de dbExpress e DataSnap - Parte XXIV
- Curso de dbExpress e DataSnap - Parte XXV
- Curso de dbExpress e DataSnap - Parte XXVI
- Curso de dbExpress e DataSnap - Parte XXVII
- Curso de dbExpress e DataSnap - Parte XXVIII
- Curso de dbExpress e DataSnap - Parte XXIX
- Curso de dbExpress e DataSnap - Parte XXX