Programação

Lógica de Programação AdvPL – Parte 2

Escritor por Vinícius Gregório

 

Estrutura de um programa em AdvPL

 

A linguagem AdvPL (Advanced Protheus Language) é baseada em uma linguagem chamada Clipper. Essa variação foi desenvolvida pela antiga Microsiga (atualmente TOTVS) para o desenvolvimento de sua ferramenta de ERP e funciona somente em instalações desse sistema.

 

Consiste da adição de comandos, reestruturação da linguagem para funcionar em ambiente cliente servidor, alterações na forma de compilação, entre outras. Porém, os comandos que existiam e funcionavam para a linguagem base Clipper, também funcionam para a linguagem AdvPL.

 

Um programa em AdvPL, consiste das seguintes seções:

 

//includes
#include "protheus.ch"

//defines
#define TEXTO "ISSO EH UM TESTE"

//Funções
User Function TESTE()

	//variaveis
	Local cOutroTxt	:= "UM EXEMPLO DE STRING"

	//comandos
	MsgInfo(TEXTO+cOutroTxt)

//retorno da função
Return .T.

 

Onde:

 

includes
São linhas que criam a referência desse arquivo de código-fonte com outros arquivos de código-fonte. É uma forma de fazer com que um conjunto de instruções e variáveis específicos da linguagem (que estão no arquivo referenciado) estejam “disponíveis” para ser utilizado dentro do seu programa.

 

Em linhas gerais, você sempre utilizará a seguinte linha de include:

 

#include "protheus.ch"

 

No entanto, não é raro encontrar a seguinte linha no lugar:

 

#include "rwmake.ch"

 

Em ambos os casos, é um include padrão para carregar algumas funções e variáveis da linguagem de programação AdvPL. A segunda linha – rwmake.ch – é mais antiga e a biblioteca importada não tem todas as funções e variáveis do protheus.ch. Portanto, embora você ainda possa encontrá-la em vários arquivos de código-fonte, não recomendamos o seu uso.

 

defines
Defines são instruções que determinam uma constante em seu programa. Essa constante é definida por um nome e sempre terá o mesmo valor durante a execução do programa. Atente que para se referenciar a constantes, o AdvPL é case sensitive. Ou seja, definir uma constante com o nome de XTEXTOTESTE e tentar utilizá-la dentro de seu programa chamando por xTextoTeste irá disparar um erro de variável não encontrada!

 

Inicialmente, um Define pode não parecer útil sendo que você pode definir variáveis e escopos diferentes para essas variáveis (se não sabe do que estou falando, relaxa que você aprenderá isso no próximo artigo…). No entanto, quando começamos a pensar em boas práticas para a manutenção de nosso código, os Defines serão de extrema valia para tornar nosso código legível, mais fácil de alterar e coerente.

 

Atente também que, embora não esteja listada nas seções acima, também existe uma área especifica para definir variáveis estáticas.

 

Static cTextoTeste	:= “Isso é um teste!”

 

Elas também são muito úteis em casos específicos. Porém, vamos nos ater ao básico, por enquanto.

Fique atualizado, É GRÁTIS!
Cadastre o seu endereço de e-mail e fique por dentro de todas as atualizações da AcademiaERP.
Não enviamos spam.

funções
Funções representam uma parte fundamental em nosso estudo de lógica de programação. Provavelmente uma das áreas que mais vamos nos dedicar. Uma função pode ser definida como um trecho de código que, através da execução de um ou mais algoritmos, irá realizar uma determinada tarefa.

 

Um programa/rotina é dividido em várias funções. Cada uma executando uma tarefa específica do algoritmo. Pensando em nosso exemplo do miojo, podemos pensar em funções mais ou menos assim:

 

1 Ferver Água
2 Preparar Macarrão
3 Servir Macarrão

 

Porém, essas instruções estão muito subjetivas e não nos dizem muita coisa, embora representem os passo principais do processo. Mas assim como no desenvolvimento de programas, para executar cada uma delas, você precisará executar passos intermediários:

 

1 Ferver Água
1.1 Acender bocal do fogão
1.2 Pegar uma panela
1.3 Encher 2,5 copos de água
1.4 Despejar os copos na panela
1.5 Levar a panela ao fogo
2 Preparar Macarrão
2.1 Pegar o saquinho de miojo
2.2 Abrir o saquinho
2.3 Colocar o macarrão na panela
2.4 Esperar 3 minutos
3 Servir Macarrão
3.1 Desligar o fogo
3.2 Abrir o saquinho de tempero
3.3 Despejar o tempero
3.4 Misturar o tempero no macarrão
3.5 Pegar um prato
3.6 Despejar o macarrão no prato

 

Perceba que, embora os passos sejam simples, eles precisam ser executados em ordem para que a coisa funcione. Criaríamos a função PREPARAR_MIOJO() e dentro dela chamaríamos cada uma das outras funções listadas. Implementaríamos o código de cada uma dessas funções e, quando executássemos PREPARAR_MIOJO(), cada uma delas seria executada, na sequência correta.

 

