Você está na página 1de 53

AS/400 Capítulo 1: Introdução

Este tutorial serve de introdução ao sistema AS/400 (System i5) e as linguagens de


programação RPG e DDS. Este é o primeiro de uma série de nove capítulos que
tratam vários aspectos deste sistema.

O AS/400 é uma plataforma computacional lançada em 1988 pela IBM. Atualmente é


oficialmente designado por System i5 embora o termo AS/400 seja ainda muito
usado. Ao longo dos capítulos vamo-nos referir a este sistema como AS/400, fique
apenas ciente que esta já não é a sua designação oficial.

O sistema operativo presente nestas máquinas é, na maioria das vezes, o OS400. Este
sistema contém um sistema gestor de bases de dados integrado assim como diversos
compiladores,editores e outras aplicações. O AS/400 suporta várias linguagens de
programação como o Java, C, SQL, Assembly, COBOL, PHP, etc.

Requisitos mínimos para completar este tutorial:

• Conhecimentos básicos de programação.


• Conhecimentos básicos de bases de dados (modelo relacional, SQL).
• Acesso a um servidor AS/400.
• Terminal de ligação a um servidor AS/400 (para criar este tutorial foi usado o
software Moshasoft).

Será construída uma pequena aplicação onde constarão exemplos das matérias
tratadas em cada capítulo. A aplicação que vamos construir permitirá gerir um
conjunto de lojas e respectivos clientes. No último capitulo encontra-se um conjunto
de ficheiros de texto com todo o código criado ao longo do tutorial.

A aplicação irá ter o seguinte modelo de dados:

Modelo de Dados
AS/400 Capítulo 2: Comandos
Para navegar no sistema AS/400 é necessário conhecer alguns comandos. Os
comandos têm uma sintaxe simples que o poderão ajudar, por exemplo, a relembrar
comandos esquecidos.

Os comandos em AS/400 podem ser executados a partir do prompt do sistema


tipicamente situado em baixo com o seguinte aspecto:

==> ______________________

Por baixo do prompt pode encontrar a lista das teclas de função ativas neste menu.

Colocando o cursor em cima da linha escreva GO e pressione em seguida F4. Aparece


um menu especifico ao comando GO com todas as opções que este pode ter. Pode
utilizar o F4 para ajudá-lo a completar a sintaxe de qualquer comando.

Escreva MAJOR na opção 'MENU' e pressione Enter. Isto seria o mesmo que escrever
na linha de comandos: GO MAJOR. Este comando mostra-lhe o conjunto dos grupos
de comandos mais importantes em AS/400.

A palavra “Mais...” no fim da listado lado direito indica-lhe que existem linhas que não
estão visíveis, pode vê-las carregando na tecla Page Down ou movendo o scroll do
rato para baixo.

Coloque agora o cursor em cima de qualquer uma das opções da lista e pressione
F1.Aparece uma janela com a ajuda relativa a essa opção. Esta funcionalidade
encontra-se disponível em grande parte dos menus e utilitários (pressione F3 para
fechar a janela de ajuda).

Para selecionar uma das opções basta escrever no prompt o número que lhe
corresponde.

Pressione agora F3 para voltarmos ao menu inicial.


Sintaxe dos comandos
Os comando AS/400 são tipicamente constituídos por duas partes(geralmente de três
letras cada): o verbo e o sujeito. Por exemplo, CRTLIB é o comando create library e é
constituído por um verbo CRT (create) e o sujeito LIB(library). Existem contudo
exceções à regra como é o caso do comando GO que já vimos antes. Em seguida
estão alguns exemplos de verbos e sujeitos comuns.

Verbo Significado

CPY Copiar (Copy)


DSP Mostrar (Display)
DLT Apagar (Delete)
WRK Trabalho (Work)
Verbo Significado

DEV Dispositivo (Device)


F Ficheiro (File)
MSG Mensagem (Message)
SPLF SpoolFile

Quando não souber o nome exato de um comando pode escrever GO VERB onde
encontra uma listagens dos comandos organizada por tipo de utilidade.

AS/400 Capítulo 3: Bibliotecas


Pode usar uma biblioteca em AS/400 da mesma forma que utilizaria uma pasta em
Windows para organizar ficheiros, por exemplo, existem contudo algumas diferenças,
como seria de esperar. Neste capítulo vamos ver como funcionam as bibliotecas em
AS400.

Uma biblioteca assemelha-se a uma pasta do Windows. Em AS/400 uma biblioteca é


mais um objeto do sistema que tem a função específica de conter outros objetos
(ficheiros executáveis, ficheiros source, etc). As bibliotecas não podem conter outras
bibliotecas. Assim a estrutura do sistema é uma lista de bibliotecas, ao contrário do
Windows onde existe uma estrutura em árvore.

Criar uma biblioteca


Vamos criar agora uma biblioteca onde vamos colocar os ficheiros necessários ao
longo do tutorial. Escreva o comando:

CRTLIB DEMO
A sua biblioteca está criada.

Mudar de biblioteca atual (CURLIB)


Agora para trabalhar com objetos da biblioteca DEMO pode se posicionar dentro dela,
assim não tem que especificar de cada vez que quer trabalhar com um ficheiro a
biblioteca onde este se encontra.

Todos os objetos que criar vão ser colocados por defeito na sua CURLIB.
Paras e colocar na biblioteca DEMO escreva:

CHGCURLIB DEMO

Sempre que se quiser referir à biblioteca onde se encontra presentemente pode usar
tanto o nome da biblioteca como a palavra CURLIB.

Se quiser alterar a sua biblioteca de abertura no sistema, para não ter que fazer
sempre CHGCURLIB ao iniciar a sessão, pode executar o comando:

CHGPRF CURLIB DEMO

Caso execute este comando, sempre que iniciar uma sessão AS/400 irá ser colocado
por defeito na biblioteca DEMO.
Note que se não mudar a sua biblioteca de abertura e no início da sessão não fizer
CHGCURLIB poderão surgir erros de compilação caso use no código um ficheiro cuja
biblioteca não esteja explicitamente definida.

Lista de bibliotecas

Todos os comandos que executamos estão guardados em bibliotecas específicas do


sistema. Quando nao é explicitamente indicada a biblioteca onde o comando se
encontra o sistema vai procurar em cada biblioteca pela ordem em que estas se
encontram na lista de bibliotecas do sistema. Por exemplo, se existirem dois
comandos com o mesmo nome no sistema (em bibliotecas diferentes) o AS/400 vai
executar aquele que estiver na biblioteca colocada mais acima na lista de bibliotecas.
Só podem existir ficheiros na mesma biblioteca com nomes iguais se forem de tipos
diferentes.

