
_Créditos das imagens: ChatGPT
Em 2025 ainda existe muito código Legado AdvPL que pode ser otimizado.
Como tornar o código **ADVPL mais rápido, limpo e profissional** — com **exemplos fictícios**, dicas práticas e **boas práticas que todo mundo pode (e deveria!) adotar**.
Vamos aos 5 pilares de hoje:
1. 🔁 **Evite chamadas repetidas em loops**
2. 🧠 **Cacheie o que for constante (Cache preditivo: + static/local)**
3. 🛡️ **Use `local` ao invés de `private`**
4. 🔁 **Escreva `while` que você entende de primeira**
5. 🎯 **Resolve o campo dinâmico uma vez só***
6. 🧠 **Pense como o interpretador pensa**
---
## 1. O Vilão dos Loops: "Ei, função, posso entrar?"
```advpl
// Exemplo fictício: 1000 pedidos
For nI := 1 To 1000
if SC5->C5_FILIAL==xFilial("SC5") // 1000 chamadas Empilhando e Desempilhando!
...
endif
Next
```
O que acontece?
A cada iteração, o ADVPL:
Empilha o estado
Chama xFilial()
Desempilha
1000 vezes = 1000 viagens de elevador
para que, para obter um valor constante que não mudará durante o laço.
**Solução:**
```advpl
local cSC5Filial := xFilial("SC5") // 1 vez só!
For nI := 1 To 1000
if SC5->C5_FILIAL==cSC5Filial // 1000 chamadas Lendo uma constante!
...
endif
Next
```
> **Ganho**: até **15% mais rápido**.
---
## 2. Cache com `static` – "Já sei disso!"
```advpl
static lIsUnix := IsSrvUnix()
```
> `static` = **post-it na geladeira**: cola uma vez, usa sempre.
---
## 3. `private` vs `local`: Escopo Seguro
```advpl
// Ruim: vaza e pode ser alterado
private cCliente := "ACME"
// Bom: isolado e rápido
local cCliente := "ACME"
```
> `local` = **caixa-forte**: só você abre.
---
## 4. O Monstro do `while !(alias)->(Eof())` – Herança dos Padrões
### Versão herdada (confusa e lenta):
```advpl
while !(cAlias)->(Eof()) .and. (cAlias)->FILIAL==xFilial(cAlias) .AND. (cAlias)->FIELD1 == "X" .AND. (cAlias)->FIELD2 == "Y"
// o que eu estou negando mesmo?
(cAlias)->(DbSkip())
enddo
```
### Problemas:
- **`!(alias)->(Eof())`** → "não não é fim" → **dupla negação**
- **`(cAlias)->`** repetido **3x por linha**
- **Não se vê o alias principal de cara**
- **Mais lento**: o interpretador precisa avaliar o alias toda vez
---
### Versão clara, rápida e profissional:
```advpl
cAliasFilial:=xFilial(cAlias)
while (cAlias)->(!Eof() .and. FILIAL==cAliasFilial .AND. FIELD1 == "X" .and. FIELD2 == "Y")
(cAlias)->(DbSkip())
enddo
```
### Melhorias:
| Antes | Depois | Ganho |
|-------------------------------------|--------------------------------------------|------------------------------------------------------|
| `!(cAlias)->(Eof())` | `(cAlias)->(!Eof())` | **Clareza + velocidade** |
| `(cAlias)->FIELD1+(cAlias)->FIELD2` | `(cAlias)->(FIELD1+FIELD2)` | **Menos digitação + menos avaliação + legibilidade** |
> **Regras de ouro**:
>> **Use o Operador ! junto ao que você quer negar. Torna o código mais legível. Ex. !Eof() e não !(cAlias)->(Eof()) Tem um caminhão de distância aqui.**
>> **Se o alias já está posicionado, use `->` só no `while`. Dentro do bloco, use campos diretos. Ex.: (cAlias)->(FIELD1,FIELD2,FIELDN)**
---
### Exemplo completo (fictício):
```advpl
// Posiciona no alias
(cAlias)->(DbSetOrder(1))
(cAlias)->(DbSeek(cChave))
// Loop limpo e rápido
while (cAlias)->(!Eof() .and. PEDIDO == cPedido .and. STATUS $ "AB")
ProcessaItem()
(cAlias)->(DbSkip())
enddo
```
---
## 5. Campo Dinâmico: FieldPos() + FieldGet()
```advpl// Exemplo: volumes em campos F2_VOLUME1, F2_VOLUME2...
cScan := "1"
While ( !Empty(cScan) )
cEspecie := Upper(FieldGet(FieldPos("F2_ESPECI"+cScan)))
If !Empty(cEspecie)
nScan := aScan(aEspVol,{|x| x[1] == cEspecie})
If ( nScan==0 )
aadd(aEspVol,{ cEspecie, FieldGet(FieldPos("F2_VOLUME"+cScan)) , SF2->F2_PLIQUI , SF2->F2_PBRUTO})
Else
aEspVol[nScan][2] += FieldGet(FieldPos("F2_VOLUME"+cScan))
EndIf
EndIf
cScan := Soma1(cScan,1)
If ( FieldPos("F2_ESPECI"+cScan) == 0 )
cScan := ""
EndIf
EndDo
```
Otimizado:
```advpl
cScan:="1"
while ((nF2Scan:=SF2->(FieldPos("F2_ESPECI"+cScan)))>0)
cEspecie:=SF2->(FieldGet(nF2Scan))
If !Empty(cEspecie)
nScan:=aScan(aEspVol,{|x| x[1] == cEspecie})
If (nScan==0)
SF2->(aadd(aEspVol,{cEspecie,FieldGet(FieldPos("F2_VOLUME"+cScan)),F2_PLIQUI,F2_PBRUTO}))
Else
aEspVol[nScan][2] += SF2->(FieldGet(FieldPos("F2_VOLUME"+cScan)))
EndIf
EndIf
cScan:=__Soma1(cScan)
EndDo
```
### Melhorias:
Menos código, menos chamadas, mais velocidade.
> **Regras de ouro**:
>> **Resolva o campo Dinâmico apenas uma vez**
---
## 6. Checklist Rápido (Cole na sua mesa!)
```advpl
[ ] xFilial() está FORA de loops?
[ ] Usei LOCAL ao invés de PRIVATE?
[ ] Cacheei com STATIC o que é constante?
[ ] FieldPos() está em variável (nPos)?
[ ] Usei __Soma1() em vez de Soma1()?
[ ] Evitei funções "leves" e que retornam constantes dentro de loops?
[ ] while usa (alias)->(!Eof()) e não !(alias)->(Eof())?
[ ] Dentro do while, uso campos diretos (sem (alias)->)?
[ ] Testei com 100+ registros?
```
---
## Exemplos Práticos para Copiar e Colar
```advpl
// 1. Cache de filial
local cSC5Filial := xFilial("SC5")
// 2. Cache de ambiente
static lWindows := !IsSrvUnix()
// 3. Loop limpo e rápido
while (cAlias)->(!Eof() .and. STATUS == "P")
(cAlias)->(DbSkip())
enddo
// 4. Campo dinâmico otimizado
local cSeq := "1"
while ((nPos := FieldPos("F2_VOLUME"+cSeq))) > 0
nTotal += FieldGet(nPos)
cSeq := __Soma1(cSeq)
enddo
```
---
## Dica Final: Seja o Exemplo
> Muitos códigos "padrão" (de qualquer origem) têm **hábitos antigos**.
> Mas **você não precisa herdar o que não presta**.
**Escreva como se alguém fosse ler amanhã.**
**Escreva como se fosse rodar em 10.000 registros.**
> **Um bom código não é só funcional — é rápido, claro e fácil de entender.**
---
## Conclusão
Pequenas mudanças = **grandes resultados**:
- **Menos chamadas** → mais velocidade
- **Menos `private`** → menos bugs
- **Menos `(alias)->`** → mais clareza
- **Mais `local`, `static` e `!Eof()`** → mais profissionalismo
> **Você não precisa reescrever tudo. Só precisa melhorar uma linha por vez.**
---
**Quer mais?**
> **Mande um `while` confuso do seu código** (pode ser fictício!) e eu mostro **como deixar cristalino**.
---
Fique ligado!
*Naldo DJ – Seu parceiro em código limpo, rápido e eficaz.*
Torne-se um Sponsor:
🥊(дави)={0.5x[(Налдо)+(Алине)]}🥊
Comentários
Postar um comentário