Você está na página 1de 27

Programao Bsica em AdvPl ( padro xBase/CodBase ) Curso 1

A linguagem AdvPl um Super-Conjunto da linguagem padro xBase/CodBase e evoluiu partir do padro do Clipper 5.3 e das bibliotecas do FiveWin. Ela comporta quase todos os comandos e funes utilizados no Clipper 5.3 e no FiveWin. O AdvPl a liguagem utilizada pela Microsiga para o desenvolmento do ERP e no desenvolvimento de rotinas especficas nas empresas usurias desse sistema. Os elementos sintticos que formam as instrues de programao em AdvPl podem ser divididas nos seguintes grupos: instrues, comandos, diretivas, funes, classes, mtodos, constantes , campos e operadores. Instrues e Comandos: As instrues so elementos fixos da linguagem, que lidam com afirmaes e com o controle do programa; c := IF( a > b , a , b ) While ( ( cAlias )->( !Eof() ) //... mais instrues ( cAlias )->( dbSkip() ) End While nLoops := 10 For nLoop := 1 To nLoops //... mais instrues Next nLoop ... J os comandos, representam o conjunto de tipos de instrues da linguagem que no so nem rotinas nem chamadas de funo e nem atribuies. Replace cCampo1 With Conteudo do Campo 1,; cCampo2 Whit Conteudo do Campo 2

Obs.: Como padro, um caractere de final de linha encerra uma instruo. Para continuar na outra linha, use o caractere de ponto-e-vrgula.

Use cTable New Via DBFCDX Copy To cNewTable Via DBFCDX

Totas as instrues so fixadas em determinada verso da linguagem e, todos os comandos so convertidos pelo pr-processador em chamadas de funes e atribuies. Onde: Replace cCampo1 With Conteudo do Campo 1,; cCampo2 Whit Conteudo do Campo 2

ser convertido pelo pr-processador em : _FIELD->cCampo1 := "Conteudo do Campo1"; _FIELD->cCampo2 := "Conteudo do Campo2 Use cTable New Via DBFCDX ser convertido pelo pr-processador em : dbUseArea( .T., "DBFCDX", "cTable",, if(.F. .OR. .F., !.F., NIL), .F. ) Copy To cNewTable Via DBFCDX ser convertido pelo pr-processador em : __dbCopy( "cNewTable", { },,,,, .F., "DBFCDX" ) No AdvPl so permitidas vrias instrues numa linha ( separando-as com um caracter de ponto-e-vrgula ) como em: i := 0 ; j := 1 ; a := c ; d := 99 //... Esse recurso interessante ao criar macros do compilador e blocos de codificao, mas se utilizado em todo lugar prejudica a legibilidade do programa. Comentrios: O compilador Advpl ignora as linhas em branco e a endentao. Ambas tornam o programas mais legvel e, devemos abrir mo deste recurso para tornar os programas mais legveis. Os comentrios tambm so ignorados pelo compilador. Na realidade, as linhas em branco, a identao e os comentrios nos programas so tratados pelo pr-processador. No AdvPl programa: so permitidas as seguintes formas de se comentar um

//Para efetuar o comentrio em uma linha. ( Tudo o que estiver direita //das ( // ) ser considerado como um comentrio.
Obs.: Pode-se utilizar o sinal de * ou && no inicio da frase para se efetuar o comentrio de uma nica linha. Deve-se escolher uma por padro e ser coerente.

/* Para efefuar o comentrio em mais de uma linha. ( Tudo o que estiver entre ( /* e */ ) ser considerado como comentrio. */
Obs.: para facilitar a utilizao do modelo de comentrio acima utilize /*/ para abrir o comentrio e /*/ para garantir que um comentrio nunca deixar de ser fechado.

altamente recomendvel que as rotinas importantes e de utilidade sejam comentadas com um bloco de abertura. Devero ser especificados: o propsito da rotina, os tipos de parmetros e, se for uma funo que retorna algo, o valor de retorno. /*/ Funo Autor Data Verso SomaUm( nLast ) nLast /*/
Obs.: A melhor documentao de um programa o prprio programa ( desde que bem escrito e seguindo-se as regras que foram estabelecidas )

: : : :

SomaUm( nLast ) Marinaldo de Jesus 18/02/2005 1

-> Retorna valor de nLast incrementado de 1 -> Valor onde dever ser somado um