Pode ver a lista de bibliotecas com o comando:

DSPLIBL

Como pode ver na listagem existem diferentes tipos de bibliotecas:


• SYS: Bibliotecas de sistema. Contém os objectos essenciais ao bom
funcionamentos do sistema (comandos,utilitários, compiladores, etc).
• CUR: Indica a biblioteca onde se encontra actualmente.
• USR: Bibliotecas de utilizador (podem tanto ser criadas pelo próprio utilizador
como pelo fabricante do sistema).

Prima agora F3 para voltar ao menu anterior.

AS/400 Capítulo 4: SQL

Agora que já criamos uma biblioteca e vimos o funcionamento básico do AS/400


vamos ver como podemos usar SQL para manipular tabelas.

Para prosseguir com esta secção já deve ter criado a biblioteca DEMO e definido-a
como a sua CURLIB.

Insira na linha de comandos o comando Start SQL:


STRSQL

É assim iniciada uma sessão SQL numa aplicação AS/400. Esta aplicação reconhece a
sintaxe da maioria dos comandos SQL comuns (CREATE, INSERT, DELETE, SELECT,
DROP, etc).

STRSQL
Criar uma tabela com SQL

A partir da linha de comandos SQL vamos criar a tabela CLIENTES e inserir alguns
registos. Vamos supor que os numeros de telefone só poderão ter no máximo 9
dígitos.

CREATE LIBRARY DEMO/CLIENTS( id_cli numeric(10) PRIMARY KEY, name_cli char(50), birth_cli date, phone_cli
numeric(9) )

Nota: Pode escrever o código em linhas separadas, como no exemplo ou


continuamente numa linha desde que não prima ENTER antes de terminar de inserir
o comando.

Deve-lhe aparecer uma mensagem a dizer que a tabela foi criada.

Se quiser ver mais linhas de comando pode carregar em Page Down ou mover o scroll
do rato para baixo. Ao fazê-lo o prompt move-se para cima no ecrã dando mais
espaço a novas linhas.

Faça:

SELECT * FROM CLIENTS

Pode ver que a tabela foi criada, o nome das colunas e também que não tem nenhum
registo. Vamos então inserir alguns registos.

Prima F3 para sair da vista da tabela e introduza os seguintes comandos.


INSERT INTO CLIENTS (ID_CLI, NAME_CLI, BIRTH_CLI, PHONE_CLI) VALUES (1, 'Mary', '12/09/1967', '999999999')
INSERT INTO CLIENTS
(ID_CLI, NAME_CLI, BIRTH_CLI, PHONE_CLI) VALUES (2, 'Tom', '09/01/1979', '123456789')

Inserir dados numa tabela


Faça de novo o SELECT para verificar se as linhas foram inseridas corretamente.

Prima agora F3 para sair da linha de comandos. Aparece-lhe agora um conjunto de


opções para selecionar a que pretende. No campo onde deve inserir o valor escreva
um número fora das opções dadas, por exemplo 5, e prima ENTER. Aparece-lhe, como
seria de esperar, uma mensagem de erro no fundo do ecrã. Experimente pressionar
F3 ou inserir outro valor no campo. Não vai conseguir pois o ecrã encontra-se
bloqueado. Existem alguns erros que bloqueiam o menu, quando isto acontecer
prima ESC e o ecrã voltará ao normal.
Selecione depois a opção 1 para sair da aplicação de SQL guardando a sessão.

Funções SQL embutidas


Existem algumas funções pré definidas no sistema que se revelam bastante úteis
quando usamos SQL. Nas tabelas que se seguem descrevem-se algumas das funções
mais relevantes.

Funções básicas
Se está familiarizado com o SQL deve estar familiarizado com estas funções.
Function Description

MAX Retorna o valor mínimo dentro do conjunto de valores definidos.


MIN Retorna o valor máximo dentro do conjunto de valores definidos.
AVG Retorna a média do conjunto de valores definidos.
SUM Retorna a soma total do conjunto de valores definidos.
COUNT Retorna o número de registos existentes no conjunto de valores definidos.

Exemplo (retorna o valor máximo da coluna ID_CLI da tabela CLIENTS):

SELECT MAX(ID_CLI) FROM CLIENTS

Funções numéricas
Function Description

ABS(N) Retorna o valor absoluto do conjunto de N.


COS(A) / ACOS(A)
SIN(A) / ASIN(A) Funções trigonométricas básicas.
TAN(A) / ATAN(A)
CEILING(N)
Retorna o arredondamento de N à unidade acima/abaixo.
FLOOR(N)
DEGREES(R) Converte um valor em radianos num valor em graus.
RADIANS(D) Converte um valor em graus para radianos
LN(N) Retorna o valor do logaritmo natural (base e) / logaritmo base 10
Function Description

LOG10(N)

Funções de tratamento de strings


Function Description

CHAR(N) Returns the the string representation of the number N.


CHAR_LENGTH(S) Returns the length of a string.
CONCAT(S1, S2) Concatenates S1 with S2.
SUBSTR(S, I, L) Returns a substring of S, starting at index I of lenght L.
LOWER(S) Returns the lowercase representation of S.
UPPER(S) Returns the uppercase representation of S.
TRIM(S) Removes spaces from the beggining and and of S.
RTRIM(S) LTRIM(S) Removes spaces at the begging (right) or end (left) of S.

Funções de data e hora


Function Description

CURDATE()

Retorna a data/hora atual do sistema.

CURTIME()

DATE(D)
Converte uma string que contém uma representação de uma data/hora
num valor no formato data/hora.
DATE(T)

DAY(D) Extrai de uma variável do tipo data o número do dia (1-31). 


WEEK(D) Extrai de uma variável do tipo data o número da semana num ano (1-54).
MONTH(D) Extrai de uma variável do tipo data o número do mês (1-12).
YEAR(D) Extrai de uma variável do tipo data o ano.
Retorna o dia da semana de uma dada data (1-7). O valor 1 representa o
DAYOFWEEK(D)
Domingo.
Retorna o dia da semana de uma dada data (1-7). O valor 1 representa a
DAYOFWEEK_ISO(D)
segunda-feira.
DAYOFYEAR(D) Retorna um valor que identifica o número do dia num ano (1-366).
Function Description
HOUR(T) Extrai de uma variável do tipo TIME o valor da hora (0-24).
MINUTE(T) Extrai de uma variável do tipo TIME o valor do minutos.
SECOND(T) Extrai de uma variavel do tipo TIME o valor do segundo.
MICROSECOND(T) Extrai de uma varável do tipo TIME o valor do microsegundo.

