Progress V8.2A Enviado por: CLAUDIUS EDELSBRUNNER Progress V8.2A Por Sandro Matos Fábio Victor Pfeiff Claudius Edelsbrunner 2 Porto Alegre, agosto de 1998. Sumário 1 Conhecendo o Progress 1.1 O que é Progress 1.2 Gerenciamento da Base de Dados Relacional Progress 1.3 DataServer para outros Sistemas de Gerenciamento 1.4 Client / Server Parameters: Arquivo .pf 1.5 Formas de Conexão a bancos Progress via sessões Progress 1.5.1 Mono-usuário 1.5.2 Multi-usuário 1.5.3 Exercício: conectando a um banco Progress mono-usuário 1.6 Principais Extensões dos Arquivos Gerados pelo Progress 1.7 Variáveis de Ambiente - Propath 1.8 Dump 2 Procedure Editor 2.1 File – operações sobre arquivos 2.2 Edit 2.2.1 Desfazendo ações 2.2.2 Recortando, copiando e colando 2.2.3 Inserindo campos de tabelas 2.3 Search – buscando/substituindo no programa corrente ocorrências de texto 2.4 Buffers 2.4.1 Abrindo um novo buffer 2.4.2 Alternando entre buffers 2.5 Compile 2.5.1 Run 2.5.2 Check Sintax 2.6 O Menu de Contexto 3 Conhecendo os Comandos do Progress 3.1 Comentários em Progress 3.2 Tipo de Dados 3.3 Declaração de Estruturas Auxiliares 3.3.1 Variáveis 3.3.2 Buffers Auxiliares 3.3.3 Tabelas Temporárias 3.3.4 Procedures e Funções 3.3.5 Parâmetros 3.4 Exercícios 3.5 Comandos Básicos 3.5.1 Atribuição 3.5.2 Entrada e Saída 3.5.3 Bloco e Repetição 3.5.4 Condicionais 3.5.5 Para manipulação de registros 3.5.6 Querys 3.5.7 Quebra de bloco 3.5.8 Execução de programas externos 3 3.6 3.7 3.8 3.8.1 3.8.2 3.9 3.10 Funções mais Utilizadas Exercícios (reservar um simples para a aula do dia seguinte) Pré-processamento Diretivas Funções Exercício Includes 4 User Interface Builder 4.1 User Interface Builder 4.2 A Palette de Componentes 5 Suporte a Interface Gráfica embutida em Progress 4GL 5.1 Atributos Básicos 5.2 Exercícios (utilizando screen-value, num-items, sensitive, …) 5.3 Métodos Básicos 5.4 Diretivas de Pré-processamento mais utilizadas 5.5 Exercícios 6 Progress ACE 6.1 Apresentando o ACE 6.2 Apresentando o ADM 6.3 SmartObjects 6.4 Exercícios 7 Links 7.1 Criando um Master Object a partir de um template 7.2 Tabelas Externas 7.2.1 O que são / para quê servem 7.2.2 Exercício 7.3 Organizando Masters em Diretórios 7.4 O que é um Link? 7.5 Exercícios 7.6 Tabela de Links possíveis 7.7 Progress Advisor 7.8 Estratégias de Links para Múltiplos Record Targets 7.9 Definição de Links no UIB 8 Paginando uma Aplicação 8.1 Paginando uma Aplicação 8.2 Links 8.3 Exercícios 8.4 Persistent Procedures 9 Enviando Mensagens (Messaging) 9.1 Messaging 9.2 Messaging e Tipo de Links 9.3 ADM messaging para cada Tipo de Link 9.4 Event Procedure e Method Procedure 9.4.1 Event Procedure 4 9.4.2 Method Procedure 9.4.3 Comparação entere Event Procedure e Method Procedure 9.4.4 Como Trabalhar com Event Procedure 9.4.4.1 Dispatch 9.4.4.2 Notify 9.4.5 Como Alterar Event Procedures? 9.5 Mapa de Eventos 10 SmartBrowse com Enable Column 11 New-State Method 5 1 Conhecendo o Progress 1.1 O que é PROGRESS ? Progress é um ambiente de desenvolvimento baseado na tecnologia cliente/servidor que visa oferecer soluções informatizadas a problemas das inúmeras áreas de negócio existentes. Para atingir tal meta, o Ambiente de Desenvolvimento de Aplicações Progress (ADE) oferece um completo e integrado conjunto de ferramentas de desenvolvimento gráfico para produtivamente construir, testar, e manter aplicações. No centro do ADE está a linguagem de 4ª geração Progress (4GL). A ferramenta apresenta recursos das modernas técnicas de orientação a objetos, que busca reduzir custos de desenvolvimento e manutenção, aumento de produtividade, de qualidade, eliminação de redundância de código, entre outros. Como base temos o Data Dictionary (Dicionário de Dados) que auxilia as definições de dados com armazenamento centralizado e suporte para análise e projeto de ferramentas. 1.2 Gerenciamento da Base de Dados Relacional Progress Para as demandas especiais de aplicações ‘Críticas’, muitas empresas escolheram o Sistema de Gerenciamento de Base de Dados Relacional (RDBMS – Relational Database Management System) Progress. O Progress RDBMS é totalmente integrado à arquitetura Progress DataServer. É uma solução de base de dados de alta performance para aplicações do mundo real. Aplicações ‘Críticas’ exigem não somente a habilidade de suportar alto volume de processamento de transações simples, mas também alto rendimento e baixo tempo de resposta para transações mais complexas que integram várias aplicações de negócio. O Progress RDBMS possui um conjunto de recursos com o objetivo específico de suportar tais ambientes onde a execução de um alto volume de transações, integridade de dados garantida e alta disponibilidade são necessárias. O máximo rendimento é proporcionado por capacidades tais como: • lock a nível de registro, que minimiza a contenção de dados; • estratégias de otimização de consultas que melhoram o tempo para recuperação de dados; • uma inteligente buferização de registros que reduz o tráfego da rede. A integridade dos dados é assegurada através de características de recovery. O Progress RDBMS é projetado com flexibilidade para tirar o máximo proveito das características únicas de desempenho de diferentes plataformas e sistemas operacionais. E, quando utilizado no ambiente cliente/servidor, com configuração baseada em rede, as aplicações Progress podem comunicar-se com o RDBMS, utilizando qualquer protocolo padrão de rede. 1.3 DataServer Para Outros Sistemas de Gerenciamento Para quem deseje acessar dados ou executar aplicações utilizando sistemas de gerenciamento de bases de dados não-Progress, existe o Progress DataServer, que 6 suporta a maioria das bases de dados e sistemas de arquivos de terceiros. Esta ferramenta possibilita gerenciamento e acesso de alta performance, portabilidade das aplicações através de gerenciadores de dados e suporte a características específicas da base de dados. Alguns dos gerenciadores de dados suportados: Oracle, RMS, Sybase, RDB/VMS, OS/400, Object Store, DB2, Albase, ODBC, C-Isam, Informix. 1.4 Client Server Parameters: Arquivo .pf -E -d -yy -cpinternal -db -1 -H -S -N -T -trig -Mm -s -mmax -Mr -TB -TM -p dmy 1920 iso8859-1 u:\sports\sports.db meta1 ssports tcp C:\TMP e:\trg\ 8192 40 2048 2048 08 10 _desk.p # European Numeric Format # Date Format # Century # Internal Code Page # Database Name # Single-user Mode # Host Name # Service Name # Protocol Name # Temporary Directory File # Trigger Directory # Message Buffer Size # Stack Size # Maximum Memory # Record Buffer Size # Speed Sort # Merge Number # Program Manager Obs.: Parâmetros client-server são case-sensitive. O mesmo caracter (ou conjunto de caracteres ) pode especificar diferentes parâmetros à sessão Progress. Exemplo: -S (especifica o serviço utilizado para conexão a um servidor de banco Progress) e -s (tamanho da pilha alocada no client). 1.5 1.5.1 Formas de Conexão a bancos Progress via sessões Progress Mono-usuário Uma conexão mono-usuário permite a somente um único usuário acessar a(s) base(s) conectada(s) desta forma. O usuário monopoliza o(s) banco(s) de dado(s). 1.5.2 Multi-usuário Progress, no entanto, é destinado ao desenvolvimento de aplicações baseado na arquitetura client-server (um programa cliente faz uma solicitação a um programa servidor, que usualmente está executando em uma máquina remota). O acesso concorrente (ou seja, vários usuários disputando um registro) é gerenciado por um programa conhecido por servidor de banco de dados. Os usuários fazem solicitações a esse programa, que as responde conforme a sua disponibilidade e a do registro. 7 1.6 Principais Extensões dos Arquivos Gerados pelo Progress .p Procedures e Triggers de Banco de Dados .i Includes .r Programas compilados .db Base de Dados .bi Before Image da Base de Dados .ai After image da Base de Dados .lk Lock da base da dados .lg Registro das todas as ocorrências relativas a uma base de dados .w Smart Windows, Smart Dialog, Smart Frames, Smart Browsers, Smart Viewers, Smart Panels e Smart Querys .wx Templates .wbx Quando compilada um objeto contendo um componente VBX/OCX, é gerado um arquivo de mesmo nome com esta estensão .uib Arquivo temporário do User Interface Builder (UIB) .ped Arquivo temporário do Procedure Editor .dbg Arquivo temporário do Application Debugger .df Dump de definição da Base de Dados .d Dump dos dados .ds Dados ou definições que foram carregados para a Base de Dados através do comando ‘Load’ .e 1.7 Log de erro gerado na carga de dados ou definições Variáveis de Ambiente - Propath Progress possui algumas variáveis de ambiente. A mais importante para quem desenvolve software utilizando Progress é o propath. Esta variável contém os diretórios, separados por vírgulas, que a sessão Progress enxerga quando tem que procurar um programa para execução. A importância de conhecê-la é simples: se você coloca um programa em um diretório que não está presente no propath, e tenta executá-lo, o Progress lhe devolverá uma mensagem de erro com o seguinte texto: “<programa> not found.”. Seu valor pode ser alterado por um administrador de sistemas conforme a necessidade. 1.8 Dump 8 ADD TABLE "CLIENTE" DESCRIPTION "Cadastro de Clientes" DUMP-NAME "cliente" LABEL "Cliente Geral" ADD FIELD "numcliente" OF "CLIENTE" AS INTEGER DESCRIPTION "Número do Cliente" FORMAT "999999999" LABEL "Número do Cliente" VALEXP "numcliente > 0" VALMSG "Número do Cliente inválida" HELP "Número do Cliente." ORDER 10 MANDATORY ADD FIELD "nomcliente" OF "CLIENTE" AS CHAR DESCRIPTION "Nome do Cliente" FORMAT "X(80)" LABEL "Nome do Cliente" VALEXP "nomcliente <> """"" VALMSG "Nome do Cliente inválida" HELP "Nome Completo do cliente" ORDER 30 MANDATORY ADD INDEX "XPKCLIENTE" ON "CLIENTE" UNIQUE INDEX-FIELD "numcliente" ASCENDING UPDATE PRIMARY INDEX "XPKCLIENTE" ON "CLIENTE" ADD INDEX "XAK1CLIENTE" ON "CLIENTE" UNIQUE INDEX-FIELD "nomabrev" ASCENDING 9 2 Procedure Editor O Procedure Editor é uma Window Editor provida de funções auxiliares à edição de código Progress. O desenvolvedor pode fazer uso do Procedure Editor para criar, escrever, compilar e executar programas. O presente capítulo dedica-se a conduzí-lo pelas funcionalidades desta ferramenta mais utilizadas no dia-a-dia. 2.1 File – Operações Sobre Arquivos (exemplo – p-c02e01.p) 2.2 Edit 10 2.2.1 Desfazendo Ações Este comando desfaz a última ação executada pelo usuário. 2.2.2 Recortando, copiando e colando Semelhante a qualquer aplicação Windows que possua estas opções. 2.2.3 Inserindo campos de tabelas Uma opção bastante interessante oferecida pelo Procedure Editor: se deseja-se incluir um ou mais campos de uma tabela no código-fonte que se está construindo, seleciona-se esta opção. Há três listas de seleção: Databases – apresenta todas as base de dados ao qual a sessão cliente Progress está conectada; 11 Tables – mostra todas as tabelas contidas na base selecionada na lista “Databases”; Fields – apresenta todos os campos definidos para a tabela selecionada na lista “Tables”. Note que só é possível seleção múltipla na lista “Fields”. O prefixo acrescido ao campo quando de sua inserção no código-fonte é opção do construtor do código. 2.3 Search – buscando/substituindo no programa corrente ocorrências de texto 2.4 Buffers Atalhos de teclado para os principais comandos: F7 Torna o próximo buffer o corrente (se é o último, retorna ao primeiro) 12 2.5 Compile O editor do Progress possui recursos para a execução direta de comandos e programas, e para a checagem da sintaxe do código que foi escrito ou alterado. Atalhos de teclado para os principais comandos: F2 Executa o programa/comando do buffer corrente do editor Shift-F2 Verifica a sintaxe 2.6 O Menu de Contexto Contém atalhos para algumas das funções mais utilizadas dos itens de menu já abordados. Acessível via botão direito do mouse. 13 3 Conhecendo os Comandos do Progress Dica – Acesso ao Help Para conhecer a sintaxe de algum comando ou tirar alguma dúvida, basta marcar o comando escrito no Procedure Editor e pressionar a tecla F1. 3.1 Comentários em Progress A linguagem 4GL Progress permite a inserção de comentários em um programa: • /* Abre um comentário • */ Encerra um comentário Tudo o que é escrito entre estes dois tokens é ignorado pelo compilador. Muito útil para: • identificar um programa; • descrever determinada solução dentro do programa (porquê foi fito de um jeito e não de outro). Podem existir comentários aninhados. 3.2 Tipo de Dados Os Progress são: - 3.3 3.3.1 tipos de dados comumente utilizados na implementação de aplicações integer character date decimal logical handle rowid Declaração de Estruturas Auxiliares Variáveis DEFINE VARIABLE DEFINE VARIABLE <nome-variavel> AS <DataType> NO-UNDO. <nome-variavel> LIKE <Field> NO-UNDO. Exemplos: DEFINE DEFINE DEFINE DEFINE DEFINE DEFINE DEFINE DEFINE VARIABLE variavel AS integer NO-UNDO INITIAL 100. VARIABLE variavel AS integer NO-UNDO. VARIABLE variavel Like Table.Campo NO-UNDO. NEW SHARED VARIABLE variavel AS logical INIT YES. SHARED VARIABLE variavel AS logical INIT YES. NEW GLOBAL SHARED VARIABLE variavel AS char NO-UNDO. SHARED VARIABLE variavel AS char NO-UNDO. VARIABLE variavel AS integer NO-UNDO EXTENT 03. 14 3.3.2 Declaração de Buffers Auxiliares Um buffer é uma referência a uma tabela pertencente a um banco de dados. Qualquer programa escrito em Progress sempre tem, por default, tantos buffers prédefinidos quantas são as tabelas pertencentes aos bancos aos quais está conectado o client Progress – um para cada tabela. Se temos uma tabela de nome CLIENTE em um banco ao qual estamos conectados, então temos o buffer CLIENTE pré-definido para uso. É por meio de buffers de tabelas que acessamos estas e seus atributos (também conhecidos por campos). Há situações, contudo, que nos obrigam a definir buffers auxiliares. Pode-se, por exemplo, precisar de dois indicadores econômicos simultaneamente para compará-los. Problemas de hierarquias (auto-relacionamentos) exigem buffers auxiliares. Sintaxe resumida (maiores detalhes – Help Progress): DEFINE BUFFER <nome-buffer> FOR <nome-tabela>. Exemplos: DEFINE BUFFER bf-cargo FOR cargo. DEFINE NEW SHARED BUFFER bf-funcao FOR funcao. DEFINE SHARED BUFFER bf-funcao FOR funcao. 3.3.3 Tabelas Temporárias Pode-se definir uma tabela pelo tempo de vida de um programa, ou mesmo para trocar informações entre programas. Para tal, deve-se definir a mesma. A sintaxe para definição de temp-tables é bastante abrangente, permitindo que se defina tabelas auxiliares com todas as características encontradas em tabelas criadas via Dicionário de Dados. Exemplos: DEFINE TEMP-TABLE tt-funcao LIKE FUNCAO. DEFINE NEW GLOBAL SHARED TEMP-TABLE tt-tarefa NO-UNDO FIELD tarefa-cod LIKE TAREFA.TAREFA-COD FIELD t-deno LIKE TAREFA.DENOMINA FIELD funcao-cod LIKE FUNCAO.FUNCAO-COD FIELD f-deno LIKE FUNCAO.DENOMINA FIELD status AS CHAR INDEX xpkindprim IS PRIMARY UNIQUE tarefa-cod. 3.3.4 Procedures e Funções Muitas vezes, deseja-se executar a mesma porção de código em mais de um lugar de nosso programa, ou mesmo em mais de um programa. Um exemplo típico são as regras de negócio que regem uma aplicação. Solução: abrir o programa, copiar a porção de interesse e colar no lugar onde a queremos, certo? Correto, se você gosta de passar trabalho. Suponha que a regra de negócio mude. Você só terá que abrir todos os programas que contém aquela porção de código e alterá-los… 15 O melhor é isolar esta lógica num único lugar, executando-a de onde quiser. Se a Equipe Econômica resolve de um dia para o outro “alterar algumas regras”, e isso afeta um programa seu, basta alterar um lugar. Progress oferece dois mecanismos para auxiliar nesse processo: procedures e funções (há um terceiro mecanismo, que será discutido posteriormente). Digite, no Procedure Editor, “Procedure Statement”. Selecione esta expressão e acompanhe a sintaxe. Agora apague a expressão anterior e digite, no Procedure Editor, “Function Statement”. Selecione esta expressão e acompanhe a sintaxe. 3.3.5 Parâmetros Procedures e funções podem receber parâmetros (Input Parameters) e devolver resultados através dos mesmos parâmetros pelos quais recebem (Output Parameters) ou por outros parâmetros (Input-Output Parameters). Da mesma forma que variáveis comuns, parâmetros tem um tipo (que pode ser herdado de um campo de tabela ou definido a partir dos tipos básicos). Procedures e funções diferem na sintaxe como são definidos os parâmetros. Exemplo de definição de parâmetros para procedures PROCEDURE EXEMPLO : DEFINE INPUT PARAMETER parametro AS integer UNDO. DEFINE OUTPUT PARAMETER parametro LIKE Tabela.Campo UNDO. DEFINE INPUT-OUTPUT PARAMETER parametro LIKE Tabela.Campo UNDO. NONONO- <corpo da procedure> END PROCEDURE. Exemplo de definição de parâmetros para funções FUNCTION EXEMPLO RETURNS decimal (INPUT vp-a as integer, OUTPUT vp-b as character, INPUT-OUTPUT vp-c as logical). <corpo da função> RETURN <expressão que resulte decimal>. END FUNCTION. 3.4 Exercícios 1) Abra o procedure editor. Crie um cabecalho com as seguintes informações, utilizando comentários (cada informação deve iniciar nova linha): Autor; Data; Hora; Descrição (pode ocupar mais de uma linha); Verifique a sintaxe do programa; Salve no diretório “c:\prow82a\curso\exercicio” com o nome “p-c03x01.p”. Feche o programa. 16 2) Serão necessárias, para o próximo programa: Três variáveis do tipo integer; Uma variável do tipo decimal; Uma variável do tipo logical; Uma procedure, de nome p-baskara; Uma função, de nome f-baskara, que retorna um valor decimal. Defina-as. Ao concluir, verifique a sintaxe. 3) Selecione e copie o que foi feito no exercício anterior. 4) Abra o programa feito no exercício “1”, e logo abaixo dos comentários, cole o que foi copiado no exercício anterior. Verifique a sintaxe. Salve as alterações. 5) Defina três parâmetros de entrada para a procedure p-baskara, todos do tipo inteiro, e um parâmetro de saída, do tipo decimal, respectivamente com os seguintes nomes: “vp-a”, “vp-b”, “vp-c” e “vp-raiz”. 6) Abra, em outro buffer, o arquivo “baskara-p.p” e copie seu conteúdo. Feche este buffer e retorne a seu programa. Cole o que foi copiado no corpo da procedure “p-baskara” (logo após os parâmetros da mesma). Verifique a sintaxe. Salve as alterações. 7) Defina três parâmetros de entrada para a função f-baskara, todos do tipo inteiro, respectivamente com os seguintes nomes: “vp-a”, “vp-b”, “vp-c”. 8) Abra, em outro buffer, o arquivo “baskara-f.p” e copie seu conteúdo. Feche este buffer e retorne a seu programa. Cole o que foi copiado no corpo da procedure “f-baskara. Verifique a sintaxe. Salve as alterações. 9) Abra, em outro buffer, o arquivo “baskara-exec.p” e copie seu conteúdo. Feche este buffer e retorne a seu programa. Cole o que foi copiado duas linhas abaixo da função. Verifique a sintaxe. Salve as alterações. Execute o programa. 17 3.5 3.5.1 Comandos Básicos Comandos de Atribuição Assign <variavel> = <expressao>. Atribui a <variavel> o resultado de <expressao>. 3.5.2 Comandos de Entrada/Saída Há varios comandos em Progress que podem ser utilizados para efetuar operações de entrada/saída. Os principais: 3.5.3 Display Update Put Message Comandos de bloco e de repetição End Indica o fim de um bloco iniciado com um PROCEDURE, FUNCTION, DO, REPEAT, CASE ou FOR EACH. No caso de procedures e funções, pode-se encerrar também com “End Procedure.” ou “End Function.”. Do Basicamente, agrupa comandos em um único bloco. O bloco aberto por este comando deve ser encerrado por um comando End. Exemplo: c:\Prow82a\Curso\Exemplos\p-c03e01.p Repeat Inicia um bloco de comandos que são processados repetidamente, até que uma condição de saída definida ocorra. Exemplo: c:\ Prow82a\Curso\Exemplos\p-c03e02.p 3.5.4 Comandos Condicionais (ou de Controle de Fluxo) if <condicao> then <bloco/comando> else <bloco/comando> A execução de um bloco fica condicionada a uma expressão. Exemplo: c:\Prow82a\Curso\Exemplos\p-c03e01.p case Quando, a partir da avaliação de uma expressão, tem-se múltiplas possibilidades de execução (e não somente duas, como no comando “if”), utiliza-se o comando case. Obs.: O comando suporta dois encerramentos de bloco: “End.” e “End Case.”. Exemplo: c:\Prow82a\Curso\Exemplos\p-c03e03.p 3.5.5 Comandos para manipulação de registros Create <buffer>. Cria um novo registro na tabela associada ao buffer. 18 Delete <buffer>. Exclui um registro da tabela associada ao buffer. Find <first/last/next/prev> <buffer> where <selecao> <lock>. Busca um registro na tabela especificada com o filtro de seleção informado. Exemplo: c:\Prow82a\Curso\Exemplos\p-c03e04.p For Junto com o comando “find”, é um dos comandos mais importantes e poderosos do Progress 4GL. É uma instrução de bloco que permite percorrer uma tabela inteira. Se o registro atende à seleção imposta, o bloco interno ao comando é executado, estando o registro selecionado disponível para consulta, exclusão, alteração, etc. Exemplos c:\Prow82a\Curso\Exemplos\p-c03e05.p c:\Prow82a\Curso\Exemplos\p-c03e06.p 3.5.6 Querys Querys são outra forma oferecida pelo Progress para se trabalhar com tabelas. As diferenças básicas entre estas e o comando For são: • querys não delimitam um bloco; a abertura e o fechamento de uma query são comandos independentes, que não delimitam uma transação; • uma query aberta não significa um registro disponível para manipulação. Deve ser especificado à query que se deseja um registro (por exemplo, via comando Get). Define query Define uma query a ser utilizada. Open query Abre uma query. Esta pode ter sido previamente definida, ou sua definição pode fazer parte deste comando. Close query Fecha uma query previamente aberta. Exemplo: “c:\Prow82a\Curso\Exemplos\p-c03e07.p” 3.5.7 Comandos de quebra de bloco São comandos utilizados quando se deseja evitar que um bloco execute até o fim. Next Todos os comandos até o fim do bloco são desprezados. Se faz parte de uma iteração, segue imediatamente para a próxima iteração. Leave Abandona o bloco, mesmo que se trate de um bloco iterativo. As iterações seguintes não são efetuadas. Return Utilizado em procedures e funções. Quando encontrado, força o fim da execução da rotina. No caso de ser uma função, uma expressão a acompanha. 19 Exemplos: Função Procedure “c:\Prow82a\Curso\Exercicio\p-c03x01.p” “c:\Prow82a\Curso\Exercicio\p-c03r01.p” “c:\Prow82a\Curso\Exemplos\p-c03e08.p” Quit Encerra a execução da aplicação, retornando ao programa chamador, ou ao sistema operacional (se o programa está executando diretamente sobre o client runtime). 3.5.8 Comando para Execução de Procedures e Programas Externos RUN Utilizado para executar internal procedures (que fazem parte do mesmo programa de onde a chamada é feita), external procedures (procedures de programas externos) ou até outros programas. Exemplos: Internal Procedures “c:\Prow82a\Curso\Exemplos\pc03e08.p” External Procedures “c:\Prow82a\Curso\Exemplos\pc03e09.p” Programas Externos “c:\Prow82a\Curso\Exemplos\pc03e10.p” 3.6 3.6.1 Funções mais utilizadas Para conversão de tipos c03e14.p” “c:\Prow82a\Curso\Exemplos\p- Date(string) Date(mês,dia,ano) Integer Decimal String Rowid 3.6.2 Sobre registros c03e15.p” “c:\Prow82a\Curso\Exemplos\p- Available Can-find 3.6.3 Sobre listas c03e16.p” “c:\Prow82a\Curso\Exemplos\p- Entry Num-entries Lookup Substring Index Replace 3.6.4 Sobre strings Begins Matches Contains 3.6.5 Função Condicional If Then Else 20 3.7 Exercícios 1) Exibir o conteúdo de todos os registros da tabela “Customer”. 2) Exibir o conteúdo de todos os registros da tabela “State”. 3) Executar as seguintes operações sobre a tabela “Customer”: criar um novo registro, atribuindo valores a seus campos de forma consistente; exibir o conteúdo do registro criado; alterar o registro criado; exibir o conteúdo do registro alterado; achar o último registro da tabela e apresentar uma mensagem ao usuário perguntando se ele deseja excluí-la ou não. Caso o usuário queira, proceder à exclusão do registro. 4) Executar as seguintes operações sobre a tabela “Order”: procurar um registro na tabela de tal forma que não seja encontrado; ao invés de retornar uma mensagem de erro do Progress, programar uma mensagem de erro para mandar ao usuário, indicando a inexistência do registro. 21 3.8 Pré-processamento Exemplos: 3.8.1 Diretivas 3.8.2 “c:\Prow82a\Curso\Exemplos\p-c03e11.p” “c:\Prow82a\Curso\Exemplos\p-c03e12.p” “c:\Prow82a\Curso\Exemplos\p-c03e13.p” &GLOBAL-DEFINE &SCOPED-DEFINE &UNDEFINE &IF &THEN &ELSEIF &ELSE &ENDIF Funções DEFINED (preprocessor) 3.9 Exercício 1) A tabela “Customer” possui um campo que determina o limite de crédito que um cliente possui junto a nossa empresa – “Credit-Limit”. Suas tarefas são: mostrar em tela os campos “Cust-num”, “Name”, “Contact” e “Phone” de todas as ocorrências da tabela “Customer” que possuem limite de crédito maior que um valor qualquer, sendo que esse valor será definido em um preprocessor (ou seja, no filtro a ser utilizado sobre a tabela, deve-se usar uma referência ao preprocessor, e não o valor fixo). Inicialmente, fixe o valor em $40.000,00. 3.10 Includes Pode-se agregar a um programa trechos de código escritos porções espalhadas por vários arquivos. Para tal, basta escrever o trecho de código que se deseja incluir no programa, salvá-lo e, no programa que em se deseja utilizá-lo, fazer referência a ele usando a seguinte sintaxe: {<nome-do-include> [<parametro-1> … <parametro-n>]} Os parâmetros são opcionais (sua existência é determinada pelo programador e pelo progblema que se está resolvendo). Dentro do include, para fazer refeência a um parâmetro, basta usar, entre chaves, o número de ordem do parâmetro desejado ( {1}, {2} ). Se utilizado para bibliotecas de procedures, deve-se ter em mente as seguintes diferenças entre executar uma procedure externa e utilizar um include: o código-objeto gerado pelo Progress incorpora todo o código do include, em tempo de compilação (se o programa não foi previamente compilado execução); executar procedures e programas externos exige passagem de parâmetros – o programa ou a procedure externa não conhece as estruturas internas do programa chamador (o mesmo não vale para internal procedures). Exemplo: “c:\Prow82a\Curso\Exemplos\p-c03e12.p” “c:\Prow82a\Curso\Exemplos\p-c03e13.p” 22 4 UIB – User Interface Builder O User Interface Builder é a ferramenta de programação visual do ambiente de desenvolvimento Progress. O código gerado pelo UIB apresenta as seguintes seções: 4.1 Definitions Main Block Triggers Procedures Functions User Interface Builder Novo Objeto Executar um programa Edição de Código para o Widget Ativo na Tela Propriedades do Objeto Selecionado 23 4.2 Palette de Componentes Pointer Legenda Frame Componentes de Acesso a Banco Widgets Componentes OCX Smarts 24 5 Suporte a Interface Gráfica embutida em Progress 4GL Progress 4GL implementa um enfoque orientado a objetos em vários pontos distintos de sua ferramenta. A começar por seus widgets. Cada widget possui um conjunto de atributos e métodos de instância comuns à sua classe (um combo-box ou um toggle-box em nossa aplicação, nada mais são que instâncias de suas respectivas classes, Combo-Box e Toggle-Box). O valor contido em um atributo pode diferir entre duas instâncias de uma mesma classe, mas o acesso a este atributo é feito da mesma maneira em ambos. A sintaxe utilizada para referência a atributos e métodos é praticamente idêntica. Atributos < widget >:< atributo > Métodos < widget >:< método(<arg1>, …,<argn>) > 5.1 Atributos Básicos “c:\Prow82a\Curso\Exemplos\w-c05e17.w” Visible Controla se o widget está ou não visível. Sensitive Controla se o widget está ou não habilitado. Screen-value Contém o valor em tela de um componente (contido no screen buffer). Não necessariamente é o valor real armazenado no widget. Checked O widget está ou não selecionado. Aplicável a toggles e e itens de menu toggle. Read-only Só aplicável aos widgets Browse, coluna de Browse, Editor e Menu-item. List-items Num-items 5.2 Exercícios 5.3 Métodos Básicos add-first / add-last (Combo-box) delete 5.4 Diretivas de Pré-processamento mais utilizadas {&SELF-NAME} {&FRAME-NAME} {&BROWSE-NAME} 25 {&OPEN-QUERY-{&BROWSE-NAME}} {&DISPLAYED-FIELDS} {&ENABLED-FIELDS} 5.5 Exercícios 26 6 Usando Progress ACE 6.1 Apresentando o ACE O ACE (Application Component Environment) é a ferramenta que permite a construção de aplicações na versão 8. Ela acrescenta ao UIB diversas características como o SMARTOBJECT palette, Wizards, Cue Cards, Progress Advisor e novos ‘Include files’. 6.2 Apresentando o ADM O ADM (Application Development Model) é um novo método para desenhar e construir aplicações. Ela possibilita a rápida construção de aplicações a partir do reuso de objetos e da fácil manutenção de componentes e, consequentemente, de sistemas. 6.3 SmartObjects SmartWindow (*) SmartFrame (*) SmartDialog (*) SmartFolder SmartPanel (navigation) SmartPanel (update) SmartQuery SmartBrowser SmartViewer w-nomearq.w f-nomearq.w d-nomearq.w p-nomearq.w p-nomearq.w q-nomearq.w b-nomearq.w v-nomearq.w (*) Object Containers Reuso de código através de referência Todos os SmartObjects são instâncias run-time persistentes de programas Progress. É desnecessário copiar fisicamente o código fonte 4GL do objeto para um SmartContainer. Um desenvolvedor pode dar manutenção a todas as instâncias de um determinado SmartObject alterando um único arquivo. Este ganho em manutenção é possível porque o SmartContainer apenas referencia os objetos que contém. 6.4 1) Exercícios: Desenvolver um submódulo de pesquisa seguindo os passos abaixo: criar um SmartFrame; sem usar o recurso de SmartFolders, criar três browser, colocando-os em três páginas distintas; criar um radio-set com os valores “Customer”, “Order” e “Salesrep”; criar um fill-in; 27 criar um botão para pesquisa; programar a tela de pesquisa de tal forma que, ao selecionar um dos valores do radio-set, é ativada a página disponibilizando o browse correspondente. Ao pressionar o botão de disparo da pesquisa, deve ser aberta a query de acordo com o valor informado no fill-in. 2) Desenvolver um submódulo que compreenda os seguindes cadastros, seguindo os procedimentos correspondentes: Cadastro de Customer - crie um SmartViewer; - neste SmartViewer, crie um fill-in; - salve o SmartViewer; - crie uma SmartWindow, instanciando o SmartViewer anteriormente criado nesta; - nesta SmartWindow, crie botões para as operações que você imagina possíveis sobre um cadastro; - programe a tela de cadastro de Customer de tal forma que seja efetuada validação para evitar duplicação de nomes na base de dados e seja ajustada a interface* de acordo com a operação que está sendo executada. Cadastro de Order - crie uma SmartViewer; - neste SmartViewer, crie um combo-box e um fill-in; - salve o SmartViewer; - crie uma SmartWindow, instanciando o SmartViewer anteriormente criado nesta; - nesta SmartWindow, crie botões para as operações que você imagina possíveis sobre um cadastro; - programe a tela de cadastro de Order de tal forma que o combo-box traga para o usuário a lista de todos os Customers. Tal como o cadastro de Customer, deve ser feita validação quanto à duplicação de nomes na base de dados, bem como o ajuste de interface* de acordo com a operação que está sendo executada. Cadastro de Invoice - crie um SmartViewer; - neste SmartViewer, crie um fill-in e um editor; - salve o SmartViewer; - crie uma SmartWindow, instanciando o SmartViewer anteriormente criado nesta; - programe a tela de tal forma que o usuário informe a Data (Invoice-Date) e o total pago (Total-Paid). Assim como nos dois cadastros anteriores, faz-se necessária a validação de nomes e o ajuste de interface* de acordo com a operação. * validação dinâmica 3) De acordo com os procedimentos, desenvolver um submódulo para atribuir as tarefas, anteriormente cadastradas, às suas funções. 3.1 - crie uma SmartWindow; - crie um SmartBrowser; - crie um botão; - o primeiro browse deve trazer todos os cargos, enquanto o segundo deve trazer as funções do cargo selecionado anteriormente; - SmartBrowser deve ser carregado com todas as funções cadastradas no sistema. 3.2 - Criar uma SmartDialog; - crie dois browsers; - crie dois botões; - crie um fill-in; - ao ser pressionado o botão da tela anterior é chamada a SmartDialog; - o fill-in deve ser preenchido com a denominação da função escolhida na SmartWindow; - o primeiro browse deve ser carregado com todas as tarefas cadastradas no sistema, enquanto que o segundo deve trazer todas as tarefas executadas por aquela função; - os botões devem permitir alterar o domínio de tarefas por função; 28 - devem ser programadas validações para impedir atribuir tarefas já existentes. 29 7 Links Ao colocar SmartObjects em um Container você deve interligá-los através de Links. 7.1 Criando um Master Object a partir de um Template • • • A criação de um Master Object pode ter diversas razões: tirar proveito da tecnologia SmartObjects; diminuir a complexidade de um programa, criando-se programas menores e integrando-os – “dividir para conquistar”; a mesma lógica é utilizada em tantos programas/aplicações quanto se queira. Obs. A alteração de um Master Object afeta todos os Containers que o possuam encapsulado. 7.2 7.2.1 Definindo Tabelas Externas O que são / para quê servem É possível, para SmartBrowsers e SmartQueries, definir uma ou mais tabelas externas. A utilidade vem do que segue: • Consultas a várias tabelas em uma mesma consulta são mais pesadas que consultas a uma tabela em uma consulta; 30 • Com este mecanismo, pode-se encadear consultas. O registro lido de uma consulta pode ser utilizado para join em outra. Para definir tabelas externas, clique sobre a opção Procedure Properties e adicione o nome das tabelas externas à sua query. Exemplo: 7.2.2 “p:\curso82a\Exemplos\f-c05e19.w” Exercício 1) Adicione ao exemplo um detalhe de pedidos de cliente (Order of Customer). 7.3 Organizando Masters em Diretórios Existe um arquivo chamado Smart.cst (geralmente contido na pasta \dlc\src\template\) que contém as configurações dos objetos contidos na palette. Para alterar o caminho de busca destes objetos altere a linha DIRECTORY-LIST . #SmartBrowser UP-IMAGE-FILE DOWN-IMAGE-FILE LABEL DB-CONNECT NEW-TEMPLATE DIRECTORY-LIST FILTER TITLE &Default adeicon/wp_up 28,196 adeicon/wp_down 28,196 SmartBro&wser src/adm/template/browser.w .,adm/samples b-*.*,b-*.w,b-*.r,*.* Choose SmartBrowser Atualize na palette, através da opção Menu – Use Custom... , com o nome do novo arquivo padrão a ser utilizado. 31 7.4 O que é um link ? Um link é uma conexão entre dois SmartObjects que define como eles interagem e quais os tipos de mensagens eles podem trocar. Tipo de Link Record TableIO O que ele envia RowId de um registro Mensagem para Inclusão, Alteração e Exclusão de registro Mensagem para ir para o próximo registro, anterior, primeiro ou último registro Navigation 7.5 Exercícios 1) Coloque os links necessários. |< < > >| 1.1 Clientes |< 1.2 < > >| < > >| Clientes Detalhe de Clientes |< 1.3 Browse Clientes 32 Detalhe de Clientes |< 1.4 < > >| Clientes Add 7.6 Update Delete Reset Tabela de Links Possíveis SOURCE SmartPanel Navigation SmartPanel Update Link Type Navigation TableIO SmartPanel Transaction TableIO SmartBrowser Record SmartViewer Record SmartQuery Record Qualquer SmartObject State Targets Possíveis SmartQuery SmartViewer SmartBrowser SmartViewer SmartBrowser SmartQuery SmartViewer SmartBrowser SmartQuery SmartViewer SmartBrowser SmartQuery SmartViewer SmartBrowser SmartQuery Qualquer SmartObject 33 7.7 Progress Advisor 7.8 Estratégias de links para múltiplos Record Targets Alternativa 1 Q Q R R R R Observação: o que ocorre no exemplo abaixo? Q R R 34 Alternativa 2 7.9 Definição de links no UIB Advisor Link Editor 35 8 Paginando uma Aplicação 8.1 Paginando uma Aplicação Para paginar uma window deve-se utilizar o seletor de páginas (ou o item Edit - Goto Page do menu). Duplo Click Características da paginação: Objetos colocados na página 0 são sempre visíveis Procedure oferecida pelo ADM para mudança de página: RUN Select-Page(n). SmartFolders São widgets que controlam automaticamente as mudanças de página (quando linkadas ao seu container). É possível, com um pouco de programação, controlar a mudança de página utilizando outros widgets (por exemplo, radio-sets). O SmartFolder apenas oferece uma maneira simples, rápida e elegante de fazê-lo. 36 Exemplo de utilização de SmartFolder: 1. Crie uma Window 2. Insira os objetos desejados na página 0 3. Crie um SmartFolder 4. Especifique os labels das páginas 5. Instancie os objetos em suas páginas, conforme desejado. 37 8.2 Links 8.3 Exercícios: 1) Altere o programa-exemplo “c:\Prow82a\Curso\Exemplos\w-c08e20.w”, de modo que a mudança de página seja acionada por botões, e não mais por um SmartFolder (o qual deve ser excluído). 2) Monte um módulo de uma aplicação seguindo os seguintes procedimentos: crie uma SmartWindow; crie um SmartBrowser; instancie o SmartBrowser na página 0 da SmartWindow; crie, nesta SmartWindow, dois botões; crie um SmartViewer; instancie o SmartViewer na página 1 da SmartWindow; crie um segundo SmartBrowser; instancie o SmartBrowser na página 2 da Smart Window; ao ser executada a SmartWindow, o browse principal deverá ser carregado com todas as funções do sistema, de tal forma que o SmartViewer traga os dados correspondentes dos atributos da função selecionada e o SmartBrowser da página 2 seja carregado com todas as tarefas executadas por alguém que exerce a função. 3) Desenvolver um módulo semelhente ao solicitado no exercício 1, usando, porém, folders ao invés de botões. 38 8.4 Persistent Procedures Embora executada de maneira diferente, uma persistent procedure é semelhante a outra procedure qualquer. Quando uma persistent procedure é executada, esta fica residente em memória até que seja explicitamente excluída. Exemplo: Suponha que seja preciso executar duas SmartWindows ao mesmo tempo. Ao selecionar um registro na primeira SmartWindow é possível visualizar, de maneira sincronizada, dados correspondentes na segunda SmartWindow. 39 9 Enviando Mensagens (Messaging) 9.1 Messaging É o mecanismo pelo qual SmartObjects executam internal procedures de outro SmartObject. Exemplo: Toda SmartQuery sabe como enviar um registro para um SmartViewer. Todo SmartViewer sabe como receber e exibir o registro informado pela SmartQuery. SmartViewer SmartQuery 1 Internal Procedures adm-display-fields Internal Procedures 2 adm-open-query adm-row-available send-records 40 9.2 Messaging e tipo de Links Uma maneira de identificar uma internal procedure do ADM é considerar como cada SmartObject na comunicação através de links. O tipo de link determina quais mensagens o source e o target objects esperam para proceder à troca de informações e, posteriormente, executarem suas funções. A tabela a seguir apresenta os tipos de links que cada SmartObject suporta, e se este Smart pode ser source, target ou ambos para cada link. SmartObject SmartContainer Tipos de Links Container Source Container Target Page(n) Source Page Target Container Target Record Source Record Target Navigation Target Container Target Record Source Record Target TableIO Target Container Target Record Target Record Source TableIO Target Container Target Navigation Source Container Target TableIO Source Container Target Page Source SmartQuery SmartBrowser SmartViewer Navigation SmartPanel Update SmartPanel SmartFolder 41 9.3 ADM messaging para cada tipo de link Para um determinado tipo de link, um source object espera poder executar um conjunto específico de internal procedures de um target object. Da mesma forma o target object também espera poder executar um conjunto de internal procedures do object source. Todo SmartObject possui um conjunto default de procedures que permite esta troca de mensagens. Exemplos: 1) Um container pode criar e destruir os SmartObjects no Container, e instanciar os SmartObjects na sua devida posição. Container Source e Target Objects possuem as seguintes internal procedures: Container Source Adm-create-objects Container Target Set-position Set-size Init-objects Adm-destroy Adm-destroy Adm-exit 2) Um Container é capaz de gerenciar seu conjunto de páginas. SmartObjects em cada página são linkados ao Container com o link página(n). Container Source Select-Page Container Target Adm-hide Adm-change-page Adm-view Adm-create-objects 9.4 Event Procedure e Method Procedure Cada SmartObject possui uma série de include files. Alguns são responsáveis pela comunicação (messaging), e estão localizados na divisão Internal Procedure do UIB. Existem dois tipos de Internal Procedures nos SmartObject include files: Event Procedures e Method Procedures. 9.4.1 Event procedures Exemplo: o SmartQuery, através da procedure adm-row-available, pergunta ao SmartViewer sobre a existência de um novo registro. Adm-row-available é uma event procedure. 42 9.4.2 Method procedures Exemplo: o SmartViewer, através da method procedure do SmartQuery, pergunta quando é preciso receber um novo registro. Send-records é um method procedure. 9.4.3 Comparação entre Event procedure e Method procedure Event Procedure Inicia sempre com “adm” Pode ser alterada É executada utilizando Dispatch ou Notify Não pode ser definido nenhum parâmetro 43 Method Procedure Não possui padrão para nomes Não pode ser alterada É chamada utilizando o comando “Run” Pode ser especificada uma lista de parâmetros 9.4.4 Como trabalhar com Event Procedure Exitem duas formas de forcar a execução de Event Procedures: RUN DISPATCH RUN NOTIFY 9.4.4.1 Dispatch Sintaxe do comando: RUN dispatch [IN handle] (“base-procedure-name”). Onde: - Handle: nome do SmartObject. Base-procedure-name: nome do evento sem o prefixo “adm”. Exemplo: RUN DISPATCH IN v-cli01 (“display-fields”). Início RUN dispatch ("display-fields"). Existe "local-display-fields" ? Sim Executa versão local Sim Executa versão adm Não Existe "adm-display-fields" ? Não Fim 44 9.4.4.2 Notify Sintaxe do comando: RUN dispatch [IN handle] (“base-procedure-name [,link-types]”). Onde: - Handle: o nome do SmartObject. Base-procedure-name: o nome do evento sem o prefixo “adm”. Link types: uma lista de tipos de links para os quais a mensagem é enviada. Exemplo: RUN NOTIFY IN this-procedure (“row-available”). Início RUN notify ("base-procedure,link-type"). Existe outro target object para este tipo de link ? Sim Run dispatch IN target-object ("base-procedure"). 45 Não Fim 9.4.5 Como Alterar Event Procedures ? no Section Editor, após selecionar “Procedures”, clique no botão “New”; escolha “Local ADM Event”; 46 selecione o Event que você precisa alterar; escreva seu código. 47 Os exemplos a seguir baseiam-se em uma tela de cadastro para as tabelas “Customer”, “Order” e “Invoice”. À medida que avançarmos nos exemplos, acresceremos o que aprendermos ao programa abaixo descrito. Salve todos os objetos criados em “c:\Prow82a\Curso\exercicio”. (a) crie uma SmartWindow. Salve-a com o nome “w-c09e23.w”; (b) crie um SmartFolder nesta janela, com os seguintes tab folders: “Customer”, “Order” e “Invoice”. Confirme a criação do link Container ao Advisor; (c) crie três SmartQuerys, uma para cada tabela. Salve-as, respectivamente, com os seguintes nomes: “q-c09e23cust.w”, “q-c09e23orde.w” e “qc09e23invo.w”; (d) crie dois SmartViewers, com os seguintes campos para cada tabela: Customer: Name, Address, City, State, Country, Postal-Code, Contact, Phone; Order: Cust-num, Ordered, Promised, Shipped, Instructions. Salve-os, respectivamente, com os seguintes nomes: “v-c09e23cust.w” e “vc09e23orde.w”; (e) crie um SmartPanel Navigation e um SmartPanel Update na primeira e segunda páginas do SmartFolder. Dê a estes SmartPanels os seguintes nomes: “Customer-Navico”, “Order-Navico”, “Customer-Updsav” e “Order-Updsav”. 1. Criação de uma alert-box para confirmar a exclusão de um registro da tabela Customer. Defina a procedure local-delete-record, de modo que esta mostre uma mensagem perguntando ao usuário se ele realmente deseja excluir o registro antes de efetivamente excluí-lo (observe que há uma divisão em toda procedure do ADM à qual deseje-se acrescer código – antes da execução do procedimento default do ADM, e após a execução do mesmo). A seguir é listado o que ocorre quando o usuário pressiona o botão ‘Delete’. (a) o trigger do botão ‘Delete’ do SmartPanel Update executa “NOTIFY (‘deleterecord’)”; (b) o viewer, estando linkado ao SmartPanel Update, executa “DISPATCH ‘delete-record’”; (c) ‘DISPATCH’ encontra e executa a procedure ‘local-delete-record’. Nosso código é executado; (d) ao ser questionado quanto à exclusão do registro, se o usuário escolher ‘Sim’, a procedure ‘adm-delete-record’ é executada e exclui o registro. Se o usuário escolher ‘Não’, a procedure é abortada. 48 2. Cadastrar um novo Order (Pedido) para um Customer (Cliente). crie um SmartBrowser sobre a tabela “Invoice”, com as seguintes colunas: ‘Custnum’, ‘Name’, ‘Contact’ e ‘Phone’; salve este SmartBrowser com o nome “b-c09e23orde.w”. A seguir é listado o que ocorre quando da operação desta tela: (a) o usuário pressiona o botão ‘Add’; (b) o ADM ‘limpa’ os campos do SmartViewer; (c) o usuário entra com os dados do novo registro e pressiona ‘Save’; (d) o viewer, como está linkado ao SmartPanel Update, executa “DISPATCH assign-record”, o qual executa a procedure ‘local-assign-record’; 49 (e) a procedure ‘local-assign-record’ primeiro chama ‘adm-assign-record’. O código do programador é executado a seguir; (f) o controle retorna à tela. 3. Ordenar registros de uma query de n maneiras. crie um SmartBrowser sobre a tabela “Invoice”, com as seguintes colunas: ‘Custnum’, ‘Invoice-num’, ‘Ship-Charge’, ‘Amount’, ‘Invoice-Date’ e ‘Total-Paid’; adicione um radio-set horizontal a este, com o label ‘Ordenar por’, e as seguintes opções: ‘Customer’ e ‘Invoice’; salve este SmartBrowser com o nome “b-c09e23invo.w”; crie, no SmartBrowser, uma procedure ‘local-open-query’ para reabrir a query de acordo com a seleção do usuário; crie, no SmartBrowser, uma procedure ‘local-initialize’ para inicializar o valor do radio-set e, se preciso, inicializar outros valores e/ou procedimentos. 50 A seguir é listado o que ocorre quando da operação desta tela: (a) a SmartWindow executa o SmartBrowser; (b) o SmartBrowser executa sua própria ‘local-initialize’ e, simultaneamente, o código escrito nesta procedure é executado; (c) o SmartBrowser executa sua própria ‘local-open-query’ e, simultaneamente, a query é aberta de acordo com as condições especificadas nesta procedure; (d) o SmartBrowser executa a procedure ‘display-fields’para mostrar os dados no browse. 51 9.5 Mapa de eventos Os diagramas abaixo representam os principais eventos utilizados pelo ADM. Com o auxílio destes diagramas você pode definir onde fazer as alterações necessárias em sua aplicação. As linhas pontilhadas representam uma ‘execução condicional’. 1. O diagrama que segue representa diversas seqüências de eventos que ocorrem durante a inicialização de um SmartObject. adm-initialize adm-create-objects adm-enable adm -open-query adm-view adm-row-available Adm-initialize é executado quando a aplicação é executada. Ele chama: • • • • • adm-create-objects para colocar e rodar os SmartObjects no Frame adm-enable para ‘habilitar’ os objetos (se não estiverem DISABLE-ON-INIT) adm-view para mostrar os objetos (se não forem HIDE-ON-INIT) adm-open-query para abrir uma SmartQuery ou SmartBrowser adm-row-available para enviar o registro corrente para uma SmartQuery ou SmartBrowser, apenas se um registro estiver ativo. 2. Este diagrama representa eventos que ocorrem quando a aplicação é terminada. adm-exit in object local-exit in container 2. Adm-destroy in object 3. Adm-exit é o evento utilizado por um container para requisitar o fim da aplicação. O container passa para cada objeto uma ‘destroy message’. Para cada objeto os seguintes passos são realizados: • • • Apaga o objeto (apaga a procedure persistente da memória); Remove todos os links definidos para o objeto; Executa a procedure disable_ui para o objeto. 52 3. Os próximos dois diagramas representam a seqüência de eventos que ocorrem durante uma troca de página em uma Window. Note que a única diferença entre admview-page e adm-select-page é que adm-view-page não oculta os objetos. adm-view-page adm-change-page adm-create-objects adm-view Adm-view-page chama adm-change-page para mostrar a nova página (sem ocultar a anterior antes). Caso for a primeira vez que a página for mostrada, ele chamará o evento adm-create-objects. Em seguida chama adm-view e mostra os objetos. Neste caso utilizando adm-select-page os objetos da página anterior serão ocultados antes de ser mostrada a próxima página. adm-select-page adm-hide adm-change-page adm-create-objects adm-view 4. Este diagrama representa a seqüência de eventos que ocorrem durante a navegação entre registros. adm-get-next adm-row-changed adm-get-first adm-get-prev adm-row-available adm-get-last adm-reposition-query adm-display-fields Os eventos get-next/first/prev/last e reposition-query chamam adm-rowchanged que notifica (notify) todos os objetos de destino (record target) que o registro foi trocado. 53 5. Os próximos diagramas representam os eventos utilizados quando ocorre a atualização de um registro adm-update-record adm-assign-record adm-current-changed adm-end-update adm-assign-statement adm-display-fields Adm-update-record chama os eventos na seguinte ordem: 1. adm-assign-record que chama: 2. adm-current-changed para encontrar o registro (find) e ver se ele não está sendo alterado/bloqueado por outro usuário (lock); 3. adm-assign-statement faz a gravação (assign); 4. adm-display-record mostra o registro (se for um novo registro); 5. adm-end-update reposiciona a query e notifica os outros objetos que o registro foi alterado. (continuação) Este diagrama representa mais seqüências de eventos que ocorrem durante a atualização de um registro adm-copy-record adm-add-record adm-delete-record adm-apply-entry adm-reset-record adm-end-update Os eventos copy, delete,add e reset chamam adm-apply-entry para mover o ponteiro para o registro corrente, seguido do comando add, copy, delete ou reset. A troca do registro corrente, faz com que sejam notificados todos os object targets que um novo registro está disponível para ser mostrado adm-row-changed adm-row-available adm-display-fields 54 10 SmartBrowser com Enable Column Para habilitarmos a edição de colunas em um browser, devemos alterar a opção enable da Column Editor (Propriedades da Query do Browser). Com o SmartBrowser possuindo Enable Columns podemos criar um link tipo TableIO entre um SmartBrowser e um SmartPanel de Update (p-updsav.r). 55 11 NEW-STATE METHOD O método new-state é chamado por meio de um comando “RUN”. Exemplo: Run new-state (‘param’). Este comando envia uma mensagem para os ‘Target Objects’ que possuem um link tipo ‘State’, com o número do handle e uma variável. Os ‘Target Objects’ recebem a mensagem e executam a procedure ‘StateChanged’ recebendo o parâmetro na variável ‘p-state’. T add del cancel Procedure add-record Run new-state (‘param’) State Procedure state-changed case p-state: when … 56