Lembrando que você pode agrupar os passos em etapas mais abrangentes, tudo depende da estrutura desejada em seu código-fonte.

 

Pensando agora na sintaxe AdvPL para a definição de uma função, podemos dividir uma função em Assinatura, Implementação e Retorno.

 

A Assinatura é a primeira linha de uma função. Ela define o seu escopo (User Function, Function ou Static Function), qual o nome da função (como ela será chamada dentro do código) e os parâmetros que uma função recebe.

 

No caso do AdvPL, a chamada de uma função é feita por, no máximo, 10 caracteres. Se você definir um nome extremamente longo para a sua função, somente os 10 primeiros caracteres que contarão. Caso ela tenha um nome menor ou igual, não haverá problemas para referenciá-la. No caso de User Functions, antes do nome da Função são concatenados os caracteres “U_”. Ou seja, “User Function PREPARAMIOJO()” seria chamada em outras linhas de código pelo texto “U_PREPARAM()

 

User Function TESTE()
   Local lRetorno	:= .T.

   MsgInfo(U_PreparaMiojo())
   MsgInfo(U_PreparaM())

Return lRetorno

User Function PreparaMiojo()
Return "Teste"

User Function PreparaM()
Return "Teste 2"

 

No caso acima, o fonte é compilado sem problemas. No entanto, no momento da execução, ambos os testes de MsgInfo (uma simples janela de aviso que aparece na tela) irão imprimir o texto “Teste”. Isso ocorre porque, embora ambas as funções estejam disponíveis no repositório após a compilação, no momento da execução, o Protheus irá procurar a primeira função que atender à chamada U_PREPARAM() e, no nosso caso, é a primeira função especificada.

 

Na assinatura de uma função é possível passar parâmetros para ela, de forma que esses parâmetros possam ser utilizados em sua implementação, como qualquer outra variável:

 

Static Function PreparaM(nQtdCopos)

   MsgStop(“quantidade de copos de água: “+nQtdCopos)

Return .T.

 

A Implementação da função é o trecho de código que descreve cada uma das etapas necessárias para completar um passo do algoritmo. É onde estarão listados todos os comandos, em ordem, para que uma funcionalidade seja executada.

 

Nos próximos artigos, vamos aprender um pouco sobre a sintaxe básica da linguagem (controle de fluxo, laços, operadores e outras diretivas) e sobre as principais funções que a linguagem disponibiliza para seus desenvolvedores;

 

O Retorno é a seção que faz com que o resultado de passo executado pela função seja enviado de volta para o código que a chamou. Esse retorno, definido pela linha Return <conteúdo do retorno> pode ser utilizado diretamente no código que o chamou ou armazenado em uma variável:

 

If ConfirmCli()
EndIf

ou

lConfCli	:= ConfirmCli()//supondo que ConfirmCli()
                               //retorne uma variável booleana

If lConfCli
EndIf

 

variáveis
Tecnicamente, variáveis são representadas por uma quantidade definida de memória RAM do computador que é separada e identificada para representar uma ou mais informações voláteis durante a execução de um processo.

 

O que tudo isso quer dizer (rs) é que uma variável é onde você pode colocar definições, resultados de cálculos, processos ou funções durante a execução de seu código. Você pode utilizá-las para armazenas informações preenchidas pelo usuário, carregadas de parâmetros, da base de dados ou desenhar elementos na tela.

 

As variáveis são definidas com um tipo e recebem um nome. No caso do Clipper/AdvPL, uma variável pode ser definida apenas atribuindo um valor a ela:

 

cTeste	:= “TESTE”

 

As variáveis são categorizadas de acordo com o tipo de informação que elas armazenam e essas categorias devem ser respeitadas durante a execução de suas funções. Seguem os tipos de variáveis existentes no AdvPL:

 

Caracteres (string)

 

É a representação de informações de texto. Uma string pode ser definida por aspas (“) ou apóstrofo (‘), sendo obrigatório fechar com o mesmo sinal que foi aberta. Ex.:

 

cAspas		:= “Vinícius Gregório”
cApost		:= 'Vinícius Gregório'

 

Número (number – seja integer ou float)

 

Representam informações numéricas no sistema, não diferenciando se são números inteiros ou fracionários (ao contrário de outras linguagens fortemente tipadas). Ex.:

 

nInteiro	:= 1
nFracao	:= 0.25 //a separação de frações é sempre feita por ponto e não vírgula

 

Data (date)

 

Armazenam datas dentro do sistema. Essas variáveis, embora tenham um tipo específico e são tratadas diferente de outras categorias, são definidas utilizando funções que convertam um valor em outro tipo para data ou pegando a data atual do sistema. Ex.:

 

dData	:= CtoD(“30/09/13”)//a função CtoD (caracter to date) converte uma string no
			   //formato dd/mm/aa para uma variável data;

dHjPC	:= Date()//função oriunda do Clipper que pega a data do computador
		 //executando a rotina. No caso do Protheus, o servidor de aplicação;

dHjSis	:= dDatabase//dDataBase é uma variável padrão do Protheus que armazena a data
		    //selecionada pelo usuário na tela de entrada do sistema ou da rotina;

 