AS/400 Capítulo 5: Ficheiros Físicos

Pode usar ficheiros físicos para definir tabelas, criar código executável, etc. Vamos ver
agora os aspectos básicos necessários para trabalhar com ficheiros.

Após a criação de uma tabela em SQL vamos criar as restantes com código DDS.

Os ficheiros de sources são ficheiros que podem ter vários membros. Cada membro
representa o código fonte de um objeto executável ou um objeto executável.

Podemos dizer que um ficheiro de sources é uma espécie de pasta onde organizamos
os vários ficheiros com o código propriamente dito e com os respectivos objetos
executáveis (isto depois de se terem compilado os ficheiros fonte).

Por convenção os ficheiros source seguem um certo padrão:


•QRPGLESRC – ficheiro que guarda os membros escritos em linguagem RPG-ILE
•QDDSSRC – guarda os membros escritos em DDS
•QRPGSRC – ficheiro que guarda os membros escritos na linguagem RPG
tradicional.
Como é possível ver os nomes começam sempre por Q e terminam em SRC. Não é
obrigatório seguir estas definições, nem existe nenhum problema ao nível do sistema
se existir, por exemplo, um membro RPG no ficheiro QDDSSRC, mas por uma questão
de organização e por ser uma convenção plenamente estabelecida é aconselhável
segui-la.
Vamos então criar o nosso ficheiro de sources de DDS para depois criarmos a nossas
tabelas.
CRTSRCPF FILE(DEMO/QDDSSRC)

Se se encontrar na biblioteca DEMO não precisa especificá-la, escreva apenas o nome


do ficheiro.
PDM (Programming Development Manager)

Vamos agora usar o utilitário PDM que nos ajuda a criar o código fonte e compilá-lo. O
PDM utiliza o editor de texto SEU (Source Entry Utility), que mais à frente veremos
como utilizar.

STRPDM

Deve surgir um ecrã semelhante a este:

Ecrã do PDM

Escolha a opção '3. Work with members', pois vamos criar alguns membros do
ficheiro QDDSSRC. A opção 2 permite trabalhar com objetos executáveis e a 1 com
bibliotecas.
O menu seguinte pede-lhe o nome do ficheiro com que pretende trabalhar e a
biblioteca onde este se encontra. Insira QDDSSRC no ficheiro e DEMO na biblioteca.

Note que apesar de no PDM estar a ver ficheiro de uma dada biblioteca não está
necessariamente colocado dentro dela. Pode estar na biblioteca DEMO1 a ver
ficheiros da biblioteca DEMO2, por exemplo.
Criar ficheiro de sources

Deve-lhe surgir o menu onde pode encontrar todas as opções para trabalhar com os
membros do ficheiro.

Listagem do ficheiro de sources

Vamos então criar o nosso primeiro membro. Carregue em F6 (como pode ver nas
opções em baixo “F6=Create”). Escreva os dados como vê na imagem em baixo:

Criar um membro

Trabalhar com o SEU (Source Entry Utility)

Ecrã do SEU:
Ecrã do SEU

A linguagem DDS e RPG são linguagens posicionais o que significa que cada elemento
têm uma linha e coluna específica onde deve ser colocado. No entanto, o SEU dá uma
ajuda a colocar cada opção no seu lugar. Se colocar o cursor numa linha qualquer e
carregar F4 aparecer-lhe-á um prompt como o da figura seguinte onde puderá por os
valores diretamente e o SEU faz a colocação de cada campo no sítio correto. Se quiser
fechar o prompt carregue F12.

Trabalhar com SEU

Inserir nova linha


Coloque um caracter 'i', sem plicas, em qualquer posição da coluna numerada à
esquerda. Ao carregar ENTER é inserida uma nova linha imediatamente abaixo.

Apagar uma linha

Escreva o carácter 'd', sem plicas, em qualquer posição da coluna numerada à


esquerda e prima ENTER.

Apagar um conjunto de linhas

Para apagar um conjunto de linhas seguidas de uma só vez insira, na coluna


numerada à esquerda, 'dd' na primeira linha que quer apagar e na última, prima
ENTER .
Sintaxe DDS

Vamos começar por definir o ficheiro SHOPS como está em baixo e de seguida
apresenta-se detalhadamente as instruções linha a linha.

UNIQUE R
SHOPR
ID_SHP 10P
NAME_SHP 25A
MANAGER_SH 50A K ID_SHP

Linha 1

Temos de especificar o comando UNIQUE para a primeira linha da definição da


tabela, para nos certificarmos que a chave primária tem um valor único para cada
registo. Carregue em F4 e escreva unique no campo functions.

Linha 2

Definição do tipo de registo do ficheiro. O tipo de registo serve para identificar todas
os campos do ficheiro, vamos ver um exemplo do seu uso mais à frente nos display
files. Insira uma nova linha como explicado anteriormente e carrega em F4
novamente. A letra 'R' deve constar no campo Name Type e SHOPR no Name.

Linhas 3, 4 e 5

Definem os campos da tabela. Na linha 3, por exemplo, ID_SHP é o Name, 10 é a


Length do campo (deve estar alinhado à direita), P é o tipo de dados que vão ser
guardados (Data Type), neste caso um valor numérico.

Os tipos de dados mais comuns:


•A - Alfanumérico
•S – Numérico (Zoned Decimal)
•P – Numérico (Packed Decimal)
•L - Data
Para mais informações sobre os tipos de dados carregue em F1 quando tiver o cursor
no campo Data Type.Ou consulte a Referência ILE RPG.

Linha 6
Definição do campo chave, com 'K' no Name Type e o nome do campo exactamente
como foi definido acima no campo Name. Para definir mais que uma chave basta
definir uma linha começada por 'K' para cada uma das chaves.

Quando tiver o seu ficheiro completo carregue em F3 para sair e confirme que quer
guardar as alterações.
Funções úteis DDS
Se quiser usar alguma destas funções deve colocá-la no campo functions.

CHECK
•CHECK(AB): Permite que o campo tenha o valor nulo. (Allow Blank).
•CHECK(ME): Obriga a que seja inserido um valor no campo (Mandatory Enter).
•CHECK(MF): Obriga a que todos os caracteres do campo sejam preenchidos
(Mandatory Fill).

COMP

Permite fazer comparações de valores. A sintaxe é COMP(operador-relacional valor).


Onde o operador relacional pode tomar os seguintes valores:

•NL (not less than)


•GT (greater than)
•NG (not greater than)
•LE (less than or equal to)
•GE (greater than or equal to)

DATFMT

Especifica o formato que uma data irá tomar. As possibilidade são:

•*ISO: yyyy-mm-dd
•*EUR: dd.mm.yyyy
•*USA: mm/dd/yyyy
•*MDY: mm/dd/yy
•*DMY: dd/mm/yy
•*YMD: yy/mm/dd

TIMFMT

Especifica o formato que uma hora irá tomar. As possibilidade são:

•*ISO: hh.mm.ss
•*EUR: hh.mm.ss
•*USA: hh:mm AM/PM
•*HMS: hh:mm:ss

RANGE

Define o valor máximo e mínimo que um campo pode tomar.

Exemplos:
•Para um campo numérico: RANGE(4 9)
•Para um campo não numérico: RANGE('4' '9')

VALUES
Permite especificar todos os valores válidos num campo.

Exemplo:
•Para um campo numérico: VALUES(4 5 6 7 8 9)
•Para um campo não numérico: VALUES('a' 'b' 'c' 'd')

DFT

Especifica um valor por defeito.

REFFLD

Define que um campo está a referenciar outro de outra tabela. Nestes casos não se
define nem o tipo de dados nem o comprimento e coloca-se um 'R' no campo Ref do
prompt.

Exemplo:

CARD_MOV R REFFLD(ID_CRD DEMO/CARDS)

Compilação de ficheiros

Para criar o objeto que vai realmente guardar os dados (como já foi dito atrás, este
ficheiro guarda só o código fonte) escolha a opção '14-Compilar' para o ficheiro que
acabou de criar.

Listagem do ficheiro
Este tutorial não vai incidir sobre a análise dos ficheiros resultantes da compilação,
mas se se quiser aventurar e tentar analisar os ficheiros pode fazê-lo escrevendo o
comando WRKSPLF (Work Spool File) no prompt. As mensagens mais importantes da
compilação aparecem usualmente no final do ficheiro com o mesmo nome que o
ficheiro que acabou de compilar (a compilação mais recente aparece mais abaixo na
lista).

Uma maneira rápida de verificar se a compilação foi bem sucedida é confirmar a


criação do ficheiro. Para isso vá à opção '2-Work with Objects' do menu inicial do PDM
e coloque as opções como estão descritas na imagem seguinte e pressione Enter.

PDM: Trabalhando com objetos

Agora verifique se existe na lista um membro com o nome SHOPS (o mesmo que deu
ao membro com o código fonte).

Tenha no entanto atenção que isto só funciona corretamente para a primeira


compilação, porque um objeto mantém-se sempre com os dados da última
compilação bem sucedida. Portanto se for alterar o seu ficheiro e compilá-lo
novamente, mesmo que a compilação resulte em erro, o ficheiro continua a existir no
sistema. Pode no entanto apagá-lo antes da compilação (no mesmo menu onde vai
verificar a sua existência), assim certifica-se que o ficheiro resultou da última
compilação.

Tem agora toda a informação necessária para conseguir criar ficheiros DDS. Crie o
ficheiro CARDS e MOVEMENTS, usando os nomes que são dados no modelo de dados,
pois vamos usá-los mais a frente. Quanto terminar, ou se surgir alguma dúvida, pode
consultar os ficheiros com o resultado final.

Para informações mais pormenorizadas sobre os ficheiros DDS visite os recursos da


IBM.
AS/400 Capítulo 6: RPG

O RPG é um dos pilares da plataforma AS/400. Foi originalmente desenhado como


uma ferramenta de consulta foi entretanto expandido e é neste momento uma
linguagem de progamação bastante poderosa. Vamos neste capítulo ver como utilizar
o RPG.

RPG é uma linguagem vocacionada para aplicações de negócios. Originalmente a sigla


significava Report Program Generator, mas atualmente a sigla já não tem oficialmente
nenhum significado. A última versão é o RPG IV, que é a versão que vamos utilizar
para seguir este tutorial.

O RPG, tal como o DDS, é uma linguagem posicional, apesar de na sua versão 4 existir
lugar para um formato livre que dentro de algumas restrições permite a colocação do
código em qualquer coluna/linha.

Dentro do código RPG existem vários tipos de expecificações possíveis. Todas seguem
uma ordem pela qual devem aparecer no ficheiro e todas têm funções diferentes.
Cada letra da expecificação representa a letra que deve ser colocada na posição inicial
de cada linha. Segue-se a listagem das especificações segundo a ordem pela qual
devem aparecer no ficheiro.

Especificação H (header)

Opções relativas à geração do programa ou à sua execução.

Especificação F (file)

Definição dos ficheiros usados e de como são usados no programa. Opções possíveis
na especificação F (para ver ao pormenor o que cada um dos campos representa
coloque o cursor no campo e carregue em F1):
Especificação F

Especificação D (definition)

Define os dados utilizados, por exemplo variáveis.

Especificação D

Especificação C

Nesta especificação define-se o código que o programa vai executar. Apenas existe
um formato livre para esta especificação (o código pode estar em qualquer posição),
mas para isso deve-se delimitar o código livre com free end-free uma posição a seguir
ao início da linha. No formato livre não se usa o 'C' no início da linha.

Sintaxe Básica RPG


Operadores válidos

= (comparação e atribuição), +, -, *, /, >, >=, <, <=, <>, NOT, AND, OR.

Expressões Condicionais

if condição;
//código else;
if
outra-condição; …
endif;
endif;

Ciclo do-while

doW condição;
// código endDo;
Criação e definição do ficheiro RPG

Vamos criar agora um programa que vai mostrar no ecrã o número de cartões que
tem o cliente com ID = 1.

Deve inserir alguns registos na tabela CARDS associados ao cliente 1. Faça-o a partir
do STRSQL.

Crie ficheiro de sources DEMO/QplainSRC. Dentro deste ficheio de sources crie um


ficheiro com o nome COUNTCARDS do tipo SQLplain.

Como não vamos precisar de abrir explicitamente nenhuma tabela, não vamos ter
nenhuma linha da especificação F.
Vamos ter que definir uma variável com o nome count, que vai guardar o número de
cartões do cliente. Coloque a letra 'd' na primeira coluna do SEU e carregue F4 para
ver os pormenores. Esta vai ser uma variável simples (no campo Declaration Type
deve estar 's') do tipo numérico com 5 dígitos de comprimento e zero casas decimais.
Inicie a variável a 0 com a ajuda da função INZ(valor-inicial) no campo Keywords.
Conseguiu criar a variável com a ajuda do prompt? Se não, pode ver o resultado final
mais à frente.

