Você está na página 1de 237

Bruno Henrique Joaquim Programando com Progress ABL v.1.

5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Programando em Progress

Advanced Business Language

Jaison Antoniazzi
Versão 1.5

Copyright © 2021 Neo Step Ltda.

Todos os Direitos Reservados.

Nenhuma parte deste documento pode ser copiada, reproduzida, traduzida ou


transmitida por qualquer meio eletrônico ou mecânico, na sua totalidade ou em parte,
sem a prévia autorização escrita da Neo Step Ltda., que se reserva o direito de efetuar
alterações sem aviso prévio. A Neo Step Ltda não assume nenhuma responsabilidade
pelas consequências de quaisquer erros ou inexatidões que possam aparecer neste
documento.
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Índice

Sobre o Progress OpenEdge .......................................................................................................... 8


Alicerces dos sistemas Progress OpenEdge............................................................................... 2
Sobre a Linguagem ABL – Advanced Business Language .............................................................. 2
Sobre esta apostila ........................................................................................................................ 8
Banco de dados Progress OpenEdge ............................................................................................. 3
Control Area .............................................................................................................................. 3
Schema Area .............................................................................................................................. 3
Application Data Area................................................................................................................ 3
Primary Recovery Area .............................................................................................................. 3
After-image Area ....................................................................................................................... 4
Transaction log Area .................................................................................................................. 4
Encryption Policy Area............................................................................................................... 4
Audit data and index Area ......................................................................................................... 4
Componentes lógicos ................................................................................................................ 4
Ferramentas especialistas ............................................................................................................. 6
Principais ferramentas............................................................................................................... 6
Composição da sessão ................................................................................................................. 10
Programas em ambiente TTY e Gráfico ....................................................................................... 11
Programa TTY de exemplo....................................................................................................... 11
Analisando o código do programa exemplo............................................................................ 12
Analisando o código do programa exemplo do Windows ...................................................... 14
ABL-DÔ - The Way of the ABL Programmer ................................................................................ 16
Debugger ..................................................................................................................................... 17
Anotações ................................................................................................................................ 17
O objeto Debugger .................................................................................................................. 17
Exercício................................................................................................................................... 18
Objetos System Handle ............................................................................................................... 20
FOCUS system handle.............................................................................................................. 20
CLIPBOARD system handle ...................................................................................................... 22
THIS-PROCEDURE system handle ............................................................................................ 22
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

LOG-MANAGER system handle ............................................................................................... 24


ACTIVE-WINDOW system handle ............................................................................................ 25
DEBUGGER system handle ...................................................................................................... 25
ERROR-STATUS system handle ................................................................................................ 26
FILE-INFO system handle ......................................................................................................... 27
SESSION system handle ........................................................................................................... 27
SELF System Handle ................................................................................................................. 28
Operadores .................................................................................................................................. 30
Exercício................................................................................................................................... 31
Banco de dados, Record Buffer e Screen Buffer ......................................................................... 32
Segmentos ............................................................................................................................... 32
Instruções de transferência ..................................................................................................... 32
Buffers, Temp-tables e Datasets ................................................................................................. 34
Buffers ..................................................................................................................................... 34
Tabelas temporárias ................................................................................................................ 36
Datasets ................................................................................................................................... 39
Exercício................................................................................................................................... 43
Criação, Atribuição e Eliminação de Registros ............................................................................ 44
Instrução Create ...................................................................................................................... 44
Instrução Insert........................................................................................................................ 45
Instrução de Assign.................................................................................................................. 46
Instrução Delete ...................................................................................................................... 47
Exercício................................................................................................................................... 48
Interação com registros............................................................................................................... 49
Instrução For............................................................................................................................ 49
Transferência de Dados ........................................................................................................... 49
Fluxograma da pesquisa com instruções................................................................................. 49
Principais opções da instrução FOR......................................................................................... 51
Opções do Record phrase........................................................................................................ 52
For Each com Where ............................................................................................................... 53
For Each com By ...................................................................................................................... 53
For each com várias tabelas .................................................................................................... 54
For Each Encadeado com Várias Tabelas ................................................................................ 54

Neo Step
Todos os Direitos Reservados 3
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

For Each Encadeado com Fields .............................................................................................. 55


Instrução For First e For Last ................................................................................................... 55
Instrução Find .......................................................................................................................... 56
Analisando pontos fortes e fracos ........................................................................................... 58
Instrução Get ........................................................................................................................... 59
Open Query ............................................................................................................................. 59
Uso da função Can-find ........................................................................................................... 62
Locks de registros .................................................................................................................... 62
Usando No-lock e Exclusive-lock ............................................................................................. 63
Exercício................................................................................................................................... 64
Exercicios Complementares For Each...................................................................................... 64
Exercícios complementares de Open Query ........................................................................... 76
Gatilhos do banco de dados ........................................................................................................ 80
Create ...................................................................................................................................... 80
Delete ...................................................................................................................................... 80
Find .......................................................................................................................................... 80
Write ........................................................................................................................................ 80
Replication-create ................................................................................................................... 80
Replication-delete ................................................................................................................... 80
Replication-write ..................................................................................................................... 80
Retorno de Erro e cancelamento da execução ....................................................................... 80
Variáveis e tipos de dados ........................................................................................................... 81
Tipos de variáveis .................................................................................................................... 81
Tipos primitivos da linguagem ABL.......................................................................................... 81
Exemplos ................................................................................................................................. 82
Rótulos ..................................................................................................................................... 83
Formato padrão ....................................................................................................................... 84
Valores iniciais ......................................................................................................................... 85
Variáveis multidimensionais ou vetores.................................................................................. 85
Opção No-Undo ....................................................................................................................... 87
Visualização De Variáveis Como Objetos ................................................................................ 87
Variáveis e herança ................................................................................................................. 92
Exercício................................................................................................................................... 95
Entrada e Atribuição de Valores .................................................................................................. 96
Neo Step
Todos os Direitos Reservados 4
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Instrução Assign....................................................................................................................... 96
Instrução de Prompt-for .......................................................................................................... 97
Instrução de Update ................................................................................................................ 98
A maldição do Screen buffer ................................................................................................. 100
Exercícios ............................................................................................................................... 102
Instruções Condicionais ............................................................................................................. 103
Instrução IF, THEN e ELSE ...................................................................................................... 103
Instrução CASE....................................................................................................................... 104
Exercícios ............................................................................................................................... 105
Includes...................................................................................................................................... 106
Anotações .............................................................................................................................. 106
Exercício................................................................................................................................. 107
Pré-processadores ..................................................................................................................... 108
Constantes locais ................................................................................................................... 108
Constantes Globais ................................................................................................................ 108
Verificando a declaração de uma constante ......................................................................... 109
Diferença entre Scoped e Global ........................................................................................... 109
Eliminando a declaração de uma constante ......................................................................... 110
Exercício................................................................................................................................. 111
Frames e Display........................................................................................................................ 112
Frames de relatórios.............................................................................................................. 112
Frames para widgets ............................................................................................................. 112
Opções Para Campos E Constantes ....................................................................................... 112
Opções para o Frame ............................................................................................................ 115
Compartilhamento ................................................................................................................ 116
Instrução Display ................................................................................................................... 117
Frame de relatório ................................................................................................................. 119
Frames Sobrepostas .............................................................................................................. 121
As sete regras da programação com eventos ....................................................................... 122
Exercício................................................................................................................................. 124
Objetos, Eventos e Gatilhos de Widgets ................................................................................... 126
Tipos de Objetos .................................................................................................................... 126
Objetos Estáticos ................................................................................................................... 126

Neo Step
Todos os Direitos Reservados 5
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Objetos Dinâmicos................................................................................................................. 130


Códigos de Gatilhos ............................................................................................................... 131
Compartilhamento de variáveis e objetos ................................................................................ 136
Compartilhamento de variáveis entre programas ................................................................ 136
Compartilhamento de variáveis e objetos na sessão ............................................................ 137
Exercícios ............................................................................................................................... 139
Procedimentos e funções .......................................................................................................... 140
Procedimentos internos ........................................................................................................ 140
Procedimentos de Bibliotecas Externas ................................................................................ 140
Passagem de parâmetros ...................................................................................................... 141
Funções.................................................................................................................................. 147
Programas e Funções Persistentes ........................................................................................ 149
Exercício................................................................................................................................. 154
Blocos de instruções e Transações ............................................................................................ 155
Desfazendo a transação ........................................................................................................ 155
Opção Undo ........................................................................................................................... 156
Início e término de uma Transação ....................................................................................... 157
Exercício................................................................................................................................. 167
Laços de repetição ..................................................................................................................... 168
Instrução Do .......................................................................................................................... 168
Instrução Repeat ................................................................................................................... 169
Instrução For.......................................................................................................................... 169
Nomeando laços de repetição............................................................................................... 172
Exercício................................................................................................................................. 175
Tratamentos On Error, On Endkey, On Quit e On Stop ............................................................. 176
Opção On Error ...................................................................................................................... 176
Opção On EndKey .................................................................................................................. 178
Opção On Stop....................................................................................................................... 180
Opção On Quit ....................................................................................................................... 180
Captura de erros ........................................................................................................................ 182
Bloco catch ............................................................................................................................ 182
Bloco de Finally ...................................................................................................................... 182
Anotações .............................................................................................................................. 187

Neo Step
Todos os Direitos Reservados 6
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Importação e exportação .......................................................................................................... 188


Instrução Output ................................................................................................................... 188
Instrução Put ......................................................................................................................... 192
Instrução Export .................................................................................................................... 195
Instrução Display ................................................................................................................... 196
Instrução Input ...................................................................................................................... 197
Exercício................................................................................................................................. 200
Eventos Nomeados em programas ........................................................................................... 201
O Primeiro programa com eventos ....................................................................................... 201
Cancelando a notificação de Eventos .................................................................................... 204
Compilador ................................................................................................................................ 205
Opção Preprocess .................................................................................................................. 206
Opção Listing ......................................................................................................................... 206
Anexos ....................................................................................................................................... 208
Prova de certificação ............................................................................................................. 208
Componentes do banco de dados Sports2000 ..................................................................... 218

Neo Step
Todos os Direitos Reservados 7
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Sobre esta apostila


A autoria desta apostila é de Jaison Antoniazzi e não deve ser reproduzida.

Todas as sintaxes de comandos e instruções foram extraídas do arquivo de ajuda da Progress, assim como
alguns exemplos, outros exemplos foram confeccionados pelo autor e somente podem ser reutilizados para
aprendizagem em treinamentos ministrados pela Neo Step em parceria com a IDBA.

Neo Step Todos os Direitos Reservados.

Neo Step
Todos os Direitos Reservados 8
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Sobre o Progress OpenEdge


É um ambiente para desenvolvimento e execução de aplicações empresariais que:

• Possui linguagem interpretada conhecida como ABL - Advanced Business Language,


• Possui uma máquina virtual que o torna multiplataforma (AVM – ABL Virtual Machine),
• Tem banco de dados embutido que suporta 32.000 Petabytes de fácil gestão, mas que pode acessar
nativamente Oracle, Microsoft SQL Server e outros bancos,
• Possui várias ferramentas especialistas.

Alicerces dos sistemas Progress OpenEdge


Sistemas Progress OpenEdge podem ser constituídos por centenas, até dezena de milhares de programas,
por isso, são três alicerces:

1. A máquina virtual AVM que interpreta os programas compilados de um sistema,


2. Propath,
3. Conexão com banco de dados.

Sobre a Linguagem ABL – Advanced Business Language


• É Procedural, Orientada a eventos e Orientada a Objetos, organizada com procedimentos internos,
gatilhos e códigos de gatilho, e com classes e objetos,
• É estruturada em blocos de instruções,
• Possui transações e tratamento de erros,
• É formada por uma ou várias instruções,
• Combina procedimentos, e variáveis, e campos e tabelas implícitos dos diversos bancos conectados,
com elementos de iteração com usuário, utilizando-se de padrões para integrações com objetos
COM.
• Após a compilação gerará um arquivo binário, com extensão .R que depende da Máquina Virtual
para ser executado,
• É muito simples e com a pequena curva de aprendizagem,
• Aceita forma reduzida de comandos e instruções.
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Banco de dados Progress OpenEdge


Seguro, de simples gestão, poderoso e leve.

Control Area
Arquivo .DB que contém os caminhos de todos os arquivos que compõem o banco.

Schema Area
É o meta-schema ou esquema do banco de dados, são as tabelas e campos que um banco utiliza para se
autogerenciar.

Application Data Area


É a área composta pelos vários arquivos do sistema aplicativo ou ERP. Deveria ser em arquivos diferentes do
Schema, mas na grande maioria dos clientes estará na Area do Schema.

Primary Recovery Area


É o primeiro mecanismo do banco de dados para garantir a integridade em caso de falhas e transações.

Neo Step
Todos os Direitos Reservados 3
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

After-image Area
São as informações que foram salvas no banco de dados, mas que ainda não estão no backup.

Transaction log Area


São os arquivos que garantem transações distribuídas em rede entre bancos de dados Progress OpenEdge.

Encryption Policy Area


Área onde estão armazenadas todas as informações relacionadas à criptografia do Transparent Data
Encryption.

Audit data and index Area


É a área que mantem o mecanismo de auditoria, quando ativado, do banco dados.

Componentes lógicos
Tabelas
Coleção lógica de informações semelhantes, tabela de clientes, tabela de itens, tabelas de unidades de
medida.

Registro
Uma linha com um ou vários campos das tabelas.

Campos
Cada um dos constituintes de uma tabela que armazenam suas informações, por exemplo, código do cliente,
nome do cliente.

Chaves
Temos dois tipos, chaves únicas e primárias.

Única
São as chaves que garantem a unicidade, não repetição dos registros, por exemplo, código do cliente, cada
cliente tem um código único e que não se repete.

Primária
São as chaves que serão usadas quando o mecanismo de seleção dos índices da linguagem ABL não localizar
um índice apropriado.

Índices
São estruturas semelhantes às tabelas, que mantém informações dos campos que os compõem e do
endereço do registro da tabela, permitindo ao mecanismo de localização de registros localizar os registros
solicitados de forma mais rápida do que varrendo toda a tabela e seus registros.

Sequências
São objetos que permites o sequenciamento de números através de incrementos parametrizáveis e que não
são afetados por transações após o incremento ser acionado.

Relacionamentos entre tabelas


São as interações de interseção de conjuntos entre conjuntos distintos. Podendo ser relacionamento 1x1,
1xN ou NxN.
Neo Step
Todos os Direitos Reservados 4
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

O banco de dados Sports2000, que usaremos nesse treinamento, tem suas tabelas relacionadas na seção
Anexo, no final desta apostila.

Relacionamento 1x1
Quando duas tabelas A e B estão relacionadas e esta relação é de um registro da tabela A para um registro
da tabela B, por exemplo, um cliente que possui informações complementares e estas pertencem somente a
este cliente.

Relacionamento 1xN
Quando duas tabelas A e B estão relacionadas e esta relação é de um registro da tabela A para muitos da
tabela B, por exemplo, um cliente possui muitos pedidos.

Relacionamento NxN
Quando duas tabelas A e B estão relacionadas e esta relação é de muitos para muitos, exemplo, muitos
pedidos têm relação com muitos itens.

Neo Step
Todos os Direitos Reservados 5
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Ferramentas especialistas
O OpenEdge contém várias ferramentas que auxiliam desde a construção de programas, manutenção de
dicionário de dados, exportação e importação de programas.

Além destas, as soluções Progress ainda abrangem:

• Soluções Cognitivas como DataRPM e Corticon,


• Conectividade de dados e integração com DataDirect,
• Gerenciamento WEB com Sitefinity e Sitefinity Digital Experience Cloud,
• Desenvolvimento HTML moderno com KENDO UI BUILDER e ROLLBASE,
• Backend na nuvem e sem servidor dedicado conhecido como Kinvey,
• Ainda conta com:
o Kendo UI para construção de HTML moderno usando HTML5 e Javascript,
o NativeScript para desenvolvimento mobile,
o NativeChat para desenvolvimento de ChatBots cognitivos,
o Plataforma Telerik,
o Test Studio para automação de testes.

Ferramentas especialistas da versão OE Studio

Principais ferramentas
• AppBuilder, construtor de programas de programas estruturados para ambiente TTY, Gráfico e Web,
• Application Compiler, compilador de programas,
• Audit Policy Maintenance, gestor da política de auditoria,
• Character Client, editor caracter para desenvolvimento de programas TTY,

Neo Step
Todos os Direitos Reservados 6
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

• GUI Procedure Editor, editor de programas com interface gráfica para desenvolvimento de
programas,
• Developer Studio, Eclipse com plugin Progress para desenvolver programas modernos,
• Config, visualizador das licenças instaladas,
• Data Administration, exportação e importação de dados e definições, gestor de conexão com outros
bancos, listagem de programas,
• Data Dictionary, gestor de tabelas, campos, índices e sequências,
• Debugger, debugador de programas,
• Desktop, aplicação com atalho para as principais ferramentas,
• Help, arquivo de ajuda,
• Proenv, ambiente caracter com as variáveis do ambiente OpenEdge já atribuídas,
• OpenEdge Explorer, gestor de agentes de soluções para execução de programas remotos, agentes
webspeed e webservices, iniciador de bancos,
• Results, construtor de relatórios gráficos.

AppBuilder

Application Compiler

Neo Step
Todos os Direitos Reservados 7
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Procedure Editor (Client)

Data Administration

Data Dictionary

Neo Step
Todos os Direitos Reservados 8
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Desktop

Neo Step
Todos os Direitos Reservados 9
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Composição da sessão
A grande maioria das ferramentas utilizam a máquina virtual do OpenEdge, esta aceita
parâmetros muitos parâmetros, pois foi nasceu em ambiente Unix. Para aqueles que estão
acostumados com aplicações Windows pode parecer estranho uma linha de comando, com os
três alicerces (AVM, Propath e Banco de dados) assim:

C:\DLC101B\bin\prowin32.exe -basekey ini -ini scripts\ems2.ini -pf


scripts\ems2mult.pf -p scripts\alias.p

Dissecando este comando:

• Prowin32.exe é o executável OpenEdge da Máquina Virtual que interpreta comandos


de programas .R linguagem ABL.
• -basekey é o parâmetro que determina se as variáveis padrão OpenEdge serão
buscadas do Registry ou de um arquivo INI,
• -Ini é o arquivo INI da sessão,
• -pf são os parâmetros de conexão com os bancos de dados da sessão e outros
parâmetros de sessão,
• -p é o programa a ser executado com a inicialização da sessão.

Abaixo segue um pequeno exemplo de variáveis que deverão estar atribuídas no INI, no
Registry ou no Prompt de comandos (DOS).

Variável Descrição Exemplo


DLC Caminho da instalação do Progress DLC=C:\DLC102B
Promsgs Caminho do arquivo de mensagens PROMSGS=c:\dlc102B\promsgs
do Progress
Propath Lista de pastas dos programas PROPATH=.,C:\\ems206\EMS206-
LOCAL
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Programas em ambiente TTY e Gráfico


Um programa desenvolvido para o ambiente TTY (Unix) pode executar em ambiente Gráfico (Windows) com
nenhuma ou poucas modificações.

Um programa TTY de exemplo.

/* declarando uma variavel */


DEFINE VARIABLE icodigoCliente AS INTEGER NO-UNDO
LABEL 'Codigo Cliente'.

/* criando um laço de repeticao */


REPEAT :

/* lendo um valor na variavel */


UPDATE icodigoCliente.

/* pesquisando no banco de dados */


FIND FIRST customer NO-LOCK
WHERE customer.custnum = icodigoCliente NO-ERROR.
/* se encontrou o cliente */
IF AVAILABLE customer THEN
DO:
/* mostrar o valor do registro para o usuario */
DISPLAY
customer.custnum
customer.NAME
customer.address
customer.city
customer.state
customer.creditlimit
WITH 1 COL.

END.

/* fim do bloco, mas por ser Repeat reiniciará a leitura */


END.

Programa TTY de exemplo

Programa exemplo executando em ambiente TTY (DOS ou UNIX)

Neo Step
Todos os Direitos Reservados 11
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Programa exemplo executando em ambiente gráfico (Windows)

Analisando o código do programa exemplo


/* declarando uma variavel */
1 DEFINE VARIABLE icodigoCliente AS INTEGER NO-UNDO
LABEL 'Codigo Cliente'.

/* criando um laço de repetição, use ESC para sair*/


2 REPEAT :

/* lendo um valor na variavel */


3 UPDATE icodigoCliente.

/* pesquisando no banco de dados */


4 FIND FIRST customer NO-LOCK
WHERE customer.custnum = icodigoCliente NO-ERROR.
/* se encontrou o cliente */
5 IF AVAILABLE customer THEN DO:
/* mostrar o valor do registro para o usuario */
6 DISPLAY
customer.custnum
customer.NAME
customer.address
customer.city
customer.state
customer.creditlimit
WITH 1 COL.

Neo Step
Todos os Direitos Reservados 12
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

7 END.

/* fim do bloco, mas por ser Repeat reiniciará a leitura */


8 END.

1. Definição de variável do tipo inteiro, será usada para a leitura de um valor para auxiliar na
pesquisa da tabela Customer,
2. Inicio do laço de repetição Repeat,
3. Ler o valor da variável,
4. Pesquisar o cliente (customer) que o código do cliente (customer.custnum) é igual ao valor
digitado no passo 3,
5. Decisão com uso de IF THEN, no caso usamos a função AVAILABLE CUSTOMER para verificar se o
registro de cliente está disponível,
6. Utilizamos a instrução DISPLAY para mostrar o valor do BUFFER da tabela CUSTOMER,
7. Final do bloco IF THEN,
8. Final do bloco de REPEAT.

Um programa para Windows de exemplo.

/* declarando uma variavel */


DEFINE VARIABLE icodigoCliente AS INTEGER NO-UNDO
LABEL 'Codigo Cliente'.

DEFINE FRAME principal


icodigoCliente
WITH
SIDE-LABELS
SIZE 40 BY 2.

ON RETURN OF icodigoCliente IN FRAME principal


DO:

ASSIGN INPUT icodigoCliente.


/* pesquisando no banco de dados */
FIND FIRST customer NO-LOCK
WHERE customer.custnum = icodigoCliente NO-ERROR.
/* se encontrou o cliente */
IF AVAILABLE customer THEN
DO:
/* mostrar o valor do registro para o usuario */
DISPLAY
customer.custnum
customer.NAME
customer.address
customer.city
customer.state
customer.creditlimit
WITH 1 COL.

END.

END.

VIEW FRAME principal.


Neo Step
Todos os Direitos Reservados 13
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

ENABLE ALL WITH FRAME principal.


DISPLAY icodigoCliente
WITH FRAME principal.

WAIT-FOR ENDKEY OF FRAME principal.


Programa para Windows de exemplo.

O resultado é:

Programa desenvolvido em ABL para ambiente gráfico (Windows).

Analisando o código do programa exemplo do Windows


/* declarando uma variavel */
1 DEFINE VARIABLE icodigoCliente AS INTEGER NO-UNDO
LABEL 'Codigo Cliente'.

2 DEFINE FRAME principal


icodigoCliente
WITH
SIDE-LABELS
SIZE 40 BY 2.

3 ON RETURN OF icodigoCliente IN FRAME principal DO:

3.1 ASSIGN INPUT icodigoCliente.


/* pesquisando no banco de dados */
3.2 FIND FIRST customer NO-LOCK
WHERE customer.custnum = icodigoCliente NO-ERROR.
/* se encontrou o cliente */
3.3 IF AVAILABLE customer THEN DO:
/* mostrar o valor do registro para o usuario */

