Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

Índice

...

1       Linguagem 4GL

O TotvsTec 4GL surgiu com base nas linguagens nativas 4GL do banco de dados Informix e também com base na linguagem 4JS da IBM.

...

Quando compilados, todos os arquivos de código fonte tornam-se unidades de inteligência básicas, chamadas de RPO´s (Repository Protheus Objects). Esses RPO´s são mantidos em um repositório e carregados dinamicamente pelo servidor de aplicação (Application Server) para a execução. No entanto, não existe link ou união física do código compilado a um determinado ambiente ou aplicação, o que permite executar funções criadas em 4GL em qualquer ponto do ambiente ERP.

...

2       Estrutura de um programa

Um programa é constituído por funções e declarações. A primeira função a ser executada é a função "MAIN", e, tem de existir em todos os programas.

...

A declaração de variáveis é sempre efetuada depois da palavra chave "DEFINE". Uma variável declara-se da seguinte forma:
     

 

DEFINE nome_da_variavel TIPO
 OU
DEFINE nome_da_variavel LIKE tabela.coluna 

 

...

Se a variável elementos das variáveis tipo ARRAY podem ser acessadas através do operador [] (colchetes) e dá indicação do número do elemento a que se quer ter acesso, assim:

 

 la_dados[10]

 Neste caso representa o 10º elemento do ARRAY la_dados.

Se a variável for um array deve ser declarada da seguinte forma:

...

O escopo de referência de uma variável é determinado pelo lugar em que a cláusula DEFINE aparece no fonte .4gl. Os identificadores de variáveis podem ser locais, modulares, ou (em alguns casos) globais em seu escopo:

2.3.1       Variáveis locais

 

DEFINE nome_da_variável tipo [, ...]

 

...

Se declarar duas variáveis com o mesmo nome em duas funções distintas, cada variável somente será reconhecida na função de declaração. Concluindo, as variáveis com o mesmo nome localizadas em funções diferentes são variáveis diferentes.

2.3.2       Variáveis globais

 

GLOBALS "fonte.4gl"

 OU 

GLOBALS
   {instrução DEFINE}
END GLOBALS}

Definição genérica de uma declaração global

...

No programa dado como exemplo não havia grande necessidade de declarar as variáveis como globais. Á medida que for programando pode-se sentir a necessidade de utilizar este tipo de variável.

2.3.3       Variáveis modulares

 

DEFINE nome_da_variável tipo [, ...]

 

...

Se declarar duas variáveis modulares com o mesmo nome em dois fontes (módulos) distintos, cada variável só vai ser reconhecida no fonte onde foi declarado. Efetivamente as variáveis com o mesmo nome localizadas em fontes diferentes são variáveis diferentes.

2.3.4       Atribuições, comparações e inicializações

Uma das operações básicas a realizar sobre variáveis é a atribuição.

...

A instrução INITIALIZE inicializa as variáveis com valor NULL.

2.3.5       Operadores

Os operadores de comparação no Informix 4GL são:

...

Operador

Descrição

Exemplo

.

Para referenciar um membro de uma variável do tipo RECORD.

lr_dados.código

[]

Para referenciar um elemento de uma variável do tipo ARRAY ou um conjunto de caracteres de uma variável do tipo CHAR.

la_dados[10]

()

Para chamada de funções.

CALL entrada_dados()

UNITS

Para referenciar a unidade de qualificador.

LET data = data + 5 UNITS DAY

|| ou ,

Concatenação

“abc” || “def”  ou  “abc”,”def”

ASCII

Retorna o caracter ASCII correspondente.

LET letra = ASCII(65)

ORD

Retorna o código ASCII correspondente.

LET cod_ascii = ORD(“A”)

CLIPPED

Elimina espaços em branco do final de um string.

LET l_texto = l_texto CLIPPED, “x”

COLUMN

Para posicionar a coluna de impressão de dados.

PRINT COLUMN 10, “Texto”.

SPACES

Para inserir espaços em branco.

DISPLAY 5 SPACES

USING

Para formatar um conteúdo atribuído a um string.

LET texto = TODAY USING “dd/mm/yy”

WORDWRAP

Impressão de um texto com quebra automática de linhas.

PRINT texto WORDWRAP