Tente criar os seguintes pontos com atenção a que em formato livre pode identar o
código da maneira que preferir e tem que colocar sempre um ponto e vírgula no final
de todas as linhas (entre o /free /end-free) e cada linha dentro do formato livre deve
começar pelo menos na posição 3 do SEU (na coluna seguinte á barra do /free).
•Inicie (/free) e finalize (/end-free) o bloco de código em linhas separadas,
começando na 2º coluna do SEU.
•Mostre o conteúdo da variável count. Para mostrar valores no ecrã usa-se a
função dsply, cuja sintaxe é: dsply valor.
•Na última linha, antes do /end-free, deve ativar o indicador de fim de código
*inlr (in last row) como activo: *inlr = *on; .

Deve ficar com algo deste género.

* definição da variável Dcount s 5P 0


INZ(0) /free
dsply count;
* //mostra no ecrã o valor contido na variável *inlr = *on; * //indica ao
compilador que se encontra na última linha /end-free

Se compilar agora este codigo (opção 14 do PDM)  e a compilação for bem sucedida
chame o programa a partir do prompt:
call DEMO/COUNTCARDS

Deve surgir a seguinte informação:

dsply 0

Podem aparecer vários valores (de eventos anteriores), mas o que lhe interessa é
sempre o que está na linha mais em baixo.

Ainda nos falta contar o número de cartões que o cliente tem.

SQL Embutido e Subrotinas

Para fazer consultas e alterações a tabelas vamos usar código SQL, pois já deve saber
usá-lo, mas note que é possível fazer consultas a tabelas usando código especifico do
RPG.

Para imbutir SQL no código RPGILE temos que o colocar no formato:

c/EXEC SQL c+
instrução-SQL c/END-EXEC

Repare que eu escrevi instrução e não instruções. Isso é porque em cada EXEC só
pode existir uma função SQL, mas vamos ver um exemplo melhor mais à frente.
Sendo assim teríamos (escreva o código seguinte no final do ficheiro, depois do /end-
free):

c/EXEC SQL c+
SELECT COUNT(*) INTO :count FROM DEMO/CARDS c+
WHERE CLIENT_CRD = 1 c/END-
EXE

Para poder organizar melhor o código vamos colocar esta instrução SQL dentro de
uma subrotina. Uma subrotina é uma espécie de função que não recebe parâmetros,
nem devolve nenhum valor, mas pode alterar valores definidos a nível global do
programa. Dentro da subrotina pode ter código em formato livre, formato fixo e
instruções EXEC.

Fora do bloco /free vou definir a subrotina getNrCards e colocar la dentro o código do
EXEC SQL. Pode usar a ajuda do prompt (F4) para situar corretamente as palavras.

Sendo assim teríamos:

c getNrCards begsr c/EXEC SQL


c+ SELECT
COUNT(*) INTO :count FROM DEMO/CARDS c+ WHERE
CLIENT_CRD = 1 c
endsr

Para agora conseguir executar este bloco de código preciso invocar a subrotina
dentro do bloco /free principal:

exSr getNrCards; //execute sub-routine getNrCards

Não se esqueça que isto tem de estar antes de fazer o display da variável.
Tente agora compilar e correr novamente. Obteve o mesmo resultado? Se sim,
certifique-se que o cliente 1 existe e que este tem registos associados na tabela
CARDS (e que todo o tutorial até aqui está corretamente concluído!). Se mesmo assim
não resultar verifique se o seu código está completamente correto:

Dcount s 5P 0 INZ(0)
*------------------------------------------------* /free
exSr
getNrCards; dsply count;
*inlr = *on;
/end-free
*------------------------------------------------*
c getNrCards begsr
c/EXEC SQL
c+ SELECT COUNT(*) INTO :count FROM DEMO/CARDS
c+ WHERE CLIENT_CRD = 1
c/END-EXEC
c endsr

AS/400 Capítulo 7: Módulos e Procedimentos


A utilização de módulos revela-se extremamente útil, principalmente em grandes
aplicações, pois permite a reutilização de código de forma relativamente simples.

Um módulo é um componente de um programa executável. Quando compilamos um


módulo não obtemos um programa executável, mas antes uma unidade que, quando
interligada com outras, resulta no programa executável.

Um módulo pode ser constituído por um ou mais procedimentos. Um procedimento


é uma espécie de função. É possível passar variáveis por parâmetro e retornar valores
de um procedimento.

Uma das vantagens dos módulos é permitir a reutilização do código, visto que o
mesmo módulo pode ser utilizado por mais que um programa.

Criação de um programa a partir de módulos


Os módulos são interligados com o comando:
CRTPGM(PGM_NAME) MODULE(MAIN_MOD MOD1 MOD2...)

Assume-se sempre que o primeiro módulo da lista é o principal. Neste caso,


MAIN_MOD é o módulo principal do programa.

Para chamar o programa só tem que escrever no prompt: CALL PGM_NAME

Criação dos módulos


Vamos criar dois módulos que depois vamos interligar. O que os nossos módulos vão
fazer é o seguinte: o módulo principal envia uma data de aniversário para um
procedimento noutro módulo; este por sua vez retorna o número de anos passados
desde essa data (a idade). Vamos fazer isto para todos os elementos da tabela
clientes.
Vamos começar pelo módulo principal. Comece por criar um ficheiro SQLplain com o
nome MAIN_MOD.

Defina uma variável do tipo data que vai guardar o valor da data de aniversário -
chame-lhe birth. Define também uma variável numérica para guardar a idade
retornada - chame-lhe age.

Vamos construir um cursor para correr a tabela de clientes. Para isso temos que ter 4
sub-rotinas para as seguintes funções:

Declarar o cursor (declareCursor)

DECLARE CURSOR1 CURSOR FOR SELECT BIRTH_CLI FROM


DEMO/CLIENTS

Abrir o cursor (openCursor)

OPEN CURSOR1

Ir buscar dados ao cursor (fetchCursor)

FETCH CURSOR1 INTO :birth

Fechar o cursor (closeCursor)

CLOSE CURSOR1

Agora na parte principal do programa vamos ter que chamar a subrotina para
declarar e depois para abrir o cursor, dentro de um ciclo fazer o fetch do cursor e
depois fechar o cursor. Pode fazer o ciclo da seguinte maneira:
exSr fetchCursor; dow
sqlcod <> 100; …

exSr fetchCursor; enddo;

Ou:
dow sqlstt = '00000';
exSr fetchCursor;
… enddo;

As variáveis sqlcod e sqlstt guardam o estado que resulta da última instrução de SQL.
O sqlstt = '00000' representa sucesso, enquanto que o sqlcod = 100 indica que a
instrução não retornou nenhuns dados.

Vamos deixar este módulo assim e passar agora ao módulo com o procedimento que
calcula a idade e no final fazemos a ligação entre os dois.