Constantes: Constantes so Valores predefinidos que no mudam durante o programa. Elas podem ser strings de caracteres, nmeros, valores lgicos, blocos de codificao, arrays ( vetores ). Ex.: pressione uma tecla para continuar 15 1970.15 .T. { || MyTest() } {Domingo,Segunda,Tera,Quarta,Quinta,Sexta,Sbado} No Advpl, as constantes numrias so sempre decimais. No so suportados outros sistemas de nmeros nem notao cientfica.

No h diferena entre caracteres isolados a e strings Isso uma string. Uma string simplesmente um ou mais caracteres. Para definir uma constante do tipo string maior que uma linha, continue-a com um ponto e vrgula e junte as partes com o operador + Ex.: esta string ser continuada+; na prxima linha

No AdvPl no existem constantes de datas. Ser necessrio contru-las partir de uma string de caracteres e com a funo CToD() como no exemplo: Ex.: Ctod( 18/02/2005) O resultado ser uma data, mas ela no ser realmente uma constante. Pois o sistema na execuo a avaliar. As constantes so sempre avaliadas no momento da compilao. Comandos vs Literais: Alguns comandos em AdvPl exigem argumentos literais. Uma literal uma sequancia de caracteres interpretada literalmente. No ser possvel usar uma constante ou expresso no lugar da literal. Ex.: Use cTable No exemplo acima, cTable uma literal. Ela interpretado literalmente, no como uma varivel. O pr-compilador ir transformar a Literal em uma string de caracter da seguinte forma: dbUseArea( .F.,, "cTable",, if(.F. .OR. .F., !.F., NIL), .F. ) Para que cTable no seja considerado como uma literal mas sim como uma varivel coloque-a entre parenteses como em: Use ( cTable ) Que o pr-processador converter em: dbUseArea( .F.,, ( cTable ),, if(.F. .OR. .F., !.F., NIL), .F. )

Variveis: No Advpl, as regras para a nomeao de identificadores so parecidas com as das linguagens tpicas de computadores. A nomeao poder ser iniciada com uma letra ou um caractere de sublinhado e podero conter letras, sublinhados e dgitos. Para manter compatibilidade com o legado foi mantida a limitao de dez primeiros caracteres como significativos. Por isso, deve-se ter muito cuidado com nomes extensos. Se for utilizar nomes extensos lembre-se que atualmente apenas os dez primeiros caracteres sero considerados mas, se declarar uma varivel com nome extenso, utilize-a da forma como foi declarada para que, se um dia a limitao de dez caracteres foi modificada, no seja necessrio estar modificando os programas. A restrio em dez caracteres pode ser fonte de defeitos ardilosos. Por exemplo, as seguintes variveis: cSNome_do_Pai cSNome_do_Avo Sero consideradas idnticas. A truncagem dos identificadores longos conseqncia do tamanho fixo dos nomes nas tabelas mantidas pelo compilador e pelo pr-processador, portanto os nomes completos dos identificadores so passados sem alterao para o pr-processador. Tenha cuidado, esse tipo de erro muito difcil de se depurar. O estilo de codificao recomendada usar letras masculas para destacar partes significativas de um identificador ao inves de usar sublinhados para serpar-las. Dessa forma ser possvel criar identificadores menores, sem afetar a legibilidade. Como em: cSNomeDoPai cSNomeDoAvo Apesar dos identificadores acima terem mais de dez caracteres, os 10 mais significativos no so conflitantes. O primeiro ser considerado como cSNomeDoPa e o segundo como cSNomeDoAv
Lembre-se: Somente os dez primeiros caracteres do nome de uma varivel so significativos.

Uma varivel tem os seguintes atributos: Tipo Tamanho Durao Visibilidade

Tipo: O Advpl suporta os seguintes Tipos: Array Bloco Caractere ( Caractere isolado ou string at 1Mb ) Data Lgico Memo Numrico Objeto Diferentemente das linguagens como C, C++, Java, etc..., as variveis em Advpl no so prototipadas. Seus tipos so definidos no momento aps a atribuio de valores. Para testar o tipo de uma varivel pode-se utilizar a funo Type() ou ValType(). Type() para variveis pblicas e privadas declaradas em outras instncias do programa e ValType() para variveis que pertencem mesma instncia. Ex.: Function Test1() Local aTest Private aTest1 := {} Test2( aTest ) Return( NIL )