Lógico (boolean)

 

Variáveis lógicas, ou booleanas, armazenam informações binárias simples. Verdadeiro ou Falso. Em geral são utilizadas para armazenar configurações para o comportamento da rotina ou verificações de estados (imprime relatório? Sim ou Não. Usuário clicou no botão? Sim ou Não). Os estados possíveis são .T. = True (Verdadeiro) ou .F. = False (Falso). Ex.:

 

lContinua	:= .T.
lImprime	:= MsgYesNo(“Deseja imprimir o resultado da importação?”)//MsgYesNo pode retornar
                                                                         //.T. ou .F.

 

Vetor (array)

 

Um vetor  representa uma lista de variáveis e informações inseridas dentro dela. É como agrupar diversos valores através da afinidade do significado de seus valores.

 

Ao contrário de outras linguagens de programação, um array em AdvPL é completamente flexível e permite que você insira diversos valores, de tipos diferentes ou não, dentro dele. Inclusive outros arrays!

 

Esse tipo de flexibilidade, além de extremamente útil, deve ser usada com cuidado para que o seu código não fique confuso e difícil de alterar posteriormente (imagine outro programador olhando valores e mais valores dentro de uma estrutura confusa, com diversos tipos de variáveis, sem entender direito o que são…).

 

Seguem exemplos do que são arrays:

 

aNumeros	:= {}//definição de um array
aVariosTipos	:= {1,”Teste”,CtoD(“30/09/13”)}

MsgInfo(aVariosTipos[2])//irá imprimir a primeira posição do array → “Teste”

 

Bloco de Código (code block)

 

Os blocos de código são variáveis que armazenam trechos de código que podem ser executados. É como poder armazenar comandos em uma variável e, por funcionarem, esses comandos podem ser diferentes, dependendo do conteúdo armazenado.

 

Blocos de código são (quase) exclusivos de Clipper e AdvPL. É uma forma de metaprogramação utilizado pela linguagem (no caso do AdvPL/Clipper, também há a macrosubstituição). Serve para que, em tempo de execução, os comandos que compõe uma rotina sejam alterados de acordo com o conteúdo de uma ou mais variáveis

 

Posteriormente, com uso de funções, como Eval(), esses comandos são executados, como se estivessem sido compilados dentro do arquivo de código-fonte. Ex.:

 

bCodeBlock	:= {|| dData := Date}

 

Objeto (object)

 

Objetos são estruturas de código que contem atributos (variáveis próprias) e métodos (funções executadas pelo objeto). Essa é uma definição EXTREMAMENTE simplista, mas deve servir, à princípio. Para entender como objetos realmente funcionam é necessário estudar como funciona a programação orientada à objetos (inclusive as “diferenças” em programar OO no AdvPL).

 

No entanto, na maioria dos casos, no AdvPL é possível utilizar os objetos apenas como variáveis “com poderes especiais”. Têm suas estruturas, classes, atributos, métodos, herança, polimorfismo e outros conceitos. Normalmente, você não precisa se preocupar com esses conceitos, mas estudar Orientação à Objetos sempre ajuda!

Ex.:

oDlgMain := MSDIALOG():New(aSize[7],00,aSize[6],aSize[5],cCadastro,,,,,,,,/*oMainWnd*/,.T.)
//definição de uma tela simples.

 

Um pouco sobre Notação Húngara

 

Um item que os mais atenciosos deve ter reparado é que existe uma lógica na primeira letra de cada variável nos códigos acima. oDlgMain, bCodeBlock, aNumeros, lContinua…. Isso se chama  Notação Húngara e é uma forma de organizar nosso código e facilitar a sua leitura.

 

Através da Notação Húngara, embora não restrinja os tipos de dados que uma variável pode armazenar, um desenvolvedor saberá que tipo de informação deve ser/estar armazenada nela.

 

No AdvPL usamos os seguintes prefixos:

 

c = Caracter (String)

n = Numérico (Integer ou Float)

d = Data (Date)

l = Lógico (Boolean)

a = Vetor (Array)

b = Bloco de Código (CodeBlock)

o = Objeto (Object)

 

No próximo artigo, veremos a sintaxe dos comandos de controle de fluxo e, já que estamos mais acostumados com vários conceitos de programação, começaremos a pensar na lógica de escrever programas usando esse aprendizado. Até lá.

 


(fonte: http://vidadeprogramador.com.br/)

 

Artigo 1: Lógica de Programação – Parte 1

Sobre o Autor

Vinícius Gregório

Tecnólogo em análise de sistemas da informação pela Faculdade IBTA (SP), empreendedor da área de TI e consultor Protheus especializado em desenvolvimento AdvPL. Trabalhou em diversos projetos com os módulos de Compras, Estoque/Custos, Faturamento, Contabilidade Gerencial, Field Service/Gestão de Serviços, Financeiro, Gestão de Contratos e Gestão de Projetos. Atua também como desenvolvedor de sistemas web e é usuário fanático de sistemas e softwares open source... (vinicius.gregorio@academiaerp.com.br)

1 comentário

Deixe um comentário

Dúvida?