Feche e guarde as alterações ao ficheiro MAIN_MOD. Crie outro ficheiro CALC_AGE do


tipo plain.

Na primeira linha deste ficheiro deve constar HNOMAIN,a partir da 1º coluna do SEU,o
que significa que este módulo não vai ser um módulo principal.

Procedimentos
Vamos ver agora como funciona a declaração de procedimentos e a passagem de
parâmetros.

Um procedimento é delimitado pelas linhas:

Pnome_proc B EXPORT Dnome_proc PI 3i


0
Dparametro1 D
..
.declarações de código
P E

Linha 1

Definição do início do procedimento que começa com o carácter P (procedimento), o


B (begin) define o início do procedimento, assim como o E (end) da linha 4 indica o
fim. A palavra EXPORT permite que outros módulos usem este procedimento, ou seja,
o procedimento é público a todos os módulos. Se a palavra EXPORT não estivesse
definida, o procedimento só seria visível pelo módulo onde está definido.
Linha 2

Repete-se o nome do procedimento, só que desta vez temos uma especificação D.


Esta linha está a declarar o tipo de retorno '3i 0', ou seja, um inteiro com
comprimento de 3 e 0 casas decimais. Caso não seja retornado nenhum valor deve-se
declarar esta linha sem definir o tipo de variável, neste caso não se definiria o '3i 0'.

Linha 3

Define o parâmetro recebido. Um procedimento pode receber mais que um


parâmetro e cada um deles deve estar definido numa linha diferente. Por defeito um
parâmetro é passado por referência, mas se usarmos a palavra chave VALUE no
campo das functions o parâmetro é passado por valor. Com a palavra chave CONST o
parâmetro é passado por referência, mas só são permitidas operações de leitura
sobre ele.

Linha 7

Fim do procedimento. Defina agora o início e o fim do procedimento CALC_AGE (tem


o mesmo nome que o ficheiro, mas poderia ter outro qualquer), que vai receber por
parâmetro uma data e retornar um inteiro. Defina também uma variável auxiliar que
vai guardar o valor da idade. Quando terminar de fazer isto, verifique se o seu código
ficou como o que está em baixo e coloque no seu código a linha 6.

Dage S 3P 0
PCALC_AGE B EXPORT
dCALC_AGE PI 3i 0
Db_date D /free
age
= %diff (%date() : b_date : years); return age;
/end-free
P E

Linha 6

A função %date() retorna a data actual do sistema. A função diff faz a diferença entre
as duas datas (%date() e b_date) em anos (*years). Repare que existem dois pontos (:)
a separar cada valor - este é o separador de parâmetros utilizado em RPG, como
temos por exemplo a vírgula em C++, Java, etc. Se quiser saber mais informações
sobre manipulação de datas em RPG consulte este site.

Linha 7

Para retornar um valor usamos a função return. Falta ainda um pormenor na


declaração de procedimentos. Sempre que criamos um procedimento ou quando o
vamos invocar, devemos ter no cabeçalho do ficheiro a declaração do protótipo da
função. Que seria algo deste género:
DCALC_AGE PR 3i 0 Db_date
D

Portanto, no ficheiro CALC_AGE vamos ter que definir estas linhas (podem estar antes
ou depois da variável age). Repare que no protótipo está a definir o tipo de retorno e
o parâmetro recebido. Estes valores têm de coincidir com os que indicamos no início
do procedimento.

Ficamos assim com o resultado final:

*
HNOMAIN
*
Dage S 3P 0

DCALC_AGE PR 3i 0 Db_date D
*
PCALC_AGE B
EXPORT dCALC_AGE PI 3i 0
Db_date D
/free
age = %diff
(%date() : b_date : *years); return age;
/end-free
P E

Voltando ao MAIN_MOD, só nos falta agora declarar o protótipo deste procedimento


e invocá-lo. Voltemos então a este ficheiro. Deve estar com algo deste género:

Dbirth s d
Dage s 3i 0
/free
exsr declareCursor;
exsr openCursor;
exsr fetchCursor;

dow sqlcod <> 100;


exsr fetchCursor; enddo;
exsr
closeCursor;
*inlr = *on;
return;
/end-free
*
* sub-routines
declaration *

Defina agora o protótipo do procedimento, exactamente igual ao que colocou no


outro ficheiro. Dentro do ciclo é necessário chamar o procedimento:
age = CALC_AGE(birth);

O ciclo ficaria então assim:

dow sqlcod <> 100;


age = CALC_AGE(birth);

dsply age;
exsr fetchCursor; enddo;

Compilação de módulos

Compile os dois módulos, mas tenha no entanto atenção pois um módulo não é
compilado da mesma forma que outro ficheiro qualquer. Um módulo é compilado
com a opção 15 do PDM 'Create Module'. Depois da compilação bem sucedida faça a
ligação entre os módulos e teste o programa. Vamos ver a seguir como interligar os
módulos.

Criação de um programa a partir de módulos

Os módulos são interligados com o comando:

CRTPGM(PGM_NAME) MODULE(MAIN_MOD MOD1 MOD2...)

Assume-se sempre que o primeiro módulo da lista é o principal. Neste caso,


MAIN_MOD é o módulo principal do programa.

Para chamar o programa só tem que escrever no prompt: CALL PGM_NAME


AS/400 Capítulo 8: Display Files

Neste capítulo vamos mostrar-lhe como pode criar menus e ecrãs em AS/400.

São ficheiros definidos em DDS que permitem criar menus e ecrãs no AS/400 para
interacção com os utilizadores. Os display files são constituídos por vários registos
que correspondem a diferentes partes do ecrã (definidas pelo programador). Estas
partes podem ou não sobrepor-se.

O utilitário SDA permite “desenhar” o que queremos que apareça no ecrã e o utilitário
encarrega-se de gerar o código DDS. Vamos em seguida criar um ecrã com a ajuda do
SDA e depois vamos analisar as partes mais relevantes do código gerado, para ficar
com uma ideia da estruturação do código, pois existem situações em que é mais fácil
fazer uma alteração manipulando o código.

Vamos neste capitulo criar um ecrã que nos mostrará os dados de um cliente.

Para abrir o SDA escreva na linha de comando STRSDA. Vai lhe surgir este ecrã:

STRSDA

Escolha a opção 1 e coloque os dados como vê na figura abaixo, onde o source file é
onde o ficheiro vai ser guardado (deve ser QDDSSRC, pois o código destes ficheiros é,
como ja disse antes, DDS). Member refere-se ao nome que vamos dar ao membro do
ficheiro.

Criar ficheiro