Function Test2( aTest ) IF ( Type( aTest1 ) == A )//A varivel deve estar entre aspas IF ( ValType( aTest ) == A ) aTest := aTest1 Else Alert( A variavel aTest nao eh um Array ) EndIF EndIF Return( NIL ) Antes de Atribuir um valor a uma varivel, seu tipo indefinido (U). Se a varivel for declarada como Private, Local ou Static, seu valor, na declarao, ser NIL. As variveis declaradas como Public recebem automaticamente a atribuio de um valor lgico .F.. As variveis s obtero o seu valor real na atribuio. Converso de variveis: No Advpl possvel converter os tipos usando uma funo ou expresso condicional.

De /Pa r a Ca r a c te r e

D a ta

L g ic o Nu m r ic o B lo c o

A rray

C a ra c t e re

<c V C T oD ( < c > ) ou S T oD ( < c d> ) > $ " Tt" a l( < c > )

_ _ E x e c M a c ro (< c b > ) o u & (c b )

Da ta

D T o C (< d > ) o u D T o S ( < d > )

V a l(D t o S (< d > ))

L g ic o IF( < l> , " .T." , ".F." ) S tr ( < n > ) o u S tr Z e r o ( < n > ) o u Nu m r ic Tr a n s f o r m ( < n > ,< c P> ) o B lo c o G e tC B S o u r c e ( < b > ) O b je to A rray Cla s s D a ta A r r ( < a > )

Tamanho: Faz-se necessrio observar o tamanho de variveis de caracteres e numricas uma vez que um problema difcil de analisar a comparao de variveis de tamanhos diferentes; os espaos de preenchimento podem ser significativos.:

Variveis Caractere Ex.: Local cUsuario Local cUser Local lEqual := Administrador := Administrador

lEqual := ( cUsuario == cUser ) No exemplo acima lEqual ir retornar .F. uma vez que o contedo armazenado na varivel cUsuario ( apesar de parecer igual ) diferente do contedo da varivel cUser. O que diferencia o contedo entre uma varivel e outra so os espaos direita. Para resolver o problema na comparao teremos que abir mo de uma funo que remova os espaos direita ( RTrim( ) ). Ex.: Local cUsuario Local cUser Local lEqual := Administrador := Administrador //Removendo //direita espaos a

lEqual := ( cUsuario == RTrim( cUser ) ) ou lEqual := ( cUsuario == AllTrim( cUser ) )

//Removendo espaos //direita e esquecerda

Nos dois exemplos acima lEqual ir ser igual .T. Se ao invs de usarmos o operador de comparao de igualdade == (exatamente igual ) utilizssemos o operador = ( que pode ser utilizado tanto para comparao de igualdade como para atribuio neste caso depende do contexto ) teramos: Ex.: Local cUsuario Local cUser Local lEqual := Administrador := Administrador

lEqual := ( cUsuario = cUser ) No Exemplo acima, lEqual ser .T. pois no fizemos uma comparao exata.
8

No AdvPl possvel obter o tamanho de uma varivel do tipo caractere ou array utilizando a funo Len( <uVar> ). Ex.: Local aArray1 Local aArray2 Local cUsuario Local cUser Local nArray1 Local nArray2 Local nUsuario Local nUser := { 1 , 2 , 3 } := Array( 10 ) := Administrador := Administrador := Len( aArray1 ) //3 := Len( aArray2 ) //10 := Len( cUsuario ) //13 := Len( cUser ) //16

Variveis Numricas: O Advpl, na leitura de uma varivel numrica, atribui, automaticamente, dez posies antes da casa decimal, a despeito do seu tamanho atual. Portanto, esse tamanho passvel de ser aumentado. J em relao ao nmero de posies depois do ponto decimal determinado quando voc o atribui a ela. Assim, se para montar um Get, tivermos o seguinte bloco de programa: Local nValor := 15.1270 @ 10 , 10 Say Digite um novo valor: Get nValor nValor ter 4 posies aps o ponto decimal e duas posies antes do ponto decimal ( conforme valor atribudo varivel ); portanto o Get usa 7 colunas da tela: 2 para ates do ponto decimal, uma para o prprio ponto decimal e quatro depois dele. Ao inicializar variveis numricas para uso em um Get, certifique-se de atribuir a elas o nmero correto de casas decimais ou utilize picture como em: Local nValor := 15.12 @ 10 , 10 Say Digite um novo valor: Get nValor Picture @R 999.99999 Apesar de nValor ter sido declarado como tendo apenas 2 posies aps o ponto decimal e ele ainda possuir dez posies antes do ponto, ao delimitarmos a digitao da informao definindo a Picture teremos ( para digitao ): 3 posies antes do ponto decimal, 5 posies aps o ponto decimal ( alm do prprio ponto ) totalizando 9 o nmero de colunas no Get para a visualizao e manuteno do valor. Obs.: Ao contrrio das variveis do Tipo Array e Caractere, que utilizam a funo Len() para retornar o seus tamanhos, em AdvPl no existe funo ou operador que retorne o tamanho de uma varivel do tipo numrica. Mas nada impede de que ela seja desenvolvida pelo prprio usurio do sistema.

