Escolar Documentos
Profissional Documentos
Cultura Documentos
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 capítulo encontra-se um
conjunto de arquivos de texto com todo o código criado ao longo do tutorial.
Modelo de Dados
==> _______________________
Por baixo do prompt pode encontrar a lista das teclas de função ativas neste
menu.
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 do 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 mouse para baixo.
Para selecionar uma das opções basta escrever no prompt o número que lhe
corresponde.
Verbo Significado
Verbo Significado
F Arquivo (File)
SPLF SpoolFile
CRTLIB DEMO
Todos os objetos que criar vão ser colocados por defeito na sua CURLIB.
CHGCURLIB DEMO
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:
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
arquivo 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 não é 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.
DSPLIBL
Para prosseguir com esta secção já deve ter criado a biblioteca DEMO e
definindo-a como a sua CURLIB.
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
Se quiser ver mais linhas de comando pode carregar em Page Down ou mover
o scroll do mouse para baixo. Ao fazê-lo o prompt move-se para cima na tela
dando mais espaço a novas linhas.
Faça:
Pode ver que a tabela foi criada, o nome das colunas e que não tem nenhum
registo. Vamos então inserir alguns registos.
Funções básicas
Function Description
Funções numéricas
Function Description
SIN(A) / ASIN(A)
TAN(A) / ATAN(A)
FLOOR(N)
LOG10(N)
Function Description
CURDATE()
CURTIME()
DATE(T)
WEEK(D) Extrai de uma variavel do tipo data o número da semana num ano (1-
54).
Function Description
DAYOFYEAR(D) Retorna um valor que identifica o número do dia num ano (1-366).
Após a criação de uma tabela em SQL vamos criar as restantes com código
DDS.
Os arquivos de sources são arquivos que podem ter vários membros. Cada
membro representa o código fonte de um objeto executável ou um objeto
executável.
Vamos então criar o nosso arquivo de sources de DDS para depois criarmos a
nossas tabelas.
CRTSRCPF FILE(DEMO/QDDSSRC)
STRPDM
Tela do PDM
Escolha a opção '3. Work with members', pois vamos criar alguns membros do
arquivo QDDSSRC. A opção 2 permite trabalhar com objetos executáveis e a 1
com bibliotecas.
Note que apesar no PDM estar a ver arquivo de uma dada biblioteca não está
necessariamente colocado dentro dela. Pode estar na biblioteca DEMO1 a ver
arquivos da biblioteca DEMO2, por exemplo.
Deve-lhe surgir o menu onde pode encontrar todas as opções para trabalhar com
os membros do arquivo.
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
Tela 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 pudera pôr os valores diretamente e o SEU faz a colocação de
cada campo na página correto. Se quiser fechar o prompt carregue F12.
Sintaxe DDS
Vamos começar por definir o Tabela 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
Linha 2
Linhas 3, 4 e 5
A - Alfanumérico
S – Numérico (Zoned Decimal)
P – Numérico (Packed Decimal)
L - Data
Linha 6
Quando tiver o seu arquivo completo carregue em F3 para sair e confirme que
quer guardar as alterações.
CHECK
COMP
DATFMT
*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
*ISO: hh.mm.ss
*EUR: hh.mm.ss
*USA: hh:mm AM/PM
*HMS: hh:mm:ss
RANGE
Exemplos:
VALUES
Exemplo:
DFT
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:
Compilação de arquivos
Para criar o objeto que vai realmente guardar os dados (como já foi dito atrás,
este arquivo guarda só o código fonte) escolha a opção '14-Compilar' para o
arquivo que acabou de criar.
Listagem do arquivo
Este tutorial não vai incidir sobre a análise dos arquivos resultantes da
compilação, mas se se quiser aventurar e tentar analisar os arquivos pode fazê-
lo escrevendo o comando WRKSPLF (Work Spool File) no prompt. As
mensagens mais importantes da compilação aparecem usualmente no final do
arquivo com o mesmo nome que o arquivo que acabou de compilar (a
compilação mais recente aparece mais abaixo na lista).
Tem agora toda a informação necessária para conseguir criar arquivos DDS.
Crie o arquivo CARDS e MOVEMENTS, usando os nomes que são dados no
modelo de dados, pois vamos usá-los mais à frente. Quando terminar, ou se
surgir alguma dúvida, pode consultar os arquivos com o resultado final.
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.
Especificação H (header)
Especificação F (file)
Especificação F
Especificação D (definition)
Especificação D
Especificação C
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;
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).
* definição da variável
Dcount s 5P 0 INZ(0)
/free
/end-free
Material disponível para uso acadêmico V1.1
Tutorial sobre AS400 – Treinamento Interno da Galindo Enterprises
call DEMO/COUNTCARDS
dsply 0
Podem aparecer vários valores (de eventos anteriores), mas o que lhe interessa
é sempre o que está na linha mais em baixo.
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.
c/EXEC SQL
c+ WHERE CLIENT_CRD = 1
c/END-EXEC
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.
c getNrCards begsr
c/EXEC SQL
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:
Não se esqueça que isto tem de estar antes de fazer o display da variável.
Dcount s 5P 0 INZ(0)
*------------------------------------------------*
/free
exSr getNrCards;
Material disponível para uso acadêmico V1.1
Tutorial sobre AS400 – Treinamento Interno da Galindo Enterprises
dsply count;
*inlr = *on;
/end-free
*------------------------------------------------*
c getNrCards begsr
c/EXEC SQL
c+ WHERE CLIENT_CRD = 1
c/END-EXEC
c endsr
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.
Vamos começar pelo módulo principal. Comece por criar um arquivo 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:
FROM DEMO/CLIENTS
OPEN CURSOR1
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;
...
exSr fetchCursor;
enddo;
Ou:
exSr fetchCursor;
...
enddo;
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.
Procedimentos
Vamos ver agora como funciona a declaração de procedimentos e a passagem
de parâmetros.
Pnome_proc B EXPORT
Dnome_proc PI 3i 0
Dparametro1 D
...declarações de código
P E
Linha 1
Linha 2
Linha 3
Linha 7
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
return age;
/end-free
P E
Linha 6
A função %date() retorna a data atual 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.
Linha 7
DCALC_AGE PR 3i 0
Db_date D
Portanto, no arquivo 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.
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
return age;
/end-free
P E
Dbirth s d
Dage s 3i 0
/free
exsr declareCursor;
exsr openCursor;
exsr fetchCursor;
exsr fetchCursor;
enddo;
exsr closeCursor;
*inlr = *on;
return;
/end-free
* sub-routines declaration
age = CALC_AGE(birth);
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 arquivo 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.
São arquivos definidos em DDS que permitem criar menus e telas no AS/400
para interação com os utilizadores. Os displays files são constituídos por vários
registos que correspondem a diferentes partes da tela (definidas pelo
programador). Estas partes podem ou não se sobrepor.
Vamos neste capítulo criar uma tela que nos mostrará os dados de um cliente.
Para abrir o SDA escreva na linha de comando STRSDA. Vai lhe surgir esta tela:
STRSDA
Criar arquivo
Clique Enter. Vai lhe surgir um nova tela. Adicione um registo ao arquivo da
maneira que pode ver na próxima imagem:
Agora deve especificar de que tipo vai ser este registo, neste caso será
RECORD:
Adicionar registo
Após o Enter aparece-lhe uma tela vazio. Nessa tela poderá desenhar o registo
do topo da tela 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 na tela.
A função *USER vai mostrar na tela o nome do utilizador. Existem outras funções
deste género como *DATE (mostra a data atual do sistema), *TIME (mostra a
hora atual do sistema) *SYSNAME (mostra o nome do sistema).
Desenhando no SDA
Mover um campo
Mover um campo
Centrar um campo
Clique F3 para terminar a edição desta tela. 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 a tela de edição do registo clique F9. Vai lhe aparecer esta tela:
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 clique Enter.
Alterar propriedades
Aparece-lhe a tela seguinte. Coloque um 'Y' na opção Colors, pois vamos alterar
a cor de visualização do campo.
Dê Enters até regressar à tela de desenho. O campo aparece agora com a cor
azul. Saia da edição deste registo (F3) e guarde o seu trabalho.
Adicionar campos
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 na
tela 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.
Resultado
Clique Enter até voltar ao menu dos registos. Clique F3 e guarde o arquivo.
Pode ver o código do membro que acabou de criar indo ao arquivo de source
QDDSSRC e abrindo o membro com o nome SHW_CLI. No início do arquivo
deve ter algo deste género:
A DSPSIZ(24 80 *DS3)
A CF03(03 'Exit')
Estas opções afetam todo o arquivo. Deve acrescentar nesta área uma linha
que vai mais à frente permitir renomear os indicadores no arquivo plain
(acrescente, por exemplo, a seguir à linha com DSPSIZ):
A INDARA
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 na tela na linha 1 coluna 65.
Agora para conseguir “rodar” esta tela tem que criar um membro plain que vai
tratar de mostrar o conteúdo do display file na tela. Consulte o arquivo
QplainSRC.SHW_CLI para ver como este arquivo deve ser definido. Este
arquivo está bastante comentado assim pode perceber melhor a sua estrutura.
Tente criar este arquivo e corra-o. O resultado deve ser o seguinte:
Se carregar Enter:
Bottom record
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:
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
Options
Estes indicadores vão nos depois permitir manipular o estado do subfile a partir
do código em RPG.
Clique Enter para voltar ao menu anterior. Seleccione a opção Subfile display
layout.
Options
Options
Clique Enter para voltar ao menu anterior. Selecione Select Record Keyword:
Options
Options
Options
Finish Options
Abra o registo SFLCTL, por defeito o registo LIST já aparece visível no tela.
Selecione também os registo BOTTOM e TOP, com os números 2 e 3 (o 1 já
esta associado ao LIST).
Open records
Selecting fields
Coloque também os títulos dos campos que vão constar no subfile e uma linha
separadora.
Columns description
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
Adding an indicator
Feche agora este registo e abra o registo LIST, selecione para visualização o
registo TOP e BOTTOM (F9).
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.
Selected fields
E o resultado final:
Final Result
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 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
arquivo QplainSRC.SHW_SFL para mais pormenores sobre como deve estar
estruturado este arquivo.
Fields User System Name Date and Time will be retrieved from
system date and time. User name will be retrieved from Job
Attributes.
IDENTIFICATION DIVISION.
PROGRAM-ID. CUSTMAST.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT Customer-FILE ASSIGN TO DISK-Customer
ORGANIZATION IS Indexed
Access Mode Is Dynamic
Record Key Is Cust-No.
DATA DIVISION.
FILE SECTION.
FD Cust-FILE
LABEL RECORDS ARE STANDARD.
01 Custs-REC.
Copy DDS-ALL-FORMATS of CUSTOMER.
FD SCREEN-FILE
LABEL RECORDS ARE STANDARD.
01 SCREEN-REC.
COPY DDS-ALL-FORMATS OF CUSTFMTS.
WORKING-STORAGE SECTION.
01 SCREEN-INDICATORS.
05 F03-EXIT PIC 1.
05 F12-PRV-SCRN PIC 1.
05 CUST-SPACES PIC 1.
05 CUST-NAME-SPACES PIC 1.
05 CUST-ADDRESS-SPACES PIC 1.
05 CUST-CITY-SPACES PIC 1.
05 CUST-STATE-SPACES PIC 1.
05 CUST-NOT-FOUND PIC 1.
PROCEDURE DIVISION.
MAIN-RTN.
OPEN I-O CUSTOMER-FILE
SCREEN-FILE.
CLOSE CUSTOMER-FILE
SCREEN-FILE.
STOP RUN.
CUSTOMER-INPUT-RTN.
IF CUST-NO = SPACES
MOVE IND-ON TO CUST-SPACES
GO TO CUSTOMER-INPUT-RTN.
PERFORM CHECK-CUSTOMER.
MOVE ZEROS TO SCREEN-INDICATORS.
PERFORM CUSTOMER-DETILAS.
CUSTOMER-DETAILS.
WRITE SCREEN-REC FORMAT IS "CUSTFMT2'
INDICATORS ARE SCREEN-INDICATORS.
READ SCREEN-REC INDICATORS ARE SCREEN-INDICATORS.
IF CUST-NAME = SPACES
MOVE IND-ON TO CUST-NAME-SPACES
GO TO CUSTOMER-DETAILS.
IF ADDRESS = SPACES
MOVE IND-ON TO CUST-ADDRESS-SPACES
GO TO CUSTOMER-DETAILS.
IF CITY = SPCACES
MOVE IND-ON TO CUST-CITY-SPACES
GO TO CUSTOMER-DETAILS.
IF STATE = SPACES
MOVE IND-ON TO CUST-STATE-SPACES
GO TO CUSTOMER-DETAILS.
CHECK-CUSTOMER.
MOVE IND-OFF TO CUST-NOT-FOUND.
READ CUST-FILE INVALID KEY
MOVE SPACES TO CUST-NAME
MOVE SPACES TO ADDRESS
MOVE SPACES TO CITY
MOVE SPACES TO STATE
MOVE IND-ON TO CUST-NOT-FOUND
NOT INVALID KEY
MOVE IND-OFF TO CUST-NOT-FOUND
MOVE CORR CUST-REC TO CUSTFMT1.