Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas

ADVPL Básico, Notas de estudo de Análise de Sistemas de Engenharia

Material de ADVPL Básico

Tipologia: Notas de estudo

2010
Em oferta
30 Pontos
Discount

Oferta por tempo limitado


Compartilhado em 17/09/2010

rafael-pinheiro-17
rafael-pinheiro-17 🇧🇷

4.3

(3)

1 documento

1 / 225

Documentos relacionados


Pré-visualização parcial do texto

Baixe ADVPL Básico e outras Notas de estudo em PDF para Análise de Sistemas de Engenharia, somente na Docsity! Educação Corporativa Introdução à programação e ADVPL básico (Capacitação Interna) Matriz – Av. Braz Leme, 1.717 – 02511-000 – São Paulo – SP – Brasil. Tel.: 55 (11) 3981-7001 www.microsiga.com.br - 2 - Introdução á programação e ADVPL Básico ESTRUTURA DO TREINAMENTO OBJETIVOS DO CURSO................................................................................................................................. 6 MÓDULO 01: Introdução à programação...................................................................................................... 7 1. Lógica de Programação e Algoritmos .................................................................................................. 7 1.1. Lógica de Programação............................................................................................................... 7 1.2. Desenvolvendo algoritmos.......................................................................................................... 8 1.2.1. Estudando algoritmos..................................................................................................................9 1.2.2. Teste de mesa..........................................................................................................................11 2. Estruturas de programação............................................................................................................... 12 2.1. Diagrama de bloco .................................................................................................................... 12 2.2. Estruturas de decisão e repetição ............................................................................................. 15 2.2.1. Estruturas de decisão................................................................................................................15 2.2.2. Estruturas de repetição .............................................................................................................18 MÓDULO 02: A linguagem ADVPL .............................................................................................................. 20 3. Estrutura de um Programa ADVPL..................................................................................................... 22 3.1. Áreas de um Programa ADVPL .................................................................................................. 24 4. Declaração e Atribuição de Variáveis ................................................................................................ 27 4.1. Tipo de Dados ........................................................................................................................... 27 4.2. Declaração de variáveis ............................................................................................................ 28 4.3. Escopo de variáveis................................................................................................................... 29 4.4. Entendendo a influência do escopo das variáveis...................................................................... 33 4.5. Operações com Variáveis .......................................................................................................... 34 4.5.1. Atribuição de variáveis ..............................................................................................................34 4.5.2. Operadores da linguagem ADVPL................................................................................................35 4.5.3. Operação de Macro Substituição .................................................................................................40 4.5.4. Funções de manipulação de variáveis ..........................................................................................41 5. Estruturas básicas de programação................................................................................................... 47 5.1. Estruturas de repetição............................................................................................................. 47 5.1.1. Influenciando o fluxo de repetição ..............................................................................................50 5.2. Estruturas de decisão ............................................................................................................... 52 6. Arrays e Blocos de Código ................................................................................................................. 56 6.1. Arrays ....................................................................................................................................... 56 6.1.1. Inicializando arrays ...................................................................................................................58 6.1.2. Funções de manipulação de arrays..............................................................................................59 6.1.3. Cópia de arrays ........................................................................................................................61 6.2. Listas de Expressões e Blocos de Código................................................................................... 63 6.2.1. Premissas para utilização de Blocos de Código..............................................................................63 6.2.2. Lista de expressões...................................................................................................................64 6.2.3. Blocos de Código ......................................................................................................................66 6.2.4. Funções para manipulação de blocos de código ............................................................................68 7. Funções............................................................................................................................................. 69 7.1. Tipos e escopos de funções....................................................................................................... 70 7.2. Passagem de parâmetros entre funções ................................................................................... 73 8. Diretivas de compilação .................................................................................................................... 79 MÓDULO 03: Desenvolvendo pequenas customizações.............................................................................. 84 9. ADVPL e o ERP Microsiga Protheus.................................................................................................... 84 9.1. O Ambiente Protheus ................................................................................................................ 84 9.2. Organização e configuração inicial do ambiente Protheus ........................................................ 88 - 5 - Introdução á programação e ADVPL Básico TIME()....................................................................................................................................... 196 YEAR() ...................................................................................................................................... 196 Manipulação de variáveis numéricas ................................................................................................... 197 ABS() ........................................................................................................................................ 197 INT()......................................................................................................................................... 197 NOROUND() ............................................................................................................................... 198 ROUND() ................................................................................................................................... 198 Manipulação de arquivos ..................................................................................................................... 199 SELECT() ................................................................................................................................... 199 DBGOTO() ................................................................................................................................. 199 DBGOTOP()................................................................................................................................ 200 DBGOBOTTON().......................................................................................................................... 200 DBSELECTAREA()........................................................................................................................ 201 DBSETORDER() .......................................................................................................................... 201 DBSEEK() E MSSEEK()................................................................................................................. 202 DBSKIP() ................................................................................................................................... 203 DBSETFILTER()........................................................................................................................... 204 DBSTRUCT() .............................................................................................................................. 205 RECLOCK() ................................................................................................................................ 205 MSUNLOCK().............................................................................................................................. 206 SOFTLOCK()............................................................................................................................... 207 DBDELETE() ............................................................................................................................... 208 DBUSEAREA() ............................................................................................................................ 208 DBCLOSEAREA()......................................................................................................................... 209 Controle de numeração seqüencial...................................................................................................... 209 GETSXENUM() ............................................................................................................................ 209 CONFIRMSXE() ........................................................................................................................... 209 ROLLBACKSXE() ......................................................................................................................... 210 Validação............................................................................................................................................. 210 EXISTCHAV() ............................................................................................................................. 210 EXISTCPO() ............................................................................................................................... 210 NAOVAZIO() .............................................................................................................................. 211 NEGATIVO()............................................................................................................................... 211 PERTENCE() ............................................................................................................................... 211 POSITIVO()................................................................................................................................ 211 TEXTO() .................................................................................................................................... 211 VAZIO()..................................................................................................................................... 212 Parâmetros.......................................................................................................................................... 212 GETMV().................................................................................................................................... 212 GETNEWPAR() ............................................................................................................................ 212 PUTMV() .................................................................................................................................... 213 SUPERGETMV()........................................................................................................................... 213 Componentes da interface visual......................................................................................................... 214 MSDIALOG() .............................................................................................................................. 214 MSGET().................................................................................................................................... 215 SAY() ........................................................................................................................................ 216 BUTTON() .................................................................................................................................. 216 SBUTTON() ................................................................................................................................ 217 Interfaces de cadastro ........................................................................................................................ 218 AXCADASTRO() .......................................................................................................................... 218 MBROWSE() ............................................................................................................................... 218 AXPESQUI() ............................................................................................................................... 218 AXVISUAL() ............................................................................................................................... 219 AXINCLUI() ................................................................................................................................ 219 AXALTERA() ............................................................................................................................... 220 AXDELETA() ............................................................................................................................... 221 Funções visuais para aplicações .......................................................................................................... 222 ALERT()..................................................................................................................................... 222 AVISO()..................................................................................................................................... 222 FORMBACTH() ............................................................................................................................ 223 MSGFUNCTIONS()....................................................................................................................... 224 Funções ADVPL para aplicações .......................................................................................................... 225 GETAREA()................................................................................................................................. 225 RESTAREA() ............................................................................................................................... 225 - 6 - Introdução á programação e ADVPL Básico OBJETIVOS DO CURSO Objetivos específicos do curso: Ao final do curso o treinando deverá ter desenvolvido os seguintes conceitos, habilidades e atitudes: a) Conceitos a serem aprendidos  fundamentos e técnicas de programação;  princípios básicos da linguagem ADVPL;  comandos e funções específicas da Microsiga. b) Habilidades e técnicas a serem aprendidas  resolução de algoritmos através de sintaxes orientadas a linguagem ADVPL;  análise de fontes de baixa complexidade da aplicação ERP Protheus;  desenvolvimento de pequenas customizações para o ERP Protheus. c) Atitudes a serem desenvolvidas  adquirir conhecimentos através da análise dos funcionalidades disponíveis no ERP Protheus;  embasar a realização de outros cursos relativos a linguagem ADVPL. - 7 - Introdução á programação e ADVPL Básico MÓDULO 01: Introdução à programação 1. Lógica de Programação e Algoritmos No aprendizado de qualquer linguagem de programação é essencial desenvolver os conceitos relacionados a lógica e a técnica da escrita de um programa. Com foco nesta necessidade, este tópico irá descrever resumidamente os conceitos envolvidos no processo de desenvolvimento de um programa através dos conceitos relacionados à:  Lógica de programação  Algoritmos  Diagramas de blocos 1.1. Lógica de Programação Lógica A lógica de programação é necessária para pessoas que desejam trabalhar com desenvolvimento de sistemas e programas, ela permite definir a seqüência lógica para o desenvolvimento. Então o que é lógica? Lógica de programação é a técnica de encadear pensamentos para atingir determinado objetivo. Seqüência Lógica Estes pensamentos, podem ser descritos como uma seqüência de instruções, que devem ser seguidas para se cumprir uma determinada tarefa. Seqüência Lógica são passos executados até atingir um objetivo ou solução de um problema. Instruções Na linguagem comum, entende-se por instruções “um conjunto de regras ou normas definidas para a realização ou emprego de algo”. Em informática, porém, instrução é a informação que indica a um computador uma ação elementar a executar. Convém ressaltar que uma ordem isolada não permite realizar o processo completo, para isso é necessário um conjunto de instruções colocadas em ordem seqüencial lógica. Por exemplo, se quisermos fazer uma omelete de batatas, precisaremos colocar em prática uma série de instruções: descascar as batatas, bater os ovos, fritar as batatas, etc. É evidente que essas instruções têm que ser executadas em uma ordem adequada – não se pode descascar as batatas depois de fritá-las. - 10 - Introdução á programação e ADVPL Básico Fritar um ovo 1. Pegar frigideira, ovo, óleo e sal 2. Colocar óleo na frigideira 3. Ascender o fogo 4. Colocar a frigideira no fogo 5. Esperar o óleo esquentar 6. Quebrar o ovo na frigideira 7. Jogar a casca no lixo 8. Retirar a frigideira do fogo quando o ovo estiver no ponto 9. Desligar o fogo 10. Colocar sal a gosto Trocar lâmpadas 1. Se a lâmpada estiver fora do alcance, pegar uma escada 2. Pegar a lâmpada nova 3. Se a lâmpada queimada estiver quente, pegar um pano 4. Tirar lâmpada queimada 5. Colocar lâmpada nova Descascar batatas 1. Pegar faca, bacia e batatas 2. Colocar água na bacia 3. Enquanto houver batatas, descascar as batatas 3.1. Colocar as batatas descascadas na bacia Jogar o jogo da forca 1. Escolher a palavra 2. Montar o diagrama do jogo 3. Enquanto houver lacunas vazias e o corpo estiver incompleto: 3.1. Se acertar a letra: escrever na lacuna correspondente 3.2. Se errar a letra: desenhar uma parte do corpo na forca Calcular a média de notas 1. Enquanto houver notas a serem recebidas: 1.1. Receber a nota; 2. Some todas as notas recebidas; 3. Divida o total obtido pela quantidade de notas recebidas; 4. Exiba a média das notas. Jogar o jogo da velha – contra o algoritmo 1. Enquanto existir um quadrado livre e ninguém ganhou ou perdeu o jogo: 1.1. Espere a jogada do adversário, continue depois 1.2. Se centro estiver livre: jogue no centro 1.3. Senão, se o adversário possuir 2 quadrados em linha com um quadrado livre, jogue neste quadrado 1.4. Senão, se há algum canto livre, jogue neste canto - 11 - Introdução á programação e ADVPL Básico 1.2.2. Teste de mesa Após desenvolver um algoritmo ele deverá sempre ser testado. Este teste é chamado de TESTE DE MESA, que significa seguir as instruções do algoritmo de maneira precisa para verificar se o procedimento utilizado está correto ou não. Para avaliar a aplicação do teste de mesa, utilizaremos o algoritmo de calcular a média de notas: Algoritmo: Calcular a média de notas 1. Enquanto houver notas a serem recebidas: a. Receber a nota; 2. Some todas as notas recebidas; 3. Divida o total obtido pela quantidade de notas recebidas; 4. Exiba a média das notas. Teste de mesa: 1. Para cada nota informada, receber e registrar na tabela abaixo: ID Nota 2. Ao término das notas, a tabela deverá conter todas as notas informadas, como abaixo: ID Nota 1 8.0 2 7.0 3 8.0 4 8.0 5 7.0 6 7.0 3. Somar todas as notas: 45 4. Dividir a soma das notas, pelo total de notas informado: 45/6  7.5 5. Exibir a média obtida: Mensagem(Média: 7.5) - 12 - Introdução á programação e ADVPL Básico 2. Estruturas de programação 2.1. Diagrama de bloco O diagrama de blocos é uma forma padronizada e eficaz para representar os passos lógicos de um determinado processamento. Com o diagrama podemos definir uma seqüência de símbolos, com significado bem definido, portanto, sua principal função é a de facilitar a visualização dos passos de um processamento. Simbologia Existem diversos símbolos em um diagrama de bloco. No quadro abaixo estão representados alguns dos símbolos mais utilizados: Símbolo Função Terminador Indica o início e o fim de um processamento. Processamento Processamento em geral. Entrada Manual Indica a entrada de dados através do teclado. Decisão Indica um ponto no qual deverá ser efetuada uma escolha entre duas situações possíveis. Exibição Mostra os resultados obtidos com um processamento. Documento Indica um documento utilizado pelo processamento, seja para entrada de informações ou para exibição dos dados disponíveis após um processamento. Cada símbolo irá conter uma descrição pertinente a forma com o qual o mesmo foi utilizado no fluxo, indicando o processamento ou a informação que o mesmo representa. - 15 - Introdução á programação e ADVPL Básico 2.2. Estruturas de decisão e repetição A utilização de estruturas de decisão e repetição em um algoritmo permite a realização de ações relacionadas a situações que influenciam na execução e solução do problema. Como foco na utilização da linguagem ADVPL serão ilustradas as seguintes estruturas:  Estruturas de decisão o IF...ELSE o DO CASE ... CASE  Estruturas de repetição o WHILE...END o FOR...NEXT 2.2.1. Estruturas de decisão Os comandos de decisão são utilizados em algoritmos cuja solução não é obtida através da utilização de ações meramente seqüenciais, permitindo que este avalie as condições necessárias para optar por uma ou outra maneira de continuar seu fluxo. As estruturas de decisão que serão analisadas são:  IF...ELSE  DO CASE ... CASE IF...ELSE A estrutura IF...ELSE (Se/Senão) permite a análise de uma condição e a partir da qual ser executada uma de duas ações possíveis: se a análise da condição resultar em um valor verdadeiro ou se a análise da condição resultar em um valor falso. Representação 01: IF...ELSE com ações para ambas as situações - 16 - Introdução á programação e ADVPL Básico Esta estrutura permite ainda que seja executada apenas uma ação, na situação em que a a análise da condição resultar em um valor verdadeiro. Representação 02: IF...ELSE somente com ação para situação verdadeira Ação vinculada ao resultado verdadeiro Análise da condição Verdadeiro Falso Ações anteriores ... Continuação do fluxo após a tomada da decisão Apesar das linguagens de programação possuírem variações para a estrutura IF...ELSE, conceitualmente todas as representações podem ser descritas com base no modelo apresentado. A linguagem ADVPL possui uma variação para a estrutura IF...ELSE, descrita como IF...ELSEIF...ELSE. Com esta estrutura é possível realizar a análise de diversas condições em seqüência, para as quais será avaliada somente a ação da primeira expressão cujo análise resultar em um valor verdadeiro. - 17 - Introdução á programação e ADVPL Básico DO CASE...CASE A estrutura DO CASE...ENDCASE (Caso) permite a análise de diversas condições consecutivas, para as quais somente a condição a primeira condição verdadeira será sua ação vinculada executada. O recurso de análise de múltiplas condições é necessário para solução de problemas mais complexos, nos quais as possibilidades de solução superam a mera análise de um único resultado verdadeiro ou falso. Análise da condição 1 Verdadeiro Falso Ações anteriores ... Continuação do fluxo após a tomada da decisão Ação vinculada a condição 1 Análise da condição 2 Verdadeiro Ação vinculada a condição 2 Análise da condição N Verdadeiro Ação vinculada a condição N Falso Falso Falso Apesar das linguagens de programação possuírem variações para a estrutura DO CASE...CASE, conceitualmente todas as representações podem ser descritas com base no modelo apresentado. - 20 - Introdução á programação e ADVPL Básico MÓDULO 02: A linguagem ADVPL A Linguagem ADVPL teve seu início em 1994, sendo na verdade uma evolução na utilização de linguagens no padrão xBase pela Microsiga Software S.A. (Clipper, Visual Objects e depois FiveWin). Com a criação da tecnologia Protheus, era necessário criar uma linguagem que suportasse o padrão xBase para a manutenção de todo o código existente do sistema de ERP Siga Advanced. Foi então criada a linguagem chamada Advanced Protheus Language. O ADVPL é uma extensão do padrão xBase de comandos e funções, operadores, estruturas de controle de fluxo e palavras reservadas, contando também com funções e comandos disponibilizados pela Microsiga que a torna uma linguagem completa para a criação de aplicações ERP prontas para a Internet. Também é uma linguagem orientada a objetos e eventos, permitindo ao programador desenvolver aplicações visuais e criar suas próprias classes de objetos. Quando compilados, todos os arquivos de código tornam-se unidades de inteligência básicas, chamados APO´s (de Advanced Protheus Objects). Tais APO´s são mantidos em um repositório e carregados dinamicamente pelo PROTHEUS Server para a execução. Como não existe a linkedição, ou união física do código compilado a um determinado módulo ou aplicação, funções criadas em ADVPL podem ser executadas em qualquer ponto do ambiente Advanced Protheus. O compilador e o interpretador da linguagem ADVPL é o próprio servidor PROTHEUS (PROTHEUS Server), e existe um ambiente visual para desenvolvimento integrado (PROTHEUSIDE) onde o código pode ser criado, compilado e depurado. Os programas em ADVPL podem conter comandos ou funções de interface com o usuário. De acordo com tal característica, tais programas são subdivididos nas seguintes categorias: Programação Com Interface Própria com o Usuário Nesta categoria entram os programas desenvolvidos para serem executados através do terminal remoto do Protheus, o Protheus Remote. O Protheus Remote é a aplicação encarregada da interface e da interação com o usuário, sendo que todo o processamento do código em ADVPL, o acesso ao banco de dados e o gerenciamento de conexões é efetuado no Protheus Server. O Protheus Remote é o principal meio de acesso a execução de rotinas escritas em ADVPL no Protheus Server, e por isso permite executar qualquer tipo de código, tenha ele interface com o usuário ou não. Porém nesta categoria são considerados apenas os programas que realizem algum tipo de interface remota utilizando o protocolo de comunicação do Protheus. Podem-se criar rotinas para a customização do sistema ERP Microsiga Protheus, desde processos adicionais até mesmo relatórios. A grande vantagem é aproveitar todo o ambiente montado pelos módulos do ERP Microsiga Protheus. Porém, com o ADVPL é possível até mesmo criar toda uma aplicação, ou módulo, do começo. Todo o código do sistema ERP Microsiga Protheus é escrito em ADVPL. Programação Sem Interface Própria com o Usuário As rotinas criadas sem interface são consideradas nesta categoria porque geralmente têm uma utilização mais específica do que um processo adicional ou um relatório novo. Tais rotinas não têm interface com o usuário através do Protheus Remote, e qualquer tentativa nesse sentido - 21 - Introdução á programação e ADVPL Básico (como a criação de uma janela padrão) ocasionará uma exceção em tempo de execução. Estas rotinas são apenas processos, ou Jobs, executados no Protheus Server. Algumas vezes, a interface destas rotinas fica a cargo de aplicações externas, desenvolvidas em outras linguagens, que são responsáveis por iniciar os processos no servidor Protheus através dos meios disponíveis de integração e conectividade no Protheus. De acordo com a utilização e com o meio de conectividade utilizado, estas rotinas são subcategorizadas assim:  Programação por Processos Rotinas escritas em ADVPL podem ser iniciadas como processos individuais (sem interface) no Protheus Server através de duas maneiras: Iniciadas por outra rotina ADVPL através da chamada de funções como StartJob() ou CallProc() ou iniciadas automaticamente na inicialização do Protheus Server (quando propriamente configurado).  Programação de RPC Através de uma biblioteca de funções disponível no Protheus (uma API de comunicação), podem-se executar rotinas escritas em ADVPL diretamente no Protheus Server, através de aplicações externas escritas em outras linguagens. Isto é o que se chama de RPC (de Remote Procedure Call, ou Chamada de Procedimentos Remota). O servidor Protheus também pode executar rotinas em ADVPL em outros servidores Protheus através de conexão TCP/IP direta utilizando o conceito de RPC. Do mesmo modo, aplicações externas podem requisitar a execução de rotinas escritas em ADVPL através de conexão TCP/IP direta. Programação Web O Protheus Server pode também ser executado como um servidor Web, respondendo a requisições HTTP. No momento destas requisições, pode executar rotinas escritas em ADVPL como processos individuais, enviando o resultado das funções como retorno das requisições para o cliente HTTP (como por exemplo, um Browser de Internet). Qualquer rotina escrita em ADVPL que não contenha comandos de interface pode ser executada através de requisições HTTP. O Protheus permite a compilação de arquivos HTML contendo código ADVPL embutido. São os chamados arquivos ADVPL ASP, para a criação de páginas dinâmicas.  Programação TelNet TelNet é parte da gama de protocolos TCP/IP que permite a conexão a um computador remoto através de uma aplicação cliente deste protocolo. O PROTHEUS Server pode emular um terminal TelNet, através da execução de rotinas escritas em ADVPL. Ou seja, pode-se escrever rotinas ADVPL cuja interface final será um terminal TelNet ou um coletor de dados móvel. - 22 - Introdução á programação e ADVPL Básico 3. Estrutura de um Programa ADVPL Um programa de computador nada mais é do que um grupo de comandos logicamente dispostos com o objetivo de executar determinada tarefa. Esses comandos são gravados em um arquivo texto que é transformado em uma linguagem executável por um computador através de um processo chamado compilação. A compilação substitui os comandos de alto nível (que os humanos compreendem) por instruções de baixo nível (compreendida pelo sistema operacional em execução no computador). No caso do ADVPL, não é o sistema operacional de um computador que irá executar o código compilado, mas sim o Protheus Server. Dentro de um programa, os comandos e funções utilizados devem seguir regras de sintaxe da linguagem utilizada, pois caso contrário o programa será interrompido por erros. Os erros podem ser de compilação ou de execução. Erros de compilação são aqueles encontrados na sintaxe que não permitem que o arquivo de código do programa seja compilado. Podem ser comandos especificados de forma errônea, utilização inválida de operadores, etc. Erros de execução são aqueles que acontecem depois da compilação, quando o programa está sendo executado. Podem ocorrer por inúmeras razões, mas geralmente se referem as funções não existentes, ou variáveis não criadas ou inicializadas, etc. Linhas de Programa As linhas existentes dentro de um arquivo texto de código de programa podem ser linhas de comando, linhas de comentário ou linhas mistas.  Linhas de Comando Linhas de comando possuem os comandos ou instruções que serão executadas. Por exemplo: Local nCnt Local nSoma := 0 For nCnt := 1 To 10 nSoma += nCnt Next nCnt  Linhas de Comentário Linhas de comentário possuem um texto qualquer, mas não são executadas. Servem apenas para documentação e para tornar mais fácil o entendimento do programa. Existem três formas de se comentar linhas de texto. A primeira delas é utilizar o sinal de * (asterisco) no começo da linha: * Programa para cálculo do total * Autor: Microsiga Software S.A. * Data: 2 de outubro de 2001 - 25 - Introdução á programação e ADVPL Básico Área de Identificação Esta é uma área que não é obrigatória e é dedicada a documentação do programa. Quando existente, contém apenas comentários explicando a sua finalidade, data de criação, autor, etc., e aparece no começo do programa, antes de qualquer linha de comando. O formato para esta área não é definido. Pode-se colocar qualquer tipo de informação desejada e escolher a formatação apropriada. #include “protheus.ch” /* +==========================================+ | Programa: Cálculo do Fatorial | | Autor : Microsiga Software S.A. | | Data : 02 de outubro de 2001 | +==========================================+ */ User Function CalcFator() Opcionalmente podem-se incluir definições de constantes utilizadas no programa ou inclusão de arquivos de cabeçalho nesta área. Área de Ajustes Iniciais Nesta área geralmente se fazem os ajustes iniciais, importantes para o correto funcionamento do programa. Entre os ajustes se encontram declarações de variáveis, inicializações, abertura de arquivos, etc. Apesar do ADVPL não ser uma linguagem rígida e as variáveis poderem ser declaradas em qualquer lugar do programa, é aconselhável fazê-lo nesta área visando tornar o código mais legível e facilitar a identificação de variáveis não utilizadas. Local nCnt Local nResultado := 0 // Resultado do fatorial Local nFator := 10 // Número para o cálculo Corpo do Programa É nesta área que se encontram as linhas de código do programa. É onde se realiza a tarefa necessária através da organização lógica destas linhas de comando. Espera-se que as linhas de comando estejam organizadas de tal modo que no final desta área o resultado esperado seja obtido, seja ele armazenado em um arquivo ou em variáveis de memória, pronto para ser exibido ao usuário através de um relatório ou na tela. // Cálculo do fatorial For nCnt := nFator To 1 Step -1 nResultado *= nCnt Next nCnt - 26 - Introdução á programação e ADVPL Básico A preparação para o processamento é formada pelo conjunto de validações e processamentos necessários antes da realização do processamento em si. Avaliando o processamento do cálculo do fatorial descrito anteriormente, pode-se definir que a validação inicial a ser realizada é o conteúdo da variável nFator, pois a mesma determinará a correta execução do código. // Cálculo do fatorial nFator := GetFator() // GetFator – função ilustrativa na qual a variável recebe a informação do usuário. If nFator <= 0 Alert(“Informação inválida”) Return Endif For nCnt := nFator To 1 Step -1 nResultado *= nCnt Next nCnt Área de Encerramento É nesta área onde as finalizações são efetuadas. É onde os arquivos abertos são fechados, e o resultado da execução do programa é utilizado. Pode-se exibir o resultado armazenado em uma variável ou em um arquivo ou simplesmente finalizar, caso a tarefa já tenha sido toda completada no corpo do programa. É nesta área que se encontra o encerramento do programa. Todo programa em ADVPL deve sempre terminar com a palavra chave return. // Exibe o resultado na tela, através da função alert Alert("O fatorial de " + cValToChar(nFator) + ; " é " + cValToChar(nResultado)) // Termina o programa Return - 27 - Introdução á programação e ADVPL Básico 4. Declaração e Atribuição de Variáveis 4.1. Tipo de Dados O ADVPL não é uma linguagem de tipos rígidos (strongly typed), o que significa que variáveis de memória podem receber diferentes tipos de dados durante a execução do programa. As variáveis podem também conter objetos, mas os tipos primários da linguagem são: Numérico O ADVPL não diferencia valores inteiros de valores com ponto flutuante, portanto podem-se criar variáveis numéricas com qualquer valor dentro do intervalo permitido. Os seguintes elementos são do tipo de dado numérico: 2 43.53 0.5 0.00001 1000000 Uma variável do tipo de dado numérico pode conter um número de dezoito dígitos incluindo o ponto flutuante, no intervalo de 2.2250738585072014 E–308 até 1.7976931348623158 E+308. Lógico Valores lógicos em ADVPL são identificados através de .T. ou .Y. para verdadeiro e .F. ou .N. para falso (independentemente se os caracteres estiverem em maiúsculo ou minúsculo). Caractere Strings ou cadeias de caracteres são identificadas em ADVPL por blocos de texto entre aspas duplas (") ou aspas simples ('): "Olá mundo!" 'Esta é uma string' "Esta é 'outra' string" Uma variável do tipo caractere pode conter strings com no máximo 1 MB, ou seja, 1048576 caracteres. Data O ADVPL tem um tipo de dados específico para datas. Internamente as variáveis deste tipo de dado são armazenadas como um número correspondente a data Juliana. Variáveis do tipo de dados Data não podem ser declaradas diretamente, e sim através da utilização de funções específicas como por exemplo CTOD() que converte uma string para data. - 30 - Introdução á programação e ADVPL Básico Variáveis de escopo local Variáveis de escopo local são pertencentes apenas ao escopo da função onde foram declaradas e devem ser explicitamente declaradas com o identificador LOCAL, como no exemplo: Function Pai() Local nVar := 10, aMatriz := {0,1,2,3} . <comandos> . Filha() . <mais comandos> . Return(.T.) Neste exemplo, a variável nVar foi declarada como local e atribuída com o valor 10. Quando a função Filha é executada, nVar ainda existe mas não pode ser acessada. Quando a execução da função Pai terminar, a variável nVar é destruída. Qualquer variável com o mesmo nome no programa que chamou a função Pai não é afetada. Variáveis de escopo local são criadas automaticamente cada vez que a função onde forem declaradas for ativada. Elas continuam a existir e mantêm seu valor até o fim da ativação da função (ou seja, até que a função retorne o controle para o código que a executou). Se uma função é chamada recursivamente (por exemplo, chama a si mesma), cada chamada em recursão cria um novo conjunto de variáveis locais. A visibilidade de variáveis de escopo locais é idêntica ao escopo de sua declaração, ou seja, a variável é visível em qualquer lugar do código fonte em que foi declarada. Se uma função é chamada recursivamente, apenas as variáveis de escopo local criadas na mais recente ativação são visíveis. Variáveis de escopo static Variáveis de escopo static funcionam basicamente como as variáveis de escopo local, mas mantêm seu valor através da execução e devem ser declaradas explicitamente no código com o identificador STATIC. O escopo das variáveis static depende de onde são declaradas. Se forem declaradas dentro do corpo de uma função ou procedimento, seu escopo será limitado àquela rotina. Se forem declaradas fora do corpo de qualquer rotina, seu escopo afeta a todas as funções declaradas no fonte. - 31 - Introdução á programação e ADVPL Básico Neste exemplo, a variável nVar é declarada como static e inicializada com o valor 10: Function Pai() Static nVar := 10 . <comandos> . Filha() . <mais comandos> . Return(.T.) Quando a função Filha é executada, nVar ainda existe mas não pode ser acessada. Diferente de variáveis declaradas como LOCAL ou PRIVATE, nVar continua a existir e mantêm seu valor atual quando a execução da função Pai termina. Entretanto, somente pode ser acessada por execuções subseqüentes da função Pai. Variáveis de escopo private A declaração é opcional para variáveis privadas. Mas podem ser declaradas explicitamente com o identificador PRIVATE. Adicionalmente, a atribuição de valor a uma variável não criada anteriormente automaticamente cria a variável como privada. Uma vez criada, uma variável privada continua a existir e mantém seu valor até que o programa ou função onde foi criada termine (ou seja, até que a função onde foi criada retorne para o código que a executou). Neste momento, é automaticamente destruída. É possível criar uma nova variável privada com o mesmo nome de uma variável já existente. Entretanto, a nova (duplicada) variável pode apenas ser criada em um nível de ativação inferior ao nível onde a variável foi declarada pela primeira vez (ou seja, apenas em uma função chamada pela função onde a variável já havia sido criada). A nova variável privada irá esconder qualquer outra variável privada ou pública (veja a documentação sobre variáveis públicas) com o mesmo nome enquanto existir. Uma vez criada, uma variável privada é visível em todo o programa enquanto não for destruída automaticamente quando a rotina que a criou terminar ou uma outra variável privada com o mesmo nome for criada em uma subfunção chamada (neste caso, a variável existente torna-se inacessível até que a nova variável privada seja destruída). Em termos mais simples, uma variável privada é visível dentro da função de criação e todas as funções chamadas por esta, a menos que uma função chamada crie sua própria variável privada com o mesmo nome. - 32 - Introdução á programação e ADVPL Básico Por exemplo: Function Pai() Private nVar := 10 <comandos> . Filha() <mais comandos> . Return(.T.) Neste exemplo, a variável nVar é criada com escopo private e inicializada com o valor 10. Quando a função Filha é executada, nVar ainda existe e, diferente de uma variável de escopo local, pode ser acessada pela função Filha. Quando a função Pai terminar, nVar será destruída e qualquer declaração de nVar anterior se tornará acessível novamente. No ambiente ERP Protheus, existe uma convenção adicional a qual deve ser respeitada que variáveis em uso pela aplicação não sejam incorretamente manipuladas. Por esta convenção deve ser adicionado o caracter “_” antes do nome de variáveis PRIVATE e PUBLIC. Maiores informações avaliar o tópico: Boas Práticas de Programação. Exemplo: Private _dData Variáveis de escopo public Podem-se criar variáveis de escopo public dinamicamente no código com o identificador PUBLIC. As variáveis deste escopo continuam a existir e mantêm seu valor até o fim da execução da thread (conexão). É possível criar uma variável de escopo private com o mesmo nome de uma variável de escopo public existente, entretanto, não é permitido criar uma variável de escopo public com o mesmo nome de uma variável de escopo private existente. Uma vez criada, uma variável de escopo public é visível em todo o programa onde foi declarada até que seja escondida por uma variável de escopo private criada com o mesmo nome. A nova variável de escopo private criada esconde a variável de escopo public existente, e esta se tornará inacessível até que a nova variável private seja destruída. Por exemplo: Function Pai() Public nVar := 10 <comandos> . Filha() <mais comandos> . Return(.T.) - 35 - Introdução á programação e ADVPL Básico Note também que quando uma variável é do tipo de dado lógico, ela pode ser utilizada diretamente para checagem (linha 10): If xVariavel é o mesmo que If xVariavel = .T. 4.5.2. Operadores da linguagem ADVPL Operadores comuns Na documentação sobre variáveis há uma breve demonstração de como atribuir valores a uma variável da forma mais simples. O ADVPL amplia significativamente a utilização de variáveis através do uso de expressões e funções. Uma expressão é um conjunto de operadores e operandos cujo resultado pode ser atribuído a uma variável ou então analisado para a tomada de decisões. Por exemplo: Local nSalario := 1000, nDesconto := 0.10 Local nAumento, nSalLiquido nAumento := nSalario * 1.20 nSalLiquido := nAumento * (1-nDesconto) Neste exemplo são utilizadas algumas expressões para calcular o salário líquido após um aumento. Os operandos de uma expressão podem ser uma variável, uma constante, um campo de arquivo ou uma função. Operadores Matemáticos Os operadores utilizados em ADVPL para cálculos matemáticos são: + Adição - Subtração * Multiplicação / Divisão ** ou ^ Exponenciação % Módulo (Resto da Divisão) Operadores de String Os operadores utilizados em ADVPL para tratamento de caracteres são: + Concatenação de strings (união) - Concatenação de strings com eliminação dos brancos finais das strings intermediárias $ Comparação de Substrings (contido em) - 36 - Introdução á programação e ADVPL Básico Operadores Relacionais Os operadores utilizados em ADVPL para operações e avaliações relacionais são: < Comparação Menor > Comparação Maior = Comparação Igual == Comparação Exatamente Igual (para caracteres) <= Comparação Menor ou Igual >= Comparação Maior ou Igual <> ou # ou != Comparação Diferente Operadores Lógicos Os operadores utilizados em ADVPL para operações e avaliações lógicas são: .And. E lógico .Or. OU lógico .Not. ou ! NÃO lógico Operadores de Atribuição Os operadores utilizados em ADVPL para atribuição de valores a variáveis de memória são: := Atribuição Simples += Adição e Atribuição em Linha -= Subtração e Atribuição em Linha *= Multiplicação e Atribuição em Linha /= Divisão e Atribuição em Linha **= ou ^= Exponenciação e Atribuição em Linha %= Módulo (resto da divisão) e Atribuição em Linha  Atribuição Simples O sinal de igualdade é utilizado para atribuir valor a uma variável de memória. nVariavel := 10  Atribuição em Linha O operador de atribuição em linha é caracterizado por dois pontos e o sinal de igualdade. Tem a mesma função do sinal de igualdade sozinho, porém aplica a atribuição às variáveis. Com ele pode-se atribuir mais de uma variável ao mesmo tempo. nVar1 := nVar2 := nVar3 := 0 - 37 - Introdução á programação e ADVPL Básico Quando diversas variáveis são inicializadas em uma mesma linha, a atribuição começa da direita para a esquerda, ou seja, nVar3 recebe o valor zero inicialmente, nVar2 recebe o conteúdo de nVar3 e nVar1 recebe o conteúdo de nVar2 por final. Com o operador de atribuição em linha, pode-se substituir as inicializações individuais de cada variável por uma inicialização apenas: Local nVar1 := 0, nVar2 := 0, nVar3 := 0 por Local nVar1 := nVar2 := nVar3 := 0 O operador de atribuição em linha também pode ser utilizado para substituir valores de campos em um banco de dados.  Atribuição Composta Os operadores de atribuição composta são uma facilidade da linguagem ADVPL para expressões de cálculo e atribuição. Com eles pode-se economizar digitação: Operador Exemplo Equivalente a += X += Y X = X + Y -= X -= Y X = X - Y *= X *= Y X = X * Y /= X /= Y X = X / Y **= ou ^= X **= Y X = X ** Y %= X %= Y X = X % Y Operadores de Incremento/Decremento A linguagem ADVPL possui operadores para realizar incremento ou decremento de variáveis. Entende-se por incremento aumentar o valor de uma variável numérica em 1 e entende-se por decremento diminuir o valor da variável em 1. Os operadores são: ++ Incremento Pós ou Pré-fixado -- Decremento Pós ou Pré-fixado Os operadores de decremento/incremento podem ser colocados tanto antes (pré-fixado) como depois (pós-fixado) do nome da variável. Dentro de uma expressão, a ordem do operador é muito importante, podendo alterar o resultado da expressão. Os operadores incrementais são executados da esquerda para a direita dentro de uma expressão. Local nA := 10 Local nB := nA++ + nA O valor da variável nB resulta em 21, pois a primeira referência a nA (antes do ++) continha o valor 10 que foi considerado e imediatamente aumentado em 1. Na segunda referência a nA, este já possuía o valor 11. O que foi efetuado foi a soma de 10 mais 11, igual a 21. O resultado final após a execução destas duas linhas é a variável nB contendo 21 e a variável nA contendo 11. No entanto: Local nA := 10 Local nB := ++nA + nA - 40 - Introdução á programação e ADVPL Básico 4.5.3. Operação de Macro Substituição O operador de macro substituição, simbolizado pelo "e" comercial (&), é utilizado para a avaliação de expressões em tempo de execução. Funciona como se uma expressão armazenada fosse compilada em tempo de execução, antes de ser de fato executada. Considere o exemplo: 01 X := 10 02 Y := "X + 1" 03 B := &Y // O conteúdo de B será 11 A variável X é atribuída com o valor 10, enquanto a variável Y é atribuída com a string de caracteres contendo "X + 1". A terceira linha utiliza o operador de macro. Esta linha faz com que o número 11 seja atribuído à variável B. Pode-se perceber que esse é o valor resultante da expressão em formato de caractere contida na variável Y. Utilizando-se uma técnica matemática elementar, a substituição, temos que na segunda linha, Y é definido como "X + 1", então pode-se substituir Y na terceira linha: 03 B := &"X + 1" O operador de macro cancela as aspas: 03 B := X + 1 Pode-se perceber que o operador de macro remove as aspas, o que deixa um pedaço de código para ser executado. Deve-se ter em mente que tudo isso acontece em tempo de execução, o que torna tudo muito dinâmico. Uma utilização interessante é criar um tipo de calculadora, ou avaliador de fórmulas, que determina o resultado de algo que o usuário digita. O operador de macro tem uma limitação: variáveis referenciadas dentro da string de caracteres (X nos exemplos anteriores) não podem ser locais. - 41 - Introdução á programação e ADVPL Básico 4.5.4. Funções de manipulação de variáveis Além de atribuir, controlar o escopo e macro executar o conteúdo das variáveis é necessário manipular seu conteúdo através de funções específicas da linguagem para cada situação. As operações de manipulação de conteúdo mais comuns em programação são:  Conversões entre tipos de variáveis  Manipulação de strings  Manipulação de variáveis numéricas  Verificação de tipos de variáveis  Manipulação de arrays  Execução de blocos de código Neste tópico serão abordadas as conversões entre tipos de variáveis e as funções de manipulação de strings e variáveis numéricas. Conversões entre tipos de variáveis As funções mais utilizadas nas operações entre conversão entre tipos de variáveis são:  CTOD()  CVALTOCHAR()  DTOC()  DTOS()  STOD()  STR()  STRZERO()  VAL() CTOD() Sintaxe CTOD(cData) Descrição Realiza a conversão de uma informação do tipo caracter no formato “DD/MM/AAAA” para uma variável do tipo data. CVALTOCHAR() Sintaxe CVALTOCHAR(nValor) Descrição Realiza a conversão de uma informação do tipo numérico em uma string, sem a adição de espaços a informação. - 42 - Introdução á programação e ADVPL Básico DTOC() Sintaxe DTOC(dData) Descrição Realiza a conversão de uma informação do tipo data para em caracter, sendo o resultado no formato “DD/MM/AAAA”. DTOS() Sintaxe DTOS(dData) Descrição Realiza a conversão de uma informação do tipo data em um caracter, sendo o resultado no formato “AAAAMMDD”. STOD() Sintaxe STOD(sData) Descrição Realiza a conversão de uma informação do tipo caracter com conteúdo no formato “AAAAMMDD” em data. STR() Sintaxe STR(nValor) Descrição Realiza a conversão de uma informação do tipo numérico em uma string, adicionando espaços à direita. STRZERO() Sintaxe STRZERO(nValor, nTamanho) Descrição Realiza a conversão de uma informação do tipo numérico em uma string, adicionando zeros à esquerda do número convertido, de forma que a string gerada tenha o tamanho especificado no parâmetro. VAL() Sintaxe VAL(cValor) Descrição Realiza a conversão de uma informação do tipo caracter em numérica. - 45 - Introdução á programação e ADVPL Básico UPPER() Sintaxe UPPER(cString) Descrição Retorna uma string com todos os caracteres maiúsculos, tendo como base a string passada como parâmetro. Manipulação de variáveis numéricas As funções mais utilizadas nas operações de manipulação do conteúdo de strings são:  ABS()  INT()  NOROUND()  ROUND() ABS() Sintaxe ABS(nValor) Descrição Retorna um valor absoluto (independente do sinal) com base no valor especificado no parâmetro. INT() Sintaxe INT(nValor) Descrição Retorna a parte inteira de um valor especificado no parâmetro. NOROUND() Sintaxe NOROUND(nValor, nCasas) Descrição Retorna um valor, truncando a parte decimal do valor especificado no parâmetro de acordo com a quantidade de casas decimais solicitadas. ROUND() Sintaxe ROUND(nValor, nCasas) Descrição Retorna um valor, arredondando a parte decimal do valor especificado no parâmetro de acordo com a quantidades de casas decimais solicitadas, utilizando o critério matemático. - 46 - Introdução á programação e ADVPL Básico Verificação de tipos de variáveis As funções de verificação permitem a consulta ao tipo do conteúdo da variável durante a execução do programa.  TYPE()  VALTYPE() TYPE() Sintaxe TYPE(“cVariavel”) Descrição Determina o tipo do conteúdo de uma variável, a qual não foi definida na função em execução. VALTYPE() Sintaxe VALTYPE(cVariável) Descrição Determina o tipo do conteúdo de uma variável, a qual foi definida na função em execução. - 47 - Introdução á programação e ADVPL Básico 5. Estruturas básicas de programação O ADVPL suporta várias estruturas de controle que permitem mudar a seqüência de fluxo de execução de um programa. Estas estruturas permitem a execução de código baseado em condições lógica e a repetição da execução de pedaços de código qualquer número de vezes. Em ADVPL, todas as estruturas de controle podem ser "aninhadas" dentro de todas as demais estruturas contanto que estejam aninhadas propriamente. Estruturas de controle têm um identificador de início e um de fim, e qualquer estrutura aninhada deve se encontrar entre estes identificadores. Também existem estruturas de controle para determinar que elementos, comandos, etc. em um programa serão compilados. Estas são as diretivas do pré-processador #ifdef...#endif e #ifndef...#endif. Consulte a documentação sobre o pré-processador para maiores detalhes. As estruturas de controle em ADVPL estão divididas em:  Estruturas de repetição  Estruturas de decisão 5.1. Estruturas de repetição Estruturas de repetição são designadas para executar uma seção de código mais de uma vez. Por exemplo, imaginando-se a existência de uma função para imprimir um relatório, pode-se desejar imprimi-lo quatro vezes. Claro, pode-se simplesmente chamar a função de impressão quatro vezes em seqüência, mas isto se tornaria pouco profissional e não resolveria o problema se o número de relatórios fosse variável. Em ADVPL existem dois comandos para a repetição de seções de código, que são os comandos FOR...NEXT e o comando WHILE...ENDDO. O Comando FOR...NEXT A estrutura de controle FOR...NEXT, ou simplesmente o loop FOR, repete uma seção de código em um número determinado de vezes.  Sintaxe FOR Variavel := nValorInicial TO nValorFinal [STEP nIncremento] Comandos... [EXIT] [LOOP] NEXT - 50 - Introdução á programação e ADVPL Básico Exemplo : Local nNumber := nAux := 350 nAux := Int(nAux / 2) While nAux > 0 nSomaPar += nCnt Next Alert( "A soma dos 100 primeiros números pares é: " + ; cValToChar(nSomaPar) ) Return 5.1.1. Influenciando o fluxo de repetição A linguagem ADVPL permite a utilização de comandos que influem diretamente em um processo de repetição, sendo eles:  LOOP  EXIT LOOP A instrução LOOP é utilizada para forçar um desvio no fluxo do programa de volta a análise da condição de repetição. Desta forma, todas as operações que seriam realizadas dentro da estrutura de repetição após o LOOP serão desconsideradas. Exemplo: aItens:= ListaProdutos() // função ilustrativa que retorna um array com dados dos produtos nQuantidade := Len(aItens) nItens := 0 While nItens < nQuantidade nItens++ IF BLOQUEADO(aItens [nItens]) // função ilustrativa que verifica se o produto está LOOP // bloqueado. ENDIF IMPRIME() // função ilustrativa que realiza a impressão de um item liberado para uso End // Caso o produto esteja bloqueado, o mesmo não será impresso, pois a execução da // instrução LOOP fará o fluxo do programa retornar a partir da análise da condição. - 51 - Introdução á programação e ADVPL Básico EXIT A instrução EXIT é utilizada para forçar o término de uma estrutura de repetição. Desta forma, todas as operações que seriam realizadas dentro da estrutura de repetição após o EXIT serão desconsideradas, e o programa irá continuar a execução a partir da próxima instrução posterior ao término da estrutura (END ou NEXT). Exemplo: While .T. IF MSGYESNO(“Deseja jogar o jogo da forca?”) JFORCA() // Função ilustrativa que implementa o algoritmo do jogo da forca. ELSE EXIT ENDIF End MSGINFO(“Final de Jogo”) // Enquanto não for respondido “Não” para a pergunta: “Deseja jogar o jogo da // forca”, será executada a função do jogo da forca. // Caso seja selecionada a opção “Não”, será executada a instrução EXIT que provocará o término do LOOP, permitindo a execução da mensagem de “Final de Jogo”. - 52 - Introdução á programação e ADVPL Básico 5.2. Estruturas de decisão Estruturas de desvio são designadas para executar uma seção de código se determinada condição lógica resultar em verdadeiro (.T.). Em ADVPL existem dois comandos para execução de seções de código de acordo com avaliações lógicas, que são os comandos IF...ELSE...ENDIF e o comando DO CASE...ENDCASE. O Comando IF...ELSE...ENDIF Executa um conjunto de comandos baseado no valor de uma expressão lógica.  Sintaxe IF lExpressao Comandos [ELSE Comandos...] ENDIF  Parâmetros LExpressao Especifica uma expressão lógica que é avaliada. Se lExpressao resultar em verdadeiro (.T.), qualquer comando seguinte ao IF e antecedente ao ELSE ou ENDIF (o que ocorrer primeiro) será executado. Se lExpressao resultar em falso (.F.) e a cláusula ELSE for definida, qualquer comando após essa cláusula e anterior ao ENDIF será executada. Se a cláusula ELSE não for definida, todos os comandos entre o IF e o ENDIF são ignorados. Neste caso, a execução do programa continua com o primeiro comando seguinte ao ENDIF. Comandos Conjunto de comandos ADVPL que serão executados dependendo da avaliação da expressão lógica em lExpressao. Pode-se aninhar um bloco de comando IF...ELSE...ENDIF dentro de outro bloco de comando IF...ELSE...ENDIF. Porém, para a avaliação de mais de uma expressão lógica, deve-se utilizar o comando DO CASE...ENDCASE ou a versão estendida da expressão IF...ELSE...ENDIF denominada IF...ELSEIF...ELSE...ENDIF. Exemplo: Local dVencto := CTOD("31/12/01") If Date() > dVencto Alert("Vencimento ultrapassado!") Endif Return - 55 - Introdução á programação e ADVPL Básico O Comando DO CASE...ENDCASE é utilizado no lugar do comando IF...ENDIF quando um número maior do que uma expressão deve ser avaliada, substituindo a necessidade de mais de um comando IF...ENDIF aninhados. Exemplo: Local nMes := Month(Date()) Local cPeriodo := "" DO CASE CASE nMes <= 3 cPeriodo := "Primeiro Trimestre" CASE nMes >= 4 .And. nMes <= 6 cPeriodo := "Segundo Trimestre" CASE nMes >= 7 .And. nMes <= 9 cPeriodo := "Terceiro Trimestre" OTHERWISE cPeriodo := "Quarto Trimestre" ENDCASE Return - 56 - Introdução á programação e ADVPL Básico 6. Arrays e Blocos de Código 6.1. Arrays Arrays ou matrizes, são coleções de valores, semelhantes a uma lista. Uma matriz pode ser criada através de diferentes maneiras. Cada item em um array é referenciado pela indicação de sua posição numérica na lista, iniciando pelo número 1. O exemplo a seguir declara uma variável, atribui um array de três elementos a ela, e então exibe um dos elementos e o tamanho do array: Local aLetras // Declaração da variável aLetras := {"A", "B", "C"} // Atribuição do array a variável Alert(aLetras[2]) // Exibe o segundo elemento do array Alert(cValToChar(Len(aLetras))) // Exibe o tamanho do array O ADVPL permite a manipulação de arrays facilmente. Enquanto que em outras linguagens como C ou Pascal é necessário alocar memória para cada elemento de um array (o que tornaria a utilização de "ponteiros" necessária), o ADVPL se encarrega de gerenciar a memória e torna simples adicionar elementos a um array, utilizando a função AADD(): AADD(aLetras,"D") // Adiciona o quarto elemento ao final do array Alert(aLetras[4]) // Exibe o quarto elemento Alert(aLetras[5]) // Erro! Não há um quinto elemento no array Arrays como Estruturas Uma característica interessante do ADVPL é que um array pode conter qualquer tipo de dado: números, datas, lógicos, caracteres, objetos, etc., e ao mesmo tempo. Em outras palavras, os elementos de um array não precisam ser necessariamente do mesmo tipo de dado, em contraste com outras linguagens como C e Pascal. aFunct1 := {"Pedro",32,.T.} Este array contem uma string, um número e um valor lógico. Em outras linguagens como C ou Pascal, este "pacote" de informações pode ser chamado como um "struct" (estrutura em C, por exemplo) ou um "record" (registro em Pascal, por exemplo). Como se fosse na verdade um registro de um banco de dados, um pacote de informações construído com diversos campos. Cada campo tendo um pedaço diferente de dado. Suponha que no exemplo anterior, o array aFunct1 contenha informações sobre o nome de uma pessoa, sua idade e sua situação matrimonial. Os seguintes #defines podem ser criados para indicar cada posição dos valores dentro de um array: #define FUNCT_NOME 1 #define FUNCT_IDADE 2 #define FUNCT_CASADO 3 - 57 - Introdução á programação e ADVPL Básico E considere mais alguns arrays para representar mais pessoas: aFunct2 := {"Maria" , 22, .T.} aFunct3 := {"Antônio", 42, .F.} Os nomes podem ser impressos assim: Alert(aFunct1[FUNCT_NOME]) Alert(aFunct2[FUNCT_NOME]) Alert(aFunct3[FUNCT_NOME]) Agora, ao invés de trabalhar com variáveis individuais, pode-se agrupá-las em um outro array, do mesmo modo que muitos registros são agrupados em uma tabela de banco de dados: aFuncts := {aFunct1, aFunct2, aFunct3} Que é equivalente a isso: aFuncts := { {"Pedro" , 32, .T.}, ; {"Maria" , 22, .T.}, ; {"Antônio", 42, .F.} } aFuncts é um array com 3 linhas por 3 colunas. Uma vez que as variáveis separadas foram combinadas em um array, os nomes podem ser exibidos assim: Local nCount For nCount := 1 To Len(aFuncts) Alert(aFuncts[nCount, FUNCT_NOME]) // O acesso a elementos de um array multidimensional // pode ser realizado também desta forma: // aFuncts[nCount][FUNCT_NOME] Next nCount A variável nCount seleciona que funcionário (ou que linha) é de interesse. Então a constante FUNCT_NOME seleciona a primeira coluna daquela linha. Cuidados com Arrays Arrays são listas de elementos, portanto memória é necessária para armazenar estas informações. Como estes arrays podem ser multidimensionais, a memória necessária será a multiplicação do número de itens em cada dimensão do array, considerando-se o tamanho do conteúdo de cada elemento contido nesta. Portanto o tamanho de um array pode variar muito. A facilidade da utilização de arrays, mesmo que para armazenar informações em pacotes como descrito anteriormente, não é compensada pela utilização em memória quando o número de itens em um array for muito grande. Quando o número de elementos for muito grande deve-se procurar outras soluções, como a utilização de um arquivo de banco de dados temporário. - 60 - Introdução á programação e ADVPL Básico ARRAY() Sintaxe ARRAY(nLinhas, nColunas) Descrição A função Array() é utilizada na definição de variáveis de tipo array, como uma opção a sintaxe utilizando chaves (“{}”). AADD() Sintaxe AADD(aArray, xItem) Descrição A função AADD() permite a inserção de um item em um array já existente, sendo que este item podem ser um elemento simples, um objeto ou outro array. ACLONE() Sintaxe AADD(aArray) Descrição A função ACLONE() realiza a cópia dos elementos de um array para outro array integralmente. ADEL() Sintaxe ADEL(aArray, nPosição) Descrição A função ADEL() permite a exclusão de um elemento do array. Ao efetuar a exclusão de um elemento, todos os demais são reorganizados de forma que a ultima posição do array passará a ser nula. ASIZE() Sintaxe ASIZE(aArray, nTamanho) Descrição A função ASIZE permite a redefinição da estrutura de um array pré- existente, adicionando ou removendo itens do mesmo. ASORT() Sintaxe ASORT(aArray, nInicio, nItens, bOrdem) Descrição A função ASORT() permite que os itens de um array sejam ordenados a partir de um critério pré-estabelecido. - 61 - Introdução á programação e ADVPL Básico ASCAN() Sintaxe ASCAN(aArray, bSeek) Descrição A função ASCAN() permite que seja identificada a posição do array que contém uma determinada informação, através da análise de uma expressão descrita em um bloco de código. AINS() Sintaxe AINS(aArray, nPosicao) Descrição A função AINS() permite a inserção de um elemento no array especificado em qualquer ponto da estrutura do mesmo, diferindo desta forma da função AADD() a qual sempre insere um novo elemento ao final da estrutura já existente. 6.1.3. Cópia de arrays Conforme comentado anteriormente, um array é uma área na memória, o qual possui uma estrutura permite que as informações sejam armazenadas e organizadas das mais diversas formas. Com base nesse conceito, o array pode ser considerado apenas como um “mapa” ou um “guia” de como as informações estão organizadas e de como elas podem ser armazenadas ou consultadas. Para se copiar um array deve-se levar este conceito em consideração, pois caso contrário o resultado esperado não será o obtido na execução da “cópia”. Para “copiar” o conteúdo de uma variável, utiliza-se o operador de atribuição “:=”, conforme abaixo: nPessoas := 10 nAlunos := nPessoas Ao executar a atribuição de nAlunos com o conteúdo de nPessoas, o conteúdo de nPessoas é atribuído a variável nAlunos, causando o efeito de cópia do conteúdo de uma variável para outra. Isto porque o comando de atribuição copia o conteúdo da área de memória representada pelo nome “nPessoas” para a área de memória representada pelo nome “nAlunos”. Mas ao utilizar o operador de atribuição “:=” da mesma forma que utilizado em variáveis simples para se copiar um array o efeito é diferente: aPessoas := {“Ricardo”, “Cristiane”, “André”, “Camila”} aAlunos := aPessoas - 62 - Introdução á programação e ADVPL Básico A variável aPessoas represente uma área de memória que contém a estrutura de um array (“mapa”), não as informações do array, pois cada informação está em sua própria área de memória. Desta forma ao atribuir o conteúdo representado pela variável aPessoas a variável aAlunos não está se “copiando” as informações e sim o “mapa” das áreas de memória onde as informações estão realmente armazenadas. Como foi copiado o “mapa” e não as informações, qualquer ação utilizando o rótulo aAlunos irá afetar as informações do rótulo aPessoas. Com isso ao invés de se obter dois arrays distintos, tem-se o mesmo array com duas formas de acesso (rótulos) diferentes. Por esta razão deve ser utilizado o comando ACLONE() quando deseja-se obter um array com a mesma estrutura e informações que compõe outro array já existente. - 65 - Introdução á programação e ADVPL Básico Convertendo para uma lista de expressões Quando parênteses são colocados ao redor do código e o sinal de ponto-e-vírgula substituído por uma vírgula apenas, o código torna-se uma lista de expressões: Alert( cValToChar ( ( X := 10 , Y := 20 ) ) ) ==> 20 O valor de retorno resultante de uma lista de expressões é o valor resultante da última expressão ou elemento da lista. Funciona como se fosse um pequeno programa ou função, que retorna o resultado de sua última avaliação (efetuadas da esquerda para a direita). Neste exemplo, a expressão x := 10 é avaliada, e então a expressão y := 20, cujo valor resultante é passado para a função alert e cvaltochar, e então exibido. Depois que essa linha de código é executada, o valor de X é igual a 10 e o de y igual a 20, e 20 será exibido. Teoricamente, não há limitação para o número de expressões que podem ser combinadas em uma lista de expressões. Na prática, o número máximo é por volta de 500 símbolos. Debugar listas de expressões é difícil porque as expressões não estão divididas em linhas de código fonte, o que torna todas as expressões associadas a uma mesma linha de código. Isto pode tornar muito difícil determinar onde um erro ocorreu. Onde pode-se utilizar uma lista de expressões? O propósito principal de uma lista de expressões é agrupá-las em uma única unidade. Em qualquer lugar do código ADVPL que uma expressão simples pode ser utilizada, pode-se utilizar uma lista de expressões. E ainda, pode-se fazer com que várias coisas aconteçam onde normalmente apenas uma aconteceria. X := 10 ; Y := 20 If X > Y Alert("X") Z := 1 Else Alert("Y") Z := -1 Endif Aqui temos o mesmo conceito, escrito utilizando listas de expressões na função IIF(): X := 10 ; Y := 20 iif( X > Y , ; ( Alert("X"), Z := 1 ) , ; ( Alert("Y"), Z := -1 ) ) De listas de expressões para blocos de código Considere a seguinte lista de expressões: Alert( cValToChar( ( x := 10, y := 20 ) ) ) ==> 20 O ADVPL permite criar funções, que são pequenos pedaços de código, como se fosse um pequeno programa, utilizados para diminuir partes de tarefas mais complexas e reaproveitar código em mais de um lugar num programa. Para maiores detalhes consulte a documentação sobre a criação de funções em ADVPL. Porém, a idéia neste momento é que a lista de expressões utilizada na linha anterior pode ser criada como uma função: - 66 - Introdução á programação e ADVPL Básico Function Lista() X := 10 Y := 20 Return Y E a linha de exemplo com a lista de expressões pode ser substituída, tendo o mesmo resultado, por: Alert( cValToChar( Lista() ) ) ==> 20 Como mencionado anteriormente, uma lista de expressões é como um pequeno programa ou função. Com poucas mudanças, uma lista de expressões pode se tornar um bloco de código: ( X := 10 , Y := 20 ) // Lista de Expressões {|| X := 10 , Y := 20 } // Bloco de Código Note as chaves {} utilizadas no bloco de código. Ou seja, um bloco de código é uma matriz. Porém na verdade, não é uma lista de dados, e sim uma lista de comandos, uma lista de código. // Isto é uma matriz de dados A := {10, 20, 30} // Isto é um bloco de código, porém funciona como // se fosse uma matriz de comandos B := {|| x := 10, y := 20} 6.2.3. Blocos de Código Diferentemente de uma matriz, não se pode acessar elementos de um bloco de código através de um índice numérico. Porém blocos de código são semelhantes a uma lista de expressões, e a uma pequena função. Ou seja, podem ser executados. Para a execução, ou avaliação, de um bloco de código, deve- se utilizar a função Eval(): nRes := Eval(B) ==> 20 Essa função recebe como parâmetro um bloco de código e avalias todas as expressões contidas neste bloco de código, retornando o resultado da última expressão avaliada. Passando Parâmetros Já que blocos de código são como pequenas funções, também é possível a passagem de parâmetros para um bloco de código. Os parâmetros devem ser informados entre as barras verticais (||) separados por vírgulas, assim como em uma função. B := {| N | X := 10, Y := 20 + N} Porém deve-se notar que já que o bloco de código recebe um parâmetro, um valor deve ser passado quando o bloco de código for avaliado. C := Eval(B, 1) ==> 21 - 67 - Introdução á programação e ADVPL Básico Utilizando Blocos de Código Blocos de código podem ser utilizados em diversas situações. Geralmente são utilizados para executar tarefas quando eventos de objetos são acionados ou para modificar o comportamento padrão de algumas funções. Por exemplo, considere a matriz abaixo: A := {"GARY HALL", "FRED SMITH", "TIM JONES"} Esta matriz pode ser ordenada pelo primeiro nome, utilizando-se a chamada da função asort(A), resultado na matriz com os elementos ordenados dessa forma: {"FRED SMITH", "GARY HALL", "TIM JONES"} A ordem padrão para a função asort é ascendente. Este comportamento pode ser modificado através da informação de um bloco de código que ordena a matriz de forma descendente: B := { |X, Y| X > Y } aSort(A, B) O bloco de código (de acordo com a documentação da função asort) deve ser escrito para aceitar dois parâmetros que são os dois elementos da matriz para comparação. Note que o bloco de código não conhece que elementos está comparando - a função asort seleciona os elementos (talvez utilizando o algoritmo QuickSort) e passa-os para o bloco de código. O bloco de código compara-os e retorna verdadeiro (.T.) se encontram na ordem correta, ou falso (.F.) se não. Se o valor de retorno for falso, a função asort irá então trocar os valores de lugar e seguir comparando o próximo par de valores. Então, no bloco de código anterior, a comparação X > Y é verdadeira se os elementos estão em ordem descendente, o que significa que o primeiro valor é maior que o segundo. Para ordenar a mesma matriz pelo último nome, também em ordem descendente, pode-se utilizar o seguinte bloco de código: B := { |X, Y| SUBSTR(X, At(" ",X)+1) > SUBSTR(Y, At(" ",Y)+1) } Note que este bloco de código procura e compara as partes dos caracteres imediatamente seguinte a um espaço em branco. Depois de utilizar esse bloco de código para a função asort, a matriz conterá: {"GARY HALL", "TIM JONES", "FRED SMITH"} Finalmente, para ordenar um sub-elemento (coluna) de uma matriz por exemplo, pode-se utilizar o seguinte bloco de código: B := { |X, Y| X[1] > Y[1] } - 70 - Introdução á programação e ADVPL Básico possam desenvolver suas próprias funções sem que as mesmas conflitem com as já disponíveis no ambiente ERP, foi implementada pela Tecnologia Microsiga um tipo especial de função denominado “User Function”. Nos tópicos a seguir serão detalhados os tipos de funções disponíveis na linguagem ADVPL, suas formas de utilização e respectivas diferenças. 7.1. Tipos e escopos de funções Em ADVPL podem ser utilizados os seguintes tipos de funções:  Function()  User Function()  Static Function()  Main Function() Function() Funções ADVPL convencionais, restritas ao desenvolvimento da área de Inteligência Protheus da Microsiga. O interpretador ADVPL distingue nomes de funções do tipo Function() com até dez caracteres. A partir do décimo caracter, apesar do compilador não indicar quaisquer tipos de erros, o interpretador ignorará os demais caracteres. Exemplo: // Fonte MATA100INCL.PRW #INCLUDE "protheus.ch" Function MATA100INCL01() ALERT("01") Return Function MATA100INCL02() ALERT("02") Return Ao executar a função MATA100INCL01() será exibida a mensagem “01”, mas ao executar a função MATA100INCL02() também será exibida a mensagem “01”, pois o interpretador considera o nome da função como “MATA100INC”. 1. Funções do tipo Function() somente podem ser executadas através dos módulos do ERP. 2. Somente poderão ser compiladas funções do tipo Function() se o MP- IDE possuir uma autorização especial fornecida pela Microsiga. 3. Funções do tipo Function() são acessíveis por quaisquer outras funções em uso pela aplicação. - 71 - Introdução á programação e ADVPL Básico User Function() As “User Defined Functions” ou funções definidas pelos usuários, são tipos especiais de funções implementados pelo ADVPL para garantir que desenvolvimentos específicos não realizados pela Inteligência Protheus da Microsiga sobreponham as funções padrões desenvolvidas para o ERP. O interpretador ADVPL considera que o nome de uma User Function é composto pelo nome definido para a função precedido dos caracteres “U_”. Desta forma a User Function XMAT100I será tratada pelo interpretador como “U_XMAT100I”. 1. Como ocorre o acréscimo dos caracteres “U_” no nome da função e o interpretador considera apenas os dez primeiros caracteres da função para sua diferenciação, é recomendado que os nomes das User Functions tenham apenas oito caracteres para evitar resultados indesejados durante a execução da aplicação. 2. Funções do tipo User Function são acessíveis por quaisquer outras funções em uso pela aplicação, desde que em sua chamada sejam utilizados os caracteres “U_” em conjunto com o nome da função. As User Functions podem ser executadas a partir da tela inicial do client do ERP (Microsiga Protheus Remote), mas as aplicações que pretendem disponibilizar esta opção devem possuir um preparo adicional de ambiente. Para maiores informações consulte no DEM o tópico sobre preparação de ambiente e a documentação sobre a função RpcSetEnv(). Static Function() Funções ADVPL tradicionais, cuja visibilidade está restrita as funções descritas no mesmo arquivo de código fonte no qual estão definidas. Exemplo: //Fonte FINA010.PRW Function FINA010() CriaSx1(“FIN010”) Return Static Function CRIASX1() //Fonte FINA020.PRW Function FINA020() CriaSx1(“FIN020”) Return Static Function CRIASX1() - 72 - Introdução á programação e ADVPL Básico No exemplo acima, existem duas funções denominadas CRIASX1() definidas em arquivos de código fonte distintos: FINA010.PRW e FINA020.PRW. A função FINA010() terá visibilidade apenas da função CRIASX1() definida no arquivo de código fonte FINA010.PRW, sendo que o mesmo ocorre com a função FINA020(). Este recurso permite isolar funções de uso exclusivo de um arquivo de código fonte, evitando a sobreposição ou duplicação de funções na aplicação. Neste contexto as Static Functions() são utilizadas para: 1. Padronizar o nome de uma determinada função, que possui a mesma finalidade, mas que sua implementação pode variar de acordo com a necessidade de função principal / aplicação. 2. Redefinir uma função padrão da aplicação, adequando-a as necessidades específicas de uma função principal / aplicação. 3. Proteger funções de uso específico de um arquivo de código fonte / função principal. O ambiente de desenvolvimento utilizado na aplicação ERP (MP-IDE) valida se existem Functions(), Main Functions() ou User Functions() com o mesmo nome mas em arquivos de código fontes distintos, evitando a duplicidade ou sobreposição de funções. Main Function() Main Function() é outro tipo de função especial do ADVPL incorporado para permitir tratamentos diferenciados na aplicação ERP. Uma Main Function() tem a característica de poder ser executada através da tela inicial de parâmetros do client do ERP (Microsiga Protheus Remote), da mesma forma que uma User Function, com a diferença que as Main Functions somente podem ser desenvolvidas com o uso da autorização de compilação, tornando sua utilização restrita a Inteligência Protheus da Microsiga. Na aplicação ERP é comum o uso das Main Functions() nas seguintes situações: 1. Definição dos módulos da aplicação ERP: Main Function Sigaadv() 2. Definição de atualizações e updates: AP710TOMP811() 3. Atualizações específicas de módulos da aplicação ERP: UpdateATF() - 75 - Introdução á programação e ADVPL Básico Como a linguagem ADVPL trata os parâmetros de forma posicional, o conteúdo da variável nFatorUser será atribuído diretamente a variável definida como primeiro parâmetro da função chamado, no nosso caso nFator. Por ser uma atribuição de parâmetros por conteúdo, o interpretador da linguagem basicamente executa uma operação de atribuição normal, ou seja, nFator := nFatorUser. A passagem de parâmetros não necessita que as variáveis informadas na função chamadora tenham os mesmos nomes das variáveis utilizadas na definição de parâmetros da função chamada. Desta forma podemos ter: User Function DirFator() Local nFatorUser := GetFator() nResultado := CalcFator(nFatorUser) ... Function CalcFator(nFator) ... As variáveis nFatorUser e nFator podem ter nomes diferentes pois o interpretador fará a atribuição de conteúdo com base na ordem dos parâmetros e não pelo nome das variáveis. Passagem de parâmetros por referência A passagem de parâmetros por referência é uma técnica muito comum nas linguagens de programação a qual permite que variáveis de escopo LOCAL tenham seu conteúdo manipulado por funções específicas, mantendo o controle destas variáveis restrito a função que as definiu e as funções desejadas pela aplicação. A passagem de parâmetros por referência utiliza o conceito de que uma variável é uma área de memória e portanto passar um parâmetro por referência nada mais é do que ao invés de passar o conteúdo para a função chamada, passar qual a área de memória utilizada pela variável passada. - 76 - Introdução á programação e ADVPL Básico Passagem de parâmetros tradicional – Duas variáveis x Duas áreas de memória Passagem de parâmetros por referência – Duas variáveis x uma única área de memória - 77 - Introdução á programação e ADVPL Básico Desta forma a função chamada tem acesso não apenas ao conteúdo, mas a variável em si, pois a área de memória é a variável, e qualquer alteração nesta será visível a função chamadora quando tiver o retorno da função chamadora. Tratamento de conteúdos padrões para parâmetros de funções O tratamento de conteúdos padrões para parâmetros de funções é muito utilizado nas funções padrões da aplicação ERP, de forma a garantir a correta execução destas funções por qualquer função chamadora, evitando situações de ocorrências de erros pela falta da definição de parâmetros necessários a correta utilização da função. A linguagem ADVPL não obriga a passagem de todos os parâmetros descritos na definição da função, sendo que os parâmetros não informados serão considerados com conteúdo nulo. Desta forma o uso do identificador DEFAULT permite ao desenvolvedor garantir que na utilização da função determinados parâmetros terão o valor com um tipo adequado a função. Exemplo: User Function CalcFator(nFator) Local nCnt Local nResultado := 0 Default nFator := 1 For nCnt := nFator To 1 Step -1 nResultado *= nCnt Next nCnt Return nResultado No exemplo descrito, caso o parâmetro nFator não seja informado na função chamadora, o mesmo terá seu conteúdo definido como 1. - 80 - Introdução á programação e ADVPL Básico O include PROTHEUS.CH ainda contém a referência a outros includes utilizadas pela linguagem ADVPL que complementam esta funcionalidade de compatibilidade com a sintaxe Clipper, tais como: o DIALOG.CH o FONT.CH o INI.CH o PTMENU.CH o PRINT.CH Fique atento A utilização do include “protheus.ch” nos fontes desenvolvidos para a aplicação ERP Protheus é obrigatória e necessária ao correto funcionamento das aplicações.  AP5MAIL.CH: Permite a utilização da sintaxe tradicional na definição das seguintes funções de envio e recebimento de e-mail: o CONNECT SMTP SERVER o CONNECT POP SERVER o DISCONNECT SMTP SERVER o DISCONNECT POP SERVER o POP MESSAGE COUNT o SEND MAIL FROM o GET MAIL ERROR o RECEIVE MAIL MESSAGE  TOPCONN.CH: Permite a utilização da sintaxe tradicional na definição das seguintes funções de integração com a ferramenta TOPCONNECT (MP10 – DbAcess): o TCQUERY  TBICONN.CH: Permite a utilização da sintaxe tradicional na definição de conexões com a aplicação Server do ambiente ERP, através da seguintes sintaxes: o CREATE RPCCONN o CLOSE RPCCONN o PREPARE ENVIRONMENT o RESET ENVIRONMENT o OPEN REMOTE TRANSACTION o CLOSE REMOTE TRANSACTION o CALLPROC IN o OPEN REMOTE TABLES  XMLXFUN.CH: Permite a utilização da sintaxe tradicional na manipulação de arquivos e strings no padrão XML, através das seguintes sintaxes: o CREATE XMLSTRING o CREATE XMLFILE o SAVE XMLSTRING o SAVE XMLFILE - 81 - Introdução á programação e ADVPL Básico o ADDITEM TAG o ADDNODE NODE o DELETENODE Os recursos de tratamentos de e-mails, integração com a ferramenta TOPCONNECT (DbAcess), preparação de ambientes e manipulação de arquivos e strings do padrão XML serão abordados no curso de ADVPL Avançado. O diretório de includes deve ser especificado no ambiente de desenvolvimento do ERP Protheus (MP-IDE) para cada configuração de compilação disponível. Caso o diretório de includes não esteja informado, ou esteja informado incorretamente será exibida uma mensagem de erro informando: “Não foi possível criar o arquivo <caminho\nome> .ERX” As funções desenvolvidas para a aplicação ERP costumam utilizar includes para definir o conteúdo de strings e variáveis diversas utilizadas pela aplicação em diferentes idiomas. Desta forma é normal verificar que um fonte possui um arquivo “.CH” com o mesmo nome, o que caracteriza este tipo de include. Diretiva: #DEFINE A diretiva #DEFINE permite que o desenvolvedor crie novos termos para serem utilizadas no código fonte. Este termo tem o efeito de uma variável de escopo PUBLIC, mas que afeta somente o fonte na qual o #DEFINE está definido, com a característica de não permitir a alteração de seu conteúdo. Desta forma um termo definido através da diretiva #DEFINE pode ser considerado como uma constante. Os arquivos de include definidos para os fontes da aplicação ERP contém diretivas #DEFINE para as strings de textos de mensagens exibidas para os usuários nos três idiomas com os quais a aplicação é distribuída: Português, Inglês e Espanhol. Por esta razão a aplicação ERP possui três repositórios distintos para cada uma das bases de dados homologadas pela Microsiga, pois cada compilação utiliza uma diretiva referente ao seu idioma. - 82 - Introdução á programação e ADVPL Básico Diretivas: #IFDEF, IFNDEF, #ELSE e #ENDIF As diretivas #IFDEF, #IFNDEF, #ELSE e #ENDIF permitem ao desenvolvedor criar fontes flexíveis e sensíveis a determinadas configurações da aplicação ERP. Através destas diretivas, podem ser verificados parâmetros do sistema, tais como o idioma com o qual está parametrizado e a base de dados utilizada para armazenar e gerenciar as informações do ERP. Desta forma, ao invés de escrever dois ou mais códigos fontes que realizam a mesma função, mas utilizando recursos distintos para cada base de dados ou exibindo mensagem para cada um dos idiomas tratados pela aplicação, o desenvolvedor pode preparar seu código fonte para ser avaliado pelo pré-processador, o qual irá gerar um código compilado de acordo com a análise dos parâmetros de ambiente. Estas diretivas de compilação estão normalmente associadas as seguintes verificações de ambiente:  Idioma: verifica as variáveis SPANISH e ENGLISH, disponibilizadas pela aplicação. O idioma português é determinado pela exceção: #IFDEF SPANISH #DEFINE STR0001 “Hola !!!” #ELSE #IFDEF ENGLISH #DEFINE STR0001 “Hello !!!” #ELSE #DEFINE STR0001 “Olá !!!” #ENDIF #ENDIF Apesar da estrutura semelhante ao IF-ELSE-ELSEIF-ENDIF, não existe a diretiva de compilação #ELSEIF, o que torna necessário o uso de diversos #IFDEFs para a montagem de uma estrutura que seria facilmente solucionada com IF-ELSE-ELSEIF-ENDIF. A aplicação ERP disponibiliza a variável de escopo PUBLIC - __LANGUAGE, a qual contém uma string que identifica o idioma em uso pelo sistema, cujo os conteúdos possíveis são:  “PORTUGUESE”  “SPANISH”  “ENGLISH” - 85 - Introdução á programação e ADVPL Básico sintaxe; permite o debug (execução passo a passo do programa, verificando o conteúdo das variáveis) e fornece assistentes (modelos) de programas. Figura: Manutenção no repositório de objetos Após compilar o programa, o resultado é um objeto, o qual é carregado na memória ficando disponível para sua execução através da aplicação PROTHEUS. O objeto não é um executável, ou seja, não está convertido para a linguagem nativa do equipamento. Quem faz esse trabalho é o Protheus Server em tempo de execução. Por isso, o Protheus Server está sempre presente na memória em tempo de execução, permitindo:  Proteger o programa fonte, evitando que seja alterado indevidamente, pois somente os objetos são distribuídos com uma execução mais rápida em função da compilação no DEV-Studio;  Flexibilização à plataforma de trabalho. Assim, um mesmo programa pode rodar em ambientes Windows, Linux ou mesmo em um Hand Held, ficando a tarefa de adequação para o Servidor Protheus;  Que o sistema cresça de forma ilimitada, pois os objetos ficam fora do executável;  O uso de macro substituições, ou seja, o uso de rotinas exteriores ao sistema armazenadas em arquivos e que podem facilmente alteradas pelo usuário, pois o Server também interpreta o código fonte em tempo de execução. - 86 - Introdução á programação e ADVPL Básico Figura: Diagrama esquemático de objetos Protheus O Repositório de Objetos é a biblioteca de objetos de todo o ambiente Protheus, incluindo tanto os objetos implementados para as funcionalidades básicas do ERP como aqueles gerados pelos usuários. A figura abaixo demonstra a estrutura e a interconexão entre as várias camadas. Figura: Estrutura de interconexão do Protheus - 87 - Introdução á programação e ADVPL Básico Ela demonstra também que os dados a serem processados podem estar armazenados em bases ISAM ou em Bancos de Dados padrão SQL. No primeiro caso o server comunica- se diretamente com os dados. Em Bancos SQL é a interface TOPCONNECT / DBACCESS que converte os comandos de entrada e saída, adequando-os ao SQL utilizado (SQl Server Microsoft, Oracle, DB2, etc.). Uma vez terminado o processamento do objeto chamado, o ele é descartado da memória, ou seja, o Protheus é um sistema que pode crescer de forma ilimitada pois os objetos, armazenados em um repositório praticamente não ocupam espaço no HD (Hard Disk). O Protheus é uma plataforma multicamada. Entre as diversas camadas, temos a interface de apresentação ao usuário (Remote), o tratamento dado para as regras de negócio implementadas (Server), o acesso aos objetos do repositório (Server), o acesso aos dados disponíveis no Banco de Dados (Server ou TOPCONNECT / DBACCESS ) e ao gerenciamento de serviços WEB (Server). Neste processo, o Protheus possui, basicamente, quatro aplicativos utilizados com diferentes finalidades:  Protheus Server / TOTVS AppServer: Responsável pela comunicação entre o cliente, o banco de dados e o RPO. O nome do executável depende da versão do sistema (TOTVSAPPSERVER.EXE) sendo que as plataformas ISAM suportadas pelo Protheus Server são DBF e CTREE.  Protheus Remote / TOTVS SmartClient: Instalado no Server ou na estação. O nome também depende da versão do sistema (TOTVSSMARTCLIENT.EXE).  TopConnect / DbAccess: Responsável pela conversão dos comandos de banco de dados, adequando-os ao SQL utilizado.  Protheus Monitor / TOTVS Monitor: Programa de análise que verifica quem está usando o sistema e possibilita o envio de mensagens ou mesmo derrubar conexões (TOTVSMONITOR.EXE). Alguns nomes referem-se a um conjunto de programas para facilitar a sua identificação:  RPO: É o arquivo binário do APO (Advanced Protheus Objects), ou seja, os objetos.  Build: Executáveis, DLLs e o RPO completo.  Patch: Atualizações pontuais do RPO, aplicadas por meio do IDE.  Update: Pacote de atualização para o repositório (RPO) liberado periodicamente contendo todas as adequações e melhorias disponibilizadas para o sistema em um determinado período, sendo não cumulativo, aplicadas por meio do DEV-Studio. A interface de apresentação é realizada pelo SmartClient que processa a parte da estação, basicamente, tela e teclado. Pode estar gravado no Server e ser carregado via rede para a memória da estação. Ou, de preferência, deve ficar armazenado no HD da estação. Pode também ser carregado pelo Internet Explorer, rodando dentro do próprio browser com o SmartClient ActiveX e permitindo o acesso ao Protheus Server pela Internet, com as mesmas funcionalidades do SmartClient, sendo que o browser precisa suportar o uso da tecnologia ActiveX. Caso exista algum Firewall ou Proxy entre o WEB Server e o Browser que vai acessar o SmartClient ActiveX, eles deverão ser configurados para permitir o seu download. - 90 - Introdução á programação e ADVPL Básico Para isso, é necessário configurar, ou seja, informar ao Protheus onde está cada uma delas. Esse tipo de informação consta nos arquivos de parâmetros de configuração do sistema (TOTVSAPPSERVER.INI e TOTVSSMARTCLIENT.INI) existentes nas respectivas pastas APPSERVER e SMARTCLIENT. Os parâmetros do TOTVSAPPSERVER.INI são lidos pelo programa TOTVSAPPSERVER.EXE logo no início de sua execução. O mesmo procedimento ocorre em relação aos parâmetros do TOTVSSMARTCLIENT.INI pelo programa TOTVSSMARTCLIENT.EXE. A execução desses dois programas é feita por meio de ação do usuário, facilitada pelos atalhos TOTVS APPSERVER e TOTVS SMARTCLIENT. Figura: Links dos parâmetros de configuração Para que o TOTVS AppServer e o TOTVS SmartClient sejam executados, os arquivos TOTVSAPPSERVER.INI e TOTVSSMARTCLIENT.INI devem estar disponíveis nas respectivas pastas APPSERVER e SMARTCLIENT pois são eles que indicam o endereço das demais pastas conforme a ilustração da figura anterior. O detalhe de preenchimento das propriedades dos respectivos atalhos TOTVS AppServer e o TOTVS SmartClient é demonstrado a seguir. No atalho do TOTV SAppServer, é necessário que seja informado o parâmetro “-debug” ou “-console”. - 91 - Introdução á programação e ADVPL Básico Propriedades dos atalhos Destino: c:\protheus\bin\appserver\totvsappserver.exe - console  Iniciar em: c:\protheus\bin\appserver  -Console ou -Debug Executado como uma JanelaConsole, as informações recebidas das conexões com o TOTVS Application Server conectados são exibidas diretamente na tela do console do TOTVS Application Server, bem como informações de Não Conformidades.  -Install Se o TOTVS Application Server, não for instalado como um Serviço do NT, durante a Instalação, isto pode ser realizado, executando-o com a opção de Linha de Comando.  -Remove Para removê-lo da Lista de Serviços do NT, pode-se executá-lo com a opção de Linha de Comando. Destino: c:\protheus\bin\smartclient\totvssmartcliente.exe –M  Iniciar em: c:\protheus\bin\smartclient  -Q (Quiet) Indica que o TOTVS Smart Client, não deverá mostrar o Splash (Imagem de Apresentação) e a tela de identificação de Parâmetros Iniciais, necessita ser acompanhada da (Cláusula –P).  -P (Main Program) Identifica o Programa (APO) Inicial.  -E (Environment) Nome da Seção de Environment, no (Ini do Server), que será utilizada, para definições gerais.  -C (Connection) Nome da Seção de Conexão, que será utilizada, para a conexão ao TOTVS Application Server.  -M (AllowMultiSession) Permite múltiplas instâncias (Cópias) do TOTVS Smart Client, na mesma máquina, o que por Default não é permitido. - 92 - Introdução á programação e ADVPL Básico Os parâmetros que configuram o local do RPO, o Banco de Dados (ISAM ou SQL), os arquivos de menus, configurações e customizações do sistema no arquivo INI são:  SourcePath: Indica o local de origem dos objetos. É o endereço do Repositório de Objetos (Exemplo: SourcePath=C:\PROTHEUS\APO)  RootPath: Aponta para a pasta raiz (inicial), a partir da qual serão localizados os dados (no caso de ISAM), bem como o próprio Dicionário de Dados (Exemplo: RootPath=C:\PROTHEUS\PROTHEUS_DATA)  StartPath: Indica qual é a pasta dentro da pasta raiz (informada no parâmetro RootPath) que contém os arquivos de menus, os arquivos de configurações e os arquivos de customizações (SXs) do sistema Protheus (Exemplo: StartPath=\SYSTEM\). Não há necessidade de que os parâmetros estejam em ordem nos arquivos de configuração (.ini). Além dos parâmetros já detalhados, existem outros que podem indicar a versão do sistema, o tipo de banco de dados, à linguagem do país em que está sendo utilizado e as máscaras de edição e formatação. [ENVIRONMENT] SOURCEPATHC:\PROTHEUS\APO ROOTPATH= C:\MP811\PROTHEUS_DATA STARTPATH=\ PROTHEUS\ RPODB=TOP RPOLANGUAGE=PORTUGUESE RPOVERSION=101 LOCALFILES=ADS TRACE=0 LOCALDBEXTENSION=.DBF PICTFORMAT=DEFAULT DATEFORMAT=DEFAULT [DRIVERS] ACTIVE=TCP [TCP] TYPE=TCPIP PORT=1234 Figura: Exemplo de um ambiente em um arquivo de parâmetros No exemplo da figura anterior, o rótulo [environment] descreve um conjunto de parâmetros que serão inicializados no sistema. Os rótulos [Drivers] e [TCP] identificam a comunicação que pode ser estabelecida entre o Protheus Server e o Protheus Remote. Outros ambientes podem ser configurados no mesmo arquivo (TOTVSAPPSERVER.INI). Já o arquivo de parâmetros do Protheus Remote (TOTVSSMARTCLIENT.INI) contém apenas as configurações locais, basicamente as informações necessárias para a inicialização e a comunicação com o Protheus Server, conforme o exemplo da figura a seguir. - 95 - Introdução á programação e ADVPL Básico SXS Cadastro de programas (utilizado na validação para mostrar/inibir os filtros na execução da mbrowse). SXT Tabela de usuários (contém as informações dos usuários que poderão utilizar os filtros da mbrowse). SXOffice Cadastro de relacionamento entre as entidades (tabelas) e as consultas TOII. Ambientes e tabelas Na aplicação PROTHEUS as tabelas de dados podem ter uma estrutura mais simples e econômica, com tabelas em DBF/ADS, do fabricante Extended System ou CTREE do fabricante FAIRCOM ou uma estrutura mais robusta e complexa, em bases SQL (SQLSERVER da Microsoft, ORACLE, DB II da IBM, SYBASE, MYSQL, POSTGREE, etc.). No caso do SQL, o acesso é feito através do TOPCONNECT / DBACESS, que converte os comandos do ADVPL para este ambiente. Para permitir uma utilização adequada das tabelas de dados do sistema por cada um dos ambientes da aplicação ERP, as tabelas foram divididas em grupos denominados “famílias”. Cada módulo pode utilizar uma ou mais famílias de tabelas especificas para suas atividades, e ainda compartilhar informações com outros módulos através de famílias comuns a todas as operações realizadas no sistema. A tabela a seguir demonstra alguns dos módulos que compõe a aplicação ERP PROTHEUS atualmente: Ambiente Identificação SIGAATF ATIVO FIXO SIGACOM COMPRAS SIGACON CONTABILIDADE SIGAEST ESTOQUE E CUSTOS SIGAFAT FATURAMENTO SIGAFIN FINANCEIRO SIGAFIS LIVROS FISCAIS SIGAPCP PLANEJAMENTO E CONTROLE DA PRODUÇÃO SIGAGPE GESTÃO DE PESSOAL SIGAFAS FATURAMENTO DE SERVIÇOS SIGAVEI VEÍCULOS SIGALOJ CONTROLE DE LOJAS/AUTOMAÇÃO COMERCIAL SIGATMK CALL CENTER SIGAOFI OFICINAS SIGAPON PONTO ELETRÔNICO SIGAEIC EASY IMPORT CONTROL SIGATCF TERMINAL SIGAMNT MANUTENÇÃO DE ATIVOS SIGARSP RECRUTAMENTO E SELEÇÃO DE PESSOAL SIGAQIE INSPEÇÃO DE ENTRADA – QUALIDADE SIGAQMT METODOLOGIA – QUALIDADE O nome de cada tabela no Protheus é constituído de seis dígitos, os quais são utilizados para formar a seguinte representação: F X X E E 0 - 96 - Introdução á programação e ADVPL Básico Onde: F SF X Primeiro dígito representa a família, o segundo dígito pode ser utilizado para detalhar ainda mais a família especificada no primeiro nível (subfamília), e o terceiro dígito é a numeração seqüencial das tabelas da família iniciando em “0” e finalizando em “Z”. E E 0 Os dois primeiros dígitos identificam a que empresa as tabelas estão vinculadas, lembrando que a informação de filial está contida nos dados da tabela. O último dígito é fixo em “0”. A tabela a seguir demonstra algumas das principais famílias de tabelas utilizadas pela aplicação ERP Protheus: Família Descrição S - Tabelas pertencentes ao sistema básico, também chamado Classic S A Cadastros de entidades compartilhadas entre os ambientes (Clientes, Fornecedores, Bancos entre outros). S B Cadastros dos ambientes de Materiais (Produtos, Saldos entre outros). S C Arquivos de movimentações diversas utilizados pelos ambientes de Materiais (Solicitação ao Almoxarifado, Solicitação de Compras, Pedido de Compras, Pedido de Vendas, Ordens de Produção entre outros). S D Arquivos de movimentações de estoque (Itens de notas fiscais de entrada e saída, movimentos internos de estoque entre outros). S E Cadastros e movimentações do ambiente Financeiro. S F Cadastros e movimentações Fiscais (Cabeçalhos das notas fiscais de entrada e saída, cadastro de tipos de entrada e saída, livros fiscais, entre outros). S G Cadastros do ambiente de Planejamento e Controle de Produção S H Movimentos do ambiente de Planejamento e Controle de Produção S I Cadastros e movimentos do ambiente Contábil (descontinuado) S N Cadastros e movimentos do ambiente Ativo Fixo S R Cadastros e movimentos do ambiente Gestão de Pessoal S X Tabelas de configuração do sistema S Z Tabelas livres para utilização e projetos específicos em clientes. A - Gestão de Projetos C - Contabilidade Gerencial C T Contabilidade Gerencial C V Contabilidade Gerencial C W Contabilidade Gerencial D - Transportadoras e derivados E - Comércio exterior e derivados G - Gestão Hospitalar J - Gestão Educacional N - Serviços Públicos P - Reservado para projetos da fábrica de software Q - Qualidade e derivados R - Recursos Humanos e derivados T - Plano de Saúde W - Workflow Z - Tabelas livres para utilização e projetos específicos em clientes em adição a família SZ. - 97 - Introdução á programação e ADVPL Básico Índices Cada tabela do sistema possui seus índices definidos no arquivo de configuração SIX, o qual pode ser atualizado através do módulo Configurador. Os arquivos de índices das tabelas de sistema serão criados de acordo com o banco de dados utilizado (ISAM ou conexão via TOPCONNECT). Para bancos de dados ISAM, será gerados arquivos com a mesma nomenclatura da tabela de dados, mas com uma extensão diferenciada (atualmente .CDX). No caso da utilização de um banco de dados, cada índice será uma numeração seqüencial em função do nome da tabela original. As especificações das chaves de índices de cada um das tabelas está disponível no arquivo de sistema SIX, e a chave única da tabela utilizada para banco de dados está descrita na tabela SX2. Menus Cada módulo da aplicação ERP possui um menu padrão com todas as funcionalidades disponíveis para o ambiente, menu este definido através de sintaxe XML (arquivos .XNU). Os menus possuem uma estrutura padrão que permite ao usuário localizar e identificar facilmente cada uma das funcionalidades oferecidas pelo ambiente. 9.3.3. Acessando o módulo Configurador Para executar o módulo Configurador é necessário que a aplicação Protheus Server esteja em execução e através da aplicação Protheus Remote deverá ser informada como programa inicial a opção SIGACFG. Figura: Parâmetros de inicialização do sistema
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved