Postagem em destaque
- Gerar link
- X
- Outros aplicativos
Protheus :: Otimizando o Relatório FINR550 ( Razonete de Contas Correntes )
- Chamadas de funções desnecesárias;
- Resolver xFilial();
- Prefixar os campos e funções de db com seus respectivos Alias;
- Resolver "Localização";
- Resolver compilação condicional;
- Retirar parte do código específica para CodeBase;
- Armazenar retorno de funções em variáveis locais e reaproveitá-las quando necessário;
- Substituir a chamada a MsSeek() por dbSeek(); e
- Retirar a parte de relatório personalizável (tReport).
Vamos ao que interessa:
1. Chamadas de funções desnecesárias
Notei que o código original possuia várias chamadas a dbSelectArea(
Notei que chamavam Abs(
Pude verificar que xFilial(
2. Resolver xFilial()
xFilial() é uma função em Advpl() para retornar a filial correte para uma determinada tabela conforme modo de acesso definido no dicionário de Tabelas ( o SX2). Se a Tabela estiver compartilhada entre filiais xFilial() retornará brancos, caso contrário, retornará a Filial armazenada na variável de ambiente setada com o conteúdo da filial correte. É uma péssima prática resolver xFilial() dentro de um laço, seja ele qual for ( While, For, etc.). Então para cada alias em que xFilial() precisava ser resolvido criei uma variável para esse fim e usei variável no lugar de xFilial como em:
Local cSA1Filial := xFilial("SA1")
Local cSA2Filial := xFilial("SA2")
Local cSE1Filial := xFilial("SE1")
Local cSE2Filial := xFilial("SE2")
Local cSE5Filial := xFilial("SE5")
Local cSX5Filial := xFilial("SX5")
e Depois usando:
While SE1->( !Eof() )
If mv_par18 == 1 // Seleciona clientes por conta contabil
SA1->( dbSeek(cSA1Filial+SE1->(E1_CLIENTE+E1_LOJA) ) )
If SA1->( A1_CONTA <> mv_par20 )
SE1->( dbSkip() )
Loop
Endif
Endif
ao ivés de
If mv_par18 == 1 .And. !(TcGetDb() $ "MSSQL/MSSQL7/ORACLE") // Seleciona clientes por conta contabil
dbSelectArea("SA1")
MsSeek(xFilial()+SE1->E1_CLIENTE+SE1->E1_LOJA)
If SA1->A1_CONTA <>A1_CONTA > mv_par20
dbSelectArea("SE1")
dbSkip()
Loop
Endif
Endif
3. Prefixar os campos e funções de db com seus respectivos Alias
Para evitar chamadas desnecessárias à função dbSelectArea(
Onde estava, por exemplo:
dbSelectArea("SE1")
IF E1_TIPO $ MVRECANT
dbSkip()
ENDIF
Alterei para
IF SE1->E1_TIPO $ MVRECANT
SE1->( dbSkip() )
EndIF
Onde estava:
dbSelectArea("SE1")
dbSetOrder(1)
Alterei para:
SE1->( dbSetOrder(1) )
Onde estava:
dbSelectArea("SE1")
...
dbSkip()
Alterei para:
SE1->( dbSkip() )
e assim por diante.
4. Resolver "Localização"
Para que testar se o País Local é o Brasil se sei que o código só será utilizado aqui. Então para deixa-lo mais enxuto e evitar testes desnecessários, retirei toda parte do código que não se referiam ao cPaisLoc == "BRA".
5. Resolver compilação condicional
Sabendo que o SGBD a ser utilizado seria o DB2, toda parte do código específica para CodeBase e/ou AS400() ou outro SGBD foi retirada.
6. Retirar parte do código específica para CodeBase
Idem ao item 5 e considerando que a parte retirada estava diretamente relacionada ao tratamento já dado à "View" retornada pela "Query".
7. Armazenar retorno de funções em variáveis locais e reaproveitá-las quando necessário
Tinha algo como:
nSaldoAtu -= ABS(cNomeArq->VALOR)
nTotDeb += ABS(cNomeArq->VALOR)
nTotDebG += ABS(cNomeArq->VALOR)
nSalAtuG -= ABS(cNomeArq->VALOR)
Oberve que ABS(cNomeArq->VALOR) era chamada 4 vezes para retornar o valor absoluto de um mesmo campo e armazena-la em variáveis diferentes. Imagine isso dentro de um Laço executado 1000 vezes. ABS seria executada 4000 vezes desnecessáriamente. Para solucionar o problema fiz o seguinte:
nABSValor := Abs(cNomeArq->VALOR)
nSaldoAtu -= nABSValor
nTotDeb += nABSValor
nTotDebG += nABSValor
nSalAtuG -= nABSValor
Observe que agora Abs(), se o laço for executado 1000 vezes só será executado 1000 vezes.
8. Substituir a chamada a MsSeek() por dbSeek(); e
MsSeek() é uma função "bufferizada" criada em Advpl para evitar o reposicionamento do "Ponteiro" do Banco de Dados quando este já estiver posicionado na chave que se deseja procurar. É útil, por exemplo, se usou a função de pesquisa dbSeek() para pesquisar e depois quer saber se o registro está posicionado evitando ter que pesquisa-lo novamente. Ai sim MsSeek() é útil, caso contrário é um desperdício, uma vez que MsSeek() faz vários tratamentos para verificar se a chave atual é a que procura e, se não for, irá chamar dbSeek() para posicionar.
9. Retirar a parte de relatório personalizável (tReport).
Considerando que o cliente não utiliza o FINR55o personalizável, a parte do código foi retirada para facilitar a manutenção do código.
Bem, é isso o que tinha a dizer sobre otimização do códgo FINR550 (baseado no código padrão). Para consultar na íntegra as alterações feitas no código e poder comparar com o original da microsiga utilizado como base para a otimização clique aqui
Utilize o apdiff ou outra ferramenta para comparar os códigos e visualizar as alterações.
Obs.: Sempre que for otimizar um código do padrão obtenha a última versão disponível junto a Totvs/Microsiga. Lembrando que a Totvs/Microsiga só disponibiliza os fontes de Relatórios.
[]s
иαldσ
- Gerar link
- X
- Outros aplicativos
Comentários
Postagens mais visitadas
BlackTDN :: RLeg ~ Desvendando a Função ParamBox
- Gerar link
- X
- Outros aplicativos
Protheus :: Chamando Funções do Menu Diretamente e sem a Necessidade de Login
- Gerar link
- X
- Outros aplicativos
Boa noite Naldo.
ResponderExcluirMuito bom, parabéns.
Att.,
Talvane (Arapiraca/AL)
Bom dia Naldo, teria como voce me enviar o fonte do FINR550 otimizado??
ResponderExcluirjfernandocv@gmail.com ou jfcvilela@sistemafieg.org.br
ResponderExcluirBoa tarde,
ResponderExcluirTeria como me enviar o fonte
cleberfiscal23@gmail.com