Programação Advpl I - P10 PDF
Programação Advpl I - P10 PDF
Programação Advpl I - P10 PDF
Programação em
ADVPL
Ao final do curso o treinando deverá ter desenvolvido os seguintes conceitos, habilidades e atitudes:
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
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?
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.
Dessa maneira, uma instrução tomada em separado não tem muito sentido; para obtermos o resultado,
precisamos colocar em prática o conjunto de todas as instruções, na ordem correta.
Algoritmo
Um algoritmo é formalmente uma seqüência finita de passos que levam a execução de uma tarefa.
Podemos pensar em algoritmo como uma receita, uma seqüência de instruções que dão cabo de uma
meta específica. Estas tarefas não podem ser redundantes nem subjetivas na sua definição, devem ser
claras e precisas.
Como exemplos de algoritmos podemos citar os algoritmos das operações básicas (adição, multiplicação,
divisão e subtração) de números reais decimais. Outros exemplos seriam os manuais de aparelhos
eletrônicos, como um videocassete, que explicam passo-a-passo como, por exemplo, gravar um evento.
Até mesmo as coisas mais simples, podem ser descritas por seqüências lógicas, tais como:
1. Pegar a bala;
2. Retirar o papel;
3. Chupar a bala;
4. Jogar o papel no lixo.
Desenvolvendo algoritmos
Pseudocódigo
Os algoritmos são descritos em uma linguagem chamada pseudocódigo. Este nome é uma alusão à
posterior implementação em uma linguagem de programação, ou seja, quando for utilizada a linguagem
a de programação propriamente dita como, por exemplo, ADVPL.
Por isso os algoritmos são independentes das linguagens de programação, sendo que ao contrário de
uma linguagem de programação não existe um formalismo rígido de como deve ser escrito o algoritmo.
O algoritmo deve ser fácil de interpretar e fácil de codificar. Ou seja, ele deve ser o intermediário entre a
linguagem falada e a linguagem de programação.
2. Imaginar que você está desenvolvendo um algoritmo para pessoas que não trabalham com
informática;
4. Ser objetivo;
Fases
Estudando algoritmos
Neste tópico serão demonstrados alguns algoritmos do cotidiano, os quais foram implementados
utilizando os princípios descritos nos tópicos anteriores.
- Mascar um chiclete
- Utilizar um telefone público – cartão
- Fritar um ovo
- Trocar lâmpadas
- Descascar batatas
- Jogar o jogo da forca
- Calcular a média de notas
- Jogar o jogo da velha – contra o algoritmo
Mascar um chiclete
1. Pegar o chiclete
2. Retirar o papel
3. Mastigar
4. Jogar o papel no lixo
Anotações
Fritar um ovo
Trocar lâmpadas
Descascar batatas
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
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:
Teste de mesa:
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
Anotações
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
Processamento em geral .
Processamento
Decisão
Exibição
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.
Fique
atento
Início
Retirar a
Ascender o fogo frigideira do fogo
quando o ovo
estiver no ponto
Colocar a
frigideira no Desligar o fogo
fogo
FIM
Anotações
Início
Ainda há Não
notas?
Sim
Receber notas
Somar notas
recebidas
Dividir o total da
soma pela
quantidade de
notas informadas
Exibir média
das notas
FIM
Anotações
Estruturas de decisão
- IF...ELSE
- DO CASE ... CASE
Estruturas de repetição
- WHILE...END
- FOR...NEXT
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.
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.
Ações anteriores
...
Ação vinculada ao
Ação vinculada ao
resultado
resultado falso
verdadeiro
Continuação do
fluxo após a
tomada da
decisão
Ações anteriores
...
Análise da Falso
condição
Verdadeiro
Ação vinculada ao
resultado
verdadeiro
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.
Fique
atento
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
Dica a ação da primeira expressão cujo análise resultar em um valor verdadeiro.
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.
Falso
Falso
Falso
Falso
Continuação do
fluxo após a
tomada da
decisão
Estruturas de repetição
Os comandos de repetição são utilizados em algoritmos nas situações em que é necessário realizar uma
determinada ação ou um conjunto de ações para um número definido ou indefinido de vezes, ou ainda
enquanto uma determinada condição for verdadeira.
- WHILE...END
- FOR...TO...NEXT
WHILE...END
Nesta estrutura, o conjunto de ações será executado enquanto a análise de uma condição de referência
resultar em um valor verdadeiro. É importante verificar que o bloco somente será executado, inclusive se
na primeira análise a condição resultar em um valor verdadeiro.
Representação: WHILE...END
Análise da Falso
condição
Loop Verdadeiro
Ação vinculada ao
resultado
verdadeiro
Continuação do
fluxo
...
Existem diversas variações para a estrutura WHILE...END, na qual há a possibilidade da primeira execução
ser realizada sem a análise da condição, a qual valerá apenas a partir da segunda execução.
A linguagem ADVPL aceita a sintaxe DO WHILE...ENDDO, que em outras linguagens representa a situação
descrita anteriormente (análise da condição somente a partir da segunda execução), mas em ADVPL esta
sintaxe tem o mesmo efeito do WHILE...END.
For...To...Next
Nesta estrutura, o conjunto de ações será executado uma quantidade de vezes definida, normalmente
referenciada como “passo”.
Para cada “passo” realizado pela estrutura FOR...TO...NEXT, será avaliada uma condição que verificará se foi
atingido o número de execuções previamente definido. Desta forma a estrutura compreende um controle
de número de “passos” executados, o qual é incrementado na análise da expressão NEXT.
Semelhante a estrutura WHILE...END, a primeira ação somente será realizada mediante um resultado
verdadeiro na análise da condição.
Anotações
Ações anteriores
...
Análise da Falso
condição
Verdadeiro
Ação vinculada ao
resultado
verdadeiro
Incrementa o
contador de
“passos”
Continuação do
fluxo
...
Fique Em ADVPL pode ser utilizada a instrução “STEPS” para alterar o valor a ser adicionado no contador de passos a cada
atento execução da instrução NEXT, sendo que este valor poderá ser até negativo, viabilizando uma contagem decrescente.
Exercícios
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.
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:
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.
De acordo com a utilização e com o meio de conectividade utilizado, estas rotinas são subcategorizadas
assim:
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.
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:
Outra forma de documentar textos é utilizar as barras transversais juntamente com o asterisco, podendo-
se comentar todo um bloco de texto sem precisar comentar linha a linha:
/*
Programa para cálculo do total
Autor: Microsiga Software S.A.
Data: 2 de outubro de 2001
*/
Todo o texto encontrado entre a abertura (indicada pelos caracteres /*) e o fechamento (indicada pelos
caracteres */) é considerado como comentário.
Linhas Mistas
O ADVPL também permite que existam linhas de comando com comentário. Isto é possível adicionando-
se as duas barras transversais (//) ao final da linha de comando e adicionando-se o texto do comentário:
Local nCnt
Local nSoma := 0 // Inicializa a variável com zero para a soma
For nCnt := 1 To 10
nSoma += nCnt
Next nCnt
Tamanho da Linha
Assim como a linha física, delimitada pela quantidade de caracteres que pode ser digitado no editor de
textos utilizado, existe uma linha considerada linha lógica. A linha lógica, é aquela considerada para a
compilação como uma única linha de comando.
A princípio, cada linha digitada no arquivo texto é diferenciada após o pressionamento da tecla <Enter>.
Ou seja, a linha lógica, é a linha física no arquivo. Porém algumas vezes, por limitação física do editor de
texto ou por estética, pode-se "quebrar" a linha lógica em mais de uma linha física no arquivo texto. Isto é
efetuado utilizando-se o sinal de ponto-e-vírgula (;).
GravaDados(cNome,cEnd,cTel,cFax,cEmail)
Endif
Anotações
#include protheus.ch
/*
+===========================================+
| Programa: Cálculo do Fatorial |
| Autor : Microsiga Software S.A. |
| Data : 02 de outubro de 2001 |
+===========================================+
*/
Local nCnt
Local nResultado := 1 // Resultado do fatorial
Local nFator := 5 // Número para o cálculo
// Cálculo do fatorial
For nCnt := nFator To 1 Step -1
nResultado *= nCnt
Next nCnt
// Termina o programa
Return
Área de Identificação
- Declaração dos includes
- Declaração da função
- Identificação do programa
Corpo do Programa
- Preparação para o processamento
- Processamento
Área de Encerramento
Anotações
Á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 |
+==========================================+
*/
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
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
Anotações
// Termina o programa
Return
Anotações
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.
Array
O Array é um tipo de dado especial. É a disposição de outros elementos em colunas e linhas. O ADVPL
suporta arrays unidimensionais (vetores) ou multidimensionais (matrizes). Os elementos de um array
são acessados através de índices numéricos iniciados em 1, identificando a linha e coluna para quantas
dimensões existirem.
Arrays devem ser utilizadas com cautela, pois se forem muito grandes podem exaurir a memória do
servidor.
Bloco de Código
O bloco de código é um tipo de dado especial. É utilizado para armazenar instruções escritas em ADVPL
que poderão ser executadas posteriormente.
Anotações
Declaração de variáveis
Variáveis de memória são um dos recursos mais importantes de uma linguagem. São áreas de memória
criadas para armazenar informações utilizadas por um programa para a execução de tarefas. Por exemplo,
quando o usuário digita uma informação qualquer, como o nome de um produto, em uma tela de um
programa esta informação é armazenada em uma variável de memória para posteriormente ser gravada
ou impressa.
A partir do momento que uma variável é criada, não é necessário mais se referenciar ao seu conteúdo, e
sim ao seu nome.
O nome de uma variável é um identificador único o qual deve respeitar um máximo de 10 caracteres. O
ADVPL não impede a criação de uma variável de memória cujo nome contenha mais de 10 caracteres,
porém apenas os 10 primeiros serão considerados para a localização do conteúdo armazenado.
Portanto se forem criadas duas variáveis cujos 10 primeiros caracteres forem iguais, como nTotalGeralAnual
e nTotalGeralMensal, as referências a qualquer uma delas no programa resultarão o mesmo, ou seja, serão
a mesma variável:
nTotalGeralMensal := 100
nTotalGeralAnual := 300
Alert("Valor mensal: " + cValToChar(nTotalGeralMensal))
Escopo de variáveis
O ADVPL não é uma linguagem de tipos rígidos para variáveis, ou seja, não é necessário informar o tipo
de dados que determinada variável irá conter no momento de sua declaração, e o seu valor pode mudar
durante a execução do programa.
Também não há necessidade de declarar variáveis em uma seção específica do seu código fonte, embora
seja aconselhável declarar todas as variáveis necessárias no começo, tornando a manutenção mais fácil e
evitando a declaração de variáveis desnecessárias.
Para declarar uma variável deve-se utilizar um identificador de escopo. Um identificador de escopo é
uma palavra chave que indica a que contexto do programa a variável declarada pertence. O contexto
de variáveis pode ser local (visualizadas apenas dentro do programa atual), público (visualizadas por
qualquer outro programa), entre outros.
As variáveis declaradas em um programa ou função, são visíveis de acordo com o escopo onde são
definidas. Como também do escopo depende o tempo de existência das variáveis. A definição do escopo
de uma variável é efetuada no momento de sua declaração.
Local nNumero := 10
Esta linha de código declara uma variável chamada nNumero indicando que pertence seu escopo é
local.
- Local
- Static
- Private
- Public
nNumero2 := 15
Quando um valor é atribuído à uma variável em um programa ou função, o ADVPL criará a variável caso
ela não tenha sido declarada anteriormente. A variável então é criada como se tivesse sido declarada
como Private.
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 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.
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.
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.
Anotações
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.
É 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.)
Neste exemplo, nVar é criada como public e inicializada com o valor 10. Quando a função Filha é executada,
nVar ainda existe e pode ser acessada. Diferente de variáveis locais ou privates, nVar ainda existe após o
término da a execução da função Pai.
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.
Fique
atento Exemplo: Public _cRotina
Se esta linha for executada em um programa ADVPL, ocorrerá um erro de execução com a mensagem
"variable does not exist: nPercentual", pois esta variável está sendo utilizada em uma expressão de cálculo
sem ter sido declarada. Para solucionar este erro, deve-se declarar a variável previamente:
Neste exemplo, as variáveis são declaradas previamente utilizando o identificador de escopo local. Quando
a linha de cálculo for executada, o erro de variável não existente, não mais ocorrerá. Porém variáveis não
inicializadas têm sempre o valor default nulo (Nil) e este valor não pode ser utilizado em um cálculo pois
também gerará erros de execução (nulo não pode ser dividido por 100). A resolução deste problema é
efetuada inicializando-se a variável através de uma das formas:
ou
A diferença entre o último exemplo e os dois anteriores é que a variável é inicializada no momento da
declaração. Em ambos os exemplos, a variável é primeiro declarada e então inicializada em uma outra
linha de código.
É aconselhável optar pelo operador de atribuição composto de dois pontos e sinal de igual, pois
o operador de atribuição utilizando somente o sinal de igual pode ser facilmente confundido com o
operador relacional (para comparação) durante a criação do programa.
Uma vez que um valor lhe seja atribuído, o tipo de dado de uma variável é igual ao tipo de dado do valor
atribuído. Ou seja, uma variável passa a ser numérica se um número lhe é atribuído, passa a ser caractere
se uma string de texto lhe for atribuída, etc. Porém mesmo que uma variável seja de determinado tipo de
dado, pode-se mudar o tipo da variável atribuindo outro tipo a ela:
No programa de exemplo anterior, a variável xVariavel é utilizada para armazenar diversos tipos de dados.
A letra "x" em minúsculo no começo do nome é utilizada para indicar uma variável que pode conter
diversos tipos de dados, segundo a Notação Húngara (consulte documentação específica para detalhes).
Este programa troca os valores da variável e exibe seu conteúdo para o usuário através da função ALERT().
Essa função recebe um parâmetro que deve ser do tipo string de caractere, por isso dependendo do tipo
de dado da variável xVariavel é necessário fazer uma conversão antes.
Apesar dessa flexibilidade de utilização de variáveis, devem-se tomar cuidados na passagem de parâmetros
para funções ou comandos, e na concatenação (ou soma) de valores. Note a linha 20 do programa de
exemplo. Quando esta linha é executada, a variável xVariavel contém o valor nulo. A tentativa de soma de
tipos de dados diferentes gera erro de execução do programa. Nesta linha do exemplo, ocorrerá um erro
com a mensagem "type mismatch on +".
Excetuando-se o caso do valor nulo, para os demais devem ser utilizadas funções de conversão quando é
necessário concatenar tipos de dados diferentes (por exemplo, nas linhas 07 e 17.
If xVariavel
é o mesmo que
If xVariavel = .T.
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:
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
+ Adição
- Subtração
* Multiplicação
/ Divisão
** ou ^ Exponenciação
% Módulo (Resto da Divisão)
Operadores de String
Operadores Lógicos
.And. E lógico
.Or. OU lógico
.Not. ou ! NÃO lógico
Operadores de Atribuiçã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
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.
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.
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:
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:
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
Resulta em 22, pois o operador incremental aumentou o valor da primeira nA antes que seu valor fosse
considerado.
Além dos operadores comuns, o ADVPL possui alguns outros operadores ou identificadores. Estas são
suas finalidades:
() Agrupamento ou Função
[] Elemento de Matriz
{} Definição de Matriz, Constante ou Bloco de Código
-> Identificador de Apelido
& Macro substituição
@ Passagem de parâmetro por referência
|| Passagem de parâmetro por valor
Os parênteses são utilizados para agrupar elementos em uma expressão mudando a ordem de precedência
da avaliação da expressão (segundo as regras matemáticas por exemplo). Também servem para envolver
os argumentos de uma função.
Os colchetes são utilizados para especificar um elemento específico de uma matriz. Por exemplo, A[3,2],
refere-se ao elemento da matriz A na linha 3, coluna 2.
As chaves são utilizadas para a especificação de matrizes literais ou blocos de código. Por exemplo,
A:={10,20,30} cria uma matriz chamada A com três elementos.
O símbolo -> identifica um campo de um arquivo diferenciando-o de uma variável. Por exemplo, FUNC-
>nome refere-se ao campo nome do arquivo FUNC. Mesmo que exista uma variável chamada nome, é o
campo nome que será acessado.
O símbolo & identifica uma avaliação de expressão através de macro e é visto em detalhes na documentação
sobre macro substituição.
O símbolo @ é utilizado para indicar que durante a passagem de uma variável para uma função ou
procedimento ela seja tomada como uma referência e não como valor.
O símbolo || é utilizado para indicar que durante a passagem de uma variável para uma função ou
procedimento ela seja tomada como um e valor não como referência.
Dependendo do tipo de operador, existe uma ordem de precedência para a avaliação dos operandos. Em
princípio, todas as operações com os operadores, são realizadas da esquerda para a direita se eles tiverem
o mesmo nível de prioridade.
Anotações
Em expressões complexas com diferentes tipos de operadores, a avaliação seguirá essa seqüência. Caso
exista mais de um operador do mesmo tipo (ou seja, de mesmo nível), a avaliação se dá da esquerda para
direita. Para os operadores matemáticos entretanto, há uma precedência a seguir:
1. Exponenciação
2. Multiplicação e Divisão
3. Adição e Subtração
Considere o exemplo:
O resultado desta expressão é 30, pois primeiramente é calculada a exponenciação 2^3(=8), então são
calculadas as multiplicações e divisões 10/2(=5) e 5*3(=15), e finalmente as adições resultando em
2+5+15+8(=30).
Alteração da Precedência
A utilização de parênteses dentro de uma expressão altera a ordem de precedência dos operadores.
Operandos entre parênteses são analisados antes dos que se encontram fora dos parênteses. Se existirem
mais de um conjunto de parênteses não-aninhados, o grupo mais a esquerda será avaliado primeiro e
assim sucessivamente.
No exemplo acima primeiro será calculada a exponenciação 2^3(=8). Em seguida 2+10(=12) será
calculado, 2+5(=7) calculado, e finalmente a divisão e a multiplicação serão efetuadas, o que resulta em
12/7*3+8(=13.14).
Se existirem vários parênteses aninhados, ou seja, colocados um dentro do outro, a avaliação ocorrerá do
parênteses mais intero em direção ao mais externo.
Anotações
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.
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.
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)
CVALTOCHAR()
Sintaxe CVALTOCHAR(nValor)
DTOC()
Sintaxe DTOC(dData)
DTOS()
Sintaxe DTOS(dData)
Anotações
Sintaxe STOD(sData)
Realiza a conversão de uma informação do tipo caracter com conteúdo no
Descrição
formato “AAAAMMDD” em data.
STR()
Sintaxe STR(nValor)
Realiza a conversão de uma informação do tipo numérico em uma string,
Descrição
adicionando espaços à direita.
STRZERO()
VAL()
Sintaxe VAL(cValor)
Manipulação de strings
As funções mais utilizadas nas operações de manipulação do conteúdo de strings são:
- ALLTRIM()
- ASC()
- AT()
- CHR()
- CSTUFF()
- LEN()
- RAT()
- SUBSTR()
ALLTRIM()
Sintaxe ALLTRIM(cString)
Sintaxe ASC(cCaractere)
Converte uma informação caractere em seu valor de acordo com a tabela
Descrição ASCII.
AT()
CHR()
Sintaxe CHR(nASCII)
LEN()
Sintaxe LEN(cString)
LOWER()
Sintaxe LOWER(cString)
Retorna uma string com todos os caracteres minúsculos, tendo como base a
Descrição
string passada como parâmetro.
RAT()
Anotações
SUBSTR()
UPPER()
Sintaxe UPPER(cString)
Retorna uma string com todos os caracteres maiúsculos, tendo como base a
Descrição
string passada como parâmetro.
- ABS()
- INT()
- NOROUND()
- ROUND()
ABS()
Sintaxe ABS(nValor)
INT()
Sintaxe INT(nValor)
ROUND()
- TYPE()
- VALTYPE()
TYPE()
Sintaxe TYPE(“cVariavel”)
VALTYPE()
Sintaxe VALTYPE(cVariável)
Determina o tipo do conteúdo de uma variável, a qual foi definida na função
Descrição em execução.
Anotações
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.
- Estruturas de repetição
- Estruturas de decisão
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
Uma variável ou um elemento de uma matriz é utilizado como um contador para especificar quantas vezes os comandos
ADVPL dentro da estrutura FOR...NEXT são executados.
Os comandos ADVPL depois do FOR são executados até que o NEXT seja alcançado. O contador (Variavel) é então
incrementado ou decrementado com o valor em nIncremento (se a cláusula STEP for omitida, o contador é incrementado
em 1). Então, o contador é comparado com o valor em nValorFinal. Se for menor ou igual ao valor em nValorFinal, os
comandos seguintes ao FOR são executados novamente.
Fique Se o valor for maior que o contido em nValorFinal, a estrutura FOR...NEXT é terminada e o programa continua a execução
atento no primeiro comando após o NEXT.
Os valores de nValorInicial, nValorFinal e nIncremento são apenas considerados inicialmente. Entretanto, mudar o valor
da variável utilizada como contador dentro da estrutura afetará o número de vezes que a repetição será executada. Se o
valor de nIncremento é negativo e o valor de nValorInicial é maior que o de nValorFinal, o contador será decrementado
a cada repetição.
Local nCnt
Local nSomaPar := 0
For nCnt := 0 To 100 Step 2
nSomaPar += nCnt
Next
Alert( "A soma dos 100 primeiros números pares é: " + ;
cValToChar(nSomaPar) )
Return
Este exemplo imprime a soma dos 100 primeiros números pares. A soma é obtida através da repetição
do cálculo utilizando a própria variável de contador. Como a cláusula STEP está sendo utilizada, a variável
nCnt será sempre incrementada em 2. E como o contador começa com 0, seu valor sempre será um
número par.
O Comando WHILE...ENDDO
A estrutura de controle WHILE...ENDDO, ou simplesmente o loop WHILE, repete uma seção de código
enquanto uma determinada expressão resultar em verdadeiro (.T.).
Sintaxe
WHILE lExpressao
Comandos...
[EXIT]
[LOOP]
ENDDO
Parâmetros
Os comandos entre o WHILE e o ENDDO são executados enquanto o resultado da avaliação da expressão
em lExpressao permanecer verdadeiro (.T.). Cada palavra chave WHILE deve ter uma palavra chave ENDDO
correspondente.
- 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
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.
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”.
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
Sintaxe
IF lExpressao
Comandos
[ELSE
Comandos...]
ENDIF
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
Fique expressão IF...ELSE...ENDIF denominada IF...ELSEIF...ELSE...ENDIF.
atento
Exemplo:
O Comando IF...ELSEIF...ELSE...ENDIF
Executa o primeiro conjunto de comandos cuja expressão condicional resulta em verdadeiro (.T.).
Sintaxe
IF lExpressao1
Comandos
[ELSEIF lExpressaoX
Comandos]
[ELSE
Comandos...]
ENDIF
Anotações
O campo IF...ELSE...ELSEIF...ENDIF possui a mesma estruturação de decisão que pode ser obtida com a utilização do
comando DO CASE...ENDCASE.
Fique
atento
Exemplo:
O Comando DO CASE...ENDCASE
Executa o primeiro conjunto de comandos cuja expressão condicional resulta em verdadeiro (.T.).
DO CASE
CASE lExpressao1
Comandos
[CASE lExpressao2
Comandos
...
CASE lExpressaoN
Comandos]
[OTHERWISE
Comandos]
ENDCASE
Parâmetros
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.
Fique
atento
Exemplo:
DO CASE
CASE nMes <= 3
cPeriodo := "Primeiro Trimestre"
CASE nMes >= 4 .And. nMes <= 6
cPeriodo := "Segundo Trimestre"
CASE nMes >= 7 .And. nMes <= 9
Return
Exercícios
Anotações
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:
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():
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
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 é 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.
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.
Anotações
Inicializando arrays
Algumas vezes o tamanho da matriz é conhecido previamente. Outras vezes o tamanho do array somente
será conhecido em tempo de execução.
01 Local nCnt
02 Local aX[10]
03 Local aY := Array(10)
04 Local aZ := {0,0,0,0,0,0,0,0,0,0}
05
06 For nCnt := 1 To 10
07 aX[nCnt] := nCnt * nCnt
08 Next nCnt
Este código preenche o array com uma tabela de quadrados. Os valores serão 1, 4, 9, 16 ... 81, 100. Note que
a linha 07 se refere à variável aX, mas poderia também trabalhar com aY ou aZ.
O objetivo deste exemplo é demonstrar três modos de criar um array de tamanho conhecido no momento
da criação do código.
1. Na linha 02 o array é criada usando aX[10]. Isto indica ao ADVPL para alocar espaço para 10 elementos
no array. Os colchetes [ e ] são utilizados para indicar o tamanho necessário.
2. Na linha 03 é utilizada a função array com o parâmetro 10 para criar o array, e o retorno desta função
é atribuído à variável aY. Na linha 03 é efetuado o que se chama "desenhar a imagen do array". Como se
pode notar, existem dez 0´s na lista encerrada entre chaves ({}). Claramente, este método não é o utilizado
para criar uma matriz de 1000 elementos.
3. O terceiro método difere dos anteriores porque inicializa a matriz com os valores definitivos. Nos
dois primeiros métodos, cada posição da matriz contém um valor nulo (Nil) e deve ser inicializado
posteriormente.
4. A linha 07 demonstra como um valor pode ser atribuído para uma posição existente em uma matriz
especificando o índice entre colchetes.
Se o tamanho do array não é conhecido até o momento da execução do programa, há algumas maneiras
de criar um array e adicionar elementos a ele. O exemplo a seguir ilustra a idéia de criação de um array
vazio (sem nenhum elemento) e adição de elementos dinamicamente.
1. A linha 02 utiliza os colchetes para criar um array vazio. Apesar de não ter nenhum elemento, seu tipo
de dado é array.
2. Na linha 03 a chamada da função array cria uma matriz sem nenhum elemento.
3. Na linha 04 está declarada a representação de um array vazio em ADVPL. Mais uma vez, estão sendo
utilizadas as chaves para indicar que o tipo de dados da variável é array. Note que {} é um array vazio (tem
o tamanho 0), enquanto {Nil} é um array com um único elemento nulo (tem tamanho 1).
Porque cada uma destes arrays não contém elementos, a linha 07 utiliza a função AADD() para adicionar
elementos sucessivamente até o tamanho necessário (especificado por exemplo na variável nSize).
- ARRAY()
- AADD()
- ACLONE()
- ADEL()
- ASIZE()
- AINS()
- ASORT()
- ASCAN()
ARRAY()
AADD()
Sintaxe AADD(aArray)
A função A CLONE() realiza a cópia dos elementos de u m array para o utro
Descrição
array integralmente.
ADEL()
ASIZE()
ASORT()
ASCAN()
AINS()
Anotações
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
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
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.
Memória
aPessoas[01] aAlunos[01]
:=
aPessoas[02] aAlunos[02]
aPessoas[....] aAlunos[....]
aPessoas[nx] aAlunos[nx]
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.
Memória
Array aPessoas
Rótulo[01]
Rótulo[02]
Rótulo[....]
Rótulo[nX]
Array aAlunos
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.
Memória
aPessoas[01] aAlunos[01]
aPessoas[02] Aclone aAlunos[02]
aPessoas[....] aAlunos[....]
aPessoas[nx] aAlunos[nx]
O ADVPL é uma linguagem baseada em funções. Funções têm um valor de retorno. Assim como o operador
de atribuição :=.
Pode-se escrever:
A expressão x:=10 é avaliada primeiro, e então seu resultado (o valor de X, que agora é 10) é passada para
a função cvaltochar para a conversão para caractere, e em seguida para a função alert para a exibição. Por
causa desta regra de precedência é possível atribuir um valor a mais de uma variável ao mesmo tempo:
Z := Y := X := 0
Por causa dessa regra, essa expressão é avaliada como se fosse escrita assim:
Z := ( Y := (X := 0) )
Segunda premissa
Em ADVPL pode-se juntar diversas linhas de código em uma única linha física de comando. Por exemplo,
o código:
If lAchou
Alert("Cliente encontrado!")
Endif
pode ser escrito assim:
If lAchou ; Alert("Cliente encontrado!") ;
Endif
O ponto-e-vírgula indica ao ADVPL que a nova linha de código está para começar. Pode-se então colocar
diversas linhas lógicas de código na mesma linha física através do editor de texto utilizado.
Apesar da possibilidade de se escrever todo o programa assim, em uma única linha física, isto não é
recomendado pois dificulta a legibilidade do programa e, conseqüentemente, a manutenção.
Lista de expressões
A evolução dos blocos de código começa com as listas de expressões. Nos exemplos a seguir, o símbolo
==> indicará o retorno da expressão após sua avaliação (seja para atribuir em uma variável, exibir para o
usuário ou imprimir em um relatório), que será impresso em um relatório por exemplo.
Cada uma das linhas terá a expressão avaliada, e o valor da variável será então impresso.
Este é o mesmo código que o anterior, apenas escrito em uma única linha:
Apesar desse código se encontrar em uma única linha física, existem duas linhas lógicas separadas pelo
ponto e vírgula. Ou seja, esse código é equivalente a:
Alert( cValToChar( x := 10 ) )
y := 20
Portanto apenas o valor 10 da variável x será passado para as funções cvaltochar e alert para ser exibido.
E o valor 20 apenas será atribuído à variável y.
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:
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.
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 ) )
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:
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.
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():
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.
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
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.
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:
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:
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á:
Finalmente, para ordenar um sub-elemento (coluna) de uma matriz por exemplo, pode-se utilizar o
seguinte bloco de código:
- EVAL()
- DBEVAL()
- AEVAL()
EVAL()
DBEVAL()
AEVAL()
Anotações
Para tornar uma função mais flexível, ao chamá-la pode-se passar parâmetros, o quais contém os dados e
informações que definem o processamento da função.
Os parâmetros das funções descritas utilizando a linguagem ADVPL são posicionais, ou seja, na sua
passagem não importa o nome da variável e sim a sua posição dentro da lista de parâmetros, o que
permite executar uma função escrevendo:
Return ...
A função também tem a faculdade de retornar uma variável, podendo inclusive ser um Array. Para tal
encerra-se a função com:
Return(campo)
No ADVPL existem milhares de funções escritas pela equipe de Tecnologia Microsiga, pelos analistas
de suporte e pelos próprios usuários.
“Vale mais um programador que conhece todas as funções disponíveis em uma linguagem do que aquele que, mesmo
Fique sendo gênio, reinventa a roda a cada novo programa”.
atento
No DEM (Documentação Eletrônica Microsiga) mais de 500 estão documentadas, e este número tende
a aumentar exponencialmente com os novos processos de documentação que estão em implantação na
Tecnologia e Inteligência Protheus.
O objetivo do curso é apresentar, demonstrar e fixar a utilização das principais funções, sintaxes e estruturas
utilizadas em ADVPL.
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.
Anotações
- Function()
- User Function()
- Static Function()
- Main Function()
Function()
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
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.
Fique
atento 3. Funções do tipo Function() são acessíveis por quaisquer outras funções em uso pela aplicação.
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.
Fique 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
atento 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.
Dica 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
CriaSx1(“FIN020”)
Return
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.
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.
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
Fique de funções.
atento
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:
Complementando esta definição, podem ser utilizadas duas formas distintas de passagens de parâmetros
para funções descritas na linguagem ADVPL:
A passagem de parâmetros por conteúdo é a forma convencional de definição dos parâmetros recebidos
pela função chamada, na qual a função recebe os conteúdos passados pela função chamadora, na ordem
com os quais são informados.
Local nCnt
Local nResultado := 0
Return
Avaliando a função CalcFator() descrita anteriormente podemos verificar que a mesma recebe como
parâmetro para sua execução a variável nFator.
Com base nesta função podemos descrever duas forma de passagem de parâmetros por conteúdo:
Local nResultado := 0
nResultado := CalcFator(5)
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 := 5.
Duas características da linguagem ADVPL tornam necessária uma atenção especial na chamada de funções:
1. A linguagem ADVPL não é uma linguagem tipada, de forma que as variáveis não tem um tipo previamente definido,
aceitando o conteúdo que lhes for imposto através de uma atribuição.
Fique 2. Os parâmetros de uma função são atribuídos de acordo com a ordem com os quais são definidos na chamada da mesma.
atento
Não é realizada nenhum tipo de consistência em relação aos tipos dos conteúdos e obrigatoriedade de parâmetros nesta
ação.
Os parâmetros de uma função são caracterizados como variáveis de escopo LOCAL para efeito de execução.
Desta forma os mesmos não devem ser definidos novamente como LOCAL na área de definição e inicialização de variáveis,
pois caso isto ocorra haverá a perda dos valores recebidos pela redefinição das variáveis na função.
Dica
Caso seja necessário garantir um conteúdo padrão para um determinado parâmetro deverá ser utilizado o identificador
DEFAULT conforme detalhado no tópico “Tratamento de valores padrões para parâmetros de funções”.
Local nResultado := 0
Local nFatorUser := 0
nFatorUser := GetFator() // Função ilustrativa na qual o usuário informa o fator a ser utilizado.
nResultado := CalcFator(nFatorUser)
A passagem de conteúdos como variáveis implica na utilização de variáveis de apoio para executar a
chamada de uma função. Neste caso foi informada a variável nFatorUser, a qual será definida pelo usuário
através da função ilustrativa GetFator(). O uso de variáveis de apoio flexibiliza a chamada de outras funções,
pois elas serão parametrizadas de acordo com as necessidades daquele processamento específico no
qual se encontra a função chamadora.
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.
nResultado := CalcFator(nFatorUser)
Dica ...
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.
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.
Passagem de parâmetros por referência – Duas variáveis x uma única área de memória
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.
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.
Dica
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:
Local nCnt
Local nResultado := 0
Default nFator := 1
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.
Se este tratamento não fosse realizado e com isso o parâmetro nFator não fosse informado, ocorreria o
seguinte evento de erro:
Exemplo:
Local nCnt
Local nResultado := 0
For nCnt := nFator To 1 Step -1 // nFator está como Nulo, portando nCnt é nulo
nResultado *= nCnt
Next nCnt // Ao efetuar o Next, o interpretador realiza a ação nCnt += 1.
Return nResultado
Como o interpretador realizará a ação nCnt += 1, e o conteúdo da variável nCnt é nulo ocorrerá o erro de
“type mismath on +=, expected N > U” pois os tipos das variáveis envolvidos na operação são diferentes:
nCnt > nulo (U) e 1 > numérico (N).
Anotações
As diretivas de compilação são comandos que não são compilados, sendo dirigidos ao pré-processador, o
qual é executado pelo compilador antes da execução do processo de compilação propriamente dito.
As diretivas podem ser colocadas em qualquer parte do programa, sendo que as implementadas pela
linguagem ADVPL são:
- #INCLUDE
- #DEFINE
- #IFDEF
- #IFNDEF
- #ELSE
- #ENDIF
- #COMMAND
As diretivas de compilação também são conhecidas como UDC – User Defined Commands.
Fique
atento
Diretiva: #INCLUDE
A diretiva #INCLUDE indica em que arquivo de extensão “CH” (padrão ADVPL) estão os UDCs a serem
utilizados pelo pré-processador.
A aplicação ERP possui diversos includes, os quais devem ser utilizados segundo a aplicação que
será desenvolvida, o que permitirá a utilização de recursos adicionais definidos para a linguagem,
implementados pela área de Tecnologia da Microsiga.
Os includes mais utilizados nas aplicações ADVPL desenvolvidas para o ERP são:
- DIALOG.CH
- FONT.CH
- INI.CH
- PTMENU.CH
- PRINT.CH
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.
Fique
atento
AP5MAIL.CH: Permite a utilização da sintaxe tradicional na definição das seguintes funções de envio e
recebimento de e-mail:
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):
- 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:
- CREATE RPCCONN
- CLOSE RPCCONN
- PREPARE ENVIRONMENT
- RESET ENVIRONMENT
- OPEN REMOTE TRANSACTION
- CLOSE REMOTE TRANSACTION
- CALLPROC IN
- OPEN REMOTE TABLES
- CREATE XMLSTRING
- CREATE XMLFILE
- SAVE XMLSTRING
- SAVE XMLFILE
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
Dica erro informando:
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.
Dica 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.
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.
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-
Fique ELSEIF-ENDIF.
atento
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”
Dica - “SPANISH”
- “ENGLISH”
Banco de Dados: verifica as variáveis AXS e TOP para determinar se o banco de dados em uso pela
aplicação está no formado ISAM (DBF, ADS, CTREE, etc.) ou se está utilizando a ferramenta TOPCONNECT
(DbAcess).
#IFDEF TOP
#ELSE
DbSelectArea(“SA1”)
#ENDIF
Anotações
Desta forma é necessário realizar uma verificação adicional ao #IFDEF TOP antes de executar uma query, que no caso é
Fique
atento realizada através do uso da função TcSrvType(), a qual retorna a string “AS/400” quando este for o banco em uso.
Diretiva: #COMMAND
A diretiva #COMMAND é utilizada principalmente nos includes da linguagem ADVPL para efetuar a
tradução de comandos em sintaxe CLIPPER para as funções implementadas pela Tecnologia Microsiga.
Esta diretiva permite que o desenvolvedor defina para o compilador como uma expressão deverá ser
interpretada.
Através da diretiva #COMMAND, o desenvolvedor determinou as regras para que a sintaxe tradicional
da linguagem CLIPPER para o comando SAY fosse convertida na especificação de um objeto TSAY() do
ADVPL.
Anotações
- Desenvolver um programa que permita ao usuário pesquisar um cliente informando seu CNPJ e
caso o mesmo exista na base, exibir suas principais informações.
- Utilizando a interface visual desenvolvida para o exercício anterior, desenvolver a função genérica
GetTexto(), para ser utilizada nas aplicações do Jogo da Velha e Jogo da Forca.
- Utilizando a função AVISO() desenvolver um programa que permita ao usuário selecionar a opção
de busca de CNPJ por cliente ou fornecedor, e caso encontre exiba seus dados principais.
- Desenvolver uma rotina que capture vários CNPJs de clientes informados pelo usuário, e verifique
para cada um deles se o mesmo existe ou não na base de dados. Ao final informar quais CNPJs
foram informados, e de acordo com a seleção do usuário, exibir os dados principais de um destes
clientes.
- Utilizando a função FORMBATCH() desenvolver uma rotina que verifique se para cada item
de um nota fiscal de entrada existe o respectivo cabeçalho, e caso seja encontrado algum item
inconsistente, comunique esta ocorrência ao usuário que está realizando o processamento.
- Desenvolver uma rotina que, através do uso de um bloco de código, converta a estrutura da tabela
SA1 obtida com a função DBSTRUCT() em uma string denominada cCampo.
Anotações
O PROTHEUS, por outro lado, é uma plataforma tecnológica que engloba um Servidor de Aplicação, um
Dicionário de Dados e as Interfaces para conexão com o usuário. É o Protheus que executa o código
ADVPL e o devido acesso à base da dados.
O Protheus é composto pelo ERP (que engloba, além das funcionalidades descritas nos capítulos
anteriores, mais de trinta verticais aplicadas a áreas específicas de negócios) e pelo Configurador
(programa que permite customizar o sistema às necessidades do usuário de forma fácil).
O Ambiente Protheus
O Protheus é constituído de um conjunto de Softwares que compõem as camadas de funcionalidades
básicas aos serviços de aplicação, interface, banco de dados e repositório, conforme o diagrama da
figura abaixo:
O objetivo do TOTVS DevStudio é facilitar a tarefa de escrever programas: através de cores, indica se a
palavra escrita é uma instrução, uma variável ou um comentário; organiza a biblioteca de programas
em projetos e administra o repositório de objetos; aponta erros de sintaxe; permite o debug (execução
passo a passo do programa, verificando o conteúdo das variáveis) e fornece assistentes (modelos) de
programas.
Anotações
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;
- Que o sistema cresça de forma ilimitada, pois os objetos ficam fora do executável;
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).
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.
- SPOOL: Nesta pasta são gravados os relatórios gerados em disco pelo sistema Protheus.
- SYSTEMLOAD: Contém o dicionário de dados em formato TXT. É neste arquivo que estão todos os
padrões e formatos para a geração dos arquivos de configurações e de customizações (SXs), conforme a
localização de país definida pelo usuário na entrada do sistema.
- MY PROJECTS: Sugere-se a criação desta pasta para armazenar projetos e fontes das customizações
realizadas pelo usuário.
- UPDATES: Sugere-se esta pasta para o armazenamento das atualizações a serem aplicadas no sistema
Protheus.
Apesar da estrutura ilustrada anteriormente indicar que as pastas estão subordinadas à pasta PROTHEUS,
é possível que algumas delas possam estar em máquinas diferentes ou até mesmo em ambientes
computacionais diferentes.
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.
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”.
c:\protheus\bin\appserver\totvsappserver.exe
Destino:
- console
- 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.
c:\protheus\bin\smartclient\totvssmartcliente.exe
Destino:
–M
- 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).
-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.
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.
[DRIVERS]
ACTIVE=TCP
[TCP]
TYPE=TCPIP
PORT=1234
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).
[CONFIG]
LASTMAINPROG=SIGA CFG
LANGUAGE=1
[DRIVERS]
ACTIVE=TCP
[TCP]
SERVER= 172.16.72.41
PORT=1234
Port: Indica o número da porta a ser utilizada para a comunicação entre o Protheus Server e o Protheus
Remote. É necessário que a porta utilizada na comunicação seja a mesma em ambos (no TOTVSAPPSERVER.
INI e no TOTVSSMARTCLIENT.INI). Vale ressaltar que a porta 80 é reservada para a Internet e pode causar
conflitos caso seja utilizada na comunicação do Protheus.
Server: Aponta para o endereço do servidor que pode ser a própria máquina (localhost) ou o nome da
máquina (Server= Servidor_01) ou mesmo um endereço IP (exemplo Server=172.16.72.41).
Exemplo:
O Configurador do Protheus
Funcionalidades Abordadas
O objetivo deste tópico não é abranger todo a estrutura e recursos do módulo Configurador da aplicação
ERP, mas permitir a realização de tarefas de configuração simples que serão necessárias no desenvolvimento
de pequenas customizações.
Para contextualizar a estrutura da aplicação ERP, no tópico a seguir é detalhada a forma como as tabelas
de dados do sistema estão divididas entre os diversos módulos que compõe o PROTHEUS.
Arquivo Descrição
SIGAMAT Cadastro de empresas e filiais do sistema
SIGAPSS Arquivo de usuários, grupos e senhas do sistema
SIX Índices dos arquivos
SX1 Perguntas e respostas
SX2 Mapeamento de tabelas
SX3 Dicionário de Dados
SX4 Agenda do Schedule de processos
SX5 Tabelas
SX6 Parâmetros
SX7 Gatilhos de Interface
SX8 Fora de uso
SX9 Relacionamentos entre tabelas
SXA Pastas cadastrais apontadas no S X3
SXB Consulta por meio da tecla F3 (Consulta Padrão)
SXD Controle do Schedule de processos
SXE Seqüência de documentos (+1)
SXF Seqüência de documentos (Próximo)
SXG Tamanho padrão para campos apontado pelo SX3
SXK Resposta de Perguntas (SX1) por u suários
SXO Controle de LOGs por tabela
SXP Histórico de Logs cadastrados no SXO
Cadastro de filtros inteligentes da mbrowse (contém as
SXQ informações necessárias para a criação do filtro).
Cadastro de relacionamento entre programa x filtro
SXR (util izada internamente pelo Protheus para verificar em
quais programas os filtros poderão ser utilizados).
Anotações
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 PLANEJA MENTO 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
SIGATC F 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
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”.
Família Descrição
S - Tabelas pertencentes ao sistema básico, também chamado Classic
Cadastros de entidades compartilhadas entre os ambientes
S A
(Clientes, Fornecedores, Bancos entre outros).
Cadastros dos ambientes de Materiais (Produtos, Saldos entre
S B
outros).
Arquivos de movimentações diversas utilizados pelos ambientes de
Materiais (Solicitação ao Almoxarifado, Solicitação de Compras,
S C
Pedido de Compras, Pedido de Vendas, Ordens de Produção entre
outros).
Arquivos de movimentações de estoque (Itens de notas fiscais de
S D
entrada e saída, movimentos internos de estoque entre outros).
S E Cadastros e movimentações do ambiente Financeiro.
Cadastros e movimentações Fiscais (Cabeçalhos das notas fiscais
S F 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 ambie nte 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ér cio 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 l ivres para utilização e projetos específicos em clientes em
adição a família SZ.
Anotações
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.
Funcionalidades do Configurador
A customização de um sistema como o Protheus consiste em adaptar o sistema de forma a melhor atender
as necessidades do cliente.
A flexibilidade de um sistema, ou seja, sua capacidade de adaptar-se (polimorfismo, aquele que assume
várias formas) é uma das mais importantes características de uma solução ERP.
As funcionalidades tratadas pelo Configurador definem a flexibilidade do ERP Protheus. Flexibilizar sem
despadronizar, ou seja, tudo que foi customizado permanece válido, mesmo com o desenvolvimento de
novas versões.
Anotações
Essas informações vão de simples parâmetros até complexas expressões e comandos que são interpretadas
em tempo de execução.
O objetivo do Dicionário de Dados é permitir que o próprio usuário crie novas tabelas ou altere os
campos nas tabelas existentes quanto ao seu uso, sua ordem de apresentação, legenda (nos três idiomas),
validação, help, obrigatoriedade de preenchimento, inicialização etc.
1. Para adicionar uma tabela ao dicionário de dados de uma empresa, selecione a opção Dicionário de
Dados abaixo da empresa que será atualizada. (árvore de opções da parte esquerda da interface visual do
Gerenciador de Bases de Dados).
2. Após a seleção da opção Dicionário de Dados serão exibidas as tabelas já cadastradas no arquivo de
sistema SX2.
( ). Ao utilizar esta opção será exibida a tela para definição dos dados referentes à nova tabela que
será criada:
O domínio SZ1 até SZZ (considerando todos os número e todas as letras no último byte) é reservado para
dados exclusivos do usuário pois esse intervalo não será utilizado pelo sistema. Caso seja necessário o
domínio Z00 a ZZZ também pode ser empregado para desenvolvimentos específicos do cliente.
Não devem ser criadas tabelas específicas de clientes com quaisquer outras nomenclaturas, o que pode afetar diretamente
um processo de atualização futuro.
Fique
atento
O nome da tabela é preenchido automaticamente, adicionando 990. Esse dado refere-se à empresa 99
(Teste Matriz) a qual está sendo adicionado à tabela.
O Path refere-se à pasta que conterá efetivamente os dados das tabelas, quando ISAM, nas versões
com banco de dados relacional não são utilizadas. Essa pasta será criada dentro da pasta indicada na
configuração do sistema como ROOTTPATH.
1. Para adicionar um campo a uma tabela do dicionário de dados de uma empresa, selecione a opção
Dicionário de Dados abaixo da empresa que será atualizada. (árvore de opções da parte esquerda da
interface visual do Gerenciador de Bases de Dados).
2. Após a seleção da opção Dicionário de Dados serão exibidas as tabelas já cadastradas no arquivo de
sistema SX2.
3. Após a visualização das tabelas já cadastradas no SX2 da empresa selecionada, localize e selecione
a tabela que será atualizada, e utilize o botão Editar ( ). Ao utilizar esta opção será exibida a tela de
manutenção de campos da tabela selecionada:
término confirme o cadastramento do novo campo para a tabela com o botão Confirmar ( ).
Nome do campo: Todos os campos têm como prefixo o próprio nome da tabela, sendo que para tabelas
da família “S”, o prefixo do campo é composto apenas pelos próximos dois dígitos. No caso das demais
tabelas, o prefixo do campo serão os três dígitos identificadores da tabela.
Tipo do campo: Indica se é caractere, numérico, lógico, data ou memo. É claro que a mudança do tipo de
campo deve ser feita com muito cuidado, pois, se tivermos um campo numérico usado em cálculos e ele
for alterado para caractere, certamente teremos um erro.
Tamanho do campo: Também aqui é necessário certo cuidado ao alterá-lo, pois poderemos ter
truncamentos em relatórios e consultas em que há espaço para conteúdos maiores que o original.
Formato de edição: Define como o campo aparece nas telas e nos relatórios.
Contexto: Pode ser real ou virtual. O contexto virtual cria o campo somente na memória e não na
tabela armazenada no disco. Isso é necessário porque os programas de cadastramento e de consulta
genérica apresentam somente uma tabela de cada vez. Assim, se quisermos apresentar um campo de
uma outra tabela, ou mesmo o resultado de um cálculo, sem que tal informação ocupe espaço físico no
HD, utilizamos o contexto virtual. Campos virtuais normalmente são alimentados por gatilhos.
Propriedade: Indica se um campo pode ou não ser alterado pelo usuário. Exemplo: saldos normalmente
não podem, pois quem cuida dessa tarefa são os programas.
Guia: Campo
O formato “!” indica que o caractere será sempre maiúsculo, independente da ação do usuário. O formato
“@!” indica que essa característica estende-se por todo o campo.
- O contexto real indica que o campo existirá efetivamente no banco de dados e o contexto virtual significa
que o campo existirá apenas no dicionário de dados e não fisicamente.
- Nesta janela, os dados estão classificados em seis pastas com objetivos de preenchimento bem
específicos:
Guia: Informações
- Título: É a legenda que aparece nas telas/relatórios. Há inclusive três campos para esta finalidade: em
português, espanhol e inglês. Esta propriedade pode ser alterada à vontade, pois não interfere em nenhum
processamento.
Guia: Validações
- Validações: Nesta propriedade, escreve-se uma função de validação do campo que está sendo digitado.
Existe um conjunto de funções disponíveis no ADVPL apropriadas para esse caso.
Guia: Uso
Guia: Módulos
Os índices do sistema auxiliam na seleção e obtenção de informações da base de dados além de determinar
a ordem de apresentação dos registros de uma tabela em consultas e relatórios.
Procedimento
1. Para adicionar um índice a uma tabela do dicionário de dados de uma empresa, selecione a opção
Dicionário de Dados abaixo da empresa que será atualizada. (árvore de opções da parte esquerda da
interface visual do Gerenciador de Bases de Dados).
2. Após a seleção da opção Dicionário de Dados serão exibidas as tabelas já cadastradas no arquivo de
sistema SX2.
Anotações
3. Após a visualização das tabelas já cadastradas no SX2 da empresa selecionada, localize e selecione
a tabela que será atualizada, e utilize o botão Editar ( ). Ao utilizar esta opção será exibida a tela de
manutenção de campos da tabela selecionada:
Anotações
4. Selecione a opção índices ( ), para que sejam exibidos os índices disponíveis para a
tabela no arquivo de sistema SIX.
( ). Ao utilizar esta opção será exibida a tela para definição dos dados referentes ao novo índice que
será criado:
término confirme o cadastramento do novo índice para a tabela com o botão Confirmar ( ).
- O Nickname é uma identificação complementar do índice o qual pode ser utilizada para auxiliar
o desenvolvedor na utilização desta ordem em uma aplicação, a qual pode ser padrão do sistema ou
específica de um cliente.
- Para selecionar os campos já cadastrados na tabela, pode ser utilizado o botão Campos ( ). Esta
facilidade preenche, automaticamente, os campos de descrição.
- O campo relativo à filial sempre faz parte dos índices, com exceção do SM2, para que os registros nas
tabelas estejam agrupados por filiais, independente desta tabela ser compartilhada entre as filiais.
- Uma tabela poderá ter vários índices cadastrados no Dicionário de Dados. Em determinado momento,
porém, apenas um deles oferecerá acesso ao registro. Essa ordem pode ser alterada em tempo de
execução pelos programas da aplicação, através do comando DBSetOrder(), ou através da definição de
uma ordem específica na utilização de queries para acesso as dados diretamente em bancos de dados
de ambientes TOPCONNECT (DbAcess).
Anotações
1. Para adicionar um gatilho a um campo de uma tabela do dicionário de dados de uma empresa, selecione
a opção Gatilho abaixo da empresa que será atualizada. (árvore de opções da parte esquerda da interface
visual do Gerenciador de Bases de Dados).
2. Após a seleção da opção Gatilhos serão exibidos os itens já cadastradas no arquivo de sistema SX7.
3. Após a visualização dos gatilhos já cadastrados no SX7 da empresa selecionada, utilize o botão Incluir
- Pode haver vários gatilhos para o mesmo campo. A ordem de execução é determinada pelo campo
Seqüência.
- A regra pode ser uma expressão que resulta em um valor a ser preenchido no Contra Domínio.
- O posicionamento igual a Sim indica que será executado um comando de busca do registro de acordo
com a chave indicada.
- O Alias, a Ordem e a Chave descrevem a tabela envolvida no gatilho, seu índice e a chave para que a
funcionalidade se posicione no registro adequado.
1. Para adicionar uma tabela genérica, selecione os menus Ambiente, Cadastros, Tabelas.
2. Após a seleção da opção Tabelas serão exibidos os itens já cadastradas no arquivo de sistema SX5.
Anotações
Criação de Parâmetros
Procedimento
2. Após a seleção da opção Tabelas serão exibidos os itens já cadastradas no arquivo de sistema SX6.
3. Após a visualização dos Parâmetros já cadastrados no SX6 da empresa selecionada, utilize o botão
Anotações
Anotações
Projeto
Um programa para ser compilado deve ser vinculado a um projeto. Normalmente, programas que fazem
parte de um determinado módulo ou ambiente estão em um mesmo projeto.
A vinculação dos programas a um projeto é feita por meio dos arquivos do tipo PRW. Na verdade, um
projeto pode ser constituído de um ou mais arquivos deste tipo, que por sua vez, podem ter uma ou mais
funções, conforme ilustra o diagrama a seguir:
Uma vez adicionado a um projeto e compilado sem incidências de erros de código, o objeto resultante
será cadastrado no RPO (Repositório de Objetos) e poderá ser utilizado pela aplicação ERP.
A compilação dos itens de um projeto pode ser realizada individualmente, por grupo de fontes (pastas) ou
ainda selecionando-o inteiramente. Cada uma dos fontes será processado e compilado separadamente,
permitindo a visualização do progresso da operação e das mensagens de aviso (warnings) ou erros
(critical errors) na guia Mensagens.
Execução
Para que os objetos compilados e disponíveis n RPO sejam utilizados, devem ser observadas as seguintes
regras:
- Se o programa não manipula arquivos, pode-se chamá-lo diretamente do DEV-Studio (nome no lado
direito da barra de ferramentas);
- Realizar a preparação do ambiente na própria rotina, permitindo sua execução diretamente pelo DEV-
Studio.
- Não se pode compilar um programa com o Remote e o Monitor abertos, tenha este finalizado ou não
por erro.
Para identificar as causas de erros, a ferramenta DEV-Studio possui diversos recursos que auxiliam o
DEBUG.
A ação de DEBUG necessita que o programa seja executado a partir do DEV-Studio, sendo necessário
observar as seguintes regras:
- Executar a rotina através do DEV-Studio, selecionando seu nome diretamente, ou o módulo que contém
a opção ou a ação que irá executá-la;
- Variáveis Locais
- Variáveis Privates
- Variáveis Public’s
- Variáveis Static’s
- Janela da Watch’s
- Janela de Tabelas e Campos
- Pilha de Chamadas
- Pilha de ChamadasNa pasta de Comandos, pode-se, enquanto o programa estiver pausado, escrever
qualquer comando e ao dar Enter, ele é executado, permitindo pesquisar palavras e expressões no próprio
fonte ou em qualquer fonte armazenado no HD;
- Pilha de ChamadasAo parar pode-se ou continuar o programa até o próximo ponto de parada, caso haja
um outro definido, ou executar linha a linha da rotina.
Interface da aplicação
Por ser um ambiente integrado de desenvolvimento, o DEV-Studio proporciona todas essas facilidades,
por meio de interface única como ilustra a figura a seguir:
- Na tela central, é apresentado o código das funções em ADVPL. Na parte inferior são exibidas algumas
pastas que facilitam a execução de comandos, exibição de conteúdos de variáveis e mensagens, bem
como dados sobre o projeto.
Anotações
Desta forma a linguagem possui dois grupos de funções distintos para atuar com os bancos de dados:
As funções de manipulação de dados ditas como genéricas permitem que uma aplicação ADVPL seja
escrita da mesma forma, independente se a base de dados configurada para o sistema ERP for do tipo
ISAM ou padrão SQL.
Muitas destas funções foram inicialmente herdadas da linguagem CLIPPER, e mediante novas
implementações da área de Tecnologia da Microsiga foram melhoradas e adequadas às necessidades do
ERP. Por esta razão é possível encontrar em documentações da linguagem CLIPPER informações sobre
funções de manipulação de dados utilizadas na ferramenta ERP.
A integração entre a aplicação ERP e a ferramenta TOPCONNECT permite que as funções de acesso e
manipulação de dados escritas em ADVPL sejam interpretadas e convertidas para uma sintaxe compatível
com o padrão SQL ANSI e desta forma aplicadas aos SGDBs (Sistemas Gerenciadores de Bancos de Dados)
com sua sintaxe nativa.
Para implementar um acesso mais otimizado e disponibilizar no ambiente ERP funcionalidades que utilizem
de forma mais adequada os recursos dos SGDBs homologados para o sistema, foram implementadas
funções de acesso e manipulação de dados específicas para ambientes TOPCONNECT/DBACCESS.
Estas funções permitem que o desenvolvedor ADVPL execute comandos em sintaxe SQL diretamente
de um código fonte da aplicação, disponibilizando recursos como execução de queries de consulta,
chamadas de procedures e comunicação com outros bancos de dados através de ODBCs.
As funções específicas para ambientes TOPCONNECT serão abordas no material de ADVPL Avançado.
Fique
atento
No acesso a informações em bases de dados do padrão ISAM são sempre lidos os registros inteiros,
enquanto no SQL pode-se ler apenas os campos necessários naquele processamento.
O acesso direto é feito através de índices que são tabelas paralelas às tabelas de dados e que contêm
a chave e o endereço do registro, de forma análoga ao índice de um livro. Para cada chave, é criado um
índice próprio.
Nas bases de dados padrão ISAM os índices são armazenados em um único arquivo do tipo CDX, já nos
bancos de dados padrão SQL cada índice é criado com uma numeração seqüencial tendo como base o
nome da tabela ao qual ele está relacionado.
A cada inclusão ou alteração de um registro todos os índices são atualizados, tornando necessário planejar
adequadamente quais e quantos índices serão definidos para uma tabela, pois uma quantidade excessiva
pode comprometer o desempenho destas operações.
Deve ser considerada a possibilidade de utilização de índices temporários para processos específicos, os
quais serão criados em tempo de execução da rotina. Este fator deve levar em consideração o “esforço” do
ambiente a cada execução da rotina e a periodicidade com a qual é executada.
Nas bases de dados padrão ISAM, cada registro possui um identificador nativo ou ID seqüencial e
ascendente que funciona como o endereço base daquela informação.
Este ID, mas conhecido como RECNO ou RECNUMBER é gerado no momento de inclusão do registro na
tabela e somente será alterado caso a estrutura dos dados desta tabela sofra alguma manutenção. Dentre
as manutenções que uma tabela de dados ISAM pode sofrer pode-se citar a utilização do comando
PACK, o qual irá apagar fisicamente os registros deletados da tabela forçando uma renumeração dos
identificadores de todos os registros. Esta situação também torna necessária a recriação de todos os
índices vinculados àquela tabela.
Isto ocorre nas bases de dados ISAM devido ao conceito de exclusão lógica de registros que as mesmas
possuem. Já os bancos de dados padrão SQL nativamente utilizam apenas o conceito de exclusão física
de registros, o que para outras aplicações seria transparente, mas não é o caso do ERP Protheus.
Para manter a compatibilidade das aplicações desenvolvidas para bases de dados padrão ISAM, a área de
Tecnologia e Banco de Dados da Microsiga implementou nos bancos de dados padrão SQL o conceito de
exclusão lógica de registros existente nas bases de dados ISAM através da criação de campos de controle
específicos: R_E_C_N_O_, D_E_L_E_T_ e R_E_C_D_E_L.
Estes campos permitem que a aplicação ERP gerencie as informações do banco de dados da mesma
forma que as informações em bases de dados ISAM.
Para a aplicação ERP Protheus o campo de controle R_E_C_N_O_ é definido em todas as tabelas como
sendo sua chave primária, o que transfere o controle de sua numeração seqüencial ao banco de dados.
O campo D_E_L_E_T_ é tratado internamente pela aplicação ERP como um “flag” ou marca de exclusão.
Desta forma os registros que estiverem com este campo marcado serão considerados como excluídos
logicamente. A execução do comando PACK em uma tabela de um banco de dados padrão SQL visa excluir
fisicamente os registros com o campo D_E_L_E_T_ marcado, mas não causará o efeito de renumeração de
RECNO (no caso R_E_C_N_O_) que ocorre nas tabela de bases de dados ISAM.
Dentre as funções ADVPL disponíveis para acesso e manipulação de informações, este material irá detalhar
as seguintes opções:
- SELECT()
- DBSELECTAREA()
- DBSETORDER()
- DBSEEK() E MSSEEK()
- DBSKIP()
- DBGOTO()
- DBGOTOP()
- DBGOBOTTON()
- DBSETFILTER()
- RECLOCK()
- SOFTLOCK()
- MSUNLOCK()
- DBDELETE()
- DBUSEAREA()
- DBCLOSEAREA()
DBRLOCK()
Sintaxe - DBRLOCK(xIdentificador)
Descrição - Função de base de dados, que efetua o lock (travamento) do registro identificado pelo
parâmetro xIdentificador. Este parâmetro pode ser o Recno() para tabelas em formado ISAM, ou a chave
primária para bancos de dados relacionais.
DBCLOSEAREA()
Sintaxe - DbCloseArea()
Descrição - Permite que um alias presente na conexão seja fechado, o que viabiliza seu reuso em outro
operação. Este comando tem efeito apenas no alias ativo na conexão, sendo necessária sua utilização em
conjunto com o comando DbSelectArea().
DBCOMMIT()
Sintaxe - DBCOMMIT()
DBCOMMITALL()
Sintaxe - DBCOMMITALL()
Descrição - Efetua todas as atualizações pendentes em todas as área de trabalho em uso pela thread
(conexão) ativa.
DBDELETE()
Sintaxe - DbDelete()
Descrição - Efetua a exclusão lógica do registro posicionado na área de trabalho ativa, sendo necessária
sua utilização em conjunto com as funções RecLock() e MsUnLock().
DBGOTO()
Sintaxe - DbGoto(nRecno)
Descrição - Move o cursor da área de trabalho ativa para o record number (recno) especificado, realizando
um posicionamento direto, sem a necessidade uma busca (seek) prévio.
DBGOTOP()
Sintaxe - DbGoTop()
Descrição - Move o cursor da área de trabalho ativa para o primeiro registro lógico.
DBGOBOTTON()
Sintaxe - DbGoBotton()
Descrição - Move o cursor da área de trabalho ativa para o último registro lógico.
Sintaxe - DBRLOCKLIST()
Descrição - Retorna um array contendo o record number (recno) de todos os registros travados da área
de trabalho ativa.
DBSEEK() E MSSEEK()
Descrição - DbSeek: Permite posicionar o cursor da área de trabalho ativo no registro com as informações
especificadas na chave de busca, fornecendo um retorno lógico indicando se o posicionamento foi
efetuado com sucesso, ou seja, se a informação especificada na chave de busca foi localizada na área de
trabalho.
MsSeek(): Função desenvolvida pela área de Tecnologia da Microsiga, a qual possui as mesmas
funcionalidades básicas da função DbSeek(), com a vantagem de não necessitar acessar novamente a
base de dados para localizar uma informação já utilizada pela thread (conexão) ativa.
DBSKIP()
Sintaxe - DbSkip(nRegistros)
Descrição - Move o cursor do registro posicionado para o próximo (ou anterior dependendo do
parâmetro), em função da ordem ativa para a área de trabalho.
DBSELECTAREA()
Descrição - Define a área de trabalho especificada com sendo a área ativa.Todas as operações subseqüentes
que fizerem referência a uma área de trabalho a utilização, a menos que a área desejada seja informada
explicitamente.
DBSETFILTER()
Descrição - Define um filtro para a área de trabalho ativa, o qual pode ser descrito na forma de um bloco
de código ou através de uma expressão simples.
DBSETORDER()
Sintaxe - DbSetOrder(nOrdem)
Descrição - Define qual índice será utilizada pela área de trabalho ativa, ou seja, pela área previamente
selecionada através do comando DbSelectArea(). As ordens disponíveis no ambiente Protheus são aquelas
definidas no SINDEX /SIX, ou as ordens disponibilizadas por meio de índices temporários.
Sintaxe - DbOrderNickName(NickName)
Descrição - Define qual índice criado pelo usuário seja utilizado. O usuário pode incluir os seus próprios
índices e no momento da inclusão deve criar o NICKNAME para o mesmo.
DBUNLOCK()
Sintaxe - DBUNLOCK()
Descrição - Mesma funcionalidade da função UNLOCK(), só que recomendada para ambientes de rede
nos quais os arquivos são compartilhados.
Libera o travamento do registro posicionado na área de trabalho ativa e confirma as atualizações efetuadas
naquele registro.
DBUNLOCKALL()
Sintaxe - DBUNLOCKALL()
Descrição - Libera o travamento de todos os registros de todas as áreas de trabalho disponíveis na thread
(conexão) ativa.
DBUSEAREA()
Descrição - Define um arquivo de base de dados como uma área de trabalho disponível na aplicação.
MSUNLOCK()
Sintaxe - MsUnLock()
Descrição - Libera o travamento (lock) do registro posicionado confirmando as atualizações efetuadas
neste registro.
RECLOCK()
Sintaxe - RecLock(cAlias,lInclui)
Descrição - Efetua o travamento do registro posicionado na área de trabalho ativa, permitindo a inclusão
ou alteração das informações do mesmo.
RLOCK()
Sintaxe - Select(cArea)
SOFTLOCK()
Sintaxe - SoftLock(cAlias)
Descrição - Permite a reserva do registro posicionado na área de trabalho ativa de forma que outras
operações, com exceção da atual, não possam atualizar este registro. Difere da função RecLock() pois não
gera uma obrigação de atualização, e pode ser sucedido por ele.
Na aplicação ERP Protheus, o SoftLock() é utilizado nos browses, antes da confirmação da operação de
alteração e exclusão, pois neste momento a mesma ainda não foi efetivada, mas outras conexões não
podem acessar aquele registro pois o mesmo está em manutenção, o que implementa da integridade da
informação.
UNLOCK()
Sintaxe - UNLOCK()
Anotações
Para especificar qual deve ser o elemento referenciado, deve-se utilizar o operador de identificação de
apelido (->) e um dos dois identificadores de referência, MEMVAR ou FIELD.
cRes := MEMVAR->NOME
Esta linha de comando identifica que o valor atribuído à variável cRes deve ser o valor da variável de
memória chamada NOME.
cRes := FIELD->NOME
O identificador FIELD pode ser substituído pelo apelido de um arquivo ou tabela aberto, para evitar a
necessidade de selecionar a área antes de acessar o conteúdo de terminado campo.
cRes := CLIENTES->NOME
As tabelas de dados utilizadas pela aplicação ERP recebem automaticamente do sistema o apelido ou
ALIAS especificado para as mesmas no arquivo de sistema SX2. Assim se o campo NOME pertence a uma
tabela da aplicação PROTHEUS, o mesmo poderá ser referenciado com a indicação do ALIAS pré-definido
desta tabela.
Os alias das tabelas da aplicação ERP são padronizados em três letras, que correspondem as iniciais da
tabela. As configurações de cada ALIAS utilizado pelo sistema podem ser visualizadas através do módulo
Configurador -> Bases de Dados -> Dicionários -> Bases de Dados.
No caso específico da aplicação ERP Protheus a chave primária em ambientes TOPCONNECT será o campo
R_E_C_N_O_, e para bases de dados padrão ISAM o conceito de chave primária é implementado pela
regra de negócio do sistema, pois este padrão de dados não possui o conceito de unicidade de dados.
Semáforos
Para definir o conceito do que é um semáforo de numeração deve-se avaliar a seguinte seqüência de
eventos no sistema:
- Ao ser fornecido um número, ele permanece reservado até a conclusão da operação que o
solicitou;
- Se esta operação for confirmada, o número é indisponibilizado, mas se a operação for cancelada,
o número voltará a ser disponível mesmo que naquele momento números maiores já tenham sido
oferecidos e utilizados.
Com isso, mesmo que tenhamos vários processos solicitando numerações seqüenciais para uma mesma
tabela, como por exemplo inclusões simultâneas de pedidos de vendas, teremos para cada pedido um
número exclusivos e sem o intervalos e numerações não utilizadas.
A linguagem ADVPL permite a utilização das seguintes funções para o controle das numerações
seqüenciais utilizadas nas tabelas da aplicação ERP:
- GETSXENUM()
- CONFIRMSXE()
- ROLLBACKSXE()
GETSXENUM()
Descrição - Obtém o número seqüência do alias especificado no parâmetro, através da referência aos
arquivos de sistema SXE/SXF ou ao servidor de numeração, quando esta configuração está habilitada no
ambiente Protheus.
CONFIRMSXE()
Sintaxe - CONFIRMSXE(lVerifica)
ROLLBACKSXE()
Sintaxe - ROLLBACKSXE()
Descrição - Descarta o número fornecido pelo último comando GETSXENUM(), retornando a numeração
disponível para outras conexões.
Anotações
Anotações
As funções de validação têm como característica fundamental um retorno do tipo lógico, ou seja, um
conteúdo .T. – Verdadeiro ou .F. – Falso.
Com base nesta premissa, a utilização de validações no Dicionário de Dados (SX3) ou nas Perguntas de
Processos e Relatórios (SX1) deverá focar sempre na utilização de funções ou expressões que resultem
em um retorno lógico.
Dentre as funções que a linguagem ADVPL em conjunto com os recursos desenvolvidos pela aplicação
ERP para validação de campos e perguntas serão detalhadas:
- VAZIO()
- NAOVAZIO()
- EXISTCPO()
- EXISTCHAV()
- PERTENCE()
- POSITIVO()
- NEGATIVO()
- TEXTO()
EXISTCHAV()
Descrição - Retorna .T. ou .F. se o conteúdo especificado existe no alias especificado. Caso exista será
exibido um help de sistema com um aviso informando da ocorrência.
Função utilizada normalmente para verificar se um determinado código de cadastro já existe na tabela na
qual a informação será inserida, como por exemplo o CNPJ no cadastro de clientes ou fornecedores.
EXISTCPO()
Função utilizada normalmente para verificar se a informação digitada em um campo, a qual depende
de outra tabela, realmente existe nesta outra tabela, como por exemplo o código de um cliente em um
pedido de venda.
Sintaxe - NaoVazio()
Descrição - Retorna .T. ou .F. se o conteúdo do campo posicionado no momento não está vazio.
NEGATIVO()
Sintaxe - Negativo()
Descrição - Retorna .T. ou .F. se o conteúdo digitado para o campo é negativo.
PERTENCE()
Sintaxe - Pertence(cString)
Descrição - Retorna .T. ou .F. se o conteúdo digitado para o campo está contido na string definida como
parâmetro da função. Normalmente utilizada em campos com a opção de combo, pois caso contrário
seria utilizada a função ExistCpo().
POSITIVO()
Sintaxe - Positivo()
TEXTO()
Sintaxe - Texto()
Descrição - Retorna .T. ou .F. se o conteúdo digitado para o campo contém apenas números ou
alfanuméricos.
VAZIO()
Sintaxe - Vazio()
Descrição - Retorna .T. ou .F. se o conteúdo do campo posicionado no momento está vazio.
Anotações
Funções
Conteúdo Funcionalidade
A Permite apenas caracteres alfabéticos.
C Exibe CR depois de números positivos.
E Exibe numérico com o ponto e vírgula invertidos (formato Europeu).
R Insere c aracteres diferentes d os c aracteres de t emplate na exibição, mas não os
insere na variável do GET.
S<n> Permite rolamento horizontal d o texto dentro d o GET, < n> é u m número i nteiro
que identifica o tamanho da região.
X Exibe DB depois de números negativos.
Z Exibe zeros como brancos.
( Exibe números negativos entre parênteses com os espaços em branco iniciais.
) Exibe números negativos entre parênteses sem os espaços em branco iniciais.
! Converte caracteres alfabéticos para maiúsculo.
Templates
Conteúdo Funcionalidade
X Permite qualquer caractere.
9 Permite apenas dígitos para qualquer tipo de dado, incluindo o sinal para
numéricos.
# Permite dígitos, sinais e espaços em branco para qualquer tipo de dado.
! Converte caracteres alfabéticos para maiúsculo.
* Exibe um asterisco no lugar dos espaços em branco iniciais em números.
. Exibe o ponto decimal.
, Exibe a posição do milhar.
A1_NOME – Caracter - 40
Picture: @!
Funções
Conteúdo Funcionalidade
C Exibe CR depois de números positivos
E Exibe numérico com o ponto e a vírgula invertidos (formato Europeu)
R Insere caracteres diferentes dos caracteres de template
X Exibe DB depois de números negativos
Z Exibe zeros como brancos
( Envolve números negativos entre parênteses
! Converte todos os caracteres alfabéticos para maiúsculo
Templates
Conteúdo Funcionalidade
X Exibe dígitos para qualquer tipo de dado
9 Exibe dígitos para qualquer tipo de dado
# Exibe dígitos para qualquer tipo de dado
! Converte caracteres alfabéticos para maiúsculo
* Exibe asterisco no lugar de espaços em branco inicias em números
. Exibe a posição do ponto decimal
, Exibe a posição do milhar
As regras que devem ser observadas na montagem de um gatilho e configuração de seu retorno são:
- Na definição da chave de busca do gatilho deve ser avaliada qual filial deverá ser utilizada como parte da
chave: a filial da tabela de origem do gatilho ou a filial da tabela que será consultada. O que normalmente
determina a filial que será utilizada como parte da chave é justamente a informação que será consultada,
aonde:
- Consultas de informações entre tabelas com estrutura de cabeçalho e itens devem utilizar a filial da
tabela de origem, pois ambas as tabelas devem possuir o mesmo tratamento de filial (compartilhado ou
exclusivo).
Exemplos:
Exemplos:
- Consulta a informações de tabelas de movimentos devem utilizar a filial da tabela a ser consultada,
pois apesar das movimentações de um módulo seguirem um determinado padrão, a consulta pode ser
realizada entre tabelas de módulos distintos, o que poderia gerar um retorno incorreto baseado nas
diferentes parametrizações destes ambientes.
Exemplos:
- Na definição da regra de retorno deve ser considerado o tipo do campo que será atualizado, pois é este
campo que determina qual tipo do retorno será considerado válido para o gatilho.
- Tipo do parâmetro: de forma similar a uma variável, um parâmetro terá um tipo de conteúdo pré-definido
em seu cadastro.
Esta informação é utilizada pelas funções da aplicação ERP na interpretação do conteúdo do parâmetro e
retorno desta informação a rotina que o consultou.
- Interpretação do conteúdo do parâmetro: diversos parâmetros do sistema têm seu conteúdo macro
executado durante a execução de uma rotina do ERP. Estes parâmetros macro executáveis tem como
única característica em comum seu tipo: caractere, mas não existe nenhum identificador explicito que
permite a fácil visualização de quais parâmetros possuem um retorno simples e de quais parâmetros
terão seu conteúdo macro executado para determinar o retorno “real”.
A única forma eficaz de avaliar como um parâmetro é tratado (simples retorno ou macro execução) é
através do código fonte da rotina, no qual deverá ser avaliado como é tratado o retorno de uma destas
funções:
- GETMV()
- SUPERGETMV()
- GETNEWPAR()
Um retorno macro executado é determinado através do uso do operador “&” ou de uma das funções de
execução de blocos de código em conjunto com uma das funções citadas anteriormente.
- GETMV()
- SUPERGETMV()
- GETNEWPAR()
- PUTMV()
GETMV()
Sintaxe - GETMV(cParametro)
GETNEWPAR()
Difere do SuperGetMV() pois considera que o parâmetro pode não existir na versão atual do sistema, e
por conseqüência não será exibida a mensagem de help.
PUTMV()
SUPERGETMV()
Difere do GetMv() pois os parâmetros consultados são adicionados em uma área de memória, que permite
que em uma nova consulta não seja necessário acessar e pesquisar o parâmetro na base de dados.
Apesar de haver parâmetros que permitam a configuração de expressões, e por conseqüência a utilização
de funções para definir o retorno que será obtido com a consulta deste parâmetro, é expressamente
proibido o uso de funções em parâmetros para manipular informações da base de dados do sistema.
Caso haja a necessidade de ser implementado um tratamento adicional a um processo padrão do sistema,
o mesmo deverá utilizar o recurso de ponto de entrada.
- Desta forma, quaisquer alteração na base realizada por uma rotina configurada em um parâmetro
pode ocasionar a perda da integridade das informações do sistema.
Um ponto de entrada é uma User Function desenvolvida com a finalidade de interagir com uma rotina
padrão da aplicação ERP.
A User Function deverá ter um nome pré-estabelecido no desenvolvimento da rotina padrão do ERP,
e de acordo esta pré-disposição e o momento no qual o ponto de entrada é executado durante um
processamento, ele poderá:
- Executar uma ação sem processos de atualizações, mas que necessite utilizar as informações
atuais do ambiente durante o processamento da rotina padrão para determinar as características
do processo;
- Substituir um processamento padrão do sistema por uma regra específica do cliente no qual o
mesmo será implementado.
- Um ponto de entrada não deve ser utilizado para outras finalidades senão para as quais o mesmo foi
pré-definido, sob pena de causar a perda da integridade das informações da base de dados ou provocar
eventos de erro durante a execução da rotina padrão.
- Um ponto de entrada deve ser transparente para o processo padrão, de forma que todas as tabelas
acessadas pelo ponto de entrada e que sejam utilizadas pela rotina padrão, deverão ter sua situação
imediatamente anterior à execução do ponto restaurada ao término do mesmo, e para isto recomenda-se
o uso das funções GETAREA() e RESTAREA().
- Como um ponto de entrada não é executado da forma tradicional, ou seja, ele não é chamado como uma
função, ele não recebe parâmetros. A aplicação ERP disponibiliza uma variável de sistema denominada
PARAMIXB, a qual recebe os parâmetros da função chamadora e os disponibiliza para serem utilizados
pela rotina customizada.
- A variável PARAMIXB não possui um padrão de definição nos códigos fontes da aplicação ERP, desta
forma seu tipo pode variar deste um conteúdo simples (caractere, numérico, lógico e etc.) a um tipo
complexo como um array ou um objeto. Desta forma é necessário sempre avaliar a documentação sobre
o ponto bem como proteger a função customizada de tipos de PARAMIXB não tratados por ela.
Anotações
Além das diferentes sintaxes disponíveis para definição das interfaces visuais o ERP Protheus possui
funcionalidades pré-definidas, as quais já contêm todos os tratamentos necessários a atender as
necessidades básicas de acesso e manutenção das informações do sistema.
Neste tópico serão abordadas as sintaxes convencionais para definição das interfaces visuais da linguagem
ADVPL e as interfaces de manutenção disponíveis no ambiente ERP Protheus.
Para ilustrar a diferença na utilização destes dois includes, segue abaixo as diferentes definições para o
componentes Dialog e MsDialog:
#include “rwmake.ch”
#include “protheus.ch”
DEFINE MSDIALOG oDlg TITLE "Janela em sintaxe ADVPL "FROM 000,000 TO 400,600 PIXEL
ACTIVATE MSDIALOG oDlg CENTERED
Ambas as sintaxes produzirão o mesmo efeito quando compiladas e executadas no ambiente Protheus, mas deve ser
utilizada sempre a sintaxe ADVPL através do uso do include PROTHEUS.CH
Dica
- MSDIALOG()
- MSGET()
- SAY()
- BUTTON()
- SBUTTON()
BUTTON()
Descrição - Define o componente visual Button, o qual permite a inclusão de botões de operação na tela
da interface, os quais serão visualizados somente com um texto simples para sua identificação.
MSDIALOG()
Descrição - Define o componente MSDIALOG(), o qual é utilizado como base para os demais componentes
da interface visual, pois um componente MSDIALOG() é uma janela da aplicação.
MSGET()
Sintaxe - @ nLinha, nColuna MSGET VARIAVEL SIZE nLargura,nAltura UNIDADE OF oObjetoRef F3 cF3
VALID VALID WHEN WHEN PICTURE cPicture
Descrição - Define o componente visual MSGET, o qual é utilizado para captura de informações digitáveis
na tela da interface.
SAY()
Descrição - Define o componente visual SAY, o qual é utilizado para exibição de textos em uma tela de
interface.
SBUTTON()
Sintaxe - DEFINE SBUTTON FROM nLinha, nColuna TYPE N ACTION AÇÃO STATUS OF oObjetoRet
Descrição - Define o componente visual SButton, o qual permite a inclusão de botões de operação na
tela da interface, os quais serão visualizados dependendo da interface do sistema ERP utilizada somente
com um texto simples para sua identificação, ou com uma imagem (BitMap) pré-definido.
Abaixo segue um código completo de interface, utilizado todos os elementos da interface visual descritos
anteriormente:
@ 010,050 MSGET cCGC SIZE 55, 11 OF oDlg PIXEL PICTURE "@R 99.999.999/9999-99";
VALID !Vazio()
O código demonstrado anteriormente é utilizados nos exercícios de fixação deste material e deverá produzir a seguinte
interface:
Dica
Anotações
Basicamente são duas as interfaces quer permitem a visualização das informações e a manipulação dos
dados do sistema.
- AxCadastro
- Mbrowse
Ambos os modelos utilizam como premissa que a estrutura da tabela a ser utilizada esteja definida no
dicionário de dados do sistema (SX3).
AxCadastro()
O AxCadastro() é uma funcionalidade de cadastro simples, com poucas opções de customização, a qual
é composta de:
- Browse padrão para visualização das informações da base de dados, de acordo com as configurações do
SX3 – Dicionário de Dados (campo browse).
- Funções de pesquisa, visualização, inclusão, alteração e exclusão padrões para visualização de registros
simples, sem a opção de cabeçalho e itens.
Parâmetros:
cAlias - Alias padrão do sistema para utilização, o qual deve estar definido no dicionário de dados – SX3.
cTitulo - Título da Janela
cVldExc - Validação para Exclusão
cVldAlt - Validação para Alteração
Exemplo:
#include "protheus.ch"
dbSelectArea(cAlias)
dbSetOrder(1)
AxCadastro(cAlias,cTitulo,cVldExc,cVldAlt)
Return
MBrowse()
A Mbrowse() é uma funcionalidade de cadastro que permite a utilização de recursos mais aprimorados na
visualização e manipulação das informações do sistema, possuindo os seguintes componentes:
- Browse padrão para visualização das informações da base de dados, de acordo com as configurações
do SX3 – Dicionário de Dados (campo browse).
nLin1, nCol1, nLin2, nCol2 - Coordenadas dos cantos aonde o browse será exibido. Para seguir o padrão
da AXCADASTRO() use 6,1,22,75 .
cAlias - Alias padrão do sistema para utilização, o qual deve estar definido no dicionário de dados – SX3.
aRotina - Array contendo as funções que serão executadas pela Mbrowse. Este array pode ser
parametrizados com as funções básicas da AxCadastro conforme abaixo:
AADD(aRotina,{"Pesquisar" ,"AxPesqui",0,1})
AADD(aRotina,{"Visualizar" ,"AxVisual",0,2})
AADD(aRotina,{"Incluir" ,"AxInclui" ,0,3})
AADD(aRotina,{"Alterar" ,"AxAltera",0,4})
AADD(aRotina,{"Excluir" ,"AxDeleta",0,5})
Exemplo:
#include "protheus.ch"
AADD(aRotina,{"Pesquisar" ,"AxPesqui",0,1})
AADD(aRotina,{"Visualizar" ,"AxVisual",0,2})
AADD(aRotina,{"Incluir" ,"AxInclui",0,3})
AADD(aRotina,{"Alterar" ,"AxAltera",0,4})
AADD(aRotina,{"Excluir" ,"AxDeleta",0,5})
dbSelectArea(cAlias)
dbSetOrder(1)
mBrowse(6,1,22,75,cAlias)
Return
Anotações
2. A posição das funções no array aRotina define o conteúdo de uma variável de controle que será repassada para as
funções chamadas a partir da Mbrowse, convencionada como nOpc. Desta forma, para manter o padrão da aplicação
ERP a ordem a ser seguida na definição do aRotina é;
Fique
atento 1 – Pesquisar
2 – Visualizar
3 – Incluir
4 – Alterar
5 – Excluir
6 – Livre
Ao definir as funções no array aRotina, se o nome da função não for especificado com “()”, a Mbrowse passará como
parâmetros as seguintes variáveis de controle:
#include "protheus.ch"
dbSelectArea(cAlias)
dbSetOrder(1)
mBrowse(6,1,22,75,cAlias)
Return
RETURN
AxFunctions()
Conforme mencionado nos tópicos sobre as interfaces padrões AxCadastro() e Mbrowse(), existem
funções padrões da aplicação ERP que permitem a visualização, inclusão, alteração e exclusão de dados
em formato simples.
Estas funções são padrões na definição da interface AxCadastro() e podem ser utilizadas também da
construção no array aRotina utilizado pela Mbrowse(), as quais estão listadas a seguir:
- AXPESQUI()
- AXVISUAL()
- AXINCLUI()
- AXALTERA()
- AXDELETA()
AXALTERA()
Sintaxe - AxAltera(cAlias, nReg, nOpc, aAcho, cFunc, aCpos, cTudoOk, lF3,; cTransact, aButtons, aParam,
aAuto, lVirtual, lMaximized)
Descrição - Função de alteração padrão das informações de um registro, no formato Enchoice, conforme
demonstrado no tópico sobre a interface AxCadastro().
AXDELETA()
Sintaxe - AXDELETA(cAlias, nReg, nOpc, cTransact, aCpos, aButtons, aParam,; aAuto, lMaximized)
Descrição - Função de exclusão padrão das informações de um registro, no formato Enchoice, conforme
demonstrado no tópico sobre a interface AxCadastro().
Sintaxe - AxInclui(cAlias, nReg, nOpc, aAcho, cFunc, aCpos, cTudoOk, lF3,; cTransact, aButtons, aParam,
aAuto, lVirtual, lMaximized)
Descrição - Função de inclusão padrão das informações de um registro, no formato Enchoice, conforme
demonstrado no tópico sobre a interface AxCadastro().
AXPESQUI()
Sintaxe - AXPESQUI()
Descrição - Função de pesquisa padrão em registros exibidos pelos browses do sistema, a qual posiciona o
browse no registro pesquisado. Exibe uma tela que permite a seleção do índice a ser utilizado na pesquisa
e a digitação das informações que compõe a chave de busca.
AXVISUAL()
Sintaxe - AXVISUAL(cAlias, nReg, nOpc, aAcho, nColMens, cMensagem, cFunc,; aButtons, lMaximized )
Exercícios
- Desenvolver uma validação para um campo específico do tipo caractere, cujo conteúdo esteja
relacionado a outra tabela, e que exiba uma mensagem de aviso caso o código informado não
exista nesta tabela relacionada.
- Desenvolver uma validação para um campo caractere existente na base, para que seja avaliado
se aquele código já existe cadastrado, e caso positivo exiba uma mensagem de aviso alertando
desta ocorrência.
- Desenvolver um gatilho que retorne uma descrição complementar para um campo vinculado
ao campo código utilizado nos exercícios anteriores.
- Customizar o parâmetro que define o prefixo do título de contas a pagar gerado pela integração
COMPRAS -> FINANCEIRO através da inclusão de uma nota fiscal de entrada, de forma que o
prefixo do título seja gerado com o código da filial corrente.
- Proteger a rotina desenvolvida no exercício anterior, de forma a garantir que na utilização da filial
como prefixo do título não irá ocorrer duplicidade de dados no contas a pagar do financeiro.
A utilização da identação seguindo as estruturas de controle de fluxo (while, if, caso etc) torna a
compreensão do código muito mais fácil:
Capitulação de palavras-chave
Uma convenção amplamente utilizada é a de capitular as palavras chaves, funções, variáveis e campos
utilizando uma combinação de caracteres em maiúsculo e minúsculo, visando facilitar a leitura do código
fonte. O código a seguir:
Para funções de manipulação de dados que comecem por “db”, a capitulação só será efetuada após o “db”:
- dbSeek()
Fique - dbSelectArea()
atento
Palavras em maiúsculo
A regra é utilizar caracteres em maiúsculo para:
Constantes:
#define NUMLINES 60 #define NUMPAGES 1000
Variáveis de memória:
M-> CT2_CRCONV M->CT2_MCONVER := CriaVar("CT2_CONVER")
Campos:
SC6->C6_NUMPED
Palavras reservadas
- Funções reservadas são pertencentes ao compilador e não podem ser redefinidas por uma aplicação;
- Todos os identificadores que começarem com dois ou mais caracteres “_” são utilizados como
identificadores internos e são reservados.
Anotações
CTOD()
Realiza a conversão de uma informação do tipo caracter no formato “DD/MM/AAAA” para uma variável
do tipo data.
Sintaxe - CTOD(cData)
Parâmetros:
Exemplo:
cData := “31/12/2006”
dData := CTOD(cData)
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.
Sintaxe - CVALTOCHAR(nValor)
Parâmetros:
Exemplo:
FOR nPercorridos := 1 to 10
MSGINFO(“Passos percorridos: ”+CvalToChar(nPercorridos))
NEXT nPercorridos
DTOC()
Realiza a conversão de uma informação do tipo data para em caracter, sendo o resultado no formato “DD/
MM/AAAA”.
Sintaxe - DTOC(dData)
Parâmetros:
Exemplo:
DTOS()
Realiza a conversão de uma informação do tipo data em um caracter, sendo o resultado no formato
“AAAAMMDD”.
Sintaxe - DTOS(dData)
Parâmetros:
Exemplo:
Realiza a conversão de uma informação do tipo caracter com conteúdo no formato “AAAAMMDD” em
data.
Sintaxe - STOD(sData)
Parâmetros:
Exemplo:
sData := LERSTR(01,08) // Função que realiza a leitura de uma string de um txt previamente
// aberto
dData := STOD(sData)
STR()
Realiza a conversão de uma informação do tipo numérico em uma string, adicionando espaços à direita.
Sintaxe - STR(nValor)
Parâmetros:
Exemplo:
FOR nPercorridos := 1 to 10
MSGINFO(“Passos percorridos: ”+CvalToChar(nPercorridos))
NEXT nPercorridos
STRZERO()
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.
Parâmetros:
Exemplo:
FOR nPercorridos := 1 to 10
MSGINFO(“Passos percorridos: ”+CvalToChar(nPercorridos))
NEXT nPercorridos
Sintaxe - VAL(cValor)
Parâmetros:
Exemplo:
Determina o tipo do conteúdo de uma variável, a qual não foi definida na função em execução.
Sintaxe - TYPE(“cVariavel”)
Parâmetros:
Exemplo:
IF TYPE(“dDataBase”) == “D”
MSGINFO(“Database do sistema: ”+DTOC(“dDataBase”))
ELSE
MSGINFO(“Variável indefinida no momento”)
Determina o tipo do conteúdo de uma variável, a qual não foi definida na função em execução.
Sintaxe - VALTYPE(cVariavel)
Parâmetros:
Exemplo:
LOCAL cTexto := “”
LOCAL nColF := 0
LOCAL nLargGet := 0
PRIVATE oDlg
cTexto := Space(nTamanho)
nLargGet := Round(nTamanho * 2.5,0)
nColf := Round(195 + (nLargGet * 1.75) ,0)
cTexto := IIF(nOpca==1,cTexto,"")
RETURN cTexto
Anotações
A função Array() é utilizada na definição de variáveis de tipo array, como uma opção a sintaxe utilizando
chaves (“{}”).
Parâmetros:
Exemplo:
aDados := Array(3,3) // Cria um array de três linhas, cada qual com 3 colunas.
O array definido pelo comando Array() apesar de já possuir a estrutura solicitada, não possui conteúdo em nenhum de
seus elementos, ou seja:
AADD()
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.
Parâmetros:
Exemplo:
aDados := {} // Define que a variável aDados é um array, sem especificar suas dimensões.
aItem := {} // Define que a variável aItem é um array, sem especificar suas dimensões.
// Neste ponto o array a Item possui 03 elementos os quais podem ser acessados com:
// aItem[1] -> corresponde ao conteúdo de cVariavel1
// aItem[2] -> corresponde ao conteúdo de cVariavel2
// aItem[3] -> corresponde ao conteúdo de cVariavel3
Exemplo (continuação):
// Neste ponto, o array a aDados possui apenas um elemento, que também é um array
// contendo 03 elementos:
// aDados [1][1] -> corresponde ao conteúdo de cVariavel1
// aDados [1][2] -> corresponde ao conteúdo de cVariavel2
// aDados [1][3] -> corresponde ao conteúdo de cVariavel3
AADD(aDados, aItem)
AADD(aDados, aItem)
// Neste ponto, o array aDados possui 03 elementos, aonde cada qual é um array com outros
// 03 elementos, sendo:
// Desta forma, o array aDados montando com uma estrutura de 03 linhas e 03 colunas, com
// o conteúdo definido por variáveis externas, mas com a mesma forma obtida com o uso do
// comando: aDados := ARRAY(3,3).
ACLONE()
A função ACLONE() realiza a cópia dos elementos de um array para outro array integralmente.
Sintaxe - AADD(aArray)
Parâmetros:
aArray - Array pré-existente que terá seu conteúdo copiado para o array especificado.
Exemplo:
// Neste ponto, o array aItens possui exatamente a mesma estrutura e informações do array
// aDados.
ADEL()
Parâmetros:
Exemplo:
ASIZE()
Parâmetros:
Exemplo:
// Utilizando o array aItens, o qual teve um elemento excluído pelo uso da função ADEL()
ASIZE(aItens,Len(aItens-1))
// Neste ponto o array aItens possui 02 elementos, ambos com conteúdos válidos.
ASORT()
A função ASORT() permite que os itens de um array sejam ordenados a partir de um critério pré-
estabelecido.
Parâmetros
aArray - Array pré-existente que terá seu conteúdo ordenado através de um critério estabelecido.
nInicio - Posição inicial do array para início da ordenação. Caso não seja informado, o array será ordenado
a partir de seu primeiro elemento.
nItens - Quantos itens, a partir da posição inicial deverão ser ordenados. Caso não seja informado, serão
ordenados todos os elementos do array.
bOrdem - Bloco de código que permite a definição do critério de ordenação do array. Caso bOrdem não
seja informado, será utilizado o critério ascendente.
Um bloco de código é basicamente uma função escrita em linha. Desta forma sua estrutura deve “suportar” todos os
requisitos de uma função, os quais são através da análise e interpretação de parâmetros recebidos, executar um
processamento e fornecer um retorno.
Com base nesse requisito, pode-se definir um bloco de código com a estrutura abaixo:
Retorno -> resultado da ultima ação executada pelo bloco de código, no caso
AçãoZ.
Para maiores detalhes sobre a estrutura e utilização de blocos de código consulte o tópico 6.2 – Listas de Expressões e
Blocos de código.
aAlunos := { “Mauren”,“Soraia”,“Andréia”}
aSort(aAlunos)
aAlunos := { “Mauren”,“Soraia”,“Andréia”}
bOrdem := {|x,y| x > y }
// Durante a execução da função aSort(), a variável “x” receberá o conteúdo do item que está
// posicionado. Como o item que está posicionado é a posição aAlunos[x] e aAlunos[x] ->
// string contendo o nome de um aluno, pode-se substituir “x” por cNomeAtu.
// A variável “y” receberá o conteúdo do próximo item a ser avaliado, e usando a mesma
// analogia de “x”, pode-se substituir “y” por cNomeProx. Desta forma o bloco de código
// bOrdem pode ser re-escrito como:
aSort(aAlunos,,bOrdem)
ASCAN()
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.
Parâmetros:
aArray - Array pré-existente no qual desejasse identificar a posição que contém a informação
pesquisada.
bSeek - Bloco de código que configura os parâmetros da busca a ser realizada.
Exemplo:
aAlunos := {“Márcio”,“Denis”,“Arnaldo”,“Patrícia”}
Durante a execução da função aScan, a variável “x” receberá o conteúdo o item que está posicionado no momento, no
caso aAlunos[x]. Como aAlunos[x] é uma posição do array que contém o nome do aluno, “x” poderia ser renomeada para
cNome, e a definição do bloco bSeek poderia ser re-escrita como:
Na definição dos programas é sempre recomendável utilizar variáveis com nomes significativos, desta forma os blocos de
Dica código não são exceção.
Sempre opte por analisar como o bloco de código será utilizado e ao invés de “x”, “y” e similares, defina os parâmetros
com nomes que representem seu conteúdo. Será mais simples o seu entendimento e o entendimento de outros que forem
analisar o código escrito.
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.
Parâmetros:
Exemplo:
aAlunos := {“Edson”,“Robson”,“Renato”,“Tatiana”}
AINS(aAlunos,3)
Similar ao efeito da função ADEL(), o elemento inserido no array pela função AINS() terá um conteúdo nulo, sendo
necessário trata-lo após a realização deste comando.
Dica
Anotações
A função EVAL() é utilizada para avaliação direta de um bloco de código, utilizando as informações
disponíveis no mesmo de sua execução. Esta função permite a definição e passagem de diversos
parâmetros que serão considerados na interpretação do bloco de código.
Parâmetros:
nInt := 10
bBloco := {|N| x:= 10, y:= x*N, z:= y/(x*N)}
// O retorno será dado pela avaliação da ultima ação da lista de expressões, no caso “z”.
// Cada uma das variáveis definidas em uma das ações da lista de expressões fica disponível
// para a próxima ação.
// Desta forma temos:
// N > recebe nInt como parâmetro (10)
// X > tem atribuído o valor 10 (10)
// Y > resultado da multiplicação de X por N (100)
// Z > resultado a divisão de Y pela multiplicação de X por N ( 100 / 100) > 1
DBEVAL()
A função DBEval() permite que todos os registro de uma determinada tabela sejam analisados e para cada
registro será executado o bloco de código definido.
Parâmetros:
bBloco - Bloco de código principal, contendo as expressões que serão avaliadas para cada registro do
alias ativo.
bFor - Condição para continuação da análise dos registros, com o efeito de uma estrutura For ... Next.
bWhile - Condição para continuação da análise dos registros, com o efeito de uma estrutura While ... End
Exemplo 01
dbSelectArea(“SX5”)
dbSetOrder(1)
dbGotop()
nCnt++
dbSkip()
End
dbSelectArea(“SX5”)
dbSetOrder(1)
dbGotop()
Exemplo 02 (continuação):
Na utilização da função DBEVAL() deve ser informado apenas um dos dois parâmetros: bFor ou bWhile.
Fique
atento
AEVAL()
A função AEVAL() permite que todos os elementos de um determinada array sejam analisados e para cada
elemento será executado o bloco de código definido.
Parâmetros:
Exemplo 01:
AADD(aCampos,”A1_FILIAL”)
AADD(aCampos,”A1_COD”)
SX3->(dbSetOrder(2))
For nX:=1 To Len(aCampos)
SX3->(dbSeek(aCampos[nX]))
aAdd(aTitulos,AllTrim(SX3->X3_TITULO))
Next nX
Anotações
Manipulação de strings
ALLTRIM()
Retorna uma string sem os espaços à direita e à esquerda, referente ao conteúdo informado como
parâmetro.
A função ALLTRIM() implementa as ações das funções RTRIM (“right trim”) e LTRIM (“left trim”).
Sintaxe - ALLTRIM(cString)
Parâmetros
cString String que será avaliada para remoção dos espaços a direita e a esquerda.
Exemplo:
cNome := ALLTRIM(SA1->A1_NOME)
ASC()
Converte uma informação caractere em seu valor de acordo com a tabela ASCII.
Sintaxe - ASC(cCaractere)
Parâmetros:
Exemplo:
EndCase
cRet := cRet+cLetra
Next
Return UPPER(cRet)
AT()
Parâmetros:
Exemplo:
cNoMascara := PADR(ALLTRIM(cNoMascara),nTamanho)
ELSE
cNoMascara := PADR(ALLTRIM(cString),nTamanho)
ENDIF
RETURN cNoMascara
CHR()
Converte um valor número referente a uma informação da tabela ASCII no caractere que esta informação
representa.
Sintaxe - CHR(nASCII)
Parâmetros
Exemplo:
LEN()
Sintaxe - LEN(cString)
Parâmetros
Exemplo:
cNome := ALLTRIM(SA1->A1_NOME)
Retorna uma string com todos os caracteres minúsculos, tendo como base a string passada como
parâmetro.
Sintaxe - LOWER(cString)
Parâmetros:
Exemplo:
cTexto := “ADVPL”
MSGINFO(“Texto:”+LOWER(cTexto))
RAT()
Parâmetros
STUFF()
Permite substituir um conteúdo caractere em uma string já existente, especificando a posição inicial para
esta adição e o número de caracteres que serão substituídos.
Parâmetros:
Exemplo:
Retorna parte do conteúdo de uma string especificada, de acordo com a posição inicial deste conteúdo
na string e a quantidade de caracteres que deverá ser retornada a partir daquele ponto (inclusive).
Parâmetros:
Exemplo:
cCampo := “A1_NOME”
nPosUnder := AT(cCampo)
UPPER()
Retorna uma string com todos os caracteres maiúsculos, tendo como base a string passada como
parâmetro.
Sintaxe - UPPER(cString)
Parâmetros:
Exemplo:
cTexto := “advpl”
MSGINFO(“Texto:”+LOWER(cTexto))
Anotações
Retorna um valor absoluto (independente do sinal) com base no valor especificado no parâmetro.
Sintaxe - ABS(nValor)
Parâmetros
Exemplo:
nPessoas := 20
nLugares := 18
INT()
Sintaxe - INT(nValor)
Parâmetros:
Exemplo:
RETURN nQuantidade
Retorna um valor, truncando a parte decimal do valor especificado no parâmetro de acordo com a
quantidade de casas decimais solicitadas.
Parâmetros:
Exemplo:
nBase := 2.985
nValor := NOROUND(nBase,2) 2.98
ROUND()
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.
Parâmetros:
Exemplo:
nBase := 2.985
nValor := ROUND(nBase,2) 2.99
Anotações
Sintaxe - Select(cArea)
Parâmetros:
Exemplo:
nArea := Select(“SA1”)
DBGOTO()
Move o cursor da área de trabalho ativa para o record number (recno) especificado, realizando um
posicionamento direto, sem a necessidade uma busca (seek) prévio.
Sintaxe - DbGoto(nRecno)
Parâmetros:
Exemplo:
DbSelectArea(“SA1”)
DbGoto(100) // Posiciona no registro 100
DBGOTOP()
Sintaxe - DbGoTop()
Parâmetros:
Nenhum .
Exemplo:
DBGOBOTTON()
Sintaxe - DbGoBotton()
Parâmetros:
Nenhum.
Exemplo:
DBSELECTAREA()
Define a área de trabalho especificada com sendo a área ativa. Todas as operações subseqüentes que
fizerem referência a uma área de trabalho a utilização, a menos que a área desejada seja informada
explicitamente.
Parâmetros:
nArea - Valor numérico que representa a área desejada, em função de todas as áreas já abertas pela
aplicação, que pode ser utilizado ao invés do nome da área.
cArea - Nome de referência da área de trabalho a ser selecionada.
DBSETORDER()
Define qual índice será utilizada pela área de trabalho ativa, ou seja, pela área previamente selecionada
através do comando DbSelectArea(). As ordens disponíveis no ambiente Protheus são aquelas definidas
no SINDEX /SIX, ou as ordens disponibilizadas por meio de índices temporários.
Sintaxe - DbSetOrder(nOrdem)
Parâmetros:
nOrdem - Número de referência da ordem que deseja ser definida como ordem ativa para a área de
trabalho.
Exemplo:
DbSelectArea(“SA1”)
DbSetOrder(1) // De acordo com o arquivo SIX -> A1_FILIAL+A1_COD+A1_LOJA
DBORDERNICKNAME()
Define qual índice criado pelo usuário seja utilizado. O usuário pode incluir os seus próprios índices e no
momento da inclusão deve criar o NICKNAME para o mesmo.
Sintaxe - DbOrderNickName(NickName)
Parâmetros:
DbSelectArea(“SA1”)
DbOrderNickName(“Tipo”) // De acordo com o arquivo SIX -> A1_FILIAL+A1_TIPO
NickName: Tipo
DBSEEK() E MSSEEK()
DbSeek(): Permite posicionar o cursor da área de trabalho ativo no registro com as informações
especificadas na chave de busca, fornecendo um retorno lógico indicando se o posicionamento foi
efetuado com sucesso, ou seja, se a informação especificada na chave de busca foi localizada na área de
trabalho.
Parâmetros:
cChave - Dados do registro que deseja-se localizar, de acordo com a ordem de busca previamente
especificada pelo comando DbSetOrder(), ou seja, de acordo com o índice ativo no momento para a área
de trabalho.
lSoftSeek - Define se o cursor ficará posicionado no próximo registro válido, em relação a chave de busca
especificada, ou em final de arquivo, caso não seja encontrada exatamente a informação da chave. Padrão
.F.
lLast - Define se o cursor será posicionado no primeiro ou no último registro de um intervalo com as
mesmas informações especificadas na chave. Padrão .F.
DbSelectArea(“SA1”)
DbSetOrder(1) // acordo com o arquivo SIX -> A1_FILIAL+A1_COD+A1_LOJA
Else
MsgAlert(“Cliente não encontrado”,“Consulta por cliente”)
Endif
DbSelectArea(“SA1”)
DbSetOrder(1) // acordo com o arquivo SIX -> A1_FILIAL+A1_COD+A1_LOJA
// Exibe os dados do cliente localizado, o qual pode não ser o especificado na chave:
MsSeek(): Função desenvolvida pela área de Tecnologia da Microsiga, a qual possui as mesmas
funcionalidades básicas da função DbSeek(), com a vantagem de não necessitar acessar novamente a
base de dados para localizar uma informação já utilizada pela thread (conexão) ativa.
Desta forma, a thread mantém em memória os dados necessários para reposicionar os registros já
localizados através do comando DbSeek (no caso o Recno()) de forma que a aplicação pode simplesmente
efetuar o posicionamento sem executar novamente a busca.
A diferença entre o DbSeek() e o MsSeek() é notada em aplicações com grande volume de posicionamentos,
como relatórios, que necessitam referenciar diversas vezes o mesmo registro durante uma execução.
DBSKIP()
Move o cursor do registro posicionado para o próximo (ou anterior dependendo do parâmetro), em
função da ordem ativa para a área de trabalho.
Sintaxe - DbSkip(nRegistros)
Parâmetros:
DbSelectArea(“SA1”)
DbSetOrder(2) // A1_FILIAL + A1_NOME
DbGotop() // Posiciona o cursor no início da área de trabalho ativa
While !EOF() // Enquanto o cursor da área de trabalho ativa não indicar fim de arquivo
MsgInfo(“Você está no cliente:” + A1_NOME)
DbSkip()
End
DbSelectArea(“SA1”)
DbSetOrder(2) // A1_FILIAL + A1_NOME
DbGoBotton() // Posiciona o cursor no final da área de trabalho ativa
While !BOF() // Enquanto o cursor da área de trabalho ativa não indicar início de arquivo
MsgInfo(“Você está no cliente:” + A1_NOME)
DbSkip(-1)
End
Define um filtro para a área de trabalho ativa, o qual pode ser descrito na forma de um bloco de código
ou através de uma expressão simples.
Parâmetros:
While !EOF()
MsgInfo(“Você está no cliente:”+A1_COD)
DbSkip()
End
While !EOF()
MsgInfo(“Você está no cliente:”+A1_COD)
DbSkip()
End
Retorna um array contendo a estrutura da área de trabalho (alias) ativo. A estrutura será um array
bidimensional conforme abaixo:
*Índice do array
Sintaxe - DbStruct()
Parâmetros:
Nenhum.
Exemplo:
cCampos := “”
DbSelectArea(“SA1”)
aStructSA1 := DbStruct()
FOR nX := 1 to Len(aStructSA1)
NEXT nX
ALERT(cCampos)
RECLOCK()
Efetua o travamento do registro posicionado na área de trabalho ativa, permitindo a inclusão ou alteração
das informações do mesmo.
Sintaxe - RecLock(cAlias,lInclui)
Parâmetros:
Exemplo 01 - Inclusão
DbSelectArea(“SA1”)
RecLock(“SA1”,.T.)
SA1->A1_FILIAL := xFilial(“SA1”) // Retorna a filial de acordo com as configurações do ERP
SA1->A1_COD := “900001”
SA1->A1_LOJA := “01”
MsUnLock() // Confirma e finaliza a operação
DbSelectArea(“SA1”)
DbSetOrder(1) // A1_FILIAL + A1_COD + A1_LOJA
DbSeek(“01” + “900001” + “01”) // Busca exata
- RLOCK()
- DBRLOCK()
A sintaxe e a descrição destas funções estão disponíveis no Guia de Referência Rápido ao final deste
material.
MSUNLOCK()
Sintaxe - MsUnLock()
Parâmetros:
Nenhum .
Exemplo:
DbSelectArea(“SA1”)
DbSetOrder(1) // A1_FILIAL + A1_COD + A1_LOJA
DbSeek(“01” + “900001” + “01”) // Busca exata
- UNLOCK()
- DBUNLOCK()
- DBUNLOCKALL()
SOFTLOCK()
Permite a reserva do registro posicionado na área de trabalho ativa de forma que outras operações,
com exceção da atual, não possam atualizar este registro. Difere da função RecLock() pois não gera uma
obrigação de atualização, e pode ser sucedido por ele.
Na aplicação ERP Protheus, o SoftLock() é utilizado nos browses, antes da confirmação da operação de
alteração e exclusão, pois neste momento a mesma ainda não foi efetivada, mas outras conexões não
podem acessar aquele registro pois o mesmo está em manutenção, o que implementa da integridade da
informação.
Sintaxe - SoftLock(cAlias)
Parâmetros:
cAlias - Alias de referência da área de trabalho ativa, para o qual o registro posicionado será travado.
Exemplo:
DbSelectArea(“SA1”)
DbSetOrder(1)
DbSeek(cChave)
IF Found()
SoftLock() // Reserva o registro localizado
lConfirma := AlteraSA1() // Função ilustrativa que exibe os dados do registro
// posicionado e pemite a alteração dos mesmos.
IF lConfirma
RecLock(“SA1”,.F.)
GravaSA1() // Função ilustrativa que altera os dados conforme a AlertaSA1()
MsUnLock() // Liberado o RecLock() e o SoftLock() do registro.
Endif
Endif
DBDELETE()
Efetua a exclusão lógica do registro posicionado na área de trabalho ativa, sendo necessária sua utilização
em conjunto com as funções RecLock() e MsUnLock().
Sintaxe - DbDelete()
Parâmetros:
Nenhum.
DbSelectArea(“SA1”)
DbSetOrder(1) // A1_FILIAL + A1_COD + A1_LOJA
DbSeek(“01” + “900001” + “01”) // Busca exata
IF Found()
RecLock(“SA1”,.F.) // Define que será realizada uma alteração no registro posicionado
DbDelete() // Efetua a exclusão lógica do registro posicionado.
MsUnLock() // Confirma e finaliza a operação
ENDIF
DBUSEAREA()
Define um arquivo de base de dados como uma área de trabalho disponível na aplicação.
Parâmetros:
lNovo - Parâmetro opcional que permite que se caso o cAlias especificado já esteja em uso, ele seja
fechado antes da abertura do arquivo da base de dados.
cDriver - Driver que permita a aplicação manipular o arquivo de base de dados especificado. A aplicação
ERP possui a variável __LOCALDRIVER definida a partir das configurações do .ini do server da aplicação.
cArquivo - Nome do arquivo de base de dados que será aberto com o alias especificado.
cAlias - Alias para referência do arquivos de base de dados pela aplicação.
lComparilhado - Se o arquivo poderá ser utilizado por outras conexões.
lSoLeitura - Se o arquivo poderá ser alterado pela conexão ativa.
Exemplo:
DBCLOSEAREA()
Permite que um alias presente na conexão seja fechado, o que viabiliza seu reuso em outro operação. Este
comando tem efeito apenas no alias ativo na conexão, sendo necessária sua utilização em conjunto com
o comando DbSelectArea().
Sintaxe - DbCloseArea()
Parâmetros:
Nenhum .
Anotações
Obtém o número seqüência do alias especificado no parâmetro, através da referência aos arquivos de
sistema SXE/SXF ou ao servidor de numeração, quando esta configuração está habilitada no ambiente
Protheus.
Parâmetros:
cAlias - Alias de referência da tabela para a qual será efetuado o controle da numeração seqüencial.
cCampo - Nome do campo no qual está implementado o controle da numeração.
cAliasSXE - Parâmetro opcional, quando o nome do alias nos arquivos de controle de numeração não é o
nome convencional do alias para o sistema ERP.
nOrdem - Número do índice para verificar qual a próxima ocorrência do número.
CONFIRMSXE()
Sintaxe - CONFIRMSXE(lVerifica)
Parâmetros:
ROLLBACKSXE()
Descarta o número fornecido pelo último comando GETSXENUM(), retornando a numeração disponível
para outras conexões.
Sintaxe - ROLLBACKSXE()
Parâmetros:
Nenhum .
Retorna .T. ou .F. se o conteúdo especificado existe no alias especificado. Caso exista será exibido um help
de sistema com um aviso informando da ocorrência.
Função utilizada normalmente para verificar se um determinado código de cadastro já existe na tabela na
qual a informação será inserida, como por exemplo o CNPJ no cadastro de clientes ou fornecedores.
Parâmetros:
EXISTCPO()
Retorna .T. ou .F. se o conteúdo especificado não existe no alias especificado. Caso não exista será exibido
um help de sistema com um aviso informando da ocorrência.
Função utilizada normalmente para verificar se a informação digitada em um campo, a qual depende
de outra tabela, realmente existe nesta outra tabela, como por exemplo o código de um cliente em um
pedido de venda.
Parâmetros:
NAOVAZIO()
Retorna .T. ou .F. se o conteúdo do campo posicionado no momento não está vazio.
Sintaxe - NaoVazio()
Parâmetros:
Nenhum.
Sintaxe - Negativo()
Parâmetros:
Nenhum.
PERTENCE()
Retorna .T. ou .F. se o conteúdo digitado para o campo está contido na string definida como parâmetro
da função. Normalmente utilizada em campos com a opção de combo, pois caso contrário seria utilizada
a função ExistCpo().
Sintaxe - Pertence(cString)
Parâmetros:
cString - String contendo as informações válidas que podem ser digitadas para um campo.
POSITIVO()
Sintaxe - Positivo()
Parâmetros:
Nenhum.
TEXTO()
Retorna .T. ou .F. se o conteúdo digitado para o campo contém apenas números ou alfanuméricos.
Sintaxe - Texto()
Parâmetros:
Nenhum.
VAZIO()
Sintaxe - Vazio()
Parâmetros:
Nenhum.
Sintaxe - GETMV(cParametro)
Parâmetros:
GETNEWPAR()
Difere do SuperGetMV() pois considera que o parâmetro pode não existir na versão atual do sistema, e
por conseqüência não será exibida a mensagem de help.
Parâmetros:
cPadrao - Conteúdo padrão que será utilizado caso o parâmetro não exista no SX6.
cFilial - Define para qual filial será efetuada a consulta do parâmetro. Padrão filial corrente da conexão.
PUTMV()
Parâmetros:
SUPERGETMV()
Difere do GetMv() pois os parâmetros consultados são adicionados em uma área de memória, que permite
que em uma nova consulta não seja necessário acessar e pesquisar o parâmetro na base de dados.
Parâmetros:
Anotações
Define o componente MSDIALOG(), o qual é utilizado como base para os demais componentes da interface
visual, pois um componente MSDIALOG() é uma janela da aplicação.
Parâmetros:
oObjetoDLG - Posição do objeto Say em função da janela em que ele será definido.
cTitulo Título da janela de diálogo.
nLinIni, nColIni - Posição inicial em linha / coluna da janela.
nLiFim, nColFim - Posição final em linha / coluna da janela.
oObjetoRef - Objeto dialog no qual a janela será definida.
UNIDADE - Unidade de medida das dimensões: PIXEL
Exemplo:
MSGET()
Define o componente visual MSGET, o qual é utilizado para captura de informações digitáveis na tela da
interface.
Sintaxe - @ nLinha, nColuna MSGET VARIAVEL SIZE nLargura,nAltura UNIDADE OF oObjetoRef F3 cF3
VALID VALID WHEN WHEN PICTURE cPicture
nLinha, nColuna - Posição do objeto MsGet em função da janela em que ele será definido.
VARIAVEL - Variável da aplicação que será vinculada ao objeto MsGet, que definirá suas características e
na qual será armezanado o que for informado no campo.
nLargura,nAltura - Dimensões do objeto MsGet para exibição do texto.
UNIDADE - Unidade de medida das dimensões: PIXEL
oObjetoRef - Objeto dialog no qual o componente será definido.
cF3 - String que define a consulta padrão que será vinculada ao campo.
VALID - Função de validação para o campo.
WHEN - Condição para manipulação do campo, a qual pode ser diretamente .T. ou .F., ou uma variável ou
uma chamada de função.
cPicture - String contendo a definição da Picture de digitação do campo.
Exemplo:
@ 010,050 MSGET cCGC SIZE 55, 11 OF oDlg PIXEL PICTURE "@R 99.999.999/9999-99";
VALID !Vazio()
SAY()
Define o componente visual SAY, o qual é utilizado para exibição de textos em uma tela de interface.
Parâmetros:
nLinha, nColuna - Posição do objeto Say em função da janela em que ele será definido.
cTexto - Texto que será exibido pelo objeto Say.
nLargura,nAltura - Dimensões do objeto Say para exibição do texto.
UNIDADE - Unidade de medida das dimensões: PIXEL
oObjetoRef - Objeto dialog no qual o componente será definido.
Exemplo:
BUTTON()
Define o componente visual Button, o qual permite a inclusão de botões de operação na tela da interface,
os quais serão visualizados somente com um texto simples para sua identificação.
Sintaxe - BUTTON()
Parâmetros:
nLinha,nColuna - Posição do objeto Button em função da janela em que ele será definido.
cTexto - String contendo o texto que será exibido no botão.
nLargura,nAltura - Dimensões do objeto Button para exibição do texto.
Exemplo:
SBUTTON()
Define o componente visual SButton, o qual permite a inclusão de botões de operação na tela da interface,
os quais serão visualizados dependendo da interface do sistema ERP utilizada somente com um texto
simples para sua identificação, ou com uma imagem (BitMap) pré-definido.
Sintaxe - SBUTTON()
DEFINE SBUTTON FROM nLinha, nColuna TYPE N ACTION AÇÃO STATUS OF oObjetoRet
Parâmetros:
nLinha, nColuna - Posição do objeto sButton em função da janela em que ele será definido.
TYPE N - Número que indica o tipo do botão (imagem) pré-definida que será utilizada.
AÇÃO - Função ou lista de expressões que define o comportamento do botão quando ele for utilizado.
STATUS - Propriedade de uso do botão: ENABLE ou DISABLE
oObjetoRet - Objeto dialog no qual o componente será definido.
Exemplo:
MBROWSE()
AXPESQUI()
Função de pesquisa padrão em registros exibidos pelos browses do sistema, a qual posiciona o browse
no registro pesquisado. Exibe uma tela que permite a seleção do índice a ser utilizado na pesquisa e a
digitação das informações que compõe a chave de busca.
Sintaxe - AXPESQUI()
Parâmetros:
Nenhum.
AXVISUAL()
Sintaxe - AXVISUAL(cAlias, nReg, nOpc, aAcho, nColMens, cMensagem, cFunc,; aButtons, lMaximized )
Parâmetros:
Função de inclusão padrão das informações de um registro, no formato Enchoice, conforme demonstrado
no tópico sobre a interface AxCadastro().
Sintaxe - AxInclui(cAlias, nReg, nOpc, aAcho, cFunc, aCpos, cTudoOk, lF3,; cTransact, aButtons, aParam,
aAuto, lVirtual, lMaximized)
Parâmetros:
lF3 - Indica se a enchoice esta sendo criada em uma consulta F3 para utilizar variáveis de memória
cTransact - Função que será executada dentro da transação da AxFunction()
aButtons - Botões adicionais para a EnchoiceBar, no formato:
aArray[n][1] - Imagem do botão
aArray[n][2] - bloco de código contendo a ação do botão
aArray[n][3] - título do botão
aParam - Funções para execução em pontos pré-definidos da AxFunction(), conforme abaixo:
aParam[1] - Bloco de código que será processado antes da exibição da interface.
aParam[2] - Bloco de código para processamento na validação da confirmação.
aParam[3] - Bloco de código que será executado dentro da transação da AxFunction().
aParam[4] - Bloco de código que será executado fora da transação da AxFunction().
aAuto - Array no formato utilizado pela funcionalidade MsExecAuto(). Caso seja informado este array, não
será exibida a tela de interface, e será executada a função EnchAuto().
aAuto[n][1] - Nome do campo
aAuto[n][2] - Conteúdo do campo
aAuto[n][3] - Validação que será utilizada em substituição as validações do SX3
lVirtual - Indica se a Enchoice() chamada pela AxFunction() utilizará variáveis de memória ou os campos
da tabela na edição
lMaximized - Indica se a janela deverá ser ou não maximizada
AXALTERA()
Função de alteração padrão das informações de um registro, no formato Enchoice, conforme demonstrado
no tópico sobre a interface AxCadastro().
Sintaxe - AXALTERA(cAlias, nReg, nOpc, aAcho, aCpos, nColMens, cMensagem,; cTudoOk, cTransact, cFunc,
aButtons, aParam, aAuto, lVirtual, lMaximized)
AXDELETA()
Função de exclusão padrão das informações de um registro, no formato Enchoice, conforme demonstrado
no tópico sobre a interface AxCadastro().
Sintaxe - AXDELETA(cAlias, nReg, nOpc, cTransact, aCpos, aButtons, aParam,; aAuto, lMaximized)
Parâmetros:
Anotações
Sintaxe - AVISO(cTexto)
Parâmetros:
AVISO()
Parâmetros:
Parâmetros:
{nTipo,lEnable,{|| Ação() }}
Parâmetros:
MSGALERT
MSGINFO
MSGSTOP
MSGYESNO
Função utilizada para proteger o ambiente ativo no momento de algum processamento específico. Para
salvar uma outra área de trabalho (alias) que não o ativo, a função GetArea() deve ser executada dentro
do alias: ALIAS->(GetArea()).
Sintaxe - GETAREA()
Retorno: Array contendo {Alias(),IndexOrd(),Recno()}
Parâmetros
Nenhum .
RESTAREA()
Função utilizada para devolver a situação do ambiente salva através do comando GETAREA(). Deve-se
observar que a última área restaurada é a área que ficará ativa para a aplicação.
Sintaxe - RESTAREA(aArea)
Parâmetros:
aArea - Array contendo: {cAlias, nOrdem, nRecno}, normalmente gerado pelo uso da função GetArea().
Exemplo:
LOCAL cVar
LOCAL aArea := GetArea()
LOCAL lRet := .T.
cVar := &(ReadVar())
dbSelectArea("SX5")
IF !dbSeek(xFilial()+"Z1"+cVar)
RestArea(aArea)
Return( lRet )
Número de Registro:
P10111007