Sei sulla pagina 1di 4

Code blocks

Code block. Ame-o ou suporte-o, pois no possvel a vida sem ele no ADVPL.
O code block ou bloco de cdigo uma varivel especial de memria que contm um
pedao de cdigo compilado. Quando chamada por funes especficas, o cdigo
avaliado e um retorno gerado.
Exemplo:

nCount := 0
bCount := {|| nCount++ }
SA1->( dbEval(bCount) )
// nCount = nmero de registros na tabela SA1

O primeiro uso de um code block melhorar o cdigo evitando a redundncia.


No exemplo que segue o codblock recebe uma data como parmetro e retorna a mesma
data em formato texto com 2 digitos para o dia, 2 digitos para o ms e 4 digitos para o
ano.
Exemplo:
bData := {|d| strZero(day(d),2)+"/"+strZero(month(d),2)+"/"+strZero(year(d),4) }
cData := eval(bData,dDatabase)

O segundo uso para a reduo do tamanho do cdigo.


No exemplo abaixo feito o calculo de sugesto de quantidade com base na quantidade
da embalagem. Na primeira parte vemos como feito normalmente. Na segunda parte
vemos em code block a reduo do cdigo. Para o uso de mais de uma linha de cdigo
dentro do code block essas devem ser separadas por vrgula.
O que foi escrito assim:
nEmb := 0
nSug := 5
nQe := 2
nFator := nSug / nQe
IF nFator # int(nFator)
nDif := nFator - int(nFator)
nFator := (int(nFator) * nQe) + IIF(nDif >= 0.5 .Or. int(nFator)==0,nQe,0)
nEmb := nFator
ELSE
nEmb := nSug
ENDIF

Pode ser escrito assim:


nSug := 5
nQe := 2
nEmb := eval({|S,E| X:=S/E, IIF(X#int(X),(int(X)*E)+IIF(X-int(X)>=0.5.Or.
int(X)==0,E,0),S) },nSug,nQe)

Algumas funes especficas pedem o uso de code block, como a aSort.


A estrutura do codeblock tem partes fixas que devem ser respeitadas para que o
compilador entenda que se trata de um code block.
{|[lista de argumentos]| <lista comandos>}
Deve sempre iniciar com {. Na sequencia deve conter |[lista de argumentos]|. Se no
houverem argumentos dever estar como ||. Em sequencia vem os comandos que sero
executados e deve ser finalizado com }.
Os comandos devem ser encadeados com vrgula (,).

Funes para codeblocks


eval
EVAL(<bBloco>, [<Lista de Argumentos>]) --> ltimo valor do code block

Argumentos
<bBloco> o code block a ser avaliado.
<Lista de Argumentos> a lista de argumentos que ser enviada para o code block
antes dele ser avaliado.

Retorno
EVAL() retorna o valor da ltima expresso contida no code block. Um code block pode
retornar um valor de qualquer tipo.

Descrio
EVAL() uma funo para code block. Esta a funo mais bsica para avaliar um code
block.
O code block compilado juntamente com a compilao do cdigo. Entretanto ele pode
ser montado em tempo de execuo e compilado imediatamente atravs do uso de
macro (&).
Exemplo:
Este exemplo contm um code block que incrementa 1 a um argumento passado quando
este for avaliado:
bBlock := { |nArg| nArg + 1 }
? EVAL(bBlock, 1) // Retorna: 2

Este exemplo demonstra como compilar um code block em tempo de execuo usando
macro (&):
bBlock := &("{ |nArg| nArg + 1 }")
? EVAL(bBlock, 1) // Retorna: 2

aEval
?
1 AEVAL(<aArray>,<bBloco>,[<nInicio>],[<nQtde>]) --> aArray

Argumentos
<aArray> a matriz que ser utilizada na avaliao.
<bBloco> o code block que ser executado para cada elemento da matriz.
<nInicio> o elemento de incio. Se no for especificado, ser assumido como padro o
valor 1.
<nQtde> o nmero de elementos a serem processados desde o <nInicio>. Se no for
especificado ser assumida a quantidade total de elementos da matriz.

Retorno
AEVAL() retorna uma referncia a matriz <aArray>.

Descrio
AEVAL() uma funo de matriz que avalia um code block uma vez para cada elemento
da matriz, passando como parmetros do code block o elemento avaliado e o ndice
deste elemento. Todos os elementos antes do <nInicio> e depois do <nQtde> sero
ignorados.
AEVAL() no determina o tipo de dado passado como parmetro para o code block. Est
implcito que o code block reconhece o tipo de dado de cada elemento.
Exemplo:
Este exemplo usa a AEVAL() para imprimir uma matriz com os nomes de arquivos e
tamanhos retornados pela funo DIRECTORY():
?
1#include "Directry.ch"
2LOCAL aFiles := DIRECTORY("*.dbf"), nTotal := 0
AEVAL(aFiles,{|aDbfFile| QOUT(PADR(aDbfFile[F_NAME],10),
3aDbfFile[F_SIZE]),nTotal+=aDbfFile[F_SIZE])})
4? "Total Bytes:", nTotal
Este exemplo usa a AEVAL() para construir uma lista consistindo de itens selecionados
de uma matriz multidimensional:
?
1 #include "Directry.ch"
2 LOCAL aFiles := DIRECTORY("*.dbf"), aNames := {}
3 AEVAL(aFiles,{ | file | AADD(aNames, file[F_NAME]) })
Este exemplo muda o contedo do elemento da matriz de acordo com a condio.
Observe o uso dos parmetros do code block:
?
1 LOCAL aArray[6]

2 AFILL(aArray,"old")
3 AEVAL(aArray,{|cValue,nIndex| IF(cValue == "old",aArray[nIndex] := "new")})

dbEval
?
1 DBEVAL(<bBloco>,[<bFor>],[<bWhile>],[<nNextRecords>],[<nRecord>],[<lRest>]) --> NIL

Argumentos
<bBloco> o code block que ser avaliado para cada registro processado.
<bFor> uma condio opcional que ser avaliada como um code block para cada
registro no escopo. Se o retorno de <bFor> for verdadeiro (.T.) o <bBloco> ser
avalidado.
<bWhile> uma condio opcional que ser avaliada como um code block para cada
registro. O processamento dos registros ser encerrado caso o retorno deste code block
seja falso (.F.)
<nNextRecords> um nmero opcional que especifica o nmero de registros que
dever ser processado desde o incio.
<nRecord> um nmero opcional que especifica o registro a ser processado. Se
espeficiado, o <bBloco> ser avalidado somente para o registro determinado.
<lRest> um valor lgico que determina se o <bBloco> ser avaliado a partir do
registro corrente (.T.) ou se para todos os registros na tabela (.F.).

Retorno
DBEVAL() sempre retorna NIL.

Descrio
DBEVAL() uma funo de tabelas de dados que avalia um code block para cada
registro na rea de trabalho corrente que combinam com o escopo ou com a condio
determinada. O processamento continuar at que <bWhile> retorne falso (.F.) ou
chegue o final da tabela (EOF()).
Exemplo
Preencher uma array com o cdigo de nome de todos os clientes da base de dados.
?
1 aCli := {}
2
3 SA1->( dbGoTop() )
4 SA1->( dbEval(aAdd(aCli,{A1_COD,A1_NOME})) )

Potrebbero piacerti anche