10

Operadores e Expresses:
O Advpl suporta os seguintes operadores binrios:

** * +

^ / -

Que agrupados em ordem de precedncia ( prioridade, a mais alta primeiro ). Os operadores ** e ^ tm ambos a prioridade mais alta. Os operadores *, / e % tem nveis de prioridades iguais, assim como os operadores + e -. Os operadores *, / e % tem uma precedncia maior do que + e -. O Advpl avalia os operadores, de igual precedncia, da esquerda para a direita.
Operador Descrio ** e ^ * / % + Exponenciao Multiplicao Diviso Modulo Soma Subtrao

Operadores Unrios: O Advpl suporta um sinal negativo ( o chamado operador unrio). Ele tem a maior prioridade entre os operadores aritimticos. Por Exemplo: -1+2 resulta 1 e no -3.

11

O Advpl suporta os operadores de incrementos e decrementos unrios ++ e --. O Operador ++ acrescenta 1 a seu operando, -- subtrai 1. Ambos tm parceiros nas instrues regulares de atribuies. Exemplo: nContador++ idntico a nContador := nContador + 1 Entretanto, a vantagem desses operadores unrios o fato de serem concisos e de poderem ser utilizados para deferir a operao at depois de processado o valor. Por Exemplo, para carregar um array de campo CPnome de cada registro de um banco de dados chamado Alunos, poderamos escrever: Local acPNomes Local nContador := 1 Use Alunos acPNomes := Array( RecCount() ) While ( Alunos )->( !Eof() ) acPNomes[ nContador++ ] := ( Alunos )->CPNOME ( Alunos )->( dbSkip() ) End While O Subscrito do array usa o valor de nContador, depois acrescenta 1. Dizemos que o ++, neste caso, um operador ps-determinado. Voc pode us-lo como um operador de prefixos, em cujo caso o valor ser incrementado ANTES de ser usado. Por exemplo, a codificao anterior deixa o nContador com um valor superior em 1 unidade ao nmero de registros processados. Para deix-lo com o valor real, poderamos escrever: Local acPNomes Local nContador := 0 Use Alunos acPNomes := Array( RecCount() ) While ( Alunos )->( !Eof() ) acPNomes[ ++nContador] := ( Alunos )->CPNOME ( Alunos )->( dbSkip() ) End While No modo de prefixo, o computador aplica o incremento antes de usar o valor. Operadores Relacionais:

12

No Advpl so permitidos os seguintes operadores relacionais:

Operador Descrio < > <= >= = == != <> # $ Menor que Maior que Menor ou igual a Maior ou igual a Igual Exatamente igual No Igual ( ou diferente ) Diferente Diferente Contido em

Os operadores relacionais tm menos prioridade do que os aritmticos. Por exemplo: nI < nLimite 1 avalidado como: nI < ( nLimite 1 ) e no como: ( nI < nLimite ) 1

Conectivos Lgicos:

Conectivo Descrio .and. .or. e ou

13