Prima Enter. Vai lhe surgir um novo ecrã. Adicione um registo ao ficheiro da maneira
que pode ver na próxima imagem:

Listagem de registos do ficheiro

Agora deve especificar de que tipo vai ser este registo, neste caso será RECORD:
Adicionar registo

Após o Enter aparece-lhe um ecrã vazio. Nesse ecrã puderá desenhar o registo do
topo do ecrã da figura seguinte.

Note que quando escreve uma string deve colocar plicas a delimitá-la, pois senão
cada palavra vai equivaler a um campo isolado. Colocando as plicas a string pode ser
manipulada como uma única unidade no ecrã.

A função *USER vai mostrar no ecrã o nome do utilizador. Existem outras funções
deste género como *DATE (mostra a data actual do sistema), *TIME (mostra a hora
actual do sistema) *SYSNAME (mostra o nome do sistema).

No final prima Enter. Tenha sempre atenção em verificar se tudo se encontra


corretamente posicionado antes de um Enter, pois após o Enter não é possivel alterar
o aspecto do ecrã a partir do SDA, só manipulando o código.
Desenhando no SDA

Mover um campo

Se quiser mover o campo no ecrã para a direita, coloque imediatamente à direita do


campo sinais >. O número de sinais que colocar será o numero de posições que o
campo se deslocará. Para mover o campo para a esquerda coloque sinais < à
esquerda do campo.

Mover um campo

Centrar um campo

Se quiser centrar um campo no ecrã escreva ac imediatamente antes do início do


campo, ou seja, o 'a' vai ficar na posição anterior ao campo e o 'c' vai ficar colocado
sobre a primeira letra do campo. Prima Enter.

Prima F3 para terminar a edição deste ecrã. Escolha a opção 1 para guardar as
alterações:
Centrar um campo

Crie agora outro registo com o nome BOTTOM, da mesma forma que criou o registo
TOP.

Quando abrir o ecrã de edição do registo prima F9. Vai lhe aparecer este ecrã:

Visualizar vários registos

Aqui pode selecionar os registos que deseja visualizar ao mesmo tempo que edita o
registo BOTTOM (repare que no STATUS do registo diz “In use”). Só pode selecionar no
máximo 3 registos. Deve selecioná-los com números sequenciais de 1 a 3. Selecione o
campo TOP e prima Enter.
Criar o registo Bottom

Desenhe o registo como vê na figura seguinte. Faça a linha com o auxílio da tecla
Underscore. Prima Enter.

Alterar propriedades

Alteração das propriedades de um campo

Vamos agora editar as propriedades do campo “F3=Exit”. Coloque um asterisco


imediatamente antes do início do campo, como vê na imagem seguinte, e prima
Enter.
Alterar propriedades de um campo

Aparece-lhe o ecrã seguinte. Coloque um 'Y' na opção Colors, pois vamos alterar a cor
de visualização do campo.

Selecionar opção colors

Coloque um 1 no campo Blue:


Selecionar cor azul

Dê Enters até regressar ao ecrã de desenho. O campo aparece agora com a cor azul.
Saia da edição deste registo (F3) e guarde o seu trabalho.

Crie um novo registo, MIDDLE, da mesma forma que criou o BOTTOM e o TOP.

Selecione para visualização os registos que já criou:

Criar registo middle

Desenhe os campos que vê na imagem seguinte. Prima enter no final.

Adicionar campos
Utilizar campos de tabelas

Vamos agora selecionar os campos da tabela Clients para pudermos mostrar no ecrã.
Prima F10. No menu que lhe surge deve selecionar o registo da tabela Clients para
output, opção 3, pois neste exemplo só desejamos mostrar os dados. Se desejar fazer
o input de dados ou input/output selecione entre as opções a que lhe convier. Escreva
no menu o que vê na imagem em baixo e prima Enter no final.

Selecionar a tabela

Pode ver que agora em baixo aparece uma mensagem com o nome de todos os
campos precedidos de um número. Para pudermos colocar os campos no ecrã
devemos colocar o número do campo que desejamos precedido de um &, como pode
ver na figura seguinte. Tenha atenção, pois se der um Enter antes de selecionar os
campos todos, a ordem numérica deles vai-se alterar.

Usar campos da tabela

O resultado final será este:


Resultado final

Saia da edição do registo, sem se esquecer de guardar as alterações. Só temos agora


que fazer uns pequenos ajustes nas opções dos registos e do ficheiro.

Opções ao nivel do registo (overlay)

Escolha a opção 8 para o registo TOP:

Alterar opção overlay

Selecione a opção Overlay Keywords:


Alterar opção overlay passo 2

Coloque Y na opção Overlay without erasing. Esta opção permite-lhe mostrar este
registo no ecrã simultaneamente com outros. Prima Enter até voltar ao menu com os
registos e active esta opção para os restantes dois registos.

Alterar a opção overlay passo 3

Opções ao Nível do ficheiro (indicadores)

Vamos agora identificar o indicador 03 (para o F3=Exit) ao nível do ficheiro. No menu


onde encontra a listagem dos registos pressione F14 (F13=shift+F1; F14=shift+F2;
F15=shift+F3, etc.). No ecrã seguinte escolha a opção Indicator Keywords:
Adicionar indicadores ao nível do ficheiro

Coloque uma linha como vê na imagem:

Adicionar indicador para tecla F3

Prima Enter até voltar ao menu dos registos. Prima F3 e guarde o ficheiro.

Código DDS para Display Files

Pode ver o código do membro que acabou de criar indo ao ficheiro de source
QDDSSRC e abrindo o membro com o nome SHW_CLI. No início do ficheiro deve ter
algo deste género:

A DSPSIZ(24 80 *DS3)
A CF03(03 'Exit')

Estas opções afetam todo o ficheiro. Deve acrescentar nesta área uma linha que vai
mais à frente permitir renomear os indicadores no ficheiro plain (acrescente, por
exemplo, a seguir à linha com DSPSIZ):

A INDARA

Deve ter depois uma linhas como estas:

A R TOP A OVERLAY
A 1 65USER A 3
27'Client Details:'

Estas linhas estão a definir apenas o registo TOP. Repare que aparece a opção
OVERLAY, que tínhamos definido no SDA. A palavra USER está colocada no ecrã na
linha 1 coluna 65.

Repare agora nesta linha do registo MIDDLE:

A ID_CLI R O 8 23REFFLD(CLIENTS/ID_CLI DEMO/CLIENTS)

Está definida a referência ao campo da tabela CLIENTS, a coluna (23) e linha (8) onde
está posicionado o campo, o tipo de leitura à tabela é para output: o ID_CLI é o nome
que este campo tem, é igual ao campo correspondente na tabela CLIENTS.