Neo Step
Todos os Direitos Reservados 14
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

3.4 DISPLAY
customer.custnum
customer.NAME
customer.address
customer.city
customer.state
customer.creditlimit
WITH 1 COL.

3.5 END.

3.6 END.

4 VIEW FRAME principal.


5 ENABLE ALL WITH FRAME principal.
6 DISPLAY icodigoCliente WITH FRAME principal.

7 WAIT-FOR ENDKEY OF FRAME principal.

1. Definição de variável para entrada de dados,


2. Definição de frame com a variável,
3. Gatilho de Return (ENTER),
3.1. Atribuir o valor que está no SCREEN-BUFFER para o RECORD BUFFER,
3.2. Localizar o registro no banco de dados e trazê-lo para o RECORD BUFFER,
3.3. Instrução condicional IF THEN (Se então) "Se registro do cliente estiver disponível",
3.4. Exibir os demais campos do cliente em uma tela criada automaticamente,
3.5. Fim do código do Gatilho,
4. Exibir a frame Principal,
5. Habilitar todos os campos da frame Principal, no exemplo, somente há o campo icodigoCliente,
6. Exibir o valor da variável icodigoCliente na tela, neste ponto, o Progress transfere o valor do RECORD
BUFFER para o SCREEN-BUFFER.
7. Aguardar até o ENDKEY (ESC) na tela para encerrar o programa.

Neo Step
Todos os Direitos Reservados 15
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

ABL-DÔ - The Way of the ABL Programmer


Em minha experiência consegui formular esta frase que elenca as principais características que o
programador ABL deverá seguir a fim de se tornar um expert em Progress ABL.

FoFOCA Do Dia ToDo, Para Fazer PRograma

Um acrônimo para os principais comandos da linguagem Progress ABL focando a interação com registros em
banco de dados, a estrutura de um programa e a execução destes.

1. FIND, F
2. FOR EACH, F
3. OPEN QUERY, O
4. CREATE, C
5. ASSIGN, A
6. DELETE, D
7. DISPLAY, D
8. TRANSACTION, T
9. DO, D
10. PROCEDURE, P
11. FUNCTION, F
12. PERSISTENT, P
13. RUN, R

Acredito que todo programador, que queira ser um professional diferenciado, tem que dominar estas treze
instruções.

Find, For Each e Open Query para o acesso aos registros no banco de dados.

Create, Assign, Delete e Display para trabalhar com o registro, seja criando, seja atribuindo valores,
removendo ou exibindo o valor dos campos de uma tabela.

Saber trabalhar com Transaction e o bloco Do pode resolver vários problemas que considero problemas
básicos, como a criação de uma transação gigante que se inicia no começo do programa e somente será
completada ao término deste, algo muito ruim para qualquer programa, pois, na maioria das vezes, pode
criar uma Transação gigante e que estoura o parâmetro -L.

Dominar Procedures, Functions, sejam elas locais, ou através da técnica de programas em memória, com a
opção Persistent, assim como dominar a execução delas, sua passagem de parâmetros, usando a instrução
Run, facilitará a execução, a segmentação e o tratamento de código.

Neo Step
Todos os Direitos Reservados 16
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Debugger
Permite acompanharmos a execução passo a passo de programas, visualizarmos valores de variáveis, tabelas
temporárias e valores em registros de tabelas do banco.

Para utilizarmos o debugger precisamos habilitá-lo no nosso ambiente, para isso utilize o comando
ProDebugEnable -enable-all. Este comando deverá ser executado no prompt de comando com o utilitário
Proenv.

Sintaxe

proDebugEnable {-disable-all|-enable-all}

Exemplo

ProDebugEnable –enable-all

Anotações

O objeto Debugger
Para debugarmos um programa manipularemos o objeto Debugger.

É necessário iniciar o objeto Debugger antes de adicionar pontos de parada.

DEBUGGER:INITIATE().

Estando o Debugger iniciado basta adicionarmos os pontos de parada no programa com o comando
Debugger:Set-break().

DEBUGGER:SET-BREAK().

Exemplo

DEFINE NEW SHARED BUFFER CustBuf FOR customer.

DEFINE VARIABLE debug AS LOGICAL.


debug = DEBUGGER:INITIATE().
debug = DEBUGGER:SET-BREAK("r-ordbug.p",6).

FOR EACH CustBuf:


IF CAN-FIND(order OF CustBuf) THEN
RUN r-ordbug.p.
END. /* FOR EACH CustBuf */

debug = DEBUGGER:CLEAR().

Anotações

Neo Step
Todos os Direitos Reservados 17
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercício
1. Debug o programa abaixo.

DEFINE VARIABLE icont AS INTEGER NO-UNDO INIT 1.

DEBUGGER:INITIATE().
DEBUGGER:SET-BREAK().

1 DISP icont.

RUN retornarValor ( INPUT icont).

4 DISP icont.

PROCEDURE retornarValor:
DEFINE INPUT PARAMETER valor AS INTEGER NO-UNDO.

2 valor = valor + 10.

3 DISP valor.
END.

Utilizando a opção Add Watch (botão direito) sobre as variáveis icont e valor anote os valores nos
pontos:

1.

2.

3.

4.

2. Debug o programa abaixo.

DEFINE VARIABLE icont AS INTEGER NO-UNDO INIT 1.

DEBUGGER:INITIATE().
DEBUGGER:SET-BREAK().

FOR EACH customer NO-LOCK


WHERE custnum > 3 AND custnum < 10:

Neo Step
Todos os Direitos Reservados 18
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

DISP custnum NAME.

END.

Utilizando a página Buffers, selecione o buffer Customer e visualize os valores dos campos com a opção
Dataview.

3. Debug o programa abaixo.

DEFINE VARIABLE icont AS INTEGER NO-UNDO INIT 1.


DEFINE VARIABLE iordernum AS INTEGER NO-UNDO.
DEFINE VARIABLE dtorderdate AS DATETIME NO-UNDO.

DEBUGGER:INITIATE().
DEBUGGER:SET-BREAK().

FOR EACH customer NO-LOCK


WHERE custnum > 3 AND custnum < 10:

DISP custnum NAME.

FOR EACH order OF customer:


ASSIGN
iordernum = ordernum
dtorderdate = orderdate.
END.

END.

Utilizando as páginas Buffers e Variables anote os números e datas e dos pedidos (Order) dos clientes 5
(Match Point Tennis), 7 (Aerobics Valine Ky) e 8 (Game Set Match).

Cliente Números dos Pedidos Datas dos Pedidos


Match Point Tennis

Aerobics Valine Ky

Game Set Match

Neo Step
Todos os Direitos Reservados 19
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Objetos System Handle


A linguagem ABL tem vários objetos system handle, que são objetos que não necessitam de define ou create,
pois estão presentes na AVM. Estes objetos desempenham várias funções diferentes, como manipulação da
área de transferência (CLIPBOARD), manipulação do arquivo de log, tratamento de do objeto com foco
(FOCUS) e muitas outras funcionalidades.

Principais objetos:

• FOCUS system handle,


• CLIPBOARD system handle,
• THIS-PROCEDURE system handle,
• LOG-MANAGER system handle,
• ACTIVE-WINDOW system handle,
• DEBUGGER system handle,
• ERROR-STATUS system handle,
• FILE-INFO system handle,
• SESSION system handle,
• SELF system handle,

FOCUS system handle


É o handle do objeto (WIDGET) que tem o foco.

Sintaxe

FOCUS [ :attribute ]

O objeto Focus retorna o handle do objeto com o foco em uma janela.

Os atributos do objetos Focus variarão conforme o tipo do objeto com foco.

Exemplo de Focus
Construa uma janela com alguns objetos

Na sessão Main Block adicione o código

ON 'ctrl-j':U ANYWHERE
Neo Step
Todos os Direitos Reservados 20
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

DO:

DEFINE VARIABLE hframe AS HANDLE NO-UNDO.


DEFINE VARIABLE hwindow AS HANDLE NO-UNDO.
hframe = FOCUS:FRAME.
hwindow = hframe:PARENT.

MESSAGE
"nome widget:" FOCUS:NAME SKIP
"tipo do widget:" FOCUS:TYPE SKIP
"nome da frame:" hframe:NAME SKIP
"titulo da janela:" hwindow:TITLE
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.

Este código mostrará o nome do objeto focado, o tipo, o nome da frame, o título da janela.

Execute o programa e pressione CTRL-J e deverá aparecer a mensagem abaixo se o botão 1 estiver
selecionado.

Agora selecionando o Fill-In e usando o CTRL-J

Habilitando objetos na tela


Este código tem a funcionalidade de habilitar objetos na tela, mas tem que existir pelo menos um objeto que
possa receber foco.

ON 'ctrl-j':U ANYWHERE
DO:

Neo Step
Todos os Direitos Reservados 21
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

DEFINE VARIABLE hframe AS HANDLE NO-UNDO.


DEFINE VARIABLE hwindow AS HANDLE NO-UNDO.
hframe = FOCUS:FRAME.
hwindow = hframe:PARENT.

DEFINE VARIABLE hobjeto AS HANDLE NO-UNDO.

/* capturar o primeiro field-group da janela */


hobjeto = hframe:FIRST-CHILD.
/* capturar o primeiro objeto do field-group */
hobjeto = hobjeto:FIRST-CHILD.

DO WHILE VALID-HANDLE(hobjeto) = TRUE:


IF CAN-QUERY(hobjeto, 'SENSITIVE') THEN
hobjeto:SENSITIVE = TRUE.

hobjeto = hobjeto:NEXT-SIBLING.
END.

END.

Anotações

CLIPBOARD system handle


É o handle da área de transferência.

Sintaxe

CLIPBOARD [ :attribute ]

Com este objeto você pode copiar ou gravar informações na área de transferência do Windows.

Exemplo

clipboard:value = "OpenEdege é muito simples!".

MESSAGE clipboard:value
VIEW-AS ALERT-BOX INFO BUTTONS OK.

Anotações

THIS-PROCEDURE system handle


É o handle do programa corrente.

Neo Step
Todos os Direitos Reservados 22
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Sintaxe

procedure-handle [ :attribute | :method ]

Exemplo de This-Procedure
Construa uma janela e adicione o código abaixo

MESSAGE
'Procedures internas='
THIS-PROCEDURE:INTERNAL-ENTRIES SKIP
'Persistent?' THIS-PROCEDURE:PERSISTENT SKIP
'Tipo=' THIS-PROCEDURE:TYPE SKIP
'Bancos do programa=' THIS-PROCEDURE:DB-REFERENCES
VIEW-AS ALERT-BOX INFO BUTTONS OK.

Localizando procedures internas de um programa persistent


Também é possível localizar as procedures internas de um programa persistente, basta substituir o THIS-
PROCEDURE pelo handle do programa persistente.

DEFINE VARIABLE hprograma AS HANDLE NO-UNDO.

RUN basico/programaA.p PERSISTENT SET hprograma.

MESSAGE
'Procedures internas=' hprograma:INTERNAL-ENTRIES SKIP
'Persistent?' hprograma:PERSISTENT SKIP
'Tipo=' hprograma:TYPE SKIP
'Bancos do programa=' hprograma:DB-REFERENCES
VIEW-AS ALERT-BOX INFO BUTTONS OK.

DELETE OBJECT hprograma.

Pegando a assinatura da procedure


É possível usar o método GET-SIGNATURE para conhecer os parâmetros de entrada e saída das procedures
internas.

Antes de executar o código, adicione a procedure interna abaixo.

PROCEDURE procedure-interna :
/*---------------------------------------------------------------------
---------
Purpose:
Parameters: <none>
Notes:
-----------------------------------------------------------------------
-------*/
DEFINE INPUT PARAMETER p1 AS CHARACTER NO-UNDO.
DEFINE INPUT-OUTPUT PARAMETER p2 AS INTEGER NO-UNDO.
DEFINE OUTPUT PARAMETER p3 AS DECIMAL NO-UNDO.
DEFINE OUTPUT PARAMETER p4 AS DATE NO-UNDO.

END PROCEDURE.

Agora execute o código abaixo.

Neo Step
Todos os Direitos Reservados 23
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