possvel negar uma expresso lgica com .NOT. ou com o ponto de exclamao, que equivalente. No Advpl as expresses lgicas so avaliadas da esquerda para a direita ( parando assim que o resultado conhecido ). Esse processo chamado avaliao de curto-cirquito. Por exemplo: #DEFINE NLIMITE 10 Local aArr[NLIMITE ] Local nIndice := 1 Local nMax := 50 ... ... While ( ( nIndice <= NLIMITE ) .and. ( aArr[ nIndice ] < nMax ) ) Process() nIndice := nIndice + 1 //ou ++nIndice End While Quando o valor de nIndice for 11, a primeira expresso provocar a interrupo da avaliao. ( no exemplo, a segunda expresso no ser avaliada, caso contrrio ocorreria o erro conhecido como erro de subscrito O erro ocorreria porque aArr for definido com 10 elementos ( NLIMITE 10 ); se a segunda comparao fosse efetuada, teramos aArr[11 ] para um array de 10 elementos apenas. O Advpl avalia os operandos de operadores binrios, tanto aritmticos como relacionais, da esquerda para a direita. Na maioria dos casos a ordem no importante, mas: IF A() < B() Onde A() e B() so funes? O problema que A() e B() poderiam provocar efeitos colateriais. Se elas dependerem de uma varivel comum, a qual pode mudar ambas, a ordem de avaliao ter importncia. IF aArr1[ ++nI ] < aArr2[ nI++ ] Se ambos os lados tiverem efeitos colaterais, seria necessrio considerar a ordem de avaliao. Os operadores, em Advpl, so sobrecarregados. Isso significa que eles se aplicam a operandos de diversos tipos. Por exemplo, pode-se utilizar o operador + para somar nmeros, concatenar string e efetuar a aritmtica de datas. De modo
14

semelhante, podemos usar o operador <= para comparar datas, nmeros e strings. O Advpl suporta dois operadores de atribuies, = e := ( torna-se igual a). A diferena entre os dois que := retorna um valor, enquanto = sobrecarregado. Quando usado dentro de uma expresso, = efetua uma comparao; caso contrrio, ele uma atribuio. O operador := sempre efetua uma atribuio e ele retorna um valor no lado direito para que possamos us-lo dentro de uma expresso, como em: IF( nHandle := fOpen( ERROS.TXT ) ) != 0 A varivel nHandle obtm o valor retornado pela abertura do arquivo ERROS.TXT. Este valor , ento, comparado com 0. Poderamos obter o mesmo resultado com: nHandle := fOpen( ERROS.TXT ) IF ( nHandle != 0 ) ... Mas no modelo anterior uma instruo foi economizada. Na verso em linha inserimos a atribuio entre parnteses. Isso ocorreu porque o operador := tem menos precedncia que o operador !=, portanto nHandle receberia, de outra maneira, um valor lgico, resultante da comparao do valor retornado por fOpen() com 0. Uma boa prtica, ento, colocar entre parnteses as instrues de atribuio em linha, para evitar problemas de precedncia. O operador := associa da direita para a esquerda, portanto podemos escrecer: cPNome := cSnome := cCep := cTel := Space( 10 ) que o efeito sera identico a escrever: cPNome := ( cSnome := ( cCep := ( cTel := Space( 10 ) ) ) ) A vantagem do operador := que ele pode aparecer dentro de expresses. Um bom uso deste operador na determinao de causa de falha de uma complexa estrutura While. Por exemplo. While TeclaValid() .and. NaFaixa() ... End While IF TeclaValid()
15

.. EndIF Quando o loop terminar, precisamos verificar que condio provocou a sada dele; para tanto, precisamos chamar novamente uma funo demorada. Podemos reescrever usando atribuies em-linha, assim: While ( ( lTv := TeclaValid() ) .and. ( lNf := NaFixa() ) ) End While IF ( lTv ) .. EndIF Quando sairmos do Loop, no precisaremos chamar nenhuma das funes demoradas para determinar por que o loop terminou. O ltimo operador que examinaremos o $ ( contido em ). Use-o para verificar se uma string est contida em outra. Por exemplo, para constatar se a varivel de memria de caractere isolado cTipoPeca R, D, ou b, podemos escrever: IF cTipoPeca $ RDB ... Para verificar se uma varivel de memria de dois caracteres PR, SP, ou AM, escreva: IF cEstado $ PR_SP_AM ... Obs.: Os separadores _ so necessrios combinaes, como RS e PA que so estados vlidos. para invalidar

Dica: Use o operador $ ao invs de vrias condies separadas. Ex.: Do Case Case cEstado == PR ; Execute() Case cEstado == SP ; Execute() Case cEstado == AM ; Execute() EndCase Poderia ser escrito como IF ( cEstado $ PR_SP_AM )
16

Execute() EndIF

Expresses condicionais:
IIF() ou IF() uma expresso condicional. So abreviaes de uma simples seqncia de IF/ELSE/ENDIF. Por exemplo, para encontrar o mnimo de a e b, poderamos escrever: nMinimo := IIF( a < b , a , b ) ou nMinimo := IF( a < b , a , b ) que seria equivalente a escrever: IF ( a < b ) nMinimo := a Else nMinimo := b EndIF As vantagens de IIF() e/ou IF() que se acomodam em qualquer lugar em que uma expresso possa estar ( incluindo blocos de codificao ) e gera menos codificao.