2.3.6       Concatenação de variáveis tipo CHAR

No 4GL é muito simples concatenar strings, basta separá-las por uma virgula (o operador de concatenação de strings é a virgula).

...

É preciso ter cuidado para que a variável em que se atribui o retorno da função seja do mesmo tipo do valor (ou variável) retornado dentro da função.

 

retfunc3.4gl

MAIN
   DEFINE x INTEGER
          y CHAR(100)

   CALL func() RETURNING x,y

   DISPLAY x
   DISPLAY y

END MAIN

FUNCTION func()
  RETURN 100,"Esta string vai ser devolvida"
END FUNCTION

RESTULTADO:
 100
 Esta string vai ser devolvida

Função com retorno de vários valores

...

Em português esta instrução poderia ser explicada por:

  

 

Se esta expressão é verdadeira
    Então faz isto
Senão faz aquilo 

 

...

Esta instrução de repetição pode ser explicada por:

   

...

   

Enquanto esta_expressão_for_verdadeira faz_isto 

 

...

Em 4GL, uma das formas do programa se comunicar com o usuário, é por intermédio da instrução PROMPT. Esta instrução envia uma mensagem para o aplicativo e recebe um caracter ou seqüência de caracteres que foram digitados pelo usuário no seu terminal.

A definição genérica de uma instrução PROMPT é a seguinte:

PROMPT mensagem FOR [CHAR] variável
        [HELP numero_do_help]
        [ON KEY (tecla)
   instrução
   ...
   ...
END PROMPT

Definição genérica da instrução PROMPT

As mensagens assinaladas são um conjunto de uma ou mais variáveis, ou string(s) constantes, separados por vírgula.

...

Esta instrução envia para a tela uma mensagem constituída por um conjunto de variáveis e strings definidas na instrução. Em alguns dos exemplos anteriores, esta instrução já foi usada na sua forma mais simples.

 

 

display.4gl

MAIN
   DISPLAY "Isto vai aparecer na tela na linha 10 coluna 3"
           AT 10,3 ATTRIBUTE(BOLD)
END MAIN

$ fglpc display.4gl
$ fglgo display.4go

Isto vai aparecer na tela na linha 10 coluna 3

 Programa utilizando DISPLAY AT com ATTRIBUTES

...

5.4      Exercício – Instrução PROMPT e MENU

...

Através de um editor de texto define-se um arquivo com a definição da form no seguinte formato: 

 

DATABASE [FORMONLY | <nome banco dados>]
  SCREEN
  {
  numero [f000 ]
  nome   [f001                   ]
         [f002                   ]
 }
 END 

 [TABLES]
 <tabela1>,
 <tabela2>,
 ...,
 <tabelaN> 

 ATTRIBUTES
 f000 = <tabela>.<coluna>;
 f001 = formonly.<nome campo>;
 f002 = formonly.<nome campo TYPE LIKE <tabela.coluna>;
 END

[INSTRUCTIONS]
   [DELIMITERS]
   [SCREEN RECORD...]
[END] 

Exemplo de definição de form

...

Este atributo faz com que o cursor, durante uma instrução de INPUT, salte para o campo seguinte quando o campo atual estiver totalmente preenchido. 

 

f011 = livros.data_entrada, AUTONEXT

 Exemplo atributo AUTONEXT

...

Pode-se especificar uma série de valores separados por virgulas ou um valor mínimo e um valor máximo separados pela palavra "TO".

 

 

f007 = livros.volumes, INCLUDE = (1 to 100); 

 Exemplo atributo INCLUDE

...

Com o comando DELIMITERS pode-se alterar os caracteres delimitadores do campo da tela, quando este é visualizado na execução do programa. Os caracteres default do 4GL são os colchetes "[...]".

 

 

DELIMITERS "{}" 

 Neste exemplo o símbolo "{" é o caracter de abertura e "}" é o caracter de fechamento.

...

 

form4gl -d f_livros livros autores livros 

 Cria e compila a form f_livros com as tabelas LIVROS e AUTORES do banco de dados LIVROS.

 

 

form4gl -v f_livros 

No comando acima é realizada apenas a compilação da form f_livros.

...

A abertura de uma form através da instrução OPEN FORM é feita da seguinte forma:

 

 

OPEN FORM nome_da_form FROM "arquivo_form" 

 Definição genérica da instrução OPEN FORM

...

Durante alguns processamentos, você pode pretender mudar de janela de trabalho (ou janela corrente). A instrução CURRENT WINDOW transforma em janela corrente o nome da janela desejado, que é passado como parâmetro.

 

 

CURRENT WINDOW IS nome_da_janela 

 Definição genérica da instrução CURRENT WINDOW

...

Um programa de 4GL assume valores por default para o funcionamento de diversas instruções. Para alterar esses valores usa-se a instrução OPTIONS. 

 

OPTIONS {MESSAGE LINE linha |
          PROMPT  LINE linha |
          COMMENT LINE linha |
          ERROR   LINE linha |
          FORM LINE linha |
          INPUT {WRAP | NO WRAP} |
          INSERT KEY tecla |
          DELETE KEY tecla |
          NEXT KEY tecla |
          PREVIOUS KEY tecla |
          ACCEPT KEY tecla |
          HELP FILE "ficheiro" |
          HELP KEY tecla }

 Definição genérica da instrução OPTIONS

...

Como ponto de partida vamos gerar a form de dados de livros para a tabela LIVROS, obtendo-se o esqueleto do programa com o comprimento e o vínculo das colunas às tabelas já definidas. 

 

DATABASE livros 

 SCREEN
 {       número: [f000 ]
         nome: [f001]
         tradução: [f003]
         volumes: [f005]
         páginas: [f006]
         edição: [f007]
         ano: [f008]
         data entrada: [f009]
         sala: [f010]
         estante: [f011]
         prateleira: [f012]
         observações: [f013] }
 END 

 TABLES
     
 livros 

 ATTRIBUTES
      
 f000 = livros.numero;
        f001 = livros.nome;
        f003 = livros.traducao;
        f005 = livros.volumes;
        f006 = livros.paginas;
        f007 = livros.edicao;
        f008 = livros.ano;
        f009 = livros.data_entrada;
        f010 = livros.sala;
        f011 = livros.estante;
        f012 = livros.prateleira;
        f013 = livros.observacoes;
END

  

...

Na form livros iremos usá-lo nas datas.

 

 

f011 = livros.data_entrada, AUTONEXT

 

...

Na form livros iremos aplicá-lo ao campo data_entrada com a seguinte mensagem: "Introduza a data em que o livro entrou na biblioteca"

 

 

f011 = livros.data_entrada, AUTONEXT,
        COMMENTS = "Informe a data em que o livro entrou na biblioteca"; 

 

...

Na form livros será aplicado aos campos volumes, sala e data da entrada. Neste último campo (data da entrada do livro) irá assumir o valor inicial como a data atual, escrevendo "today" como valor inicial. 

 

f011 = livros.data_entrada, AUTONEXT, DEFAULT = TODAY

  FORMAT

...

O programa 4GL ainda não sabe como fazer a validação do código de editor. Para conseguir realizar esta função, utiliza-se a cláusula AFTER FIELD, faz-se uma consulta na tabela de editores e apresenta-se o nome do editor encontrado na tela. 

 

DEFINE l_nome_editora LIKE editoras.nome;
 INPUT BY NAME mr_livros.* 

 AFTER FIELD editora
    INITIALIZE l_nome_editora TO NULL
    WHENEVER ERROR CONTINUE
    SELECT nome
      INTO l_nome_editora
      FROM editoras
     WHERE codigo = mr_livros.editora
    WHENEVER ERROR STOP
    IF sqlca.sqlcode = NOTFOUND THEN
       ERROR "Editora não cadastrada."
       NEXT FIELD edição
    ELSE
       DISPLAY l_nome_editora TO nome editora
    END IF
END INPUT 

Alteração das instruções INPUT para efetuar as validações

...

Os acessos são feitos com o auxilio da instrução FETCH que avança a linha corrente para a linha seguinte e armazena os dados retornados desta linha nas variáveis definidas na cláusula INTO. Se o cursor estiver posicionado na ultima linha, a variável sqlca.sqlcode será atualizada com o valor NOTFOUND (ou código 100).

 

 

WHILE 1
    FETCH cq_livros INTO numero, nome, edicao;
    IF sqlca.sqlcode != 0 THEN
       EXIT WHILE
    END IF
    DISPLAY numero, nome, editora
 END WHILE 

 

...

Não é possível invocar uma outra instrução sobre o cursor que não esteja aberto. O cursor por estar fechado não deixa de ter uma instrução SELECT associada, que ao ser invocado pela instrução OPEN é executada novamente a instrução SELECT associado ao cursor.

 

 

CLOSE cq_livros 

 

Um cursor pode também ser fechado automaticamente através de uma instrução de fim de transação (COMMIT WORK ou ROLLBACK WORK), já que uma das ações destas instruções é fechar todos os cursores que se encontrarem abertos no momento. Mas isto somente ocorre se na instrução de definição do cursor (DECLARE) tiver sido omitido o atributo WITH HOLD.

...

Para tratar este tipo de tela o 4GL possui as instruções DISPLAY ARRAY e INPUT ARRAY, associadas a novas definições nas forms.

 

 

DISPLAY ARRAY array_de_records TO array_da_tela.*
         [ATTRIBUTE(lista_de atributos)]
 {ON KEY (lista_de_teclas)
     instrução
     ...
     [EXIT DISPLAY]
 ...
 END DISPLAY 

Definição genérica da instrução DISPLAY ARRAY

...

Para a utilização das instruções acima definidas é preciso construir uma form que tenha estas capacidades. Assim, na seção SCREEN define-se o número de linhas que se pretende editar de cada vez, cada coluna de cada linha declarada deve ter o mesmo nome de label.

 

 

SCREEN
 {
 Código  Nome
 ------- ----------------------------------------------------
 [f000 ] [f001                                              ]
 [f000 ] [f001                                              ]
 [f000 ] [f001                                              ]
 [f000 ] [f001                                              ]
 [f000 ] [f001                                              ]
 [f000 ] [f001                                              ]
 [f000 ] [f001                                              ]
 [f000 ] [f001                                              ]
 }
 END 

Seção SCREEN da form de zoom editoras

...

Os campos com o mesmo label, tem que corresponder a um SCREEN RECORD. Um SCREEN RECORD declara-se na seção INSTRUCTIONS e associa-se ao array as colunas que se pretende editar.

 

 

INSTRUCTIONS
 DELIMITERS " "
 SCREEN RECORD sr_editoras[8] (editoras.codigo,editores.nome) 

 Seção INSTRUCTION

...

A função consiste_editora verifica se foi informado um código de editora válido e apresenta o nome da editora, caso encontre. Se não encontrar a editora ou esta não tiver sido informada será  acionada a função zoom_editora que fará a abertura de uma janela com a form descrita anteriormente onde serão visualizados os códigos existentes de editoras. A função zoom_editora sempre irá retorna um código de editora válido e neste caso pode-se apresentar o código e nome da editora sempre pois estará garantida a validade das informações. 

 

OPEN WINDOW w_editoras AT 5, 5 WITH FORM "editoras"
      ATTRIBUTE(BORDER) 

 

...

É possível que já existam alguns temas cadastrados para o livro em questão. Neste caso convém consultar os temas já existentes para uma eventual alteração. Se preenchermos o array de registros com os temas existentes, estes irão ser colocados na form quando se chamar a instrução INPUT ARRAY.

   

 

DECLARE cq_temas CURSOR FOR
  SELECT livro_temas.tema, temas.nome
    FROM livro_temas, temas
   WHERE livro_temas.livro  = l_livro
     AND temas.codigo = livro_temas.tema 

 INITIALIZE la_temas TO NULL
 LET l_idx_arr = 1 

 FOREACH cq_temas INTO la_temas[l_idx_arr].*
    LET l_idx_arr = l_idx_arr + 1
    IF l_idx_arr > 15 THEN
       ERROR "Temas a mais."
       EXIT FOREACH
    END IF
 END FOREACH
 FREE cq_temas 

 LET l_idx_arr = l_idx_arr - 1 

 Preenchimento do array de records com as editoras já existentes

...

A seção OUTPUT é formada pela palavra OUTPUT seguida de uma ou mais instruções:

 

 

OUTPUT
 [REPORT TO instrução]
 [LEFT MARGIN valor]
 [RIGHT MARGIN valor]
 [TOP MARGIN valor]
 [BOTTOM MARGIN valor]
 [PAGE LENGHT valor]
 [REPORT TO {"arquivo" | PIPE programa | PRINTER}] 

 Formato da seção OUTPUT

...

A seção ORDER BY tem o seguinte formato:

 

 

ORDER [EXTERNAL] BY lista_colunas 

 Formato da secção ORDER BY

...

Então na seção FORMAT poderíamos ter: 

 

 BEFORE GROUP OF a
 BEFORE GROUP OF b
 BEFORE GROUP OF c
 ON EVERY ROW
 AFTER GROUP OF c
 AFTER GROUP OF b
 AFTER GROUP OF a 

 Um exemplo da ordem de execução dos blocos de controle

...

Este bloco de controle define as ações (ou instruções) que devem ser executadas antes de ser processado um determinado grupo de linhas.

 

 

BEFORE GROUP OF variável
    Instruções 

Formato do bloco de controlo BEFORE GROUP OF

...

Este bloco define as instruções que o INFORMIX-4GL passa para cada linha de dados como argumento à rotina REPORT, ou seja, os dados impressos no relatório são os dados passados como argumentos na função REPORT.

  

...

   

ON EVERY ROW
    Instruções 

 Formato do bloco ON EVERY ROW

...

A instrução LET atribui um valor a uma variável.

 

 

LET pg1  = paid_date - ship_date
LET pgc1 = " dias" 

 Exemplo da instrução LET

...

A instrução WHILE define um ciclo, executando consecutivamente uma instrução simples ou composta, enquanto for verdadeira a condição que segue a palavra WHILE. Quando esta se verifica passa, o controlo do programa para a instrução seguinte ao fim do ciclo.  

 

WHILE PAGENO = 1
    LET a = a * a + 2
    LET b = a * 2
END WHILE 

 Exemplo da instrução WHILE

...

COUNT

Conta o número total de linhas do resultado ou do grupo e que satisfaçam a cláusula WHERE, se existir.

PERCENT

Executa um função de contagem semelhante a função COUNT, mas dá o resultado em percentagem em relação ao número total de linhas selecionadas.

TOTAL

Acumula o valor da coluna especificada para todas as linhas do resultado ou do grupo e que satisfaçam a cláusula WHERE, se existir.

AVERAGE ou AVG

Calcula o valor médio da coluna especificada para todas as linhas do resultado ou do grupo e que satisfaçam a cláusula WHERE, se existir.

MIN

Calcula o valor mínimo da coluna especificada para todas as linhas do resultado ou do grupo e que satisfaçam a cláusula WHERE, se existir.

MAX

Calcula o valor máximo da coluna especificada para todas as linhas do resultado ou do grupo e que satisfaçam a cláusula WHERE, se existir.

  

 

AFTER GROUP OF cust
    LET totcli = GROUP TOTAL OF total_price
    LET totger = totger + totcli

    PRINT COLUMN 01, "TOTAL CLIENTE:",
          COLUMN 17, totcli USING "$$$$$####&.&&" 

    PRINT GROUP TOTAL OF total_price
          WHERE total_price > 500 USING "$$$$$####&.&&" 

 Exemplos de utilização de funções agregadas

...

Esta instrução suprime os espaços em branco a direita do último caracter diferente de espaço em branco dos campos tipo alfanuméricos.

 

BEFORE GROUP OF cust
    SKIP 1 LINE
    NEED 2 LINES

    PRINT COLUMN 01, "CLIENTE:",
          COLUMN 10, cust USING "<<<<",
          COLUMN 16, company CLIPPED 

 Exemplo da instrução CLIPPED

...

Esta expressão contém o número da linha corrente que o REPORT está para imprimir.

 

IF LINENO = 24 THEN
    SKIP TO TOP OF PAGE
END IF 

Exemplo da instrução LINENO

...

Esta expressão contém o número da página que o REPORT está imprimindo no momento. 

 

PAGE HEADER
    PRINT COLUMN 01, "RESUMO DAS ENCOMENDAS POR CLIENTE DE ",
                     inic, " A ", fim,
          COLUMN 70, "Pagina ", PAGENO USING "<<<" 

 Exemplo da instrução PAGENO

...