MESSAGE
'Procedures internas=' THIS-PROCEDURE:INTERNAL-ENTRIES SKIP
'Persistent?' THIS-PROCEDURE:PERSISTENT SKIP
'Tipo=' THIS-PROCEDURE:TYPE SKIP
'Bancos do programa=' THIS-PROCEDURE:DB-REFERENCES SKIP
'Assinatura procedure-interna=' THIS-PROCEDURE:GET-SIGNATURE('procedure-
interna')
VIEW-AS ALERT-BOX INFO BUTTONS OK.
Exibirá esta mensagem

Para mais detalhes sobre THIS-PROCEDURE procure por Procedure object handle.

Anotações

LOG-MANAGER system handle


É o handle do manipulador de log, equivale ao –clientlog da sessão.

Sintaxe

LOG-MANAGER [ :attribute | :method ]

Exemplo de criação arquivo de log em tempo de execução


log-manager:LOGFILE-NAME = session:temp-dir + 'meulog.txt'.
log-manager:LOGGING-LEVEL = 4.
log-manager:log-entry-types = "4GLMessages,4GLTrace,FileID".

log-manager:write-message("gravar este texto no arquivo.").

Neo Step
Todos os Direitos Reservados 24
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Limpando o log
log-manager:clear-log().

A limpeza do Log, através do método CLEAR-LOG não funciona para AppServer e WebSpeed.

Anotações

ACTIVE-WINDOW system handle


É o handle da janela ativa.

Anotações

DEBUGGER system handle


É o handle para “debugar” um programa, para ativá-lo veja o capítulo Debugger.

Sintaxe

DEBUGGER [ :attribute | :method ]

Exemplo

DEFINE STREAM stream1.

PAUSE 0 BEFORE-HIDE.

OUTPUT stream stream1 to "c:\temp\cliente.txt"


paged
page-size 40
convert target 'ISO8859-1'.

DEBUGGER:INITIATE().
DEBUGGER:SET-BREAK().

FOR EACH customer NO-LOCK:

DISPLAY STREAM stream1


customer.custnume
customer.name
WITH STREAM-IO.

END.

OUTPUT stream stream1 close.


Deverá aparecer a janela abaixo.
Neo Step
Todos os Direitos Reservados 25
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Utilize os botões Step Into, Step Over e Step Out para continuar a execução do programa.

Use as abas Variables, Buffers, Parameters, Temp-tables e Dataset para verificar o conteúdo de cada tipo de
objeto.

Anotações

ERROR-STATUS system handle


É o handle do estado de erro da última instrução com no-error.

Sintaxe

ERROR-STATUS [ :attribute | :method

Exemplo

DEFINE VARIABLE idade AS INTEGER NO-UNDO.

idade = int("A") NO-ERROR.

IF ERROR-STATUS:ERROR THEN
DO:
MESSAGE
"Mensagem: " ERROR-STATUS:GET-MESSAGE(1) SKIP
"Numero de erros: " ERROR-STATUS:NUM-MESSAGES SKIP
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.

Neo Step
Todos os Direitos Reservados 26
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Anotações

FILE-INFO system handle


É o handle de qualquer arquivo do disco, podendo ser programa, pasta ou um arquivo qualquer.

Sintaxe

FILE-INFO [ :attribute ]

Exemplo

FILE-INFO:FILE-NAME = "c:\temp".

MESSAGE
"Tipo: " FILE-INFO:FILE-TYPE SKIP

VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

FILE-INFO:FILE-NAME = 'gui/_dict.r'.

MESSAGE
"Tipo: " FILE-INFO:FILE-TYPE SKIP
"Caminho completo: " FILE-INFO:FULL-PATHNAME
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

O atributo File-type retornará D para pastas e F para arquivos, R para arquivo acessível e W para arquivo ou
pasta com permissão para gravar.

Anotações

SESSION system handle


É o handle da sessão ativa.

Sintaxe

SESSION [ :attribute | :method ]

Entre os principais atributos, cito:

• CPSTREAM , informa o código de página da sessão.


• CLIENT-TYPE , informa o tipo da sessão em execução, podendo ser 4GLCLIENT, WEBCLIENT,
APPSERVER, WEBSPEED ou ? (desconhecido).
• DATE-FORMAT, indica o formato da data, podendo ser MDY ou DMY.

Neo Step
Todos os Direitos Reservados 27
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

• DEBUG-ALERT, deve apresentar o botão HELP na mensagem de erro, para exibir a janela com a pilha
de programas executados.
• DISPLAY-TYPE , indica se o tipo de exibição é gráfico (GUI) ou caractere (TTY),
• NUMERIC-DECIMAL-POINT, indica o caractere utilizado para a formatação de número decimal,
• WORK-AREA-WIDTH-PIXELS, indica a largura da área disponível do desktop Windows que não está
escondida pelas barras do sistema.
• WORK-AREA-HEIGHT-PIXELS, indica a altura da área disponível do desktop Windows que não está
escondida pelas barras do sistema.

Anotações

SELF System Handle


É o handle do objeto em execução do código de gatilho.

Com este handle podemos referenciar os atributos de cada tipo de objeto, vale lembrar que diferentes
objetos possuem diferentes métodos e atributos.

Resultado da execução com o SELF

Neo Step
Todos os Direitos Reservados 28
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Neo Step
Todos os Direitos Reservados 29
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Operadores
Lista de operadores da linguagem.

Operador Descrição
+ Adição
- Subtração
* Multiplicação
/ Divisão
= Igualdade
<> Desigualdade
> Maior que
< Menor que
>= Maior ou igual que
<= Menor ou igual que
AND E
OR OU
NOT NOT
BEGINS Compara o início das letras de duas expressões
MATCHES Compara duas STRINGS
GT Maior que
GE Maior ou igual que
LT Menor que
LE Menor ou igual que
Modulo Retornar o resto da divisão

No Progress ABL não há frescura de outras linguagens e você pode somar, dividir, multiplicar, subtrair e
outras operações com números inteiros, inteiros de 64 bits e decimais sem perda de valores ou erros de
ponto flutuante.

Então somar decimais com inteiros, ou dividir tipos numéricos diferentes não tem problema!

Anotações

Neo Step
Todos os Direitos Reservados 30
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercício
Para a nomenclatura dos exercícios, utilize a máscara OPER_<número do exercício>.P (oper_1.p, oper_2.p).

1. Declare duas variáveis do tipo inteiro, faça a somatória e exiba os valores delas (Instrutor).
2. Declare três variáveis caracter para armazenar nome, sobrenome e nome completo, concatene-as e
exiba o valor resultante. Uma variável receberá a soma das outras duas.
3. Faça a somatória de duas variáveis decimais.
4. Utilizando o segundo exercício, faça a concatenação do seu nome completo com a sua idade, utilize
a função String para converter valores para caracter antes de unir nome completo e idade.
5. Some a raiz quadrada de 2 com a raiz quadrada de 3 em uma variável decimal, exibindo este valor.
Utilize a função SQRT.
6. Utilizando o quinto exercício, melhore-o para exibir o valor da soma com 5 casas decimais.
7. Usando três variáveis, obtenha a razão do seu peso pelo quadrado da sua altura.
8. Usando a função MODULO obtenha o resultado da divisão de 3 por 2.

Neo Step
Todos os Direitos Reservados 31
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Banco de dados, Record Buffer e Screen Buffer


A linguagem ABL tem várias áreas de memória, estas áreas possuem diferentes valores para a mesma
variável por questão de segurança, e que anteriormente fora amplamente alardeado, mas hoje é algo básico.

Segmentos
Database
É onde estão os valores dos campos das tabelas, no banco de dados, quando fazemos um FIND o Progress ao
encontrar o registro, o transfere para o Record Buffer.

Record Buffer
É uma área da memória onde o programador pode fazer a manipulação do valor real de um campo de tabela
ou de uma variável.

Screen Buffer
É o valor da variável que é exibido ao usuário.

Instruções de transferência
Temos muitas instruções que transferem os valores entre os vários buffers.

Instrução Descrição
FIND Localizar um registro no banco de dados (Database) e disponibilizá-lo no Record
buffer.

Update É uma instrução complexa, formada pelos comandos Display, Prompt-For e Assign.
A principal função é exibir o valor da variável ou campo, habilitar para o usuário
digitar valor e atribuir do Screen-buffer para o Record Buffer.

Display Transferir o valor, do campo ou variável, que está no Record Buffer para o Screen-
buffer, em outras palavras, exibir o valor da variável.

Neo Step
Todos os Direitos Reservados 32
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Assign Atribuir o valor que está no Screen-buffer para o Record Buffer.

For Localizar um registro no banco de dados (Database) e disponibilizá-lo no Record


Buffer, mas faz um laço de repetição com os muitos registros que uma cláusula
'where' resolver.

Prompt-for Transferir o que foi digitado para o Screen-buffer da variável.

Enable Habilitar campos em uma frame.

Neo Step
Todos os Direitos Reservados 33
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Buffers, Temp-tables e Datasets


Buffers
Buffers são ponteiros para tabelas do dicionário e para tabelas temporárias.

A linguagem ABL disponibiliza um ponteiro por tabela e em algumas situações poderemos necessitar
localizar mais de um registro na tabela pesquisada, para esta situação a utilização de Buffers é obrigatória.

Sintaxe Buffer

DEFINE { [ [ NEW ] SHARED ] | [ PRIVATE | PROTECTED ] [ STATIC ] }


BUFFER buffer-name
FOR [ TEMP-TABLE ] table-name
[ PRESELECT ] [ LABEL label-name ]
[ NAMESPACE-URI namespace ] [ NAMESPACE-PREFIX prefix ]
[ XML-NODE-NAME node-name ]

O Buffer pode ser compartilhado com as opções New e Shared.

Exemplo

DEFINE BUFFER bcustomer FOR customer.

Exemplo de Buffer e Find

/* buffer */

DEF BUFFER buf-customer FOR customer.

FIND FIRST buf-customer


WHERE buf-customer.custnum = 10.

Exemplo de Buffer com For Each

DEFINE BUFFER buf-customer FOR customer.

FOR EACH customer NO-LOCK:

DISP customer.custnum customer.NAME customer.salesrep.

FIND LAST buf-customer NO-LOCK


WHERE buf-customer.salesrep = customer.salesrep NO-ERROR.

DISP buf-customer.salesrep LABEL 'Representante'.

END.
Exemplo de Buffer com passagem de parâmetro

PROCEDURE receberBuffer:
DEFINE PARAM BUFFER buf-customer FOR customer.
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

DISP buf-customer.custnum buf-customer.NAME buf-customer.address WITH 1


COL.
END.

DEF VAR codigo AS INTEGER NO-UNDO.

REPEAT :

UPDATE codigo.

FIND FIRST customer NO-LOCK


WHERE customer.custnum = codigo NO-ERROR.

IF AVAIL customer THEN DO:

DISP customer.custnum customer.NAME WITH TITLE 'cliente'.

RUN receberBuffer ( BUFFER customer ).


END.

END.
Exemplo de buffer com atualização de dados

PROCEDURE receberBuffer:
DEFINE PARAMETER BUFFER buf-customer FOR customer.

DISPLAY buf-customer.custnum.
UPDATE
buf-customer.NAME
buf-customer.address
WITH 1 COL.
END.

DEFINE VARIABLE codigo AS INTEGER NO-UNDO.

REPEAT :

UPDATE codigo.

FIND FIRST customer EXCLUSIVE-LOCK


WHERE customer.custnum = codigo NO-ERROR.

IF AVAILABLE customer THEN


DO:

DISPLAY customer.custnum customer.NAME WITH TITLE 'cliente'.

RUN receberBuffer ( BUFFER customer ).


END.

END.

Exemplo de Buffer com Display e Except

35
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

/* explicito = declarado */
DEFINE BUFFER buf-customer FOR customer.

FIND FIRST buf-customer.


IF AVAIL buf-customer THEN DO:

DISP buf-customer
EXCEPT buf-customer.comments
WITH 2 COL.

END.

Tabelas temporárias
São Tabelas que podem armazenar temporariamente grande volumes de dados, esses registros de tabelas
temporárias existem somente durante a execução de programas, podem conter índices e demais
características de uma tabela (buffer implícito ou explicito), não disparam qualquer gatilho ou e também não
geram transação.

Quanto a sua estrutura, podem ser imagens de tabelas do banco, com campos e índices, podem-se adicionar
novos campos ou ainda podem ser totalmente novas (campos e índices).

Sintaxe temp-table

DEFINE {[[ NEW [ GLOBAL ]] SHARED ]|


[ PRIVATE | PROTECTED ][ STATIC ]
[ SERIALIZABLE ]}
TEMP-TABLE temp-table-name[ NO-UNDO ]
[ NAMESPACE-URI namespace][ NAMESPACE-PREFIX prefix]
[ XML-NODE-NAME node-name][ SERIALIZE-NAME serialize-name ]
[ REFERENCE-ONLY ]
[ LIKE table-name
[ VALIDATE ]
[ USE-INDEX index-name[ AS PRIMARY ]]...]
[ LIKE-SEQUENTIAL table-name
[ VALIDATE ]
[ USE-INDEX index-name[ AS PRIMARY ]]...]
[ RCODE-INFORMATION ]
[ BEFORE-TABLE before-table-name]
[ FIELD field-name
{ AS data-type| LIKE field[ VALIDATE ]}
[field-options]
]...
[ INDEX index-name
[[ AS | IS ][ UNIQUE ][ PRIMARY ][ WORD-INDEX ]]
{index-field[ ASCENDING | DESCENDING ]}...
]...

36
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exemplo de Temp-Table

DEFINE TEMP-TABLE ttCustomer LIKE customer.

Sintaxe temp-table com novo campo

DEFINE TEMP-TABLE ttCustomer LIKE customer


FIELD icontador AS INTEGER.

Sintaxe temp-table com novo campo e novo índice*

DEFINE TEMP-TABLE ttCustomer LIKE customer


FIELD icontador AS INTEGER
INDEX ix_contador icontador.

*AO ADICIONAR NOVO ÍNDICE EM UMA TEMP-TABLE NENHUM ÍNDICE SERÁ HERDADO DA TABELA ORIGEM.

Exemplo de Temp-table

/* primeiro tipo - tabela temporaria com estrutura identica à uma tabela do


banco */

DEFINE TEMP-TABLE ttCustomer


LIKE customer.

CREATE ttCustomer.
UPDATE ttcustomer
WITH
1 COL
WIDTH 222.
Exemplo de Temp-table com índices

/* primeiro tipo - tabela temporaria com estrutura identica à uma tabela do


banco */

DEFINE TEMP-TABLE ttCustomer


LIKE customer.

/* like de outra TT */
DEFINE TEMP-TABLE ttCustomerEx LIKE ttCustomer.

DEFINE TEMP-TABLE ttCustomer2


FIELD codigo AS INTEGER
FIELD nome AS CHAR FORMAT 'x(35)' LABEL 'Nome'
FIELD endereco AS CHAR

INDEX
ix_codigo AS UNIQUE AS PRIMARY
codigo

INDEX

37
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

ix_nome
nome.

DEFINE TEMP-TABLE ttCustomer3 LIKE customer


FIELD codigo AS INTEGER
FIELD filiacao AS CHAR FORMAT 'x(35)' LABEL 'Filiação'
.

CREATE ttCustomer3.
UPDATE ttcustomer3
WITH
1 COL
SIZE 122 BY 8.
*Neste exemplo nenhum índice da tabela Customer será copiada para a temp-table ttCustomer2 pois houve
criação de índice nesta temp-table, já na ttCustomer todos os índices da tabela Customer serão usados.

Exemplo de Temp-table com Buffer-copy

DEFINE TEMP-TABLE ttCustomer


LIKE customer

FIELD codigo AS INTEGER.

/* copiar todos os dados da tabela customer para a temp-table */


FOR EACH customer NO-LOCK:

CREATE ttCustomer.
/*
BUFFER-COPY source [ { EXCEPT | USING } field ... ] TO target [ ASSIGN
assign-expression ... ] [ NO-LOBS ] [ NO-ERROR ]

*/
BUFFER-COPY customer
TO ttCustomer
ASSIGN ttCustomer.codigo = customer.custnum.

END.

PAUSE.

FOR EACH ttcustomer:


DISP ttcustomer.custnum ttcustomer.NAME ttcustomer.address
ttcustomer.codigo.
END.

Exemplo de Temp-table com erro 229 - ** Could not find Index <index-name> in table <table>. (229), pois
declaramos um índice na Temp-table, nenhum índice da tabela Customer será incluído, mas forçamos o uso
do índice ContryPost da tabela Customer.

DEFINE TEMP-TABLE ttCustomer


LIKE customer

FIELD codigo AS INTEGER


/* A linguagem progress ABL nao copia nenhum indice da tabela do banco para
a TT */

38
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

INDEX ix_name NAME .

/* copiar todos os dados da tabela customer para a temp-table */


FOR EACH customer NO-LOCK:

CREATE ttCustomer.
/*
BUFFER-COPY source [ { EXCEPT | USING } field ... ] TO target [ ASSIGN
assign-expression ... ] [ NO-LOBS ] [ NO-ERROR ]

*/
BUFFER-COPY customer
TO ttCustomer
ASSIGN ttCustomer.codigo = customer.custnum.

END.

PAUSE.

/*
** Could not find Index CountryPost in table ttCustomer. (229)
** Nao entendi a linha 24. (196)

A linguagem progress ABL nao copia nenhum indice da tabela do banco para a
TT

*/

FOR EACH ttcustomer


USE-INDEX CountryPost:
DISP
ttcustomer.custnum
ttcustomer.NAME
ttcustomer.address
ttcustomer.codigo
WITH STREAM-IO WIDTH 111.
END.
Exemplo de Temp-table com índice único e primário

/* posso fazer like dos campos da TT */


DEFINE TEMP-TABLE ttclientes
FIELD codigo LIKE customer.custnum
FIELD nome LIKE salesre.repname
FIELD endereco LIKE customer.address

INDEX ix_codigo AS UNIQUE AS PRIMARY codigo


.

Datasets
São objetos com uma ou um conjunto de tabelas temporárias, que utilizam um data-source para acessar os
registros no banco de dados através de objetos queries ou através de buffers.

Estes objetos Datasets precisam de tabelas temporárias, e cada uma destas tabelas temporárias precisa de
um data-source para poder carregar seus registros.

39
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

As tabelas temporárias de um dataset também podem salvar suas alterações nas tabelas das quais foram
carregadas.

Sintaxe do Dataset
DEFINE {[[ NEW ] SHARED ]|[ PRIVATE | PROTECTED ] [ STATIC ][
SERIALIZABLE ]}
DATASET dataset-name
[ NAMESPACE-URI namespace][ NAMESPACE-PREFIX prefix]
[ XML-NODE-NAME node-name][ SERIALIZE-NAME serialize-name ]
[ XML-NODE-TYPE node-type ][ SERIALIZE-HIDDEN ][ REFERENCE-ONLY ]
FOR buffer-name [ , buffer-name]...
[ DATA-RELATION [data-rel-name ] FOR data-rel-spec ]...
[ PARENT-ID-RELATION [data-rel-name] FOR parent-id-rel-spec]...

À primeira vista o objeto Dataset é complexo, mas vamos detalhar suas opções e incrementar a sua
complexidade em cada exemplo.

Sintaxe do Datasource
DEFINE [ PRIVATE | PROTECTED ] [ STATIC ] DATA-SOURCE data-source-name
FOR [ QUERY query-name]
[source-buffer-phrase[ , source-buffer-phrase]...]

Receita de bolo para o funcionamento


Eis as receitas...

Dataset com data-source usando buffer


1. Definir a tabela temporária,
2. Definir o dataset, relacionando o buffer da tabela temporária ao dataset,
3. Definir o data-source para acessar os dados do banco através do buffer,
4. Linkar o buffer da tabela temporária ao data-source,
a. Opcionalmente, pode-se usar o atributo Fill-Where-String para usar Where da pesquisa à
tabela,
5. Usar o método FILL do dataset para preencher a tabela temporária.

40
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Dataset com data-source usando query


1. Definir a tabela temporária,
2. Definir o dataset, relacionando o buffer da tabela temporária ao dataset,
3. Definir a query,
a. Preparar a query com a cláusula Where,
b. Abrir a query,
4. Definir o data-source para acessar os dados do banco através da query,
5. Linkar o buffer da tabela temporária ao data-source,
6. Usar o método FILL do dataset para preencher a tabela temporária.

Dataset com uma tabela e usando buffer


DEFINE TEMP-TABLE ttcustomer
LIKE customer.

DEFINE DATASET dts-customer FOR ttcustomer.

DEFINE DATA-SOURCE data-source-customer FOR customer.

BUFFER ttcustomer:ATTACH-DATA-SOURCE( DATA-SOURCE data-source-


customer:handle ).

DATASET dts-customer:FILL().

FOR EACH ttcustomer:


DISPLAY
ttcustomer.custnum
ttcustomer.name
ttcustomer.contact.
END.

Dataset com uma tabela usando query


DEFINE TEMP-TABLE ttitem LIKE sports2000.item.

DEFINE DATASET dts-item FOR ttitem.


DEFINE QUERY qitem FOR sports2000.item.

DEFINE DATA-SOURCE data-source-item FOR QUERY qitem.

/* unir o buffer da tt com o data-source */


BUFFER ttitem:ATTACH-DATA-SOURCE(DATA-SOURCE data-source-item:handle).

QUERY qitem:QUERY-PREPARE("for each item where item.itemnum >= 10 and


item.itemnum <= 15 ").
QUERY qitem:QUERY-OPEN().

/* carregar o dataset */
DATASET dts-item:FILL().

FOR EACH ttitem:


DISPLAY ttitem WITH 1 COL.
END.

Anotações

41
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

42
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercício
Para a nomenclatura dos exercícios, utilize a máscara BF_TT_<número do exercício>.P (BF_TT_1.p,
BF_TT_2.p).

1. Crie uma tabela temporária cópia da tabela customer, copie os dados para esta tabela, exibindo-os
com o For each.
2. Com o For each e Buffer, mostre os campos da tabela pedidos (Order).
3. Crie uma tabela temporária cópia da tabela customer, copie os dados para esta tabela, exibindo-os
com o For each. Localize todos pedidos dos clientes na tabela temporária.
4. Crie uma tabela temporária cópia da tabela customer,
a. Crie um novo índice para o campo custnum.
b. Copie os dados para esta tabela, exibindo-os com o For each e com o uso da cláusula “use-
index Name”.
c. Ocorre erro? Qual? Por quê? Quais as possíveis soluções?
5. No capítulo Importação e Exportação, no quinto exercício, exportamos um arquivo da tabela
salesrep,
a. Crie uma tabela temporária cópia da tabela salesrep, use Like e No-undo,
b. Importe os dados do arquivo para a tabela temporária,
c. Utilize For each para listar os registros importados na tabela temporária.
6. A partir do quinto exercício, substitua a instrução For Each por Open Query, Get e Repeat, exibindo
os registros de forma indistinta ao quinto exercício.

43
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Criação, Atribuição e Eliminação de Registros


Há vários comandos para a manipulação de registros no banco de dados, podemos citar:

• Create e Insert, para inserir registros,


• Delete, para remover registros.

Instrução Create
A instrução Create cria um registro em uma tabela, seja esta uma tabela de banco de dados ou uma tabela
temporária (temp-table, atribui aos campos seus valores iniciais e move o registro para a área de Record
Buffer.

Sintaxe

CREATE record
[ USING { ROWID ( nrow ) | RECID ( nrec ) } ] [ NO-ERROR ]

Exemplo

REPEAT:
CREATE Order.
UPDATE Order.OrderNum Order.CustNum
VALIDATE(CAN-FIND(Customer OF Order), "Customer does not
exist")
Order.CustNum Order.OrderDate.
REPEAT:
CREATE OrderLine.
OrderLine.OrderNum = Order.OrderNnum.
UPDATE OrderLine.LineNum OrderLine.ItemNum
VALIDATE(CAN-FIND(Item OF OrderLine), "Item does not
exist")
OrderLine.Qty OrderLine.Price.
END.
END.
Importante: ao executar a instrução de CREATE o gatilho de CREATE é executado em seguida.

Anotações

Exemplo de Create com verificação de existência de registro

DEF VAR codigoItem LIKE ITEM.itemnum


LABEL 'Codigo item'
NO-UNDO.

REPEAT :

UPDATE codigoItem.

FIND FIRST ITEM NO-LOCK

44
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

WHERE ITEM.itemnum = codigoItem NO-WAIT NO-ERROR.


IF AVAIL ITEM THEN DO:

FIND CURRENT ITEM EXCLUSIVE-LOCK.

/* otimizar o update item, validate e release */


UPDATE ITEM
EXCEPT
ITEM.itemnum
WITH
1 COL
THREE-D
FRAME alterar
TITLE 'Atualizacao de item'.

VALIDATE ITEM.
RELEASE ITEM.
END.
ELSE
IF NOT AVAIL ITEM THEN DO:

CREATE ITEM.
UPDATE ITEM
WITH
1 COL
FRAME inserir
THREE-D
TITLE 'Adiçaõ de item'.

VALIDATE ITEM.
RELEASE ITEM.

END.
ELSE
IF LOCKED ITEM THEN DO:
MESSAGE 'Registro ' codigoItem ' em uso por outro usuario'
VIEW-AS ALERT-BOX
ERROR
BUTTONS OK.
END.

END.

Instrução Insert
A instrução Insert é um conjunto de instruções, como Create, Display, Prompt-for e Assign.

Sintaxe

INSERT record [ EXCEPT field ... ]


[ USING { ROWID ( nrow ) | RECID ( nrec ) } ]
[ frame-phrase ]
[ NO-ERROR ]

Exemplo

45
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

REPEAT:
INSERT Order WITH 1 COLUMN.
REPEAT:
CREATE OrderLine.
OrderLine.OrderNum = Order.OrderNum.
UPDATE OrderLine.LineNum OrderLine.ItemNum OrderLine.Qty
OrderLine.Price.
/* Verify the ItemNum by finding an Item with that number */
FIND Item OF OrderLine.
END.
END.
Importante: Ao executar a instrução de INSERT o gatilho de CREATE é executado.

Anotações

Instrução de Assign
Utilize esta instrução Assign para atribuir a um campo, ou a vários campos de tabelas o valor desejado. Antes
do término da transação o gatilho de WRITE será executado, e estes valores atribuídos serão gravados no
banco quando a transação chegar ao fim, o término da transação pode ser o END de um DO TRANSACTION,
ou de um REPEAT ou de um FOR EACH, dependendo do escopo desta transação.

Instrucao de Update também pode ser utilizada, assim como somente o uso do operador igual “=”

Sintaxe

Exemplo

DEFINE VARIABLE NOME LIKE SALESREP.REPNAME NO-UNDO.

/* Pesquisando e ALTERANDO os registros


DA Tabela Salesrep usando o first para o primeiro registro da tabela = DKP
*/
FOR FIRST salesrep EXCLUSIVE-LOCK
WHERE Salesrep.SalesRep = 'DKP':

ASSIGN
NOME = Salesrep.RepName.

UPDATE nome.
ASSIGN
Salesrep.RepName = nome.

/* PESQUISANDO E ALTERANDO OS REGISTROS DA CUSTOMER IGUAIS A SALESREP


'DKP' */
FOR EACH CUSTOMER EXCLUSIVE-LOCK
OF SALESREP:

DISPLAY

46
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

customer.custnum
customer.name.
UPDATE
Customer.CreditLimit.
END.
END.

Instrução Delete
Elimina o registro do Record Buffer e do banco de dados.

Sintaxe

DELETE record
[ VALIDATE ( condition , msg-expression ) ]
[ NO-ERROR ]

Exemplo

FOR FIRST Customer


WHERE CUSTOMER.CUSTNUM = 5:
DELETE Customer.
END.
Importante: Antes de eliminar o registro da tabela, o gatilho de DELETE é executado, se utilizarmos o
RETURN ERROR é possível parar a eliminação. Vale lembrar que a eliminação do registro está em uma
TRANSAÇÃO e somente ao término desta é que o registro será eliminado.

Anotações

Importante

• Eliminando registros não diminui o tamanho do banco de dados, somente com Dump e Load,
• Se há gatilhos de Delete estas são executadas antes do registro ser eliminado,
o Se ocorrer erro durante a execução da Trigger de Delete ou esta retornar a instrução
“Return ERROR”, o registro não é eliminado.
• Se há validação “Validate” na instrução de Delete e Trigger de Delete, a validação é executada antes
da Trigger.

47
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercício
Para a nomenclatura dos exercícios, utilize a máscara INSDEL_<número do exercício>.P (INSDEL _1.p, INSDEL
_2.p).

1. Utilizando a instrução Create e Update dentro de um Repeat, crie novos registros para a tabela
Customer, o usuário deverá preencher os campos Customer.Name e Customer.SalesRep (BBB, DKP,
DOS, GPE, HXM, JAL, KIK, RDR, SLS são valores válidos para o campo SalesRep),
2. Crie um programa que contenha uma Frame para a entrada de dados, conforme a imagem abaixo.

Adicione variável LIKE customer.custnum, em um Repeat leia o código do cliente e localize-o com o
código informado (find com no-lock) e exiba o nome do cliente na Frame (customer.name).
Verifique se o registro existe (If avail) e com um bloco de Do Transaction use o find current, faça um
exclusive-lock.
Questione o usuário sobre eliminar o registro localizado, conforme a imagem abaixo, se confirmar a

eliminação, remova-o.
3. A partir do segundo exercício, adicione tratamento, se ocorrer erro de Delete Customer, retorne ao
bloco do Repeat. Use opção On Error.
4. A partir do segundo exercício, adicione tratamento para retornar ao Repeat se ocorrer erro de
Delete Customer, use Catch.
5. Crie um programa para,
a. Solicitar um número de cliente (customer.custnum), utilize like,
b. Tente localizar o número do cliente que foi infomado,
i. Se não localizou, informe ao usuário que o registro não existe,
1. Crie um novo, utilize Create e Update.
ii. Se for encontrado, pergunte ao usuário se deseja eliminar,
1. Se confirmado, elimine o registro, utilize Delete.

48
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Interação com registros


Servem para localizar registros (get, find e for each) em tabelas dos bancos de dados, temporárias ou
somente validar a existência (can-find).

Podemos utilizar a instrução FOR, FIND e GET.

Tanto o comando Find, Get e o For, e suas variantes find first, find next e for first, são utilizados para
posicionar o ponteiro em um registro disponibilizando-o para leitura, alteração e eliminação. Para as queries
utilize Get First, Get Next, Get Prev, Get Last, Get Current.

Instrução For
Inicia uma iteração com um novo bloco que lê registros de uma ou mais tabelas, permite adicionar cláusulas
where para filtrar registros, implicitamente cria um novo bloco no programa, este possui tratamento de erro
e escopo de frame, se encerra com o uso da instrução END.

Transferência de Dados
Abaixo está a movimentação de dados que a instrução FOR realiza, trazendo dados do banco de dados para
o RECORD BUFFER.

Estando os dados no RECORD BUFFER, instruções de DELETE, ASSIGN ou DISPLAY poderão trabalhar com os
valores dos campos.

Fluxograma da pesquisa com instruções


É possível realizar um fluxograma com as instruções de pesquisa Find, For Each e Open Query.

49
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Este fluxograma determina a forma de pesquisar usando as instruções do Progress ABL.

For each
Para grande volume de dados com pesquisa ascendente ou descendente de forma sequencial.

For First com Fields


Quando for validar ou utilizar poucos campos de um registro, exemplo, pesquisar se o saldo do cliente é
positivo, retornar o campo nome do cliente, localizar a descrição de um produto.

Find First
Para localizar um único registro para alterar ou eliminar.

Open Query
Para grande volume de dados com pesquisa ascendente ou descendente de forma aleatória, exemplo,
localizar o primeiro registro, o último, o próximo, o penúltimo, o anterior.

Sintaxe for each

[ label: ]
FOR [ EACH | FIRST | LAST ] record-phrase
[ , [ EACH | FIRST | LAST ] record-phrase ] ...
[ query-tuning-phrase ]
[ BREAK ]
[ BY expression [ DESCENDING ]
| COLLATE ( string , strength [ , collation ] ) [ DESCENDING ]

50
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

] ...
[ variable = expression1 TO expression2 [ BY k ] ]
[ WHILE expression ]
[ TRANSACTION ]
[ on-error-phrase ]
[ on-endkey-phrase ]
[ on-quit-phrase ]
[ on-stop-phrase ]
[ frame-phrase ] :
for-body

Principais opções da instrução FOR


Opção Sobre Indicação
EACH Para trazer todos os Os registros trazidos pelo FOR EACH estão à
registros que se disposição para eliminação, atribuição e exibição.
enquadram na cláusula Para eliminação e atribuição é necessário acessar o
where. registro com EXCLUSIVE-LOCK.
Após o bloco de FOR EACH, que se encerra com o
END deste, os registros da interação não estão
disponíveis.
FIRST Para trazer o primeiro Ao contrario do EACH, não faz interação com todos
registo que a cláusula os registros que se enquadram no where, traz
where filtrou. Se não for somente o primeiro. Para atualização ou eliminação
informado cláusula é necessário acessar o registro com EXCLUSIVE-
where trará o primeiro LOCK. Também possui END para encerrar o bloco,
registro atendido pelo mas o registro CONTINUA DISPONÍVEL após o bloco
índice primário. da instrução FOR FIRST.
LAST Para trazer o último Ao contrario do EACH, não faz interação com todos
registo que a cláusula os registros que se enquadram no where, traz
where filtrou. Se não for somente o primeiro. Para atualização ou eliminação
informado cláusula é necessário acessar o registro com EXCLUSIVE-
where trará o primeiro LOCK. Também possui END para encerrar o bloco,
registro atendido pelo mas o registro CONTINUA DISPONÍVEL após o bloco
índice primário. da instrução FOR LAST.
BREAK Para realizar opções de Poderão ser usadas em conjunto com as instruções
quebra. ACCUMULATE e a função ACCUM. Deve ser usada
em conjunto com BY.
BY expressão Para ordenar a interação Se não for informada, a AVM fornece a ordem
[DESCENDING] pelo campo informado. conforme os critérios usados na cláusula WHERE ou
no índice primário. Opcionalmente podemos
adicionar a opção DESCENDING para ordenar pela
forma descendente à informada no BY.
Campos BLOB e CLOB não podem ser inseridos em
cláusulas BY.
TRANSACTION Para explicitar a A AVM iniciará uma transação para cada interação,
transação durante a mesmo que ela não necessite.
interação do bloco.
On Error Para realizar sobrecarga
do tratamento padrão
de ERRO no bloco.
On Endkey Para realizar sobrecarga
do tratamento padrão

51
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

de pressionamento de
tecla ESC no bloco.
On Stop Para realizar a
sobrecarga do
tratamento padrão de
STOP ao bloco.
Frame-phrase O cabeçalho da
instrução de FOR pode
ter opções do FRAME a
ser usado no bloco.

Opções do Record phrase


A instrução FOR é comumente escrita com adaptações na Record phrase, estas opções podem determinar se
todos os campos virão do banco de dados ou se somente alguns, utilizar ou não uma instrução de filtro com
WHERE, informar um índice a ser utilizado com USE-INDEX, determinar o modo como o dado é acesso, se
será com NO-LOCK, SHARE-LOCK ou EXCLUSIVE-LOCK, se a instrução será relacionada com outras tabelas
através de EACH outros EACHs, se estará em transação com a opção TRANSACTION, se poussuirá opções de
ON ERROR, ON ENDKEY ou de ordenação com BY ou de quebra com BREAK.

As opções de Record phrase são uma importante base da instrução FOR.

{ record [ field-list ] }
[ constant ]
[ [ LEFT ] OUTER-JOIN ]
[ OF table ]
[ WHERE expression ]
[ USE-INDEX index ]
[ USING [ FRAME frame ] field
[ AND [ FRAME frame ] field ] ... ]
[ SHARE-LOCK | EXCLUSIVE-LOCK | NO-LOCK ]
[ NO-PREFETCH ]

Principais opções das opções Record Phrase


Opção Sobre Indicação
FIELDS Para determinar quais Pouco usada, mas pode trazer benefício
campos serão trazidos do na performance de programas, pois ao
banco de dados. contrario de trazer centenas de campos
pela rede, pode trazer somente os
campos necessários.
OF tabela Relaciona duas tabelas Para a cláusula OF funcionar é
através de campos em necessário que os campos das tuas
comum. tabelas tenham o mesmo nome e tipo
(caracter, inteiro, decimal...) e que em
uma das tabelas seja índice ÚNICO. Se o
índice ÚNICO for formado por múltiplos
campos, todos os campos participarão
do critério de pesquisa.

52
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

WHERE Permite adicionarmos filtros Provavelmente a cláusula mais usada na


nos registros do banco de programação com ABL. Esta cláusula
dados. pode ser formada por operadores como
igualdade “=”, diferença “<>”, maior que
“>=”, menor que “<=”, BEGINS,
MATCHES, Contains e possuir várias
uniões com a opção AND ou OR.
SHARE-LOCK, NO-LOCK e Para determinar a forma Share-lock é lock compartilhado e não
EXCLUSIVE-LOCK como o registro será deve ser usado pela possibilidade de
acessado. criar Dead-lock.
No-lock para acessar registro sem
travamento, normalmente usado em
relatórios ou programas consulta.
Exclusive-lock para acessar o registro em
modo exclusivo.
USE-INDEX índice Para indicar à AVM qual o Se não for usada, a AVM selecionará um
índice a ser utilizado na índice a ser usado baseado na cláusula
pesquisa. WHERE, USING e OF.
Exemplo

FOR EACH customer NO-LOCK:


DISPLAY NAME.
END.

Anotações

For Each com Where


Exemplo com cláusula Where

FOR EACH customer NO-LOCK


WHERE customer.custnum = 5:
DISPLAY
customer.custnum
customer.NAME.
END.

Anotações

For Each com By


Exemplo com cláusula By

53
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

FOR EACH customer NO-LOCK


WHERE customer.custnum >= 5
BY CUSTOMER.NAME:
DISPLAY
customer.custnum
customer.NAME.
END.

Anotações

For each com várias tabelas


Exemplo com várias tabelas

/* clientes de 5 até 10 */
FOR EACH customer NO-LOCK
WHERE customer.custnum >= 5
AND customer.custnum <= 10
BY customer.NAME:
DISPLAY
customer.custnum
customer.NAME.

/* pedidos do cliente */
FOR EACH order NO-LOCK
WHERE order.custnum = customer.custnum:

DISPLAY
order.ordernum
order.orderdate.

/* linhas do pedido do cliente */


FOR EACH orderline NO-LOCK
WHERE orderline.ordernum = order.ordernum:

DISPLAY
orderline.itemnum
orderline.qty.

END.
END.
END.

Anotações

For Each Encadeado com Várias Tabelas


/* clientes de 5 até 10 */
FOR EACH customer NO-LOCK

54
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

WHERE customer.custnum >= 5


AND customer.custnum <= 10,
EACH order NO-LOCK
WHERE order.custnum = customer.custnum,
EACH orderline NO-LOCK
WHERE orderline.ordernum = order.ordernum

BY customer.NAME:

DISPLAY
customer.custnum
customer.NAME
order.ordernum
order.orderdate
orderline.itemnum
orderline.qty
WITH STREAM-IO.

END.

For Each Encadeado com Fields


/* clientes de 5 até 10 */
FOR EACH customer
FIELDS(custnum NAME)
NO-LOCK
WHERE customer.custnum >= 5
AND customer.custnum <= 10,
EACH order
FIELDS(ordernum orderdate)
NO-LOCK
WHERE order.custnum = customer.custnum,
EACH orderline
FIELDS(itemnum qty)
NO-LOCK
WHERE orderline.ordernum = order.ordernum

BY customer.NAME:

DISPLAY
customer.custnum
customer.NAME
order.ordernum
order.orderdate
orderline.itemnum
orderline.qty
WITH STREAM-IO.

END.

Instrução For First e For Last


Instruções For com a opção First e Last são úteis para localizar os primeiros ou últimos registros, outra
vantagem que torna esta instrução única, se comparada com For, é o fato dos registros continuarem
disponíveis após o END.

Exemplo For First

FOR FIRST ITEM NO-LOCK


WHERE ITEM.itemnum = 10:

55
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

END.

IF AVAILABLE ITEM THEN


DISPLAY
ITEM.itemnum
ITEM.itemname
ITEM.price.

Anotações

Instrução Find
Localiza um único registro de uma tabela e o move para a área de record buffer. Deve ser usado para
alteração ou eliminação de registro.

Sintaxe find

FIND [ FIRST | LAST | NEXT | PREV ] record


[ constant ]
[ OF table ]
[ WHERE expression ]
[ USE-INDEX index ]
[ USING [ FRAME frame ] field
[ AND [ FRAME frame ] field ] ...
]
[ SHARE-LOCK | EXCLUSIVE-LOCK | NO-LOCK ]
[ NO-WAIT ]
[ NO-PREFETCH ]
[ NO-ERROR ]

e…

FIND CURRENT record


[ SHARE-LOCK | EXCLUSIVE-LOCK | NO-LOCK ]
[ NO-WAIT ]
[ NO-ERROR ]

A instrução Find não permite pesquisas com mais de uma tabela como o For Each e a Query.

Movimentação de registro

Principais Opções do Find


Opção Sobre Indicação

56
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

FIRST Para trazer o primeiro


registro que atenda a cláusula
WHERE.
LAST Para trazer o último registro
que atenda a cláusula
WHERE.
NEXT Para trazer o próximo registro
que atenda a cláusula
WHERE.
PREV Para trazer o registro anterior
que atenda a cláusula
WHERE.
OF tabela Relaciona duas tabelas Para a cláusula OF funcionar é
através de campos em necessário que os campos das tuas
comum. tabelas tenham o mesmo nome e tipo
(caracter, inteiro, decimal...) e que em
uma das tabelas seja índice ÚNICO. Se o
índice ÚNICO for formado por múltiplos
campos, todos os campos participarão
do critério de pesquisa.
WHERE Permite adicionarmos filtros Provavelmente a cláusula mais usada na
nos registros do banco de programação com ABL. Esta cláusula
dados. pode ser formada por operadores como
igualdade “=”, diferença “<>”, maior que
“>=”, menor que “<=”, BEGINS,
MATCHES, Contains e possuir várias
uniões com a opção AND ou OR.
SHARE-LOCK, NO-LOCK e Para determinar a forma Share-lock é lock compartilhado e não
EXCLUSIVE-LOCK como o registro será deve ser usado pela possibilidade de
acessado. criar Dead-lock.
No-lock para acessar registro sem
travamento, normalmente usado em
relatórios ou programas consulta.
Exclusive-lock para acessar o registro em
modo exclusivo.
USE-INDEX índice Para indicar à AVM qual o Se não for usada, a AVM selecionará um
índice a ser utilizado na índice a ser usado baseado na cláusula
pesquisa. WHERE, USING e OF.
NO-WAIT Faz a instrução FIND retornar Deve ser usado em conjunto com a
caso o registro esteja em uso função LOCKED e função AVAILABLE para
por outro usuário. determinar se o registro está em uso ou
não foi localizado.
NO-ERROR Evitar a exibição de ERRO Comumente usada para não exibir a
quando não localiza o mensagem que ** FIND FIRST/LAST
registro. failed for table . (565)
Exemplo

FIND LAST customer NO-LOCK NO-ERROR.


IF AVAIL customer THEN

57
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

DISP custnum NAME.

Anotações

Analisando pontos fortes e fracos


Descrição Find For Each For First Open Qurery
Indicado para Localizar Para localizar Para localizar Para localizar
registro para grande um registro de grande
alteração e quantidade de uma ou várias quantidade de
eliminação registros de tabelas, registros de uma
uma ou várias usando opção ou várias
tabelas, quando Fields para tabelas, e
a pesquisa poder validar quando a
unidirecional o valor dos pesquisa
(ascendente ou campos da aleatória é
descendente) e Felds. obrigatória.
irrelevante.
Pesquisa com Não Sim Sim Sim
mais de uma
tabela?
Indicado para Sim Não (se a Sim Não (se a
alteração de um localização for localização for
registro? para mais de para mais de um
um registro) registro)
Cuidado Para não tornar Para não varrer Não Para não varrer
o bloco de a tabela inteira. a tabela inteira.
instruções do Para usar fields Para usar fields
find em uma para campos a, para campos a, b
transação. Se b e c e trabalhar e c e trabalhar
for o bloco que com campos d, com campos d,
contém o find e, f... e, f...
for o programa, Para construir o Para construir o
todo o where e a where e a
programa pode relação entre as relação entre as
se tornar uma tabelas. tabelas.
transação Para alterações
demorada. não
transformarem
todo o programa
em uma
transação.
Usa índices? Sim Sim Sim Sim
Permite By Não Sim Sim Sim

58
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Permite Fields? Não Sim Sim Sim (mas a query


deve ser
definida)
Serve para Sim Sim Sim Sim
eliminar
registro?
Transação Não, mas com o Sim Sim Não
protegida em um Do Transaction
bloco? resolve.
Dica Use sempre Cuidado com as Use sempre Cuidado com as
Find First. cláusulas where que possível cláusulas where
eo com o Fields eo
relacionamento para validar relacionamento
entre as conteúdo de entre as tabelas.
tabelas. campos. Cuidado com as
transações.

Instrução Get
Disponibiliza um registro no record buffer de uma query, mas deve ser usada com a Open Query.

Sintaxe Get

GET { FIRST | NEXT | PREV | LAST | CURRENT } query


[ SHARE-LOCK | EXCLUSIVE-LOCK | NO-LOCK ]
[ NO-WAIT ]

A instrução GET pode realizar o lock de um registro, mas se não for especificado nenhum, este utilizará o
mesmo lock utilizado na instrução OPEN QUERY.

Exemplo

OPEN QUERY qcust FOR EACH Customer NO-LOCK.

GET FIRST qcust.

DO WHILE AVAILABLE Customer:


DISPLAY Customer.CustNum Customer.Name .

GET NEXT qcust.


END.

Open Query
Abre uma query que pode ter sido definida, disponibilizando os registros desta consulta através da instrução
GET.

Sintaxe Open Query

OPEN QUERY query { FOR | PRESELECT } EACH record-phrase


[ , { EACH | FIRST | LAST } record-phrase ] ...
[ query-tuning-phrase ]

59
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

[ BY expression [ DESCENDING ]
| COLLATE ( string , strength [ , collation ] ) [ DESCENDING ]
] ...
[ INDEXED-REPOSITION ]
[ MAX-ROWS num-results ]

record
[[ LEFT ]] [ OF table ]
[ WHERE expression ]
[ USING [ FRAME frame ] field
[ AND [ FRAME frame ] field ] ... ]
[ USE-INDEX index ]
[ SHARE-LOCK | EXCLUSIVE-LOCK | NO-LOCK ]
[ NO-PREFETCH ]

QUERY-TUNING
(
[ LOOKAHEAD [ CACHE-SIZE integer ] | NO-LOOKAHEAD ]
[ DEBUG { SQL | EXTENDED } | NO-DEBUG ]
[ SEPARATE-CONNECTION | NO-SEPARATE-CONNECTION ]
[ JOIN-BY-SQLDB | NO-JOIN-BY-SQLDB ]
[ BIND-WHERE | NO-BIND-WHERE ]
[ INDEX-HINT | NO-INDEX-HINT ]
)

Exemplo

DEFINE QUERY q-order FOR


customer FIELDS (customer.cust-num customer.name
customer.phone),
order FIELDS (order.order-num order.order-date),
order-line FIELDS (order-line.line-num order-line.price
order-line.qty),
item FIELDS (item.item-num item.item-name item.cat-desc).

OPEN QUERY q-order FOR EACH customer,


EACH order OF customer,
EACH order-line OF order,
EACH item OF order-line NO-LOCK.

GET FIRST q-order.

DO WHILE AVAILABLE(customer):

DISPLAY customer.cust-num
customer.name SKIP
customer.phone SKIP

60
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

order.order-num order.order-date SKIP


order-line.line-num
order-line.price order-line.qty SKIP
item.item-num item.item-name SKIP
item.cat-desc VIEW-AS EDITOR SIZE 50 BY 2 SCROLLBAR-
VERTICAL
WITH FRAME ord-info CENTERED SIDE-LABELS TITLE "Order
Information".

/* Allow scrolling, but not modification, of cat-desc. */


ASSIGN
item.cat-desc:READ-ONLY IN FRAME ord-info = TRUE
item.cat-desc:SENSITIVE IN FRAME ord-info = TRUE.
PAUSE.
GET NEXT q-order.
END. /* DO WHILE AVAIL(customer) */

Anotações

Exemplo de Open Query para Query não definida

OPEN QUERY qSalesrep


FOR EACH salesrep NO-LOCK
WHERE salesrep.salesrep BEGINS 'd',
EACH customer NO-LOCK OF salesrep.

GET FIRST qSalesrep.


REPEAT WHILE AVAILABLE salesrep:

DISPLAY
Salesrep.SalesRep
Salesrep.RepName
Salesrep.Region
WITH
TITLE 'Lista de representantes'
FRAME frameSalesRep.

DISPLAY
Customer.CustNum
Customer.Name
Customer.Phone
WITH
1 COL
TITLE 'Clientes do representante'.

GET NEXT qSalesrep.


END.

Exemplo de Open query com Get e Exclusive-lock

OPEN QUERY qItem


FOR EACH ITEM NO-LOCK
WHERE ITEM.itemnum > 5
AND ITEM.itemnum < 10.

61
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

GET FIRST qItem EXCLUSIVE-LOCK.

REPEAT WHILE AVAILABLE ITEM:

DISPLAY
Item.Itemnum
Item.ItemName
Item.Price.

GET NEXT qItem EXCLUSIVE-LOCK.


END.

Uso da função Can-find


A função can-find somente deverá ser usada para testar a existência do registro. A função can-find não
posiciona o ponteiro no registro e não há como fazer leitura, alteração e eliminação.

Sintaxe can-find

CAN-FIND
(
[ FIRST | LAST ] record [ constant ]
[ OF table ] [ WHERE expression ] [ USE-INDEX index ]
[ USING [ FRAME frame ] field
[ AND [ FRAME frame ] field ] ...
]
[ SHARE-LOCK | NO-LOCK ] [ NO-WAIT ] [ NO-PREFETCH ]
)

Exemplo

FOR EACH customer NO-LOCK:


IF NOT CAN-FIND(FIRST salesrep
WHERE Salesrep.SalesRep = customer.salesrep) THEN
DISPLAY customer.custnum.

DISPLAY NAME.
END.

Anotações

Locks de registros
A linguagem possui três formas de “acessar” o registro durante o Find, For e Get:

• Exclusive-lock,
• Share-lock,
• No-lock,

Exclusive-lock
Acessa o registro em modo exclusivo, não permitindo que outros usuários acessem em modo exclusivo
(concorrente exclusive-lock ou share-lock). Permitindo eliminar, alterar e visualizar.

62
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Share-lock
Acessa o registro em modo não exclusivo, permitindo que o “lock” evolua para Exclusive-lock caso ocorra
alteração no bloco corrente. Não utilize com Oracle, pois além do Oracle não ter o Share-lock real, forçara a
linguagem a encontrar o mesmo registro duas vezes.

No-lock
Acessa o registro sem travar o registro, mesmo que outro usuário esteja com Exclusive-lock, e não permite a
alteração. Use sempre que não for realizar alterações.

Recomendação! Use No-lock ou Exclusive-lock.

Anotações

Usando No-lock e Exclusive-lock


DEFINE VARIABLE codigo LIKE customer.custnum.

REPEAT:
UPDATE codigo.

/* pesquisar o primeiro cliente com o codigo informado */


FIND FIRST customer NO-LOCK
WHERE customer.custnum = codigo NO-ERROR.
IF AVAILABLE customer THEN
DO TRANSACTION:
/* pesquisa o cliente no Record buffer e
muda o lock para Exclusivo */
FIND CURRENT customer EXCLUSIVE-LOCK.
/* ler o novo nome */
UPDATE customer.NAME.
/* liberar o registro do record buffer */
RELEASE customer.
/* após o comando Release,
o registro pesquisado não está mais disponível
*/
END.
END.

63
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercício
Para a nomenclatura dos exercícios, utilize a máscara FND_FRE_<número do exercício>.P (FND_FRE_1.p,
FND_FRE_2.p).

1. Localize todos os clientes do representante (salesrep) DKP. Utilize a opção Of.


2. Localize todos os clientes do representante (salesrep) DOS. Utilize a opção Where.
3. Localize todos os clientes do representante (salesrep) DKP. Utilize a opção Of com um único For
Each.
4. Localize todos os clientes do representante (salesrep) DOS. Utilize a opção Where com um único For
Each.
5. Localize todos os clientes do representante (salesrep) DKP. Utilize a opção Of. Exiba o nome do
representante e o seu código (salesrep.salesrep, salesrep.repname). Informe o título Representante
para o frame salesrep e Cliente para o frame customer.
6. Localize todos os clientes do representante (salesrep) DKP. Utilize a opção Of. Exiba o nome do
representante e o seu código (salesrep.salesrep, salesrep.repname) no frame Representante e
centralize-a, mostre o campo salesrep.region no frame customer.
7. Crie um programa e simule o Dead-lock com Share-lock, necessário abrir duas sessões com o Editor
conectado ao mesmo banco.

Exercicios Complementares For Each


Segue lista de exercícios para FOR EACH, salve cada um como FOR_EACH_1.p, FOR_EACH_2.p e assim por
diante.

1. Solicitar o código do cliente, procurar o cliente que o usuário digitar e mostrar os


campos customer.custnum customer.NAME customer.address
customer.salesrep. Utilize Repeat, For FIRST, Update e Display. Tabela customer

64
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

2. Solicitar o código do cliente, procurar o cliente que o usuário digitar e mostrar


seus dados customer.custnum customer.NAME customer.creditlimit.
Para cada pedido do cliente exibir order.ordernum order.orderdate
Order.OrderStatus Order.ShipDate, usar clausula where. Utilize Repeat, For
FIRST, FOR EACH para ORDER, Update e Display.
Tabelas customer e order

3. Solicitar o codigo do cliente, localizar o primeiro cliente (For First)


que o usuario digitar e mostrar seus dados customer.custnum customer.NAME
customer.creditlimit.
Para cada pedido do cliente exibir os campos order.ordernum order.orderdate
Order.OrderStatus Order.ShipDate.
Para cada linha do pedido, exibir os campos OrderLine.Linenum
OrderLine.Itemnum OrderLine.Qty OrderLine.Price
Usar repeat, update, for first, for each e display.
Tabelas customer, order e orderline

65
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

4. Solicitar o numero do pedido, utilizar o for first e mostrar Order.Ordernum


Order.OrderDate Order.CustNum Order.SalesRep
Usar like para o campo numero do pedido, repeat, for first e display
Tabela order

66
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

5. Solicitar o numero do pedido, utilizar o for first e mostrar Order.Ordernum


Order.OrderDate Order.CustNum Order.SalesRep
Localizar o cliente (customer) atraves do campo order.custnum e mostrar seu
nome e telefone de contato (customer.NAME customer.phone)
Usar like para o campo numero do pedido, repeat, for first, first customer e display
tabelas order e customer

6. Solicitar o numero do pedido, utilizar o for first e mostrar Order.Ordernum


Order.OrderDate Order.CustNum Order.SalesRep
Localizar o cliente (customer) atraves do campo order.custnum e mostrar seu
nome e telefone de contato (customer.NAME customer.phone)
Localizar o representante do pedido pelo campo order.salesrep e mostrar o nome
daquele (salesrep.repname)
Usar like para o campo numero do pedido, repeat, for first, first customer e
display
Tabelas order, customer e salesrep

67
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

7. Solicitar o numero do pedido, utilizar o for first e mostrar Order.Ordernum


Order.OrderDate Order.CustNum Order.SalesRep
localizar todos as linhas do pedido (orderline) exibindo OrderLine.Linenum
OrderLine.Itemnum OrderLine.Qty OrderLine.Price OrderLine.Discount
Tabelas order, orderline

68
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

8. Solicitar o numero do pedido, utilizar o for first e mostrar Order.Ordernum


Order.OrderDate Order.CustNum Order.SalesRep
Localizar todos as linhas do pedido (orderline) exibindo OrderLine.Linenum
OrderLine.Itemnum OrderLine.Qty OrderLine.Price OrderLine.Discount
Localizar o item de cada linha do pedido (first item) e exibir o nome deste
Tabelas order, orderline e item

9. Solicitar o numero do pedido, utilizar o for first e mostrar Order.Ordernum


Order.OrderDate Order.CustNum Order.SalesRep
Localizar todos as linhas do pedido (orderline) exibindo OrderLine.Linenum
OrderLine.Itemnum OrderLine.Qty OrderLine.Price OrderLine.Discount
Exibir o total da linha do pedido que tem a seguinte formula = quantidade
(OrderLine.Qty) multiplicado pelo preco (OrderLine.Price) subtraindo o percentual
(OrderLine.Discount)
Para verificar se o valor total está calculado corretamente, veja o valor do campo
OrderLine.ExtendedPrice
Tabelas order, orderline

69
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

10. Solicitar o numero do item e mostrar os pedidos, data do pedido, nome do cliente
e nome do vendedor que este item se encontra.
Usar Like, repeat, update, for each, display e first
Tabelas orderline, order, customer e salesrep
Exibir Order.Ordernum Order.CustNum customer.NAME Order.OrderDate
Order.SalesRep salesrep.repNAME

70
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

11. Solicitar o codigo do representante, exibir os campos Salesrep.SalesRep


Salesrep.RepName.
Localizar cada cliente deste representante, exibir os campos Customer.CustNum
Customer.Name Customer.CreditLimit Customer.Contact e customer.phone.
tabelas salesrep e customer
Usar like, update, repeat, for first, for each
Codigos de representantes disponiveis para consulta
BBB
DKP
DOS
GPE
HXM
JAI
JAL
KIK
RDR
SLS

71
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

12. Solicitar o codigo do representante, exibir os campos Salesrep.SalesRep


Salesrep.RepName.
Localizar cada pedido deste representante, exibir os campos Order.Ordernum
Order.OrderDate.
Localizar os clientes de cada pedido, mostrando o código e o nome deste cliente.
tabelas order, salesrep e customer
Usar like, update, repeat, for first, for each
Codigos de representantes disponiveis para consulta
BBB
DKP
DOS
GPE
HXM
JAI
JAL
KIK
RDR
SLS

72
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

13. Solicitar duas datas de pedidos aos usuarios e exibir os campos pedidos entre
estas datas Order.OrderDate Order.Ordernum Order.OrderStatus Order.CustNum.
Usar like, repeat, update, for each e display
tabela order
As datas dos pedidos estao entre os meses de setembro de 1997 e março de 1998

73
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

14. Solicitar duas datas de pedidos e o nome do cliente, exibir os campos


(Order.OrderDate Order.Ordernum Order.OrderStatus Order.CustNum
Customer.Name) dos pedidos entre estas datas e que o nome do cliente inicie com
o nome digitado.
Usar like, repeat, update, for each e display
tabela order, customer
usar like, repeat, update, for each, first customer e begins

15. Localizar todos os pedidos, para cada pedido mostrar o total deste, exibir tambem
o nome do cliente e as linhas dos pedidos
Usar for each, first customer, for each orderline

74
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

16. Localizar todos os pedidos, para cada pedido mostrar o total deste, exibir tambem
o nome do cliente e as linhas dos pedidos
Usar for each, first customer, for each orderline
usar a opcao TOTAL para a quantidade e para o campo OrderLine.ExtendedPrice,
proibido o uso de variaveis para acumular

Para a tabela pedidos exibir order.ordernum order.custnum customer.NAME


order.orderdate
Para a tabela orderline exibir OrderLine.Linenum OrderLine.Qty OrderLine.Price
OrderLine.ExtendedPrice

75
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercícios complementares de Open Query


1. Ler código inicial e final do cliente (customer), usar like, e com uso de open query listar todos os
clientes que se encaixam na faixa informada. Exiba custnum, name e creditlimit.

2. A partir do primeiro exercício, crie mais uma query para listar os pedidos do cliente, use clausulas
where para realizar a junção entre as duas tabelas.

76
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

3. A partir do segundo exercício, crie uma alteração para listar as linhas do pedido em uma outra
frame, listando linenum, itemnum, qty, price e extentedprice. Use clausula where para realizar a
junção entre as tabelas.

4. A partir do terceiro exercício, totalize a coluna extendedprice.

77
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

5. A partir do quarto exercício, exiba o total do campo extendedprice, das linhas do pedido, na frame
da order, como segue abaixo.

6. A partir do quinto exercício, conte a quantidade de pedidos e exiba esta contagem na frame do
cliente, conforme abaixo.

78
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

79
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Gatilhos do banco de dados


Gatilhos são eventos das tabelas do dicionário, como criação, atribuição e eliminação que executarão
programas Progress ABL, na camada 4GL.

Como são programas Progress ABL, eles devem estar visíveis pelo PROPATH, ou então exceções ocorrerão e
isso não queremos.

Na camada Progress ABL há gatilhos para Create, Delete, Find, Write, Replication-create, Replication-delete
e Replication-write:

Create
Quando ocorre a criação de registro em uma tabela através da instrução Create, Insert ou do método de
Buffer-Create.

Delete
Quando ocorre a eliminação do registro, seja pela instrução Delete ou pelo método Buffer-Delete.

Find
Quando um registro da tabela é lido pelo gerenciador do banco de dados disparado pelo FIND ou FOR EACH

Write
Ocorre quando um registro é validado no banco de dados, seja pela instrução VALIDATE, RELEASE ou
BUFFER-VALIDADE e ou BUFFER-RELEASE.

Replication-create
Quando ocorre a criação do registro através do Create, Insert ou do método Buffer-Create e após a gravação
no log de alteração. Para facilitar, após a execução do gatilho de Create.

Replication-delete
Quando ocorre a eliminação do registro, seja pelo uso do Delete ou pelo Buffer-Delete, e ao gravar a
informação no log de alteração. Após a execução do gatilho de Delete.

Replication-write
Após a efetivação da gravação do registro e da gravação do log de alteração. Após a execução do gatilho de
Write.

Retorno de Erro e cancelamento da execução


É possível utilizar a instrução RETURN ERROR para cancelar a execução do gatilho, no caso do gatilho de
Write o registro não será salvo, para o Delete o registro não será eliminado.
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Variáveis e tipos de dados


São áreas da memória que armazenam dados temporariamente.

Sintaxe

DEFINE {[[ NEW [ GLOBAL ]] SHARED ]|


[ PRIVATE | PROTECTED | PUBLIC ]
[ STATIC ][ SERIALIZABLE ]}
VARIABLE variable-name
{{ AS primitive-type-name
| AS [ CLASS ]{object-type-name}
| LIKE field }[ EXTENT [constant]]}
[ BGCOLOR expression]
[ COLUMN-LABEL label]
[ CONTEXT-HELP-ID expression]
[ DCOLOR expression]
[ DECIMALS n]
[ DROP-TARGET ]
[ FONT expression]
[ FGCOLOR expression]
[ FORMAT string]
[ INITIAL
{ constant |{[ constant[ , constant]...]}}]
[ LABEL string[ , string]...]
[ MOUSE-POINTER expression]
[ NO-UNDO ]
[[ NOT ] CASE-SENSITIVE ]
[ PFCOLOR expression]
{[ view-as-phrase ]}
{[ trigger-phrase ]}

Tipos de variáveis
CHARACTER | COM-HANDLE | DATE | DATETIME | DATETIME-TZ | DECIMAL
| HANDLE | INT64 | INTEGER | LOGICAL | LONGCHAR | MEMPTR | RAW | RECID* |
ROWID

Tipos primitivos da linguagem ABL


BLOB Binary Large Objects, válido para campos do banco de dados e
para tabelas temporárias. Para ser manipulado precisa de
variáveis tipo MEMPTR.
CHARACTER Conjunto de caracteres em geral, como letras, caracteres
especiais e números.
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

CLOB Character Large Objects, válido para campos do banco de dados e


para tabelas temporárias. Para ser manipulado deve-se utilizar
variáveis do tipo LONGCHAR.
COM-HANDLE É um manipulador para objetos COM (Activex Automation Object
ou Activex Control).
DATE Para tratar campos data.
DATETIME Composto por duas partes para tratar data e tempo, sendo tempo
os milissegundos desde a meia-noite.
DATETIME-TZ Composto por três partes para tratar a data, o tempo e um inteiro
representando o fuso horário.
DECIMAL Para tratar números decimais com até 50 posições, incluindo até
10 posições para a parte decimal.
HANDLE É um ponteiro para objetos da linguagem ABL.
INT64 Um inteiro de 64 bits.
INTEGER Um inteiro de 32 bits.
LOGICAL Para tratar valores lógicos com YES e NO ou TRUE e FALSE.
LONGCHAR Tipo character que não está limitado a 32 K. Use para tratar
campos CLOB do banco ou de tabelas temporários.
MEMPTR Uma sequência de bytes na memória, pode ser usado para tratar
campos BLOB do banco ou em tabelas temporárias, e para tratar
variáveis passadas como referência em DLLs ou Bibliotecas
Dinâmicas.
RAW Pode ser qualquer tipo de dado, este tipo não tem conversão.
RECID Identificador único de registros em banco de dados ou em tabelas
temporárias, é do tipo inteiro e somente mantido por questões
de retro compatibilidade.
ROWID Identificador único de registros em banco de dados ou em tabelas
temporárias no formato Hexadecimal,
WIDGET-HANDLE É um ponteiro para objetos da linguagem ABL somente mantido
por questões de retro compatibilidade.

Exemplos
DEFINE VARIABLE CONTADOR AS INTEGER NO-UNDO.
DEFINE VARIABLE NOME AS CHARACTER NO-UNDO.
DEFINE VARIABLE TEXTO_LONGO AS LONGCHAR NO-UNDO.
DEFINE VARIABLE DIA-HOJE AS DATE NO-UNDO.
DEFINE VARIABLE AGORA AS DATETIME NO-UNDO.
DEFINE VARIABLE VALOR_REAL AS DECIMAL NO-UNDO.
DEFINE VARIABLE INTEIRO_LONGO AS INT64 NO-UNDO.
DEFINE VARIABLE ESCOLHA AS LOGICAL NO-UNDO.

DEFINE VARIABLE SOBRENOME AS CHARACTER NO-UNDO


LABEL 'Sobrenome'.
DEFINE VARIABLE NOME-MEIO AS CHARACTER NO-UNDO
LABEL 'Nome do Meio'
FORMAT 'x(40)'.
DEFINE VARIABLE OBSERVACAO AS CHARACTER NO-UNDO
LABEL 'Observação'
FORMAT 'x(500)'
VIEW-AS EDITOR
INNER-CHARS 50
INNER-LINES 5
LARGE.
DEFINE VARIABLE SEQUENCIA AS INTEGER NO-UNDO

82
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

LABEL 'Sequencia'
FORMAT '9,999,999'.
DEFINE VARIABLE VALOR_MOEDA AS DECIMAL NO-UNDO
LABEL 'Moeda'
FORMAT 'R$ >>>,>>>,>>9.99'.
DEFINE VARIABLE VERDADEIRO AS LOGICAL NO-UNDO
LABEL 'Verdadeiro'
FORMAT 'Verdadeiro/Falso'.
DEFINE VARIABLE ESTADO_PORTA AS LOGICAL NO-UNDO
LABEL 'Estado da Porta'
FORMAT 'Aberta/Fechada'.
DEFINE VARIABLE ASTERISCO AS LOGICAL NO-UNDO
LABEL 'Marcado?'
FORMAT '*/'.

Anotações

Rótulos
Variáveis em linguagem ABL têm rótulos que são exibidos aos usuários:

1. COLUMN-LABEL, quando a visualização da variável na FRAME é em colunas,


2. LABEL, que será exibido na FRAME ao lado da variável.

Exemplo do LABEL

DEFINE VARIABLE credit-percent AS INTEGER


label “Percentual de Crédito”
column-label “Percentual!de Crédito”.

DISP credit-percent WITH SIDE-LABELS.

Resultando em:

Exemplo do COLUMN-LABEL

83
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

DEFINE VARIABLE credit-percent AS INTEGER


label "Percentual de Crédito"
column-label "Percentual!de Crédito".

DISP credit-percent.

Resultando em:

Anotações

Formato padrão
A linguagem ABL utiliza formatos para exibir os valores de campos de banco de dados, tabelas temporárias e
variáveis. Esta formatação pode-se manipulada tanto na declaração de uma Frame quanto durante o Display
desta.

Importante: O formato não altera a quantidade de dados que podem ser armazenados em uma variável.
Mesmo uma variável inteira com o formato ‘99’ ainda pode armazenar o valor inteiro de 32 Bits.

BLOB Não pode ser exibido com Display diretamente, somente com
conversão.
CHARACTER X(8)
CLOB Não pode ser exibido com Display diretamente, somente com
conversão.
COM-HANDLE >>>>>>9
DATE 99/99/99
DATETIME 99/99/9999 HH:MM:SS.SSS
DATETIME-TZ 99/99/9999 HH:MM:SS.SSS+HH:MM
DECIMAL ->>,>>9.99
HANDLE >>>>>>9
INT64 ->,>>>,>>9
INTEGER ->,>>>,>>9
LOGICAL yes/no
LONGCHAR Não pode ser exibido com Display diretamente, somente com
conversão.

84
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

MEMPTR Não pode ser exibido com Display diretamente, somente com
conversão.
RAW Não pode ser exibido com Display diretamente, somente com
conversão.
RECID >>>>>>9
ROWID Não pode ser exibido com Display diretamente, somente com
conversão.

Anotações

Valores iniciais
Variáveis podem ter valores iniciais, basta atribuir um valor para a opção INITIAL.

DEFINE VARIABLE credit-percent AS INTEGER INITIAL 20.

DISP credit-percent.

Tabela de valores iniciais


CHARACTER “” caracter vazio
COM-HANDLE ? desconhecido
DATE ? desconhecido
DATETIME ? desconhecido
DATETIME-TZ ? desconhecido
DECIMAL 0
HANDLE ? desconhecido
INT64 0
INTEGER 0
LOGICAL No
LONGCHAR ? desconhecido
MEMPTR Sequencia de bytes com tamanho zero
RAW Sequencia de bytes com tamanho zero
RECID ? desconhecido
ROWID ? desconhecido

Anotações

Variáveis multidimensionais ou vetores


A linguagem ABL permite variáveis com vetores, adicione a opção EXTENT.

85
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

DEFINE VARIABLE credit-percent AS INTEGER


Extent 5
INITIAL 20.

DISP credit-percent.

Para exibir somente um valor da variável com vetor, informe o índice do vetor entre [].

DEFINE VARIABLE credit-percent AS INTEGER


Extent 5
INITIAL 20.

DISP credit-percent[3].

Anotações

86
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Opção No-Undo
A opção no-undo informa à ABL que a variável ou temp-table não precisa ter seu valor armazenado se ela
fizer parte de um bloco em transação ou tenha seu valor desfeito quando esta transação também for
desfeita.

Importante: use sempre que possível a opção No-Undo.

Anotações

Visualização De Variáveis Como Objetos


A linguagem ABL permite atribuir uma visualização de objetos para as variáveis, estes objetos podem ser
Caixas de Combinação, caixa grande de digitação de texto, caixa de digitação de texto, botões de rádio, lista
de seleção, botão de deslizar, texto, caixa de marcação.

Algumas visualizações permitem todos os tipos de variáveis, outros somente tipos inteiros.

Caixas De Combinação Todos os tipos de variáveis.


Editor Variáveis do tipo Character e LongChar.
Fill-in Character, Int64, Integer, Decimal, Date, Datetime,
Datetime-Tz E Logical.
Radio-set Character, Int64, Integer, Decimal, Date e Logical.
Selection-list Character
Slider Inteiro
Text Character, Int64, Integer, Decimal, Date e Logical.
Toggle-box Logical.

Sintaxe da Caixa de combinação

VIEW-AS COMBO-BOX
[ LIST-ITEMS item-list | LIST-ITEM-PAIRS item-pair-list ]
[ INNER-LINES lines ] [ size-phrase ] [ SORT ]
[ TOOLTIP tooltip ]
[ SIMPLE | DROP-DOWN | DROP-DOWN-LIST ]
[ MAX-CHARS characters ]
[ AUTO-COMPLETION [ UNIQUE-MATCH ] ]

Sintaxe da Caixa Grande de Digitação de Texto

EDITOR
{ size-phrase

87
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

| INNER-CHARS char INNER-LINES lines


}
[ BUFFER-CHARS chars ]
[ BUFFER-LINES lines ]
[ LARGE ]
[ MAX-CHARS characters ]
[ NO-BOX ]
[ NO-WORD-WRAP ]
[ SCROLLBAR-HORIZONTAL ]
[ SCROLLBAR-VERTICAL ]
[ TOOLTIP tooltip ]

Sintaxe Botões de Rádio

RADIO-SET
[ HORIZONTAL [ EXPAND ] | VERTICAL ]
[ size-phrase ]
RADIO-BUTTONS label , value [ , label, value ... ]
[ TOOLTIP tooltip ]

Sintaxe Lista de Seleção

SELECTION-LIST
[ SINGLE | MULTIPLE ]
[ NO-DRAG ]
[ LIST-ITEMS item-list ]
[ SCROLLBAR-HORIZONTAL ]
[ SCROLLBAR-VERTICAL ]
{ size-phrase | INNER-CHARS cols INNER-LINES rows }
[ SORT ]
[ TOOLTIP tooltip ]

Sintaxe do Botão de Deslizar

VIEW-AS SLIDER
MAX-VALUE max-value MIN-VALUE min-value
[ HORIZONTAL | VERTICAL ]
[ NO-CURRENT-VALUE ]
[ LARGE-TO-SMALL ]
[ TIC-MARKS

88
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

{ NONE | TOP | BOTTOM | LEFT | RIGHT | BOTH }


[ FREQUENCY n ]
]
[ TOOLTIP tooltip ]
[ size-phrase ]

Exemplo
DEFINE VARIABLE meucombobox
AS CHARACTER
LABEL "Combo"
INITIAL "Joinville"
VIEW-AS COMBO-BOX
LIST-ITEM-PAIRS
"Joinville", "Joinville",
"Itapoa", "Itapoa",
"São Bendo do Sul", "São Bendo do Sul",
"Campo Alegre", "Campo Alegre",
"Curitiba", "Curitiba",
"Barra do Sul", "Barra do Sul"
DROP-DOWN-LIST
AUTO-COMPLETION
INNER-LINES 5
SIZE 30 BY 1.

DEFINE VARIABLE meueditor


AS CHARACTER
LABEL "Editor"
VIEW-AS EDITOR
INNER-CHARS 30
INNER-LINES 5
MAX-CHARS 20
NO-WORD-WRAP
SCROLLBAR-VERTICAL.

DEFINE VARIABLE meuradio


AS INTEGER
LABEL "Radio"
INITIAL 1
VIEW-AS RADIO-SET
HORIZONTAL
RADIO-BUTTONS
"Carro", 1,
"Moto", 2.

DEFINE VARIABLE minhaselection


AS CHARACTER
LABEL "Selection"
INITIAL "SC"
VIEW-AS SELECTION-LIST
MULTIPLE
LIST-ITEMS
"SC", "SP", "PR", "RS", "RJ"
INNER-CHARS 10
INNER-LINES 5
SCROLLBAR-HORIZONTAL
SORT.

89
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

DEFINE VARIABLE meuslider


AS INTEGER
LABEL "Slider"
INITIAL 1
VIEW-AS SLIDER
MAX-VALUE 100
MIN-VALUE 1
HORIZONTAL
TIC-MARKS BOTTOM
FREQUENCY 10
SIZE 30 BY 3.

DEFINE VARIABLE meufillinInt


AS INTEGER
FORMAT '999'
LABEL "Fill Int"
INITIAL 10
VIEW-AS FILL-IN
SIZE 10 BY 1.

DEFINE VARIABLE meufillinDec


AS DECIMAL
FORMAT '>>9.99'
LABEL "Fill Dec"
INITIAL 22.33
VIEW-AS FILL-IN
SIZE 10 BY 1.

DEFINE VARIABLE meufillinDate


AS DATE
FORMAT '99/99/9999'
LABEL "Fill Date"
INITIAL 12/31/2013
VIEW-AS FILL-IN
SIZE 15 BY 1.

DEFINE VARIABLE meufillinChar


AS CHARACTER
FORMAT 'x(40)'
LABEL "Fill Char"
INITIAL "Funcionou"
VIEW-AS FILL-IN
SIZE 25 BY 1.

UPDATE
meucombobox
meueditor
meuradio
minhaselection
meuslider
meufillinInt
meufillinDec
meufillinDate
meufillinChar
WITH 1 COL.

90
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Resultado no ambiente Windows

91
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Resultado no Ambiente Caracter

Anotações

Variáveis e herança
Variáveis podem receber características de outras variáveis, de outros campos de tabelas do banco de
dados, de tabelas temporárias e de objetos, para isso use a opção LIKE.

92
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Alguns atributos podem ser sobrescritos mesmo usando a opção LIKE, como:

• Formato ou FORMAT,
• Rótulo ou LABEL,
• Valor inicial ou INITIAL,
• Casas decimais ou DECIMAL,
• Visualização de variáveis como objetos ou VIEW-AS,

Exemplo

DEFINE VARIABLE nome


AS CHARACTER
FORMAT 'x(50)'
LABEL 'Nome'
VIEW-AS FILL-IN
SIZE-PIXELS 90 BY 21
.

DEFINE VARIABLE sobrenome


LIKE nome
LABEL 'Sobrenome'.

UPDATE nome sobrenome.

Resultado

Anotações

Herdando características de campos de tabela


A herança com a opção Like também é válida para campos de tabela.

Exemplo

/*para este exemplo funcionar é necessário que o banco SPORTS2000


esteja conectado*/

DEFINE VARIABLE nome


LIKE customer.NAME.

DEFINE VARIABLE numero


LIKE customer.custnum.

93
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

UPDATE nome numero


WITH SIDE-LABELS.

Resultado

94
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercício
Para a nomenclatura dos exercícios, utilize a máscara VAR_<número do exercício>.P (var_1.p, var_2.p).

1. Definir variável do tipo caractere.


2. Definir variável do tipo decimal.
3. Definir variável do tipo data.
4. Definir variável do tipo inteiro.
5. Definir uma variável caractere, decimal, data, inteiro com vetor de cinco posições, utilize a opção
'extent'.
6. Crie um novo programa a partir do segundo exercício, neste a variável decimal deverá ser visualizada
(VIEW-AS) como FILL-IN.
7. Crie um novo programa a partir do quarto exercício, neste adicione uma nova variável, herde as
características da variável existente com a opção like, mostre-a como Slider, com valor mínimo 1,
valor máximo 100, horizontal e com frequência de 20.

95
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Entrada e Atribuição de Valores


Há diversas formas de realizar a entrada e atribuição de valores, as principais são:

• Assign, atribuição de valores em uma única instrução, trazendo os dados do Screen buffer para o
Record buffer.
• Prompt-for, entrada de valores utilizando o Screen-buffer, é uma conjunção de comandos como
Enable, Wait-for e Disable.
• Update, entrada e atribuição de valores com a realização de várias operações como o comando
Display, Prompt-for e Assign.

Instrução Assign
Atribuição de valores em uma única instrução, trazendo os dados do Screen buffer para o Record buffer.

Sintaxe Assign

ASSIGN {
[ [ INPUT ] FRAME frame | BROWSE browse ]
{ field [ = expression ] } [ WHEN expression ]
} ... [ NO-ERROR ]

Exemplo Assign

REPEAT:
PROMPT-FOR Customer.CustNum.
FIND Customer USING Customer.CustNum NO-ERROR.
IF NOT AVAILABLE Customer THEN DO:
CREATE Customer.
ASSIGN Customer.CustNum = 10.
END.
UPDATE Customer WITH 2 COLUMNS.
END.

Anotações

A instrução de Assign também é utilizada para a atribuição de vários valores em uma única instrução com o
uso do igual “=”.

96
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Sintaxe Assign para atribuição

Certo Errado

Assign customer.custnum = 5.
customer.custnum = 5 customer.name = “Jose da
customer.name = “Jose Silva”. Silva”.

Uma única instrução realiza múltiplas


atribuições, sendo mais rápido. Várias instruções são executadas para realizar
as mesmas atribuições.

Anotações

Instrução de Prompt-for
Entrada de valores utilizando o Screen buffer.

É uma conjunção de comandos como Enable, Wait-for e Disable.

Sintaxe

PROMPT-FOR
[ STREAM stream | STREAM-HANDLE handle ]
[ UNLESS-HIDDEN ]
{ { field
[ format-phrase ]
[ WHEN expression ]
}
| { TEXT ( { field
[ format-phrase ]
[ WHEN expression ]
} ...
)
}
| { constant
[ { AT | TO } n ]
[ VIEW-AS TEXT ]
[ FGCOLOR expression ]
[ BGCOLOR expression ]
[ FONT expression ]
}
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

| SPACE [ ( n ) ] | SKIP [ ( n ) ] | ^
} ...
[ GO-ON ( key-label ... ) ]
[ IN WINDOW window ]
[ frame-phrase ]
[ editing-phrase ]

Exemplo

REPEAT:
PROMPT-FOR Customer.CustNum.
FIND Customer USING Customer.CustNum NO-ERROR.
IF NOT AVAILABLE Customer THEN DO:
MESSAGE "No such customer number.".
UNDO, RETRY.
END.
DISPLAY Customer.Name Customer.Phone Customer.SalesRep.
END.

Anotações

Neste exemplo é utilizada a leitura do “código do cliente” diretamente no campo Customer.Custnum, mas o
valor digitado está armazenado no Screen buffer, não sendo gravada no banco de dados.

Importante: Utilize a função INPUT para atribuir o valor que está no Screen buffer para o Record Buffer.

Exemplo

Assign Input
customer.custnum
customer.name.

Instrução de Update
Entrada e atribuição de valores com a realização de várias operações como o comando Display, Prompt-for e
Assign.

A instrução de Update faz a transferência entre Screen Buffer para Record Buffer automaticamente.

Sintaxe

98
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

UPDATE
[ UNLESS-HIDDEN ]
[ field [ format-phrase ] [ WHEN expression ]
| TEXT ( field [ format-phrase ] ... )
| field = expression
| constant [ AT n | TO n ]
| ^
| SPACE [ ( n ) ]
| SKIP [ ( n )]
] ...
[ GO-ON ( key-label ... ) ]
[ frame-phrase ]
[ editing-phrase ]
[ NO-ERROR ]

Exemplo

FOR EACH Customer:


UPDATE
Customer.Name
Customer.Address
Customer.City
Customer.State
Customer.Country.
END.

Anotações

Importante

• Se algum campo de tabela faz parte da instrução Update, o Lock é primeiramente evoluído para
Exclusive para então atualizar o valor no banco de dados.
• Se somente um qualificador, como o nome de um campo “name”, for utilizado na instrução de
Update, o compilador tenta referenciar o qualificador como dbname.tablename, em caso de falha, o
compilador tenta referenciar tablename.fieldname. Para bancos com muitas tabelas é sugerido
referenciar tablename.fieldname, pois a localização do qualificador tablename.fieldname pode
demorar.
• A instrução de Update faz com que a Trigger de dicionário Assign do campo seja acionada. Se ocorrer
erro durante a execução da Trigger de Assign, a atualização no banco de dados é desfeita.
• Gatilhos de Write são executados em quatro situações:

99
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

o Final da transação, pode ser no END ou no final do bloco de instruções de um programa,


o Instrução Release,
o Instrução Validade e
o Ao trocar de registro com um FIND, por exemplo.

Anotações

A maldição do Screen buffer


Três áreas para valores é uma maldição, principalmente quando trabalhamos com comando Prompt-for.
Sempre que usar Screen buffer utilize o comando Input para transferir o valor digitado para o Record Buffer,
que guarda o valor real da variável ou registro do banco.

Simulando o problema de Screen buffer


DEFINE VARIABLE nome
AS CHARACTER NO-UNDO
VIEW-AS FILL-IN
SIZE-PIX 90 BY 21 .

REPEAT:
PROMPT-FOR nome.

MESSAGE nome
VIEW-AS ALERT-BOX INFO BUTTONS OK.
END.

Transferindo valor do Screen Buffer para o Record Buffer


Utilize o comando assign e input para atualizar o valor do Record Buffer.

DEFINE VARIABLE nome


AS CHARACTER NO-UNDO
VIEW-AS FILL-IN
SIZE-PIX 90 BY 21.

REPEAT:
PROMPT-FOR nome.
ASSIGN INPUT nome.

MESSAGE nome

100
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

VIEW-AS ALERT-BOX INFO BUTTONS OK.


END.

A função Input referencia o valor da variável no Screen Buffer, com o comando Assign este valor no Screen
Buffer é transferido para o Record Buffer.

Anotações

101
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercícios
Para a nomenclatura dos exercícios, utilize a máscara ENT_A_<número do exercício>.P (ENT_A_1.p,
ENT_A_2.p).

1. Crie um programa que leia o nome e sobrenome e mostre em uma mensagem os valores digitados,
utilize prompt-for e não esquecer do assign e input.
2. A partir do primeiro exercício substitua os comandos desnecessários pela instrução Update.

102
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Instruções Condicionais
A linguagem possui instruções condicionais IF, THEM e ELSE ou CASE, como a maioria das outras linguagens.

Instrução IF, THEN e ELSE


Sintaxe

IF expression THEN { block | statement }


[ ELSE { block | statement } ]

Exemplo

DEFINE VARIABLE A AS INTEGER NO-UNDO INITIAL 1.

IF A = 1 THEN
DISPLAY "Igual".
ELSE
DISPLAY "Diferente".

Para adicionar várias instruções em condições IF utilize o comando DO.

Exemplo

DEFINE VARIABLE A AS INTEGER NO-UNDO INITIAL 1.

IF A = 1 THEN
DO:
DISPLAY "Igual".
MESSAGE "igual"
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.
ELSE
DO:
DISPLAY "Diferente".
MESSAGE "diferente"
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.

Anotações

If, Then e Else em Assign


A instrução Assign também pode abrir IF, Then e Else. Por questões de performance, não é indicada.

Exemplo

DEFINE VARIABLE iniciou AS LOGICAL NO-UNDO INITIAL TRUE.


DEFINE VARIABLE iniciado AS CHARACTER NO-UNDO.

UPDATE iniciou.

103
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

ASSIGN
iniciado = IF iniciou THEN
"Verdadeiro"
ELSE
"Falso".

DISPLAY iniciado.

Instrução CASE
A instrução CASE permite condições com ramificações baseadas em valores.

Sintaxe

CASE expression :
{ WHEN value [ OR WHEN value ] ... THEN
{ block | statement }
} ...
[ OTHERWISE
{ block | statement }
]
END [ CASE ]

Exemplo

DEFINE VARIABLE A AS INTEGER NO-UNDO INITIAL 1.

CASE A:
WHEN 1 THEN
DO:
DISPLAY "Igual a 1".
MESSAGE "igual a 1"
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.
WHEN 2 THEN
DO:
DISPLAY "Igual a 2".
MESSAGE "igual a 2"
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.
OTHERWISE
DO:
DISPLAY "Nao é 1 ou 2".
MESSAGE "Nao é 1 ou 2"
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.
END CASE.

Anotações

104
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercícios
Para a nomenclatura dos exercícios, utilize a máscara INST_<número do exercício>.P (INST_1.p, INST_2.p).

1. A partir de duas variáveis do tipo inteiro e com valores diferentes mostre se a primeira variável é
maior que a segunda (Instrutor).
2. Repita o primeiro exercício, mas usando desta vez o operador GT.
3. Usando variáveis do tipo decimal mostre se a primeira variável é menor que a segunda.
4. Repita o terceiro exercício, mas usando o operador LT.
5. Verifique se a primeira variável do tipo inteira é maior ou igual que a segunda variável decimal.
6. Repita o quinto exercício, mas agora utilize o operador GE.
7. Verifique se a variável nome completo inicia por 'A', utilize o operador BEGINS.
8. Verifique se a variável nome completo não se inicia por 'A'.
9. Com uma variável inteira e utilizando IF mostre se o valor é maior que 1, ou 2, ou 3, utilize IF THEN e
ELSE.
10. Repita o exercício 9, mas utilize a instrução CASE.

105
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Includes
Includes são segmentos de código que são incorporados aos programas durante a compilação.

Podem receber argumentos, que são os equivalentes aos parâmetros nas procedures.

Sintaxe

{nome-arquivo-include.i}

Exemplo

{minhainclude.i}

MESSAGE “Programa com include incorporada”


VIEW-AS ALERT-BOX INFO BUTTONS OK.

Exemplo de include com argumento sem nome

{minhainclude.i 1 ”JAISON”}

MESSAGE “Programa com include incorporada e argumentos”


VIEW-AS ALERT-BOX INFO BUTTONS OK.

Exemplo de include com argumentos nomeados

{minhainclude.i
&parametro1=1
&parametro2=”JAISON”}

MESSAGE “Programa com include incorporada e argumentos com nome”


VIEW-AS ALERT-BOX INFO BUTTONS OK.

Anotações

106
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercício
Para a nomenclatura dos exercícios, utilize a máscara INC_<número do exercício>.P (INC_1.p, INC_2.p).

1. Criar programa que utilize include com três argumentos, data de hoje, nome completo, data de
nascimento e dentro do arquivo include exiba mensagem com estes dados.
2. Criar programa que utilize include com três argumentos, data de hoje, nome completo, data de
nascimento e dentro do arquivo include exiba mensagem com estes dados, utilize argumentos com
nomes.

107
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Pré-processadores
Pré-processadores são constantes utilizadas na compilação e disponíveis para o programa.

Há duas formas de definirmos uma constante: Scoped-define e Global-define.

Constantes locais
São as constantes declaradas dentro das includes que não estão disponíveis para o programa que as
incorpora.

Definindo constantes locais Scoped-define


Sintaxe

&SCOPED-DEFINE preprocessor-name definition

Exemplo

&SCOPED-DEFINE minhaconstante 1

Anotações

Constantes Globais
São as constantes declaradas dentro das includes que estão disponíveis para o programa que as incorpora.

Definindo constantes globais Global-define


Sintaxe

&GLOBAL-DEFINE preprocessor-name definition

Exemplo

&GLOBAL-DEFINE minhaNovaConstante 2

Anotações

108
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Verificando a declaração de uma constante


Pode-se testar se a constante foi definida com a função Defined e eliminar a definição desta com a diretiva
&Undefine.

Sintaxe

DEFINED ( name )

Exemplo

&GLOBAL-DEFINE minhaNovaConstante 2

&IF DEFINED(minhaNovaConstante) &THEN


FIND LAST customer NO-LOCK NO-ERROR.
IF AVAILABLE customer THEN
DISPLAY custnum NAME.
&ENDIF

Diferença entre Scoped e Global


Como mencionado acima, a diferença entre ambas é na abrangência destas quando declaradas dentro de
includes. Enquanto que uma constante declarada como Scoped não se propaga para o programa que
declarou esta include, uma constante Global se propaga e está disponível para ser usada no programa que
declarou esta include.

Exemplo minhainclude.i

&SCOPED-DEFINE minha1 1
&GLOBAL-DEFINE minha2 2

Exemplo

{minhainclude.i}

MESSAGE {&minha1} SKIP {&minha2}


VIEW-AS ALERT-BOX INFO BUTTONS OK.

Anotações

109
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Eliminando a declaração de uma constante


A linguagem ABL permite eliminarmos a definição de uma constante através do uso do UNDEFINE.

&UNDEFINE preprocessor-name

Exemplo

&GLOBAL-DEFINE minhaNovaConstante 2

&UNDEFINE minhaNovaConstante

&IF DEFINED(minhaNovaConstante) > 0 &THEN


FIND LAST customer NO-LOCK NO-ERROR.
IF AVAILABLE customer THEN
DISPLAY custnum NAME.
&ENDIF

Anotações

110
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercício
Para a nomenclatura dos exercícios, utilize a máscara CT_<número do exercício>.P (CT_1.p, CT_2.p).

1. Criar programa que defina uma constante local com o seu nome e mostre-a em uma mensagem.
2. Criar programa que defina uma constante global com o seu nome, mostre-a em uma mensagem e
elimine a definição.

111
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Frames e Display
São áreas retangulares para a exibição de variáveis e seus valores, campos de tabelas ou para interação com
o usuário.

Sintaxe

DEFINE { [ [ NEW ] SHARED ] | [ PRIVATE ] } FRAME frame


[ form-item ... ]
[{ HEADER | BACKGROUND } head-item ... ]
{ [ frame-phrase ] }

Tantos os campos quanto a frame possuem opções, e isto deve-se ser compreendido, são opções segregadas
pois são objetos distintos, algumas opções podem existir em ambos, mas não devem ser confundidas.

Durante os primeiros momentos de aprendizado da linguagem Progress ABL estas opções podem ser
confundidas entre campos e definição de frame.

Os campos possuem Opções dos Campos, conhecido como Form Item options, e ainda contam com a opção
de Formatação, ou Format phrase. Já os frames possuem somente as opções de Frame ou Frame phrase.

Há dois grupos de frames, as de relatórios (em colunas) e as frames para widgets. Esses grupos são distintos
pois suas opções são excludentes.

Frames de relatórios
São os frames padrão e que contém as opções:

down
stream-io
width 128
no-box

Frames para widgets


São os frames que contém as opções:

1 down
three-d
side-labels
size 80 by 20

Opções Para Campos E Constantes


Sintaxe para Opções dos Campos e Constantes (Form item options)

{ field [ format-phrase ]
| constant [ at-phrase | { TO n } ]

112
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

[ BGCOLOR expression ]
[ DCOLOR expression ]
[ FGCOLOR expression ]
[ FONT expression ]
[ PFCOLOR expression ]
[ VIEW-AS TEXT ]
[ WIDGET-ID id-number ]
| SPACE [ ( n ) ]
| SKIP [ ( n ) ]
}

Principais Opções dos Campos e Constantes


Opção Sobre Indicação
BGColor Especifica a cor de fundo do Janelas com campos ou
campo em ambientes relatórios.
gráficos.
DColor Especifica a cor de fundo do Janelas com campos ou
campo em ambientes relatórios.
caracter.
FGColor Especifica a cor do texto do Janelas com campos ou
campo em ambientes relatórios.
gráficos.
FONT Determina a fonte do Janelas com campos ou
campo. relatórios.
PFColor Determina a cor de prompt Janelas com campos ou
para o campo em ambientes relatórios.
caracter.
View-as text Determina a exibição do Janelas com campos ou
campo como TEXTO. relatórios. Comumente em
relatórios.
Widget-ID É o identificador único do Janelas com campos.
objeto entre 2 e 65534.
Space Determina a quantidade de Janelas com campos ou
espaços em branco. relatórios.
Skip Determina a quantidade de Janelas com campos ou
saltos de linha. relatórios.
Sintaxe para a Formatação de campos (Format phrase)

[ at-phrase ]
[ AS datatype | LIKE field ]
[ ATTR-SPACE | NO-ATTR-SPACE ]
[ AUTO-RETURN ]
[ BGCOLOR expression ]
[ BLANK ]
[ COLON n | TO n ]
[ COLUMN-LABEL label ]
[ DEBLANK ]
[ DCOLOR expression ]
[ DISABLE-AUTO-ZAP ]
[ FGCOLOR expression ]
[ FONT expression ]
[ FORMAT string ]
[ HELP string ]
[ LABEL label [ , label ] ... | NO-LABELS ]
[ NO-TAB-STOP ]
[ PFCOLOR expression ]
[ VALIDATE ( condition , msg-expression ) ]

113
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

[ view-as-phrase ]
[ WIDGET-ID id-number ]

Principais opções da Formatação de campos


Opção Sobre Indicação
AT COLUMN coluna ROW Pode determinar a coluna e Janelas com campos ou
linha linha do campo, medida em relatórios.
caracteres.
Pode opcionalmente
determinar o alinhamento
por dois pontos, pela
esquerda ou pela direita do
campo.
AT n Para determinar a coluna de Janelas com campos ou
exibição, medida em relatórios.
caracteres.
AT X x Y y Pode determinar a coluna e Janelas com campos ou
linha do campo, medida em relatórios.
pixels.
Pode opcionalmente
determinar o alinhamento
por dois pontos, pela
esquerda ou pela direita do
campo.
Colon n Determina o número da Janelas com campos ou
coluna que o dois pontos relatórios.
será exibido. Utilizar em
frames com side-label.
To n O número da coluna que Janelas com campos ou
deseja terminar a exibição relatórios.
do campo.
Column-label rótulo Determina o rótulo da Janelas de relatórios.
coluna.
Format Determina a formatação do Janelas com campos ou
campo. relatórios.
Help Determina a ajuda do Janelas com campos.
campo.
Label Determina o rótulo do Janelas com campos ou
campo. relatórios.
No-labels Sem rótulo para o campo. Janelas de relatórios.
Validate (condição, Determina a validação e a Janelas com campos e
mensagem) mensagem do campo. objetos.
View-as Determina a visualização do Janelas com campos ou
campo. relatórios.

114
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Opções para o Frame


Sintaxe da Definição da Frame

WITH [ ACCUM [ max-length ] ]


[ at-phrase ] [ ATTR-SPACE | NO-ATTR-SPACE ]
[ CANCEL-BUTTON button-name ] [ CENTERED ]
[ color-specification ]
[ COLUMN expression ] [ n COLUMNS ]
[ CONTEXT-HELP ] [ CONTEXT-HELP-FILE help-file-name ]
[ DEFAULT-BUTTON button-name ]
[ DROP-TARGET ]
[ [ expression ] DOWN ] [ EXPORT ]
[ WIDGET-ID id-number ] [ FONT expression ]
[ FRAME frame ]
[ INHERIT-BGCOLOR | NO-INHERIT-BGCOLOR ]
[ INHERIT-FGCOLOR | NO-INHERIT-FGCOLOR ]
[ KEEP-TAB-ORDER ] [ NO-BOX ]
[ NO-HIDE ] [ NO-LABELS ] [ USE-DICT-EXPS ]
[ NO-VALIDATE ] [ NO-AUTO-VALIDATE ]
[ NO-HELP ] [ NO-UNDERLINE ]
[ OVERLAY ] [ PAGE-BOTTOM | PAGE-TOP ] [ RETAIN n ]
[ ROW expression ] [ SCREEN-IO | STREAM-IO ]
[ SCROLL n ] [ SCROLLABLE ] [ SIDE-LABELS ]
[ size-phrase ] [ STREAM stream | STREAM-HANDLE handle ] [ THREE-D ]
[ title-phrase ] [ TOP-ONLY ] [ USE-TEXT ]
[ V6FRAME [ USE-REVVIDEO | USE-UNDERLINE ] ]
[ VIEW-AS DIALOG-BOX ] [ WIDTH n ] [ IN WINDOW window ]

Principais Opções da Definição da Frame


Opção Sobre Indicação
Centered Para centralizar a frame Em frames com campos e objetos que precisam
estrar centralidas.
Title titulo Para a frame ter título Em frames que precisam de título, somente
pode ser usada com frame com BOX.
No-box Para retirar a caixa em Em relatórios e em frames que não precisam de
torno do frame caixa.
Use-text Para especificar que os Em relatórios.
objetos do frame serão
textos ao contrário de
FILL-IN
View-as dialog-box Para exibir a janela como Em frames que precisam ser exibidas como
janela de diálogo diálogo.
Width n Para determinar a largura Em relatórios.
em caracteres que o
frame tem.
Three-d Para exibir a frame e os Em janelas que tenham objetos e campos.
objetos em três
dimensões.
Side-labels Para exibir os rótulos ao Em janelas com campos e em relatórios.
lado dos campos
separados por “:” dois
pontos.
Row n Para indicar a linha que a Em janelas com campos e variáveis.
frame será exibida.

115
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Page-bottom Para indicar que a frame Em relatórios.


será exibida no rodapé a
cada término de página.
Page-top Para indicar que a frame Em relatórios.
será exibida no topo a
cada início de página.
Overlay Para indicar que a frame Em janelas que fazem sobreposição sobre
pode sobrepor outro outras janelas.
frame.
No-labels Em frames que não Em relatórios.
exibirão os rótulos dos
campos.
No-underline Para indicar que não Em relatórios.
haverá linha abaixo dos
campos.
No-box Para remover a caixa em Em relatórios.
torno do frame.
Keep-tab-order Para manter a ordem de Em janels com campos e objetos.
tabulação dos campos.
Frame nome-da-frame Para dar nome ao frame. Em relatórios e janelas com campos.
Default-button Para indicar o botão Em janelas com campos e objetos.
padrão, é aquele que
recebe o ENTER.
Column n Para indicar a coluna que Em janelas de campos e objetos.
o frame será exibido.
n Column Para indicar o número de Em janelas com campos de tabela.
colunas que a frame terá
Down Para indicar que a frame Em relatórios.
será DOWN, frames Down
é aquela que exibirá
múltiplas ocorrências dos
campos definidos nela.
n Down Para indicar quantas Em relatórios.
interações uma frame
down terá.
Cancel-button Para indicar o botão que Em janelas de campos e objetos.
receberá o ESC.
Headder Para indicar o cabeçalho Em janelas de campos e relatórios.
do frame.
Stream-io Para indicar que as fontes Em relatórios.
serão ignoradas e a fonte
FIXA será usada, retirando
ainda todo espaço de
borda entre os campos.

Compartilhamento
Frames podem ser compartilhados, entre programas, com o uso de New e ou Shared.

116
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

DEFINE { [ [ NEW ] SHARED ] | [ PRIVATE ] } FRAME frame


record [ EXCEPT field ... ]
{ [ frame-phrase ] }

Exemplo

DEFINE VARIABLE bal-avail LIKE customer.balance


COLUMN-LABEL "Credito" NO-UNDO.

DEFINE FRAME frame-Balanco


customer.custnum
customer.name FORMAT "X(20)"
customer.creditlimit LABEL "Limite"
customer.balance
bal-avail
WITH CENTERED ROW 3 TITLE "Credito disponivel" USE-TEXT.

FOR EACH customer NO-LOCK WITH FRAME frame-Balanco:


DISPLAY customer.custnum
customer.name
customer.creditlimit
customer.balance
customer.creditlimit - customer.balance @ bal-avail.
END.

Instrução Display
A instrução Display transporta o valor do Record Buffer de uma variável ou registro para o Screen Buffer ou
para outro destino de saída.

Um frame definido com vários campos e variáveis pode ser usada para a instrução display exibir um único
campo ou variável ou para exibir diversos campos e variáveis, neste mesmo frame.

A linguagem Progress ABL permite que você sobrepõe opções de campos, de formatação de campos ou
opções do frame durante a instrução Display. O mais indicado é manter a definição do frame a fim de evitar
janelas com identidades diferentes das definidas.

Sintaxe

DISPLAY
{ [ STREAM stream | STREAM-HANDLE handle ] [ UNLESS-HIDDEN ] }
[ { expression
[ format-phrase ]
[ ( aggregate-phrase ) ]
[ WHEN expression ]
[ @base-field ]
}
| [ SPACE [ ( n ) ] ]
| [ SKIP [ ( n ) ] ]
] ...
{ [ IN WINDOW window ] [ frame-phrase ] [ NO-ERROR ] }

117
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Para exibir expressões.

Sintaxe

DISPLAY
{ [ STREAM stream | STREAM-HANDLE handle ] [ UNLESS-HIDDEN ] }
record [ EXCEPT field ... ]
{ [ IN WINDOW window ] [ frame-phrase ] [ NO-ERROR ] }

Para exibir campos de tabelas.

Sintaxe

DISPLAY
{ expression ...
| record [ EXCEPT field ... ]
}
WITH BROWSE browse [ NO-ERROR ]

Para exibir no browser.

Exemplo

/* definindo variaveis idade e nome */


DEFINE VARIABLE iIdade AS INTEGER NO-UNDO INIT 37
LABEL 'Idade'.
DEFINE VARIABLE cNome AS CHARACTER NO-UNDO INIT 'Jaison'
LABEL 'Nome'.

/* definer frame frameA, frameB e frameC com as mesmas variaveis */


DEFINE FRAME frameA

iidade AT ROW 1 COL 10 COLON-ALIGNED


cNome AT ROW 2 COL 10 COLON-ALIGNED

WITH SIDE-LABELS
THREE-D
SIZE 30 BY 4
ROW 1 COL 1
TITLE 'Frame A'.

DEFINE FRAME frameB

iidade AT ROW 1 COL 10 COLON-ALIGNED


cNome AT ROW 2 COL 10 COLON-ALIGNED

WITH SIDE-LABELS
THREE-D
SIZE 30 BY 4
ROW 1 COL 45
TITLE 'Frame B'.

DEFINE FRAME frameC

118
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

iidade AT ROW 1 COL 10 COLON-ALIGNED


cNome AT ROW 2 COL 10 COLON-ALIGNED

WITH SIDE-LABELS
THREE-D
SIZE 30 BY 4
ROW 5.5 COL 1
TITLE 'Frame C'.

/* exibir as variaveis na frame frameA */


DISPLAY
iIdade
cNome
WITH FRAME FRAMEA.

/* exibir as variaveis na frame frameB */


DISPLAY
iIdade
cNome
WITH FRAME FRAMEB.

/* exibir as variaveis na frame frameC */


DISPLAY
iIdade
cNome
WITH FRAME FRAMEC.

MESSAGE 'Antes de atribuir e mostrar idade...'


VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

/* atribuir novo valor a idade*/


ASSIGN
iidade = 50.

/* exibir o novo valor da idade na frame frameA */


DISPLAY
iIdade
WITH FRAME FRAMEA.

MESSAGE 'Antes de exibir o novo valor na frameB'


VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

DISPLAY
iidade
WITH FRAME frameB.

Frame de relatório
Abaixo está um exemplo completo de programa com frames e opções page-top e page-bottom, com o
funcionamento e exibição de dados com saída para impressora.

DEFINE VARIABLE titulo AS CHARACTER FORMAT 'x(40)' NO-UNDO.


DEFINE VARIABLE programa AS CHARACTER FORMAT 'x(20)' NO-UNDO.
DEFINE VARIABLE empresa AS CHARACTER FORMAT 'x(30)' NO-UNDO.

ASSIGN
titulo = 'Listagem de clientes'
programa = 'SPP/SPR0004.P'
empresa = 'Neo Step TI Ltda.'.

119
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

DEFINE FRAME frameTop


HEADER
titulo
empresa TO 127 SKIP
FILL('-', 120) FORMAT 'x(128)'

WITH
NO-LABELS
STREAM-IO
NO-BOX
/* esta frame sera do tipo page-top */
PAGE-TOP
WIDTH 128.

DEFINE FRAME frameBottom


HEADER
FILL('-', 120) FORMAT 'x(128)' SKIP
programa TO 20
'Pag.' TO 110 PAGE-NUMBER TO 120 SKIP
WITH
SIDE-LABELS
STREAM-IO
NO-BOX
/* esta frame sera do tipo page-bottom */
PAGE-BOTTOM
WIDTH 128.

/* frame normal para exibir os dados do cliente */


DEFINE FRAME frameCustomer
customer.custnum
customer.NAME
customer.address
customer.salesrep
salesrep.repname
WITH
DOWN
STREAM-IO
NO-BOX
WIDTH 128.

OUTPUT TO PRINTER PAGED PAGE-SIZE 60.

/* exibir a frame top com o titulo do programa e empresa */


VIEW FRAME frameTop.
/* exibir a frame bottom com o nome do programa e a pagina */
VIEW FRAME frameBottom.

FOR EACH customer NO-LOCK,


FIRST salesrep NO-LOCK
WHERE salesrep.salesrep = customer.salesrep :

DISPLAY
customer.custnum
customer.NAME
customer.address
customer.salesrep
salesrep.repname

120
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

WITH FRAME frameCustomer.

END.

OUTPUT CLOSE.

O programa acima gerará saída:

Frames Sobrepostas
Frames podem ser sobrepostas, mas é necessário informar a frame pai que abrigará as demais filhas.

A figura abaixo exemplifica o código que seguirá.

121
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exemplo de frames sobrepostas

DEFINE FRAME frameback


WITH
SIZE 60 BY 15
CENTERED.

DEFINE FRAME frametopleft


WITH
SIZE 15 BY 6
AT ROW 3 COL 3
.

DEFINE FRAME framebottomleft


WITH
SIZE 33 BY 2
AT ROW 9.2 COL 3 .

DEFINE FRAME frameright


WITH
SIZE 20 BY 8.2
AT ROW 3 COL 39 .

FRAME frametopleft:FRAME = FRAME FRAMEback:HANDLE.


FRAME framebottomleft:FRAME = FRAME FRAMEback:HANDLE.
FRAME frameright:FRAME = FRAME FRAMEback:HANDLE.

VIEW FRAME FRAMEback.


VIEW FRAME frametopleft.

As sete regras da programação com eventos


1. Declarar variáveis,
2. Declarar frames e colocar variáveis,
3. Codificar eventos, triggers e procedures,
4. Exibir os frames (view frame),
5. Exibir as variáveis nos frames (disp variavel-1 variavel-2),
6. Habilitar objetos nos frames,
7. Aguardar pelo wait-for.

Anotações

122
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

123
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercício
Para a nomenclatura dos exercícios, utilize a máscara FRM_<número do exercício>.P (FRM_1.p, FRM_2.p).

1. Crie um frame, adicionando o título Olá Mundo,


2. Crie um programa com uma frame conforme a figura abaixo.

3. Criar uma frame conforme a figura abaixo, utilize o banco Sports2000 e tabela CUSTOMER.

4. Criar relatório exportando o representante de vendas e seus pedidos, na frame framesalesrep exibir
os campos Salesrep.SalesRep Salesrep.RepName Salesrep.Region, na frame frameOrder exibir os
campos Order.Ordernum, Order.OrderDate, Order.CustNum, Customer.NAME, Order.Creditcard,
Order.ShipDate e Order.Terms. Os frames frameSalesrep e frameOrder deverão ter a opção DOWN.
Todas os frames deverão ter as opções STREAM-IO, NO-BOX e WIDTH 128. A frame frameTOP
conterá cabeçalho e a opção PAGE-TOP, a frame frameBottom terá a opção PAGE-BOTTOM. Utilizar
a instrução OUTPUT conforme “OUTPUT TO c:\temp\spr0018.txt PAGED PAGE-SIZE 60 NO-
CONVERT.” Não esquecendo de fechar o OUTPUT com “OUTPUT CLOSE.”. Para exibir os frames
FrameTop e FrameBottom utilize a instrução “VIEW FRAME frameTop.” e “VIEW FRAME
frameBottom.”. Para realizar a quebra de página a cada representante use a instrução “PAGE” após
o END do FOR ORDER. (Em conjunto com o Instrutor).

124
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Resultado do exercicio.

125
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Objetos, Eventos e Gatilhos de Widgets


Objetos ou Widgets são os botões, campos de entrada de texto, listas de seleção que permitem interação
com o usuário.

Eventos são as ações disponíveis para cada tipo de Widget, botões possuem evento de clique, campos de
entrada de texto possuem evento de “ao alterar”, alguns eventos são comuns a vários widgets, outros não.

Códigos de Gatilhos são as instruções executadas em um determinado evento.

Tipos de Objetos
Os tipos mais utilizados são:

1. Browse, grade de navegação,


2. Buttons, botões,
3. Combo-box, listas de seleção com um item visível,
4. Editor, caixa de entrada de texto com múltiplas linhas,
5. Fill-in, caixas de entrada de texto,
6. Frames, áreas retangulares contendo widgets,
7. Image, imagens com BMP ou JPEG,
8. Radio-set, conjunto de botões de radio,
9. Rectangle, retângulos para organização de widgets,
10. Selection-list, listas de seleção com vários itens visíveis,
11. Slider, linha de valores com botão de seleção,
12. Text, textos nas frames.
13. Toggle-box, botões de checagem,

Anotações

Estes objetos “widgets” podem ser criados de forma dinâmica ou estática.

Objetos Estáticos
Os objetos são variáveis com a opção “view-as” ou através da instrução “define” .

Sintaxe

VIEW-AS
{ combo-box-phrase
| editor-phrase
| FILL-IN
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

[ NATIVE ]
[ size-phrase ]
[ TOOLTIP tooltip ]
| radio-set-phrase
| selection-list-phrase
| slider-phrase
| TEXT
[ size-phrase ]
[ TOOLTIP tooltip ]
| TOGGLE-BOX
[ size-phrase ]
[ TOOLTIP tooltip ]
}

Exemplos de Fill-in

DEFINE VARIABLE fillin1 AS INTEGER NO-UNDO INITIAL 12


LABEL "números"
FORMAT '99999'
VIEW-AS FILL-IN
SIZE-PIXELS 70 BY 21.
DEF VAR teste3 AS INTEGER
LABEL 'Valor'
FORMAT '>>>>9'

VIEW-AS FILL-IN
SIZE 6 BY 1

INITIAL 1986.

Update Fillin1 Teste3.


Exemplos de Combo-box

DEFINE VARIABLE nomes AS CHAR


LABEL 'Nomes'
FORMAT 'x(20)'
VIEW-AS COMBO-BOX
LIST-ITEMS 'Claudiomir','willian','wellington'
INNER-LINES 5
DROP-DOWN-LIST NO-UNDO.
DEF VAR carros AS CHAR
LABEL 'Carros chiques'
FORMAT 'x(20)'
VIEW-AS COMBO-BOX
LIST-ITEM-PAIRS 'Ferrari','F',
'Brasilia','B',
'Passat','P',
'Gurgel','G',
'Lada','L'
DROP-DOWN
SORT
SIZE 10 BY 1

127
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

AUTO-COMPLETION
UNIQUE-MATCH
NO-UNDO.

DEF VAR idades AS INT


LABEL 'Idade'
FORMAT '>>>9'
VIEW-AS COMBO-BOX
LIST-ITEMS '1','2','3','4'
INNER-LINES 3
NO-UNDO.

DEF VAR datas AS DATE


LABEL 'Feriado'
FORMAT "99/99/9999"
VIEW-AS COMBO-BOX
LIST-ITEM-PAIRS '01/01/2015',01/01/2015,
'15/07/1975',15/07/1975,
'31/12/2015',31/12/2015
INNER-LINES 3
NO-UNDO.

DEFINE VARIABLE cidades AS CHAR

LABEL 'Cidade'
FORMAT 'x(50)'

VIEW-AS COMBO-BOX
LIST-ITEMS 'Joinville','Sao Francisco do Sul','Sao Paulo','Rio de
Janeiro'
INNER-LINES 5
TOOLTIP 'Cidades do Brasil'
DROP-DOWN-LIST
MAX-CHARS 50

NO-UNDO.
UPDATE
Cidades datas idades carros nomes
WITH
1 COL
THREE-D
SIDE-LABELS
SIZE 80 BY 20.

Exemplos de Editor

DEF VAR texto AS CHAR


LABEL 'Obs'
FORMAT 'x(500)'

VIEW-AS EDITOR
INNER-CHARS 40 INNER-LINES 5

NO-WORD-WRAP
SCROLLBAR-HOR
SCROLLBAR-VER

128
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

NO-UNDO.

DEF VAR texto2 AS CHAR


LABEL 'SQN'
FORMAT 'x(50)'

VIEW-AS EDITOR
SIZE 50 BY 5
MAX-CHARS 70
NO-BOX
NO-WORD-WRAP
SCROLLBAR-HOR
SCROLLBAR-VER

NO-UNDO.
Update
Texto text2.
Exemplo de Radio-set

DEF VAR valores AS DECIMAL


LABEL 'valor'
FORMAT '>>,>>9.99'

VIEW-AS RADIO-SET
HORIZONTAL EXPAND
SIZE-PIX
450 BY 70
RADIO-BUTTONS
'B', 30, 'c', 78.90,'M', 39000
NO-UNDO.
Exemplo de Selection-list

DEF VAR lista-selecao AS CHAR


LABEL 'Lista de Seleção'
FORMAT 'x(15)'

VIEW-AS SELECTION-LIST
MULTIPLE
NO-DRAG
LIST-ITEMS 'Janeiro','Fevereiro','Março','Abril'
SCROLLBAR-VERTICAL
INNER-CHARS 20 INNER-LINES 10
INITIAL 'Fevereiro'
NO-UNDO.

Exemplo de Slider

DEF VAR teste1 AS INTEGER


LABEL 'Slider'

VIEW-AS SLIDER
MAX-VALUE 200 MIN-VALUE 2
VERTICAL
TIC-MARKS LEFT FREQUENCY 15
SIZE 20 BY 10

NO-UNDO.

129
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Anotações

Objetos Dinâmicos
Há outra forma de criarmos objetos dinâmicos utilizando a instrução “create widget”, sendo “widget” o tipo
de objeto desejado.

Sintaxe

CREATE { BUTTON | COMBO-BOX


| CONTROL-FRAME | DIALOG-BOX
| EDITOR | FILL-IN
| FRAME | IMAGE
| MENU | MENU-ITEM
| RADIO-SET | RECTANGLE
| SELECTION-LIST | SLIDER
| SUB-MENU | TEXT
| TOGGLE-BOX | WINDOW
| VALUE ( string-expression )
} handle [ IN WIDGET-POOL pool-name ]
[ ASSIGN { attribute = expression } ... ]
[ trigger-phrase ]

Exemplo

CREATE FILL-IN hfillin1


ASSIGN
FRAME = FRAME framemain:handle
X = 70
Y = 10
FORMAT = 'x(80)'
WIDTH-PIXELS = 70
HEIGHT-PIXELS = 21
SCREEN-VALUE = "ola mundo"
VISIBLE = TRUE
SENSITIVE = TRUE
TRIGGERS:
ON 'value-changed':u
DO:
MESSAGE "screen-value = " hfillin1:screen-value
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.
END TRIGGERS.

Anotações

130
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Eventos

Eventos são as ações disponíveis para cada tipo de Widget.

Eventos comumente utilizados:

• Choose, ao pressionar um botão,


• Value-changed, ao alterar o valor de widget fill-in, editor...
• Mouse-select-click, quando ocorre o clique do mouse,
• Mouse-extended-click, quando ocorre o clique do mouse mais o botão CTRL.

Anotações

Códigos de Gatilhos
São as instruções executadas em um determinado evento. Códigos de gatilhos geram novos blocos e
transações.

Podemos aplicar um evento em um outro objeto com a instrução “apply” e parar a execução deste código
com a instrução “return no-apply”.

Anotações

Exemplo Objetos Estáticos

/* definicao do widget - botao */


DEFINE BUTTON button1
LABEL "clique aqui"
SIZE-PIXELS 70 BY 21.

DEFINE VARIABLE combo1 AS CHARACTER NO-UNDO INITIAL "joinville"


LABEL "combo exemplo"
FORMAT 'x(30)'
VIEW-AS COMBO-BOX
LIST-ITEMS "joinville","curitiba","sao paulo"
DROP-DOWN-LIST
SIZE-PIXELS 85 BY 71
.

DEFINE VARIABLE fillin1 AS INTEGER NO-UNDO INITIAL 12

131
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

LABEL "números"
FORMAT '99999'
VIEW-AS FILL-IN
SIZE-PIXELS 70 BY 21.

DEFINE VARIABLE toggle1 AS LOG NO-UNDO INIT TRUE


LABEL "sexo"
VIEW-AS TOGGLE-BOX
SIZE-PIXELS 70 BY 21.

DEFINE VARIABLE radio1 AS INTEGER NO-UNDO INIT 2


LABEL "uf"
VIEW-AS RADIO-SET
RADIO-BUTTONS "sc", 1,
"pr", 2.

DEFINE VARIABLE editor1 AS CHARACTER NO-UNDO INIT "openedge é simples"


LABEL "observacao"
VIEW-AS EDITOR
SIZE-PIXELS 120 BY 60.

/* definicao da frame com o botao */


DEFINE FRAME framemain
button1
combo1 AT ROW 2 COL 10
fillin1 AT ROW 3.1 COL 10
toggle1 AT ROW 4.1 COL 10
radio1 AT ROW 5.1 COL 10
editor1 AT ROW 7 COL 10
WITH
CENTERED
THREE-D
SIZE 60 BY 20
SIDE-LABELS
TITLE "janela principal".

/* definicao do evento choose e do codigo trigger */


ON 'choose':u OF button1
DO:
/* codigo trigger */
MESSAGE "ola mundo" SKIP button1:dynamic
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.

/* evento de value-changed do combo1 */


ON 'value-changed':u OF combo1
DO:
/* codigo trigger */
/* transferir o valor do screen buffer para o record buffer */
ASSIGN INPUT FRAME framemain combo1.
MESSAGE combo1
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.

/* evento de value-changed do fillini1 */


ON 'value-changed':u OF fillin1
DO:
/* codigo trigger */
/* transferir o valor do screen buffer para o record buffer */
ASSIGN INPUT FRAME framemain fillin1.

132
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

MESSAGE fillin1
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.

/* evento de value-changed do toggle1 */


ON 'value-changed':u OF toggle1
DO:
/* codigo trigger */
/* transferir o valor do screen buffer para o record buffer */
ASSIGN INPUT FRAME framemain toggle1.
MESSAGE "aplicando o evento de choose no botao"
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

/* aplicar o evento em outro objeto */


APPLY "choose" TO button1.
END.

/* evento value-changed no editor1 */


ON 'value-changed':u OF editor1
DO:

/* condicao if somente para evitar msg 15090*/


IF 1 = 1 THEN
DO:
RETURN NO-APPLY.
END.

MESSAGE "este codigo nao sera executado"


VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

END.

/* evento mouse-select-click para mostrar uso do objeto self */


ON 'mouse-select-click':u OF
button1,
combo1,
fillin1,
toggle1,
radio1,
editor1
DO:

MESSAGE SELF:name
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

END.

/* visualizar a frame */
VIEW FRAME framemain.
/* habilitar alguns ou todos all widgets */
ENABLE ALL WITH FRAME framemain.
/* exibir o valor inicial das variaveis */
DISPLAY
combo1
fillin1
toggle1
radio1
editor1
WITH FRAME framemain.

133
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

/* aguardar por determinado evento para encerrar o programa */


WAIT-FOR ENDKEY OF FRAME framemain.
VIEW FRAME frameMain.
/* habilitar alguns ou todos ALL widgets */
ENABLE ALL WITH FRAME frameMain.

/* aguardar por determinado evento para encerrar o programa */


WAIT-FOR ENDKEY OF FRAME frameMain.

Anotações

Exemplo Objetos Dinâmicos


DEFINE VARIABLE hfillin1 AS HANDLE NO-UNDO.
DEFINE VARIABLE hbuttonok AS HANDLE NO-UNDO.

/* definicao da frame com o botao */


DEFINE FRAME framemain
WITH
CENTERED
THREE-D
SIZE 60 BY 20
SIDE-LABELS
TITLE "janela principal".

CREATE FILL-IN hfillin1


ASSIGN
FRAME = FRAME framemain:handle
X = 70
Y = 10
FORMAT = 'x(80)'
WIDTH-PIXELS = 70
HEIGHT-PIXELS = 21
SCREEN-VALUE = "ola mundo"
VISIBLE = TRUE
SENSITIVE = TRUE
TRIGGERS:
ON 'value-changed':u
DO:
MESSAGE "screen-value = " hfillin1:screen-value
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.
END TRIGGERS.

CREATE BUTTON hbuttonok


ASSIGN
FRAME = FRAME framemain:handle
WIDTH-PIXELS = 70
HEIGHT-PIXELS = 21
X = FRAME framemain:width-pix - 100
Y = FRAME framemain:height-pix - 50
LABEL = "ok"
VISIBLE = TRUE
SENSITIVE = TRUE
TRIGGERS:

134
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

ON 'choose':u PERSISTENT RUN pressionarok.


END TRIGGERS.

DISPLAY
WITH FRAME framemain.

WAIT-FOR ENDKEY OF FRAME framemain.

DELETE OBJECT hfillin1.


DELETE OBJECT hbuttonok.

PROCEDURE pressionarok:
MESSAGE "ola mundo" SKIP
"valor do fill-in = " hfillin1:SCREEN-VALUE
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.

Anotações

135
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Compartilhamento de variáveis e objetos


A linguagem ABL possui duas formas de compartilhar variáveis e objetos:

1. Através do uso das opções New Shared e Shared permitido somente entre programa pai e programa
filho (A que executa B),
2. Através da opção New Global Shared, que permite o valor de variáveis e objetos ficar à disposição
enquanto a sessão estiver ativa.

Estes dois formatos permitem compartilhar quase que todos os objetos da linguagem ABL, sejam estas
variáveis, objetos como as frames, queries, browsers, buffers, datasets, menus, streams e tabelas
temporárias.

Compartilhamento de variáveis entre programas


DEFINE NEW SHARED VARIABLE del AS LOGICAL.
DEFINE NEW SHARED VARIABLE nrecs AS INTEGER.

Exemplo

DEFINE SHARED VARIABLE del AS LOGICAL.


DEFINE SHARED VARIABLE nrecs AS INTEGER.

Mostraremos um exemplo simples, um programa progSharedA executará um programa progSharedB. No


programa progSharedA temos a declaração de uma variável, esta será compartilhada entre ambos.

Exemplo

1 DEFINE
NEW SHARED
VARIABLE nome
AS CHARACTER NO-UNDO
FORMAT 'x(30)'
VIEW-AS FILL-IN
SIZE-PIX 90 BY 21
.

2 DO WITH FRAME frameA


TITLE
'Dentro do programa progSharedA'
SIZE 60 BY 3
AT ROW 1 COL 1
SIDE-LABELS:

3 UPDATE nome.

4 RUN progSharedB.p.

5 UPDATE nome.

6 END.
Programa ProgSharedA.p

136
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Durante a execução do programa progSharedB.p a variável nome deve ser declarada como Shared,
indicando que o programa pai a criou com a opção New Shared.

7 DEFINE
SHARED
VARIABLE nome
AS CHARACTER NO-UNDO
FORMAT 'x(30)'
VIEW-AS FILL-IN
SIZE-PIX 90 BY 21
.

8 DO WITH FRAME frameB


TITLE
'Dentro do programa progSharedB'
SIZE 60 BY 3
AT ROW 5 COL 1
1 COLUMN:

9 UPDATE nome.

10 END.

Programa ProgSharedB.p

Em todo a execução do progSharedA e do progSharedB, a sessão ativa da linguagem ABL compartilhará o


valor da variável, que pode ser alterada durante o processo.

Anotações

Compartilhamento de variáveis e objetos na sessão


DEFINE NEW GLOBAL SHARED VARIABLE first-time
AS LOGICAL INITIAL TRUE.

O compartilhamento de variáveis e objetos através da opção New Global Shared é bastante diferente da
opção com New Shared, pois não depende que o programa pai crie o compartilhamento da variável através
da opção New Shared e que o programa filho reutilize estes variáveis com a opção Shared.

Anotações

137
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

A tabela abaixo mostra algumas características entre as opções New Shared e New Global
Shared.

New Shared New Global Shared


Compartilha valores entre programas? Sim Sim
Depende da execução entre programas e Sim Não
subprogramas aninhados
Variáveis e objetos ficam compartilhados Não Sim
durante a sessão ABL
O compartilhamento se encerra com o fim dos Sim Não
programas
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercícios
Para a nomenclatura dos exercícios, utilize a máscara SHARE_<número do exercício>.P (SHARE
_1.p, SHARE _2.p).

1. Crie um programa que chame um subprograma, compartilhe uma variável inteira e


outra lógica entre os dois programas, utilize New Shared e Shared.
2. Crie uma variável do tipo data compartilhada com o New Global Shared e atribua valor
a esta através da instrução Update.
a. Crie um novo programa com o mesmo nome e a mesma declaração desta
variável.
b. Mostre o valor e verifique se está com o valor previamente inserido.
c. Não use programas aninhados.

139
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Procedimentos e funções
Procedimento são segmentos de códigos que podem ser internos ou externos, onde estes, externos, podem
ser chamadas à DLLs do Windows ou Bibliotecas Compartilhadas do UNIX, ou chamadas a outros programas
ABL.

Procedimentos internos
São os segmentos internos de códigos ABL que podem ser executados

Sintaxe procedimentos internos

PROCEDURE proc-name [ PRIVATE ] :

[ procedure-body ]

Exemplo de declaração de procedimento interno

PROCEDURE mostrarValor:
DISPLAY "Ola mundo".
END.

/*mostrar valor passado como parametro*/

RUN mostrarValor ( INPUT 100).

PROCEDURE mostrarValor:
DEFINE INPUT PARAMETER Valor AS INTEGER NO-UNDO.

DISPLAY valor.
END.

Anotações

Procedimentos de Bibliotecas Externas


São as chamadas às DLLs ou Bibliotecas compartilhadas do sistema operacional.

Sintaxe procedimentos externos

PROCEDURE proc-name
{ EXTERNAL "dllname" [ CDECL | PASCAL | STDCALL ]
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

[ ORDINAL n ] [ PERSISTENT ]
| IN SUPER } :

[ procedure-body ]

Exemplo com chamada ao procedimento externo

/*executando procedure externa, neste exemplo, da API do Windows*/

DEFINE VARIABLE result AS INTEGER.

MESSAGE "Usando o message do Progress ABL."


VIEW-AS
ALERT-BOX MESSAGE
BUTTONS OK
TITLE "Mensagem".

RUN MessageBoxA (0, "Agora usando a API do Windows",


"Aqui vai o titulo", 0, OUTPUT result).

PROCEDURE MessageBoxA EXTERNAL "user32.dll":


DEFINE INPUT PARAMETER hwnd AS LONG.
DEFINE INPUT PARAMETER mbtext AS CHARACTER.
DEFINE INPUT PARAMETER mbtitle AS CHARACTER.
DEFINE INPUT PARAMETER style AS LONG.
DEFINE RETURN PARAMETER result AS LONG.
END.

Anotações

Passagem de parâmetros
É a passagem de um ou mais valores para um procedimento interno, programa ou função.

Sintaxe

[ INPUT | OUTPUT | INPUT-OUTPUT ]


{ parm
| { { TABLE temp-table-name
| TABLE-HANDLE temp-table-handle
| DATASET dataset-name
| DATASET-HANDLE dataset-handle
} [ APPEND ] [ BY-VALUE | BY-REFERENCE | BIND ]
}
}

A linguagem ABL permite a passagem por valor, por referência e retorno.

141
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Por valor
[ INPUT ]
{ parm
| { { TABLE temp-table-name
| TABLE-HANDLE temp-table-handle
| DATASET dataset-name
| DATASET-HANDLE dataset-handle
} [ APPEND ] [ BY-VALUE | BY-REFERENCE | BIND ]
}
}

Exemplo

DEFINE VARIABLE icont AS INTEGER NO-UNDO INIT 1.

DISPLAY icont.

PAUSE.

RUN retornarValor ( INPUT icont ).

DISPLAY icont.

PROCEDURE retornarValor:
DEFINE INPUT PARAMETER valor AS INTEGER NO-UNDO.
valor = valor + 10.
DISPLAY valor.
END.

Anotações

Por referência
[ INPUT-OUTPUT ]
{ parm
| { { TABLE temp-table-name
| TABLE-HANDLE temp-table-handle
| DATASET dataset-name
| DATASET-HANDLE dataset-handle
} [ APPEND ] [ BY-VALUE | BY-REFERENCE | BIND ]
}
}

Exemplo

/*passagem de parametros por Referencia


*/
DEFINE VARIABLE icont AS INTEGER NO-UNDO INIT 1.

142
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

DISPLAY icont.

PAUSE.

RUN retornarValor ( INPUT-OUTPUT icont).

DISPLAY icont.

PROCEDURE retornarValor:
DEFINE INPUT-OUTPUT PARAMETER valor AS INTEGER NO-UNDO.

valor = valor + 10.


END.

Anotações

De retorno
[ OUTPUT ]
{ parm
| { { TABLE temp-table-name
| TABLE-HANDLE temp-table-handle
| DATASET dataset-name
| DATASET-HANDLE dataset-handle
} [ APPEND ] [ BY-VALUE | BY-REFERENCE | BIND ]
}
}

Exemplo

DEFINE VARIABLE icont AS INTEGER NO-UNDO INIT 1.

DISPLAY icont.

PAUSE.

RUN retornarValor ( OUTPUT icont).

DISPLAY icont.

PROCEDURE retornarValor:
DEFINE OUTPUT PARAMETER valor AS INTEGER NO-UNDO.

valor = valor + 10.


END.

Anotações

143
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Podemos passar ponteiros de tabelas e tabelas temporárias.

Passagem de ponteiros de tabelas


BUFFER buffer

Exemplo

FIND LAST customer NO-LOCK NO-ERROR.


IF AVAILABLE customer THEN
DISPLAY custnum NAME.

RUN meuprograma.p (BUFFER customer).

Exemplo meuprograma.p

DEFINE PARAMETER BUFFER bcustomer FOR customer.

DISPLAY bcustomer.NAME.

Anotações

Passagem de tabelas temporárias


TABLE temp-table-name

Exemplo

DEFINE TEMP-TABLE ttcustomer0 LIKE customer.

FIND LAST customer NO-LOCK NO-ERROR.


IF AVAILABLE customer THEN
DO:
CREATE ttcustomer0.
BUFFER-COPY customer TO ttcustomer0.
END.

144
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

RUN meuprogramat.p (INPUT TABLE ttcustomer0).

Exemplo meuprogramat.p

DEFINE TEMP-TABLE ttcustomer0 LIKE customer.

DEFINE INPUT PARAMETER TABLE FOR ttcustomer0.

FIND FIRST ttcustomer0.

DISPLAY ttcustomer0.NAME.

Anotações

145
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercício
Para a nomenclatura dos exercícios, utilize a máscara PASS_<número do exercício>.P (PASS_1.p, PASS_2.p).

1. Criar programa que execute procedimento externo, este deverá retornar a data de hoje.
2. Criar programa que execute procedimento interno, este deverá retornar a hora corrente.
3. Criar programa que execute procedimento interno, passe um número decimal, este procedimento
deverá retornar o número multiplicado por 2. Utilize um parâmetro com o número e outro
parâmetro de retorno para o valor calculado.
4. Criar programa que execute procedimento interno, passe um número decimal, este procedimento
deverá retornar o número multiplicado por 2. Utilize passagem por referência.

146
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Funções
A linguagem ABL possui várias funções como Index, Can-find, Lookup, Num-entries, mas em algumas
situações podemos ter a necessidade de criar nossas próprias funções.

São as chamadas User-Defined Functions, ou UDF.

Sintaxe

FUNCTION function-name [ RETURNS ] return-type


[ ( parameter [ , parameter ] ... ) ]
{ FORWARD
| [ MAP [ TO ] actual-name ] IN proc-handle
| IN SUPER
} .

Exemplo

FUNCTION duplicarValor RETURNS INTEGER (INPUT parm1 AS INTEGER):


RETURN (2 * parm1).
END FUNCTION.

FUNCTION retornarNome RETURNS CHARACTER ():


RETURN "Jaison Antoniazzi".
END.

MESSAGE retornarNome()
VIEW-AS ALERT-BOX.

Exemplo de Função em Programa Persistente

DEFINE VARIABLE hprogramaZ AS HANDLE NO-UNDO.

FUNCTION somar RETURNS DECIMAL ( INPUT valor1 AS DECIMAL,


INPUT valor2 AS DECIMAL) IN hprogramaZ.

RUN prog-persist-B-02-z.p
PERSISTENT
SET hprogramaZ.

DEFINE VARIABLE val1 AS DECIMAL NO-UNDO.


DEFINE VARIABLE val2 AS DECIMAL NO-UNDO.
DEFINE VARIABLE soma AS DECIMAL NO-UNDO.

UPDATE val1 val2.

soma = somar( val1, val2 ).

DISPLAY soma.
*A Função SOMAR está no programa prog-persist-b-02-z.p

Conteúdo do programa prog-persist-b-02-z.p

147
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

FUNCTION somar RETURNS DECIMAL ( INPUT valor1 AS DECIMAL,


INPUT valor2 AS DECIMAL) FORWARD.

PROCEDURE dividir:
DEFINE VARIABLE valor1 AS DECIMAL NO-UNDO.
DEFINE VARIABLE valor2 AS DECIMAL NO-UNDO.

UPDATE valor1 valor2.

DISPLAY valor1 / valor2 LABEL 'Divisao'.

END.

PROCEDURE subtrair:
DEFINE VARIABLE valor1 AS DECIMAL NO-UNDO.
DEFINE VARIABLE valor2 AS DECIMAL NO-UNDO.

UPDATE valor1 valor2.

DISPLAY valor1 - valor2 LABEL 'Subtrair'.

END.

PROCEDURE calcularMedia:
DEFINE VARIABLE valor1 AS DECIMAL NO-UNDO.
DEFINE VARIABLE valor2 AS DECIMAL NO-UNDO.
DEFINE VARIABLE valor3 AS DECIMAL NO-UNDO.
DEFINE VARIABLE valor4 AS DECIMAL NO-UNDO.

UPDATE valor1 valor2 valor3 valor4.

DISPLAY (valor1 + valor2 + valor3 + valor4) / 4


LABEL 'Media'.

END.

PROCEDURE divisivelpor2:
DEFINE VARIABLE valor1 AS DECIMAL NO-UNDO.

UPDATE valor1.

DISPLAY valor1 MODULO 2 = 0


LABEL 'Divisivel por 2?'
FORMAT 'É divisivel por 2/Nao sou divisivel!'.

END.

PROCEDURE listarClientes:
DEFINE VARIABLE valor1 LIKE customer.custnum
LABEL 'Semifinal PQP'
NO-UNDO.
DEFINE VARIABLE valor2 LIKE customer.custnum
LABEL 'Final'
NO-UNDO.

UPDATE valor1 valor2.

148
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

FOR EACH customer NO-LOCK


WHERE customer.custnum >= valor1
AND customer.custnum <= valor2:

DISPLAY customer.custnum customer.NAME customer.address


WITH
THREE-D
TITLE 'Listagem de clientes'.

END.

END.

FUNCTION somar RETURNS DECIMAL ( INPUT valor1 AS DECIMAL,


INPUT valor2 AS DECIMAL):

RETURN valor1 + valor2.

END.

Anotações

Programas e Funções Persistentes


São programas executados que ficam em memória, permitindo o uso de seus procedimentos e funções
internas que não são privados.

Sintaxe Run

RUN
{ extern-proc-name
| VALUE ( extern-expression )
| path-name<<member-name>>
}
[ PERSISTENT [ SET proc-handle ] ]
[ ON [ SERVER ] { server-handle | session-handle }
[ TRANSACTION DISTINCT ]
[ ASYNCHRONOUS
[ SET async-request-handle ]
[ EVENT-PROCEDURE event-internal-procedure
[ IN procedure-context ] ]
]
]
[ ( parameter [ , parameter ] ... ) ]
[ argument ] ...
[ NO-ERROR ]

As cinco regras dos programas persistentes


1. Declarar uma variável do tipo Handle (ponteiro de memória).
2. Executar um programa e armazenar o endereço de memória na variável Handle.

149
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

3. Testar se o programa ainda está em memória.


4. Executar os métodos ou procedimentos internos deste programa.
5. Remover o programa da memória.

Exemplo

Regra Programa

1 DEFINE VARIABLE hPrograma AS HANDLE NO-UNDO.

2 RUN meuprograma PERSISTENT SET hPrograma.

3 IF VALID-HANDLE(hPrograma) THEN
4 RUN metododentrodoPrograma1 IN hPrograma.

3 IF VALID-HANDLE(hPrograma) THEN
4 RUN metododentrodoPrograma2 IN hPrograma (INPUT 123).

3 IF VALID-HANDLE(hPrograma) THEN
4 RUN metododentrodoPrograma3 IN hPrograma (INPUT "Ola
mundo").

3
IF VALID-HANDLE(hPrograma) THEN
4
RUN metododentrodoPrograma4 IN hPrograma.

3
IF VALID-HANDLE(hPrograma) THEN
5
DELETE OBJECT hPrograma.

Para visualizar os procedimentos internos disponíveis em um programa persistente utilize a função Internal-
Entries.

Sintaxe

MESSAGE hPrograma:INTERNAL-ENTRIES
VIEW-AS ALERT-BOX INFO BUTTONS OK.

Procedimentos internos privados (Private) não poderão ser executados quando o programa estiver
persistente, pois não serão visíveis externamente.

Exemplo de programa persistente

DEFINE VARIABLE hprogramaB AS HANDLE NO-UNDO.

RUN prog-persist-b-01.p
PERSISTENT
SET hprogramaB.

150
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

RUN somar
IN hprogramaB.

RUN multiplicar
IN hprogramaB.

DELETE OBJECT hprogramaB.

Conteúdo do programa prog-persist-b-01.p

MESSAGE 'iniciou do programa B'


VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

PROCEDURE somar:

DEFINE VARIABLE valor1 AS DECIMAL NO-UNDO.


DEFINE VARIABLE valor2 AS DECIMAL NO-UNDO.

REPEAT:

UPDATE valor1 valor2.

DISPLAY valor1 + valor2 LABEL 'Soma'.

END.

END.

PROCEDURE multiplicar:

DEFINE VARIABLE valor1 AS DECIMAL NO-UNDO.


DEFINE VARIABLE valor2 AS DECIMAL NO-UNDO.

REPEAT:

UPDATE valor1 valor2.

DISPLAY valor1 * valor2 LABEL 'Produto'.

END.

END.

MESSAGE 'fim do programa b'


VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

Exemplo de programa persistente com leitura de clients

DEFINE VARIABLE hprogramaNinja


AS HANDLE NO-UNDO.

RUN prog-persist-B-02.p
PERSISTENT
SET hprogramaNinja.

RUN subtrair
IN hprogramaninja.

151
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

RUN dividir
IN hprogramaninja.

RUN listarClientes
IN hprogramaninja.

DELETE OBJECT hprogramaninja.

Conteúdo do programa prog-persist-b-02.p

PROCEDURE dividir:
DEFINE VARIABLE valor1 AS DECIMAL NO-UNDO.
DEFINE VARIABLE valor2 AS DECIMAL NO-UNDO.

UPDATE valor1 valor2.

DISPLAY valor1 / valor2 LABEL 'Divisao'.

END.

PROCEDURE subtrair:
DEFINE VARIABLE valor1 AS DECIMAL NO-UNDO.
DEFINE VARIABLE valor2 AS DECIMAL NO-UNDO.

UPDATE valor1 valor2.

DISPLAY valor1 - valor2 LABEL 'Subtrair'.

END.

PROCEDURE calcularMedia:
DEFINE VARIABLE valor1 AS DECIMAL NO-UNDO.
DEFINE VARIABLE valor2 AS DECIMAL NO-UNDO.
DEFINE VARIABLE valor3 AS DECIMAL NO-UNDO.
DEFINE VARIABLE valor4 AS DECIMAL NO-UNDO.

UPDATE valor1 valor2 valor3 valor4.

DISPLAY (valor1 + valor2 + valor3 + valor4) / 4


LABEL 'Media'.

END.

PROCEDURE divisivelpor2:
DEFINE VARIABLE valor1 AS DECIMAL NO-UNDO.

UPDATE valor1.

DISPLAY valor1 MODULO 2 = 0


LABEL 'Divisivel por 2?'
FORMAT 'É divisivel por 2/Nao sou divisivel!'.

END.

PROCEDURE listarClientes:
DEFINE VARIABLE valor1 LIKE customer.custnum
LABEL 'Semifinal PQP'

152
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

NO-UNDO.
DEFINE VARIABLE valor2 LIKE customer.custnum
LABEL 'Final'
NO-UNDO.

UPDATE valor1 valor2.

FOR EACH customer NO-LOCK


WHERE customer.custnum >= valor1
AND customer.custnum <= valor2:

DISPLAY customer.custnum customer.NAME customer.address


WITH
THREE-D
TITLE 'Listagem de clientes'.

END.

END.

Anotações

153
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Exercício
Para a nomenclatura dos exercícios, utilize a máscara PROC_<número do exercício>.P (PROC_1.p,
PROC_2.p).

1. Criar programa que execute procedimento externo, este deverá mostrar a data de hoje (Instrutor).
2. Criar programa que execute procedimento interno, este deverá mostrar a hora corrente (Instrutor).
3. Criar programa que utilize uma função para retornar a data de hoje mais 30 dias.
4. Crie um programa com os métodos mostrarData e mostrarHora (PROC_41.P). Execute o programa
(PROC_41.P) persistente para mostrar os procedimentos internos (internal-entries).
5. Execute o programa PROC_41.P persistente e execute os métodos mostrarData e mostrarHora.
Utilize as funções Date e Time.
6. Criar programa com procedimento interno e que neste procedimento exiba o seu nome completo.
7. Utilize o sexto exercício, agora utilize um procedimento externo para exibir o nome completo.
8. Construa um programa com dois procedimentos internos, leia a opção para executar o
procedimento 1 ou 2, utilizando IF THEN e ELSE execute o primeiro procedimento ou segundo.
9. Construa uma função que receberá o seu nome e sobrenome como parâmetros e retornará o seu
nome completo.
10. Construa uma função que receberá um valor decimal como parâmetro e retornará 13,85% do valor
passado.
11. Usando o nono exercício, mas agora construa na forma de programa persistente sendo chamado
pelo programa principal.
12. Usando o décimo exercício, mas agora construa na forma de programa persistente sendo chamado
pelo programa principal.
13. Usando o décimo primeiro exercício, mas agora construa na forma de programa persistente sendo
chamado pelo programa principal.

154
Bruno Henrique Joaquim Programando com Progress ABL v.1.5
bruno.joaquim@sulbras.com.br
(54) 99234.5460

Blocos de instruções e Transações


Blocos de instruções são segmentos lógicos de várias instruções iniciados com:

• Repeat,
• For,
• Programas ( na linha 0 ),
• Procedures Internas,
• Funções,
• Códigos de gatilhos,
• Do.

Transações são operações que serão executadas como uma unidade ou ACID (Atomicidade, Consistência,
Isolamento e Durabilidade), o escopo de transações está diretamente associado ao escopo de bloco que
pode ser desfeito, como Repeat, For, Programas e Procedures, Códigos de gatilhos, o bloco DO também cria
um bloco, mas por não ter características de um bloco que pode ser desfeito acaba propagando a transação,
se existir, para o bloco que contém o DO.

Para saber o número de blocos que um programa Progress ABL tem basta contar o número de “:” e adicionar
mais um pelo bloco automático criado no programa.

Comumente, na linguagem ABL, uma transação se inicia no começo do bloco (Repeat, For e Procedure,
Função) e termina no END deste.

Tipo do Bloco Cria bloco Mantêm a Transação?


Repeat Sim Sim
Procedure e Programa Sim Sim
For Sim Sim
Function Sim Sim
Do Sim Não
Código de gatilhos Sim Sim

Pode-se utilizar a função Transaction para verificar se há transação ativa ou através da compilação do
programa com a opção de LISTING.

Sintaxe função Transaction

TRANSACTION

Não confundir Opção Transaction com a Função Transaction, enquanto a opção Transaction é usada no
cabeçalho de blocos como o DO, FOR e REPEAT, a função Transaction é usada para exibir se o bloco está em
transação ou não.

Desfazendo a transação
A instrução undo informa à ABL para desfazer um bloco de transação. Também não se pode confundir a
instrução de UNDO com a opção UNDO dos cabeçalhos dos blocos DO, REPEAT e FOR.
Programando com Progress/ABL

Sintaxe da instrução UNDO

UNDO
[ label ]
[ , LEAVE [ label2 ]
| , NEXT [ label2 ]
| , RETRY [ label1 ]
| , RETURN [ return-value |
ERROR [ return-value | error-object-expression ] |

NO-APPLY ]
| , THROW error-object-expression
]

Exemplo de instrução Undo

MESSAGE "01 - Em transação?" TRANSACTION VIEW-AS ALERT-BOX.


dobloco:
DO TRANSACTION:
MESSAGE "02 - Em transacao?" TRANSACTION
VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

CREATE customer.
ASSIGN
customer.custnum = NEXT-VALUE(NextCustNum).

DISPLAY customer.custnum.
ASSIGN
customer.NAME = "<SEU NOME>"
customer.salesrep = "BBB".
/* desfazendo o bloco Do Transaction com a instrucao UNDO */
UNDO dobloco, LEAVE dobloco.
END.
DISPLAY "Terminou".

Anotações

Opção Undo
A opção UNDO utiliza-se no cabeçalho de uma das instruções DO, FOR e REPEAT para desfazer uma
transação em um bloco e para informar o que fazer a seguir quando ocorrer algum erro não esperado com
as opções ON ERROR, ON ENDKEY, ON STOP e ON QUIT.

Exemplo com opção Undo e Leave

DO TRANSACTION
ON ERROR UNDO, LEAVE:
CREATE customer.
ASSIGN
customer.custnum = NEXT-VALUE(NextCustNum).

DISPLAY customer.custnum.

156
Programando com Progress/ABL

UPDATE
customer.NAME
customer.salesrep.

/* forçando um erro no bloco */


INT('A').
RELEASE customer.
END.
DISPLAY "terminou".

Exemplo de opção Undo e Retry

DO TRANSACTION
ON ERROR UNDO, RETRY:

CREATE customer.
ASSIGN
customer.custnum = NEXT-VALUE(NextCustNum).

DISPLAY customer.custnum.
UPDATE
customer.NAME
customer.salesrep.

/* forçando um erro no bloco */


INT('A').

RELEASE customer.
END.

DISPLAY "terminou".

Importante: Não confunda a instrução Undo no corpo de um programa com a opção Undo usada no
cabeçalho Do, For e Repeat.

Anotações

Início e término de uma Transação


O início e término de uma transação está ligada ao início e término de um bloco.

A linguagem ABL por padrão inicia um bloco na linha 0 (zero) de todos os programas.

Uma regra simples para determinar onde se inicia um bloco é observar onde há “:”, com exceção dos rótulos
dos blocos.

Então, um bloco se inicia com a instrução Do, For, Repeat, Procedure, Function, procedure em ABL pode ser
tanto um programa ou uma procedure interna.

O término de um bloco está no END de um Do, For, Repeat, Procedure ou no final de um programa.

Vejamos o código:

157
Programando com Progress/ABL

DO TRANSACTION
ON ERROR UNDO, RETRY:
CREATE customer.

ASSIGN
customer.custnum = NEXT-VALUE(NextCustNum).

DISPLAY customer.custnum.
UPDATE
customer.NAME
customer.salesrep.

/* forçando um erro no bloco */


INT('A').

RELEASE customer.
END.

DISPLAY "terminou".

Seguindo a regra do dois pontos “:” o bloco se inicia na instrução “DO TRANSACTION ON ERROR UNDO,
RETRY:” e se encerra com o END deste DO TRANSACTION. Todo o código que está entre o “:” do DO
TRANSACTION e o END deste, faz parte da transação.

Mas há uma forma mais simples de constatar.

Compile o programa com a opção Listing. Você pode realizar esta compilação com a Ferramenta de
Compilação da Progress ou, ou através da instrução Compile.

Application Compiler

158
Programando com Progress/ABL

Janela Compiler Options

Ao realizarmos a compilação do nosso código, será gerado um arquivo com este formato:

...mp\progdotrans1.p 10/28/2013 22:51:57 PROGRESS(R)


Page 1
Coluna BLK

{} Line Blk
-- ---- ---
1 dobloco:
2 1 DO TRANSACTION:
3 1
4 1 MESSAGE TRANSACTION
5 1 VIEW-AS ALERT-BOX INFO BUTTONS OK.
6 1
7 1 CREATE customer.
8 1 ASSIGN customer.custnum = NEXT-VALUE(NextCustNum).
9 1
10 1 DISPLAY customer.custnum.
11 1 ASSIGN
12 1 customer.NAME = "<SEU NOME>"
13 1 customer.salesrep = "BBB".
14 1
15 1 /* desfazendo o bloco do transaction */
16 1 UNDO dobloco, LEAVE dobloco.
17 1
18 END.

159
Programando com Progress/ABL

19
20 DISPLAY "Terminou&q