Estruturas de controle:
Como acontece com a maioria das linguagens, o Advpl fornece instrues para suportar desvios e loops. As instrues de desvio permitem que seus programas selecionem entre alterantivas; as instrues de loops permitem executar um grupo de instrues repetidas vezes. Desvio: No Advpl existem dois mtodos de desvio: o bloco de instrues IF/ELSE/ELSEIF/ENDIF ou o bloco DO CASE/ENDCASE. ELSEIF apenas uma abreviao que evita a necessidade de se escrever outro IF/ENDIF. Os dois exemplos que se seguem so equivalentes: IF ( nX < 10 ) ... Else IF ( nX > 20 ) ... EndIF EndIF

17

ou IF( nX < 10 ) ... ElseIF ( nX > 20 ) ... EndIF Observe que, como o Advpl sempre insiste num ENDIF encerrando todo o bloco de IF, sempre saberemos a quem pertence um Else. Obs.: Ao testar vrias condies, prefervel uma instruo CASE a uma longa seqncia de IF/ELSEIFs. Na implementao das instrues CASE, o Advpl avalia uma condio de cada vez, at encontrar uma verdadeira. Em sequida ele avalia todas as intrues at o prximo CASE, ENDCASE ou OTHERWISE e, finalmente, salta para a instruo seguinte ao ENDCASE. A clusula OTHERWISE serve como ltima condio; ela localiza toda situao no correspondida por um CASE anterior. BEGIN SEQUENCE/END O par BEGIN SEQUENCE/END oferece outro mtodo de desvio. Use-o para delimitar um bloco de codificao; em sequida, a partir de qualquer local dentro dele, voc poder emitir uma instruo BREAK. Ele passar o controle para a instruo seguinte ao END. Exemplo: BEGIN SEQUENCE IF ... IF ... IF ... Break EndIF EndIF EndIF ... END SEQUENCE

18

BEGIN SEQUENCE pode ser aninhado; um BREAK passar o controle para o END mais prximo BEGIN SEQUENCE IF !(... ) BREAK ENDIF BEGIN SEQUENCE IF ... BREAK ELSEIF ... BREAK ENDIF IF ... BREAK ELSEIF ... BREAK ENDIF END SEQUENCE ... END SEQUENCE ... O uso bsico de BEGIN SEQUENCE manipular excees. Ele fornece um local adequado para saltar quando ocorre um erro. Podemos us-lo como um ponto de interrupo para a lgica profundamente aninhada. Por exemplo, vamos supor que precisemos testar trs condies, mas s possa testar uma aps o trmino com xito da anterior ( como uma seqncia de bloqueios de arquivos ). Usando o aninhamento tradicional escreveramos: IF <cond1 > ... ... IF <cond2> ... ... IF <cond3> ... ... ENDIF
19

ENDIF ENDIF Usando BEGIN SEQUENCE, poderamos escrever: BEGIN SEQUENCE IF !<cond1> BREAK ENDIF ... ... IF !<cond2> BREAK ENDIF IF !<cond3> BREAK ENDIF END SEQUENCE Pode-se, tambm, colocar uma instruo RECOVER dentro de um par BEGIN SEQUENCE/END. Quando seu programa executar, subseqentemente, uma instruo de interrupo, o controle ser transferido para a instruo RECOVER em vez de para o END.
Obs.: Tenha cuidado usar BEGIN SEQUENCE e BREAK; poderemos criar uma codificao ilegvel com o uso excessivo desse par.

Loops: O Advpl oferece os loops FOR e WHILE. A instruo FOR executa instrues at o NEXT correspondente durante um determinado nmero de vezes. Devemos informar a quantidade de vezes a iterar, como em Local nLoop Local nLoops := 10 For nLoop := 1 To nLoops ... ...

20

Next nLoop A inicializao da varivel para controle do Loop dever feita na declarao For nLoop :=, o NEXT incrementa-a automaticamente e, se ele no tiver ultrapassado seu limite, o controle retornar para a primeira instruo dentro do loop. O valor do incremente igual a 1, a menos que especificado de outra maneira com a opo STEP. Local nLoop Local nLoops := 100