Compile o ficheiro com a opção 14, quando fechar o membro, para as alterações se
tornarem efectivas.

Executar display files

Agora para conseguir “correr” este ecrã tem que criar um membro plain que vai tratar
de mostrar o conteúdo do display file no ecrã. Consulte o ficheiro QplainSRC.SHW_CLI
para ver como este ficheiro deve ser definido. Este ficheiro está bastante comentado
assim pode perceber melhor a sua estrutura. Tente criar este ficheiro e corra-o. O
resultado deve ser o seguinte:

Execução do display file 1

Se carregar Enter:

Execução do display file 2

AS/400 Capítulo 9: Subfiles

Com subfiles pode criar display files com listagens. Vamos ver como isso é feito.
Um subfile é um display file onde podemos criar uma listagem de valores e processar
alterações feitas sobre a lista. A listagem de membros que encontra no PDM é um
exemplo de um subfile.

Vamos neste capitulo criar um subfile que lista todos os cartões de um determinado
cliente dado o seu ID. Para nos facilitar a manipulação de várias tabelas vamos criar
uma view com campos que precisamos para a nossa subfile. No STRSQL:

CREATE VIEW CLICARD AS SELECT CL.ID_CLI, CR.ID_CRD, SH.NAME_SHP, CR.SHOP_CRD FROM


DEMO/CLIENTS CL, DEMO/SHOP SH, DEMO/CARDS CR WHERE CL.ID_CLI =
CR.CLIENT_CRD AND CR.SHOP_CRD = SH.ID_SHP

Abra o utilitário SDA (STRSDA) e crie um novo membro do QDDSSRC:

Creating a new member

Crie o registo BOTTOM e desenhe nele os seguintes elementos:

Bottom record
Crie o registo TOP com a seguinte aparência:

TOP record

Vamos criar agora a subfile propriamente dita. Crie um novo registo chamado LIST,
mas este deve ser do tipo SFL e não RECORD como temos feito até aqui:

Creating the subfile record

Ao dar o Enter aparecer-lhe-á um novo campo para preencher. Preencha-o com


SFLCTL:
Creating the subfile control

Este campo cria outro registo além do subfile, que é o registo de controlo. Este registo
é uma espécie de cabeçalho da lista.

Agora vai lhe surgir um menu com algumas opções. Vamos ver quais é que vai ter que
activar:

Options

Na opção General Keywords coloque as opções como vê na imagem seguinte:


Options

Estes indicadores vão nos depois permitir manipular o estado do subfile a partir do
código em RPG.

Prima Enter para voltar ao menu anterior. Seleccione a opção Subfile display layout.

Options

Ponha o tamanho máximo da subfile a 9999 registos e o número de registos por


página 9.
Options

Prima Enter para voltar ao menu anterior. Selecione Select Record Keyword:

Options

Agora escolha a opção Overlay keywords, para definirmos o overlay deste registo:

Options
Selecione a opção Overlay without erasing:

Options

Agora dê os Enters necessários para voltar a este menu:

Finish Options

Abra o registo SFLCTL, por defeito o registo LIST já aparece visível no ecrã. Selecione
também os registo BOTTOM e TOP, com os números 2 e 3 (o 1 já esta associado ao
LIST).
Open records

Voltando ao menu de desenho, escreva na parte superior do ecrã “Client Nr.”.


Selecione os campos da view CLICARD para input e output (F10) e coloque no ecrã o
número de Cliente.

Selecting fields

Coloque também os títulos dos campos que vão constar no subfile e uma linha
separadora.

Columns description
Vamos agora adicionar algumas propriedades ao campo de ID do cliente.

dding proprieties to the field

Vamos adicionar um indicador a este campo, que vai ficar activo no caso de não se
conseguir obter nenhum registo para mostrar a partir do número de cliente dado
(quer seja um número não existente, ou o cliente não tenha cartões associados).
Opção Error Messages:

Error Messages

Coloque a seguinte informação:


Adding an indicator

Feche agora este registo e abra o registo LIST, selecione para visualização o registo
TOP e BOTTOM (F9).

Selecting records for display

Para criar um campo de input para as opções escreva +i na posição que vê na imagem
seguinte. Dê um Enter.

Creating an input field

Repare que o campo se estendeu automaticamente ao longo das 9 linhas que


tínhamos definido anteriormente.
Resulting input field

Selecione agora os registos da view CLICARD para output.

Selecting a table

Provavelmente vão lhe aparecer os campos repetidos duas vezes, porque o SDA volta
a mostrar o registo para I/O que já tinha carregado para o SFLCTL. Deve selecionar os
campos que estão mais à direita, pois são os últimos selecionados. Tenha atenção
porque se selecionar o campo errado vai ter um campo que lhe permite o input além
do output.

Se existirem mais registos do que aqueles que cabem na linha de mensagens,


aparecerá um mais (+) no fim da linha. Carregue em Page Down para ver o resto dos
campos.
Selected fields

Coloque agora os campos nas posições corretas:

Adding the selected fields to the record

E o resultado final:

Final Result
Não se esqueça de activar o indicador 03 a nível global para o F3=Exit funcionar. No
menu com a listagem dos registos prima F14 (mais pormenores consulte o capítulo
sobre display files).

Não se esqueça de colocar a palavra chave INDARA ao nível global deste membro,
como fez no capítulo do display file.

Deve acrescentar a linha a vermelho ao código do registo SFLCTL:

A R SFLCTL SFLCTL(LIST) A
SFLSIZ(9999) A
SFLPAG(0009) A OVERLAY
A 30 SFLDSP A 31
SFLDSPCTL

A 35 SFLCLR A 33
SFLEND(*MORE) A 4 8'Client
Nr.' A ID_CLI R B 4
19REFFLD(CLICARD/ID_CLI DEMO/CLICARD) A 90 ERRMSG('No Data
Found') A 6 4'Op.'
A 6 12'Card Nr.' A 6
27'Shop Nr.' A 6 42'Shop
Name' A 7
2'__________________________________- A
___________________________________- A
__________' A RRN 4S 0H
SFLRCDNBR(CURSOR)

E no registo list altere o nome do campo de input para opções para OPTION, deve
estar com o nome FLD001, ou algo semelhante.

A R LIST SFL A OPTION


1A I 9 5 (...)

Executar o subfile

Tem agora que criar o membro plain para poder executar a subfile. Consulte o
ficheiro QplainSRC.SHW_SFL para mais pormenores sobre como deve estar
estruturado este ficheiro.

O resultado final será este:


Executing the subfile

Você também pode gostar