For nLoop := 1 To nLoops Step 10 Next nLoop ou Local nLoop Local nLoops := 0 For nLoop := 100 To nLoops Step 10 Next nLoop Podemos usar os commandos EXIT e LOOP dentro do corpo do loop FOR. Exit encerra o Loop, transferindo o controle para a instruo depois do NEXT; o LOOP d um salto para o incio, reavalidando a condio.
Obs.: Use os dois comandos com cuidado; eles podem dificultar o entendimento e a manuteno dos loops.

O Loop for sempre reavalia a expresso limite a cada passagem. Por exemplo, em: Local nLoop For nLoop := 1 To RecCount() ... Next nLoop RecCount() ser sempre reavaliada a cada passagem do Loop, o que um disperdcio. Atribua o valor retornado per RecCount() uma varivel para melhorar a performance, como em: Local nLoop Local nLoops := RecCount()

21

For nLoop := 1 To nLoops Next nLoop J um Loop WHILE continua at que sua condio venha a ser falsa. A condio avaliada primeiro, para que o loop no possa ser inserido de modo algum. A avaliao da condio ser interrompida assim for conhecido o resultado.
Obs.: Apenas o necessrio de uma condio avaliado para se determinar o resultado.

Para executar o loop pelo menos uma vez, simulando as clusulas REPEAT... UNTIL ou DO ... UNTIL de outras linguagens, poderemos escrever: Local lContinue := .T. While ( lContinue ) ... IF <condicao de sada> lContinue := .F. EndIF End While Estaremos, essencialmente, testando a condio ao final do loop.
Obs.: No uso While .T. como uma condio de loop. melhor colocar a condio de sada na instruo. Desta maneira, poderemos ver claramente o que o loop est tentando alcanar.

Pr-Processador: O pr-processador um importante recurso no Advpl. Imagine-o como um programa que executa antes do compilador. Ele l o programa como entrada e gera um arquivo pr-processado como sada. O arquivo de sada, ento, serve como a entrada do compilador. Podemos incluir comandos do pr-processador, chamadas de diretivas, no programa de origem. O pr-processador as manipular; o compilador nunca as percebe, uma vez que ele s manipula o arquivo de sada. O pr-processador do Advpl tem os seguintes recursos: - constantes simblicas ou manifestas - arquivos include

22

- macros do compilador - compilao condicional - comandos definidos pelo usurio Constantes Simblicas: No Advpl possvel a definio de constantes simblicas para uso no processo de pr-compilao. Devemos abrir mo desse recurso para tornar os programas mas legveis e fcil de entender. Por Exemplo, no fragmento de codificao: IF ( nOpc == 1 ) Inclui() ElseIF ( nOpc == 2 ) Altera() ElseIF ( nOpc == 3 ) Exclui() EndIF S conseguiremos idenfificar o que nOpc representa se acompanharmos todo o processo ou se o programa estiver documentado. Mas, se utilizssemos constantes, teramos:
Obs.: Podemos definir constates com a diretiva do pr-processador #DEFINE.

#DEFINE INCLUI 1 #DEFINE ALTERA 2 #DEFINE EXCLUI 3 IF ( nOpc == INCLUI ) Inclui() ElseIF ( nOpc == ALTERA ) Altera() ElseIF ( nOpc == EXCLUI ) Exclui() EndIF No precisaramos avaliar todo o programa para saber a que se refere o valor de nOpc. E o cdigo fica muito mais fcil de interpretar. Na realidade INCLUI, ALTERA e EXCLUI, sero substitudos no processo de pr-compilao por 1 , 2 e 3 ( respectivamente ).
Regra: A traduo de #DEFINE feita pelo pr-processador sensvel a letras maisculas e minsculas. Dica: Defina todas as constantes em letras maisculas com a diretiva #DEFINE

23

Arqivos Include: As constantes simblicas s so conhecidas no arquivo de origem que as define. O pr-processador s conhece seus valores depois da traduo. Portanto se definirmos uma constante um um programa ela s valer durante a compilao deste programa. Para que uma constante possa valer para mais de um programa, devemos usar um recurso de incluso de arquivos atravs da diretiva #include. Ou seja, as constantes seriam includas em um arquivo parte e todo programa que fosse utilizar essas constantes teria a seguinte linha #include <nome do arquivo.ch>. Macros do compilador: Podemos visualizar uma macro do compilador como uma funo diretamente na codificao de origem do programa onde poderamos parametrizar uma seqncia de comandos, exatamente como uma funo. A diferena que as macros do pr-processador so substitudas diretamente no arquivo de origem ( elas no so chamadas do mesmo modo que uma funo ) . Por exemplo, poderamos escrever uma macro de pesquisa de mnimo como: #DEFINE MIN( a , b ) IIF( a < b , a , b ) Quando, subseqentemente, chamar-mos a MIN com: nMin := MIN( nY , nZ ) O pr-processador a substituir por sua definio como em: nMin := IIF( nY < nZ , nY , nZ ) Defina a macro usando parmetros formais, exatamente como uma funo. Quando o pr-processador a expandir, ele os substituir pelos verdadeiros prmetros (argumentos). Isto basicamente o que acontece quando voc chama uma rotina ou funo. A diferena que a substituio dos arqumentos ocorre no tempo do pr-processador com as macros do compilador, no durante a execuo. Compilao Condicional: A compilao condicional nos permite incluir ou excluir codificao baseada numa condio. O propsito usual manter diferentes verses de um programa, sem precisar separar cpias da codificao de origem. Por exemplo, poderamos ter uma vero utilizando o TopConNect e outra para CodBase,
24

As diretivas do pr-processador para a compilao condicional se parecem com as instrues IF/ELSE/ENDIF. O pr-processador inclui ou exclui codificao do arquivo de sada, baseado no resultado do teste. O teste, conseqentemente, atua como um filtro. O aspecto importante a observar que o pr-processador faz o teste, no o programa. Dessa forma, a codificao no-selecionada nem sequer existe no arquivo de sada. As diretivas verificam se um smbolo est definido ou se ele tem um valor especfico ( podemos definir um smbolo com a diretiva #DEFINE ). As diretivas do pr-processador so: #IFDEF #IFNDEF #ELSE #ENDIF - Verifica se um smbolo est definido - Verifica se um smbolo no est definido - Inclui algo se #IFDEF ou uma #IFNDEF falhar - Indica o final da codificao controlada por um #IFDEF, #IFNDEF ou #ELSE

Podemos definir um smbolo sem atribuir um valor a ele. Por Exemplo, podemos escrever: #DEFINE TOP E test-la, em seguida, com: #IFDEF TOP Neste caso, estamos apenas verificando se ela est definida, no checamos o seu valor; Observemos agora, como o pr-processador manipula um exemplo simples: #DEFINE TOP #IFDEF TOP Local cquery := SELECT * FROM... #ELSE ( cAlias )->( dbSeek( ... ) ) #ENDIF

25

Funes:
As funes, em Advpl, podem ser entendidas como um mecanismo de subrotinas. Elas sempre retornam um valor. Uma funo pode retornar qualquer tipo de dados ( array, numrico, string, objeto, lgico... ) e, se nenhum tipo de retorno for definido a funo retornar NIL. Elas retornam seu valor como uma expresso aps a instruo RETURN ( Obs.: a rotina chamadora da funo no precisa, necessariamente, usar o valor de retorno ). O uso adequado das funes possibilita a grande reutilizao da codificao. As funes so definidas uma s vez dentro de um programa, mas podem ser chamadas vrias vezes. Elas podem ser definidas em qualquer ordem e voc pode chamar uma antes de defini-la. Todas as funes so armazendas no Repositrio de Objetos. E Podem ser declaradas como: Pblicas: Podem ser chamadas em qualquer programa: Funes Reservadas ( Microsiga ) Function na Microsiga Template Function Project Function -> Reservado para desenvolvimento no ERP -> Para a criao de Templates -> Para a criao de Projetos

Funes Comuns ( Microsiga / Clientes usurios ) User Function Web Function Html Function Estticas: -> Para criao de funes de usurio -> Para criao de funes para uso na Web -> Para criao de funes para uso na Web

Podem ser chamadas apenas no programa onde foram declaradas ( Static )

Static Function
Obs.: Consulte o Header ( arquivo de cabealho ) Protheus.ch ( \mp8\include\ para verificar os detalhes sobre o padro de converso das delcaraes acima nas chamadas de funo.

Parmetros:

26

No Advpl, a forma de passagem de parmetros para as funes colocando os nomes dos parmetros entre parnteses e delimitando-os por vrgula. Este mtodo conhecido como lista de parmetros formais. Como em: Function Teste( a , b , c ) User Function Teste( a , b , c ) Onde a, b, c so os parmetros formais da funo. O escopo destes parmetros Local ( tem visibilidade e durao enquanto durar a execuo da funo ).

27

Você também pode gostar