Manual de PadrõesProgramação EMS 2.0 Março/2006 Copyright © 1998 DATASUL S.A. Todos os direitos reservados. Nenhuma parte deste documento pode ser copiada, reproduzida, traduzida ou transmitida por qualquer meio eletrônico ou mecânico, na sua totalidade ou em parte, sem a prévia autorização escrita da DATASUL S.A., que reserva-se o direito de efetuar alterações sem aviso prévio. A DATASUL S.A não assume nenhuma responsabilidade pelas conseqüências de quaisquer erros ou inexatidões que possam aparecer neste documento. DATASUL S.A. Av. Santos Dumont, 831, Joinville, SC, CEP 89.222-900 i Índice CAPÍTULO 1 Revisão do Dicionário de Dados.............................................1 Construção do Dicionário de Dados..............................................................2 Gatilhos do Dicionário de Dados..................................................................3 Campos Livres..............................................................................................4 Validações.....................................................................................................4 Considerações sobre o Dicionário de Dados do Datasul-HR 1.00.................5 CAPÍTULO 2 Estrutura de Diretórios.............................................................6 Datasul-EMS 2.0...........................................................................................6 Datasul-HR 1.0...........................................................................................12 CAPÍTULO 3 Nomenclatura..........................................................................15 Sigla de bancos de dados.............................................................................15 Banco de Dados do Datasul-EMS 2.00 ................................................................................................................15 Banco de Dados do Datasul-HR 1.00......................................................16 Siglas de módulos do produto.....................................................................16 Módulos do Datasul-EMS 2.00...............................................................16 Módulos do Datasul-HR 1.00 ................................................................................................................17 Tipos de Atributos.......................................................................................18 Dump-name de tabelas................................................................................19 Gatilhos do dicionário de dados..................................................................19 Programas...................................................................................................19 Includes.......................................................................................................21 Include com view-as de campos para o dicionário de dados...................21 Includes de programas............................................................................21 Includes padrões.....................................................................................22 Widgets.......................................................................................................22 Variáveis.....................................................................................................23 Datasul-EMS 2.00...................................................................................23 Datasul-HR 1.00.....................................................................................23 Outros componentes da linguagem Progress...............................................23 Siglas de países...........................................................................................24 Nomenclatura para Caixas de diálogos em programas de Zoom e SmartBrowser.............................................................................................24 Adapters......................................................................................................25 CAPÍTULO 4 Layout de Telas.......................................................................26 Tipos de Telas (janelas)..............................................................................26 Janela Mestre..........................................................................................26 Janela Detalhe.........................................................................................26 Caixas de Diálogo...................................................................................26 Objetos........................................................................................................27 Combo-boxes..........................................................................................27 Retângulos..............................................................................................27 Botões.....................................................................................................27 Fill-in´s...................................................................................................27 Frames(Telas).........................................................................................27 Radio-Sets...............................................................................................28 Editores...................................................................................................28 Considerações sobre os SmartObjects.........................................................29 SmartBrowser.........................................................................................29 SmartViewer...........................................................................................29 SmartQuery.............................................................................................29 Considerações sobre as Imagens.................................................................29 WebEnabler............................................................................................29 CAPÍTULO 5 Estilos......................................................................................30 Cadastro Simples........................................................................................30 Cadastro Complexo.....................................................................................32 Quando utilizar o Cadastro Complexo....................................................32 Cadastro Simples - Atualiza........................................................................33 Cadastro Complexo - Atualiza....................................................................34 Pai x Filhos - Atualiza Filho.......................................................................35 Quando utilizar Pai x Filhos - Atualiza Filho..........................................35 Manutenção de Filhos.................................................................................36 Pai x Filhos - Atualiza Ambos....................................................................37 Índice iii Manutenção de Pais....................................................................................38 Consulta Cadastral Simples.........................................................................39 Consulta Cadastral Complexa.....................................................................40 Consulta Relacionamento............................................................................41 Relatórios, Cálculos, Fechamentos.............................................................42 Parâmetros Únicos......................................................................................46 Parâmetros Múltiplos..................................................................................46 Formação....................................................................................................47 Formação sem Navegação...........................................................................48 Importação..................................................................................................49 Exportação..................................................................................................51 Zoom de Tabelas.........................................................................................54 Vá Para.......................................................................................................55 Digitação Rápida.........................................................................................56 Painéis.........................................................................................................56 Funções.......................................................................................................57 Relatórios Relacionados ................................................................................................................57 Consultas Relacionadas...........................................................................57 CAPÍTULO 6 Includes e Utilitários Padrão..................................................58 UT-FIELD.I................................................................................................58 UT-RTLBL.I...............................................................................................59 UT-RUN.I...................................................................................................59 UT-MSGS.P................................................................................................64 IND01-10.I, IND11-50.I E IND51500.I......................................................65 UT-TABLE.I...............................................................................................67 UT-LITER.I................................................................................................67 UT-LIMIT.P...............................................................................................68 UT-GLOB.I................................................................................................69 I-FREEAC.I................................................................................................69 UT-DIR.P....................................................................................................69 BTB917ZX.P..............................................................................................70 BTB917ZY.P..............................................................................................71 BTB917ZZ.P...............................................................................................72 UT-VRBIN.P..............................................................................................73 UT-FINFO.P...............................................................................................74 UT-CMDLN.P............................................................................................75 UT-OSVER.P.............................................................................................75 I-COUNTDS.I.............................................................................................76 UT-WIN.I...................................................................................................77 UT-TRACE.P.............................................................................................80 CAPÍTULO 7 Tradução........................................................................................................81 TRADUÇÃO MONO-IDIOMAS...............................................................81 Tradução de variáveis com view-as nas telas..............................................81 Espaço Extra para tradução em relatórios...................................................86 TRADUÇÃO MULTI-IDIOMAS...............................................................87 Nomenclatura Padrão e Características do modelo.....................................87 Pontos de tradução .....................................................................................89 Contextos de tradução ................................................................................89 Itens de Tradução ......................................................................................90 Sequência de busca.....................................................................................92 UT-TRCAMPOS.P.....................................................................................93 UT-TRFRRP.P............................................................................................94 UT-LSTIT.P................................................................................................94 UT-LITER.P...............................................................................................95 UT-MSGS.P................................................................................................96 UT-FIELD.P...............................................................................................97 UT-TABLE.P..............................................................................................98 UT-LTMNU.P............................................................................................99 OBJETOS PROGRESS NÃO-INDEXADOS...........................................100 Tradução de variáveis com view-as nas telas............................................100 Espaço Extra para tradução em relatórios.................................................104 PRÁTICAS PARA IMPLEMENTAÇÃO MULTI-IDIOMAS.................105 Caso Prático Diferenças LIST-ITEMS para LIST-ITEM-PAIRS.............106 Caso conversão de List-items para LIST-ITEM-PAIRS...........................109 Tradução automática em frame de relatório..............................................110 Traduzir valor armazenado em uma variável............................................111 Tratando lista enorme de tradução em includes.........................................111 CAPÍTULO 8 Construção de Programas utilizando os Estilos e suas Técnicas..........116 Como construir um Cadastro Simples.......................................................116 Como construir um Cadastro Complexo...................................................118 Como construir um Cadastro Pai X Filho - Atualiza Filho........................122 Como construir um Cadastro Inclui/Modifica Filho..................................127 Como construir um Cadastro Pai X Filho - Atualiza Ambos.....................133 Como construir um Cadastro Inclui/Modifica Filho..................................137 Índice v Como construir um Cadastro Inclui/Modifica Pai.....................................141 Como construir um CustomBrowser Inclui/Modifica...............................145 Como construir um CustomBrowser Zoom Wizard..................................147 Como construir uma Consulta Simples.....................................................151 Como construir uma Consulta Complexa..................................................153 Como construir uma Consulta Relacionamentos.......................................157 Como construir um programa de Relatórios..............................................160 Preparação do Relatório - Interface.......................................................161 Página de Impressão.............................................................................164 Relatórios no formato RTF...................................................................164 Dicas para criação do Programa RP.P de Relatório...............................165 Preparando o Relatório para Execução no Módulo JOB EXECUTION....171 Como construir um programa de Parâmetros Únicos................................178 Como construir um programa de Formação..............................................179 Como construir um programa de Formação sem Navegação....................183 Seqüência..............................................................................................184 Como construir um programa de Importação............................................186 Dicas Gerais..........................................................................................186 Preparação do programa........................................................................187 Dicas para criação do Programa RP.P de Importação...........................189 Como construir um programa de Exportação............................................192 Dicas Gerais..........................................................................................192 Preparação do programa........................................................................192 Dicas para criação do Programa RP.P de Exportação...........................196 Como construir um programa de Pesquisa................................................198 Como construir um programa "Vá Para"...................................................200 Como construir um programa de Digitação Rápida..................................201 Como construir um Browse de Digitação..............................................202 Como construir uma Query.......................................................................203 Como construir viewers............................................................................204 Como definir viewer Padrão.................................................................204 Como definir viewer sem campos de tabela:.........................................207 Como definir viewers só com campos chave:.......................................213 CAPÍTULO 9 Validações.............................................................................219 Validações de Tela .................................................................................219 Validações na Navegação de Registro..................................................219 Validações Antes da Alteração.............................................................219 Validações em Entrada de Dados..........................................................220 Validações em Cadastro Simples..........................................................220 Validações em Cadastro Complexo......................................................221 Validações para Window Relatório.......................................................221 Validações em Triggers de Dicionário de Dados......................................221 CAPÍTULO 10 Mensagens..........................................................................223 Regras para a criação de novas mensagens...........................................225 Padrões para tradução de mensagens para Inglês e Espanhol................228 CAPÍTULO 11 Programas Reutilizáveis.....................................................229 Procedures Internas...................................................................................229 CAPÍTULO 12 Ferramentas........................................................................230 Application Compiler................................................................................230 Selecionar arquivos a serem compilados...............................................231 Eliminar e Modificar a lista de arquivos a serem compilados...............232 Opções de Compilação..........................................................................233 Iniciar Compilação................................................................................234 Roundtable................................................................................................234 CAPÍTULO 13 API´s.....................................................................................238 O que são API´s e como construí-las........................................................238 Código da API......................................................................................242 Como documentar API´s...........................................................................243 Como implementar evoluções de API´s....................................................244 UTAPI001.P.............................................................................................254 UTAPI002.P.............................................................................................254 UTAPI003.P.............................................................................................255 UTAPI004.P.............................................................................................255 UTAPI005.P.............................................................................................256 UTAPI006.P.............................................................................................258 UTAPI007.P.............................................................................................258 UTAPI008.P.............................................................................................259 UTAPI009.P.............................................................................................259 UTAPI010.P.............................................................................................259 UTAPI011.P.............................................................................................260 UTAPI012.P.............................................................................................260 UTAPI013.P.............................................................................................261 UTAPI018.P.............................................................................................261 UTAPI019.P.............................................................................................261 ...................................303 Como habilitar ou desabilitar botões em painéis.................................................................................................................306 Como implementar campos indicadores com view-as combo-box nas telas ....266 Caso em Especial.............264 Execução........................................................................................................................312 Como implementar mensagens para o usuário.............................................307 Como implementar campos indicadores com view-as radio-set nas telas....313 .........................269 Como alterar o caracter de senha..270 Como dar foco a qualquer objeto.............................................................................................................................272 Como utilizar OCX...................................................................................................................................................................................263 Parâmetros de Entrada...............................P.......................................................................................................................P..................................................................298 Como obter o diretório de sistema do Windows...........................................311 Como implementar labels em retângulos utilizando o dicionário de dados ............................................................................................................. 309 Como implementar campos indicadores num SmartBrowser....................................................263 Parâmetros de Saída..............................................269 Como alterar ou criar uma variável de ambiente...295 Como obter as coordenadas do mouse..............................................................................................................................................................................................................................299 Como obter o diretório do Windows....................269 Como alterar o diretório corrente............................................................................................272 Como executar um aplicativo do Windows....................................................................................................304 Como habilitar ou desabilitar botões específicos em Browse Inclui/Modifica ..............................P.......................................262 UTAPI029.......................................................................................264 CAPÍTULO 14 Portabilidade de RCODES..............................................................................262 UTAPI028............266 Regras para Portabilidade de RCODE...........................................................................................................................297 Como obter o diretório corrente.................................................300 Como obter o valor de uma variável de ambiente......................271 Como deixar uma janela sempre visível..........301 Como desabilitar Radio-Buttons..262 APAPI009...............................................299 Como obter o nome do computador.......Índice vii UTAPI027.........302 Como executar programas que são janelas......................................267 CAPÍTULO 15 Técnicas..P...........................................294 Como implementar Correção Ortográfica em Editores...........301 Como transformar uma janela em barra de ferramentas.............................................. ..............................337 Definição da Variável Global............................................................................................318 Como implementar Zoom e campos de referência para campos chave estrangeira........................................................336 Como implementar reposicionamento de registro com base nas variáveis globais......338 Como validar campos em viewers diferentes.......................313 Mensagem de Erro/Advertência/Informação com Parâmetros.........................................347 Como verificar o registro de um OCX....................................................................351 Mini-Flexibilização.....................315 Como implementar uma barra de progresso...............328 Como totalizar colunas de um browse.......................363 Como migrar relatórios antigos para RTF.............347 Como utilizar "functions" no UIB........................320 Como implementar ThinZoom e campos de referência para campos chave estrangeira em SmartObjects............................................329 Como adaptar a procedure pi-retorna-valor no Custom Browser Zoom Wizard...........................................349 Como construir um browse com ordenação por coluna..................................................................................341 Como implementar localizações.................................................................................330 Situações necessárias................332 Formato de Impressão (80 colunas ou 132 colunas):................................................................................................................................316 Como implementar acompanhamento (UT-ACOMP).....340 Como construir gatilhos de dicionários de dados..............................................376 ...346 Como setar os modos de inclusão (Simple/Multiple) ........................................................363 Como enviar gráficos ou documentos office para o WebEnabler...................................................................................................361 Como chamar um programa que é janela a partir de uma transação...........................................................................................................................314 Como implementar Tooltip em um determinado botão...........334 Como implementar Botão de Filtro em Zoom.......332 Impressão Página de Parâmetros:...................ini............................................................................................337 Reposicionamento Automático do Browser de Zoom..........................................................343 Padronização dos parâmetros do progress...................................................................................................371 Utilitário para Geração de Comandos SQL..............362 Como descobrir se o EAI está habilitado.............331 Como implementar Parâmetros de Impressão em Relatórios............353 Como registrar campo do tipo Fill-in para o WebEnabler.............364 Como converter consultas For Each para Send-SQL-Statement............................................................................................................324 Como imprimir campos editores nos relatórios............................................Mensagem de Erro/Advertência/Informação sem Parâmetros....314 Mensagens com Questionamento ao Usuário.................360 Como contar a quantidade de registros numa tabela..... ............................387 CAPÍTULO 16 Dicas de Desenvolvimento...................390 ............................................390 Segurança de Banco x Objetos Dinâmicos..............................Índice ix Conversão de Query em Frame para SmartQuery.............. 00.1 CAPÍTULO 1 Revisão do Dicionário de Dados Definição Antes do início da conversão de cada módulo deve ser realizada uma revisão n Dicionário de Dados do MAGNUS versão I. . int-1. Exemplo: editor. trocar por campo indicador correspondente com tipo de dado inteiro. Exemplo: DE PARA Emitente. para todos os campos que são indicadores. criar tabelas necessárias que hoje estão "camufladas" em arquivos temporários e/ou em tabelas não utilizadas. radio-set.ide Emitente. que abrange os seguintes itens: • • • • trocar os campos do tipo narrativa (exemplo: "x(76)" x10) nas tabelas por campos view-as editor e formato "X(2000)". e toggle-box. etc.. criar os campos necessários para limpar os campos do tipo char-1. sejam de tipo de dado caracter ou lógico... dec-1.identific ntific "C"liente 1 "F"ornecedo r "A"mbos 2 3 • implementar o view-as nos campos possíveis. as palavras que compõem os labels e column-labels. Exemplo: {inc/conta.fv}. onde 'xx' é a sigla do banco conforme tabela abaixo. Dump-Name das tabelas tem a nomenclatura: xx999. SIGL A AD BH CL DI ED IN IV MP PE RH UN BANCO Administrativo Bancos Históricos Coletor de Dados Distribuição EDI Industrial Investimentos MultiPlanta Ponto Eletrônico Recursos Humanos Universal Construção do Dicionário de Dados • • alterar o campo "CEP" único para formato x(12) com parâmetro global formato-cep. campo "Unidade da Federação" deve ter formato x(04)..-). reservando espaço extra para tradução.. . deve ser maiúscula. revisar os labels e column-labels dos campos para internacionalização. evitar column-labels com duas ou mais linhas. da. as demais minúsculas.. quando não abreviadas. que compõe o label ou col-label.• • • • • • • • substituir os campos do tipo "texto livre" por campos do tipo caracter formato "x(15000)" view-as editor. em . a primeira letra de cada palavra. os labels não podem conter preposições (de. e 999 é o número seqüencial da tabela.) e pontuação (. devem ser acentuadas. sugestão: Incorporar no Field-Validation as validações que estão no formato de include. ou seja. em todas as tabelas. As triggers de WRITE e DELETE deverão conter a chamada as includes para EPC´s em Gatilhos de Dicionário de Dados. 2. Ao especificar caminhos. a partir do diretório de instalação do produto. que representem pessoas físicas ou jurídicas. Inscrição Estadual. O caracter . os campos de "Códigos de Contribuição Fiscal (CGC. deve ser sempre assumido a empresa do corrente usuário. Todas as tabelas deverão possuir os gatilhos de dicionário de dados CREATE.. separar tudo que for especificados no Brasil em folder separados. 3. e está disponível na variável global i-ep-código-usuário.Construção de Programas utilizando os Estilos e suas Técnicas 3 • • • • • • • • • • • campo "Condado(Bairro)" deve ter formato x(30). Exemplo: Cadastro de Cliente-Código Febraban. implementar o campo para endereço eletrônico da entidade: e-mail formato 'x(40)' label "Internet E-Mail". os indicadores comuns a várias tabelas. DELETE e WRITE mesmo que não possuam código algum para validação. na confecção de Relatórios evitar posicionamento de campos... • Gatilhos do Dicionário de Dados No Dicionário de Dados. os seguintes itens deverão ser obedecidos: 1. que é definida no menu.)" devem ter como nomenclatura x(18). campo "Número do Documento (do AP/CR)" para MAGNUS deve ter como nomenclatura x(16). campo "Código do Item" deve ter formato x(16).. campo "Endereço2" deve ter formato de x(40). Cacex . deverá ser referenciado apenas o caminho relativo.. os campos de "Conta + sub-conta" devem ter formato x(8) + x(8). na composição do seu nome devem considerar o nome da tabela principal. não existe o campo do código da empresa nas telas. campo "Série do Documento" deve ter formato x(05). etc . "\" (contra-barra) NÃO pode ser utilizado, devendo ser substituído por "/" (barra). 4. Todas devem ser overrideables (override = yes). 5. Todas devem ter o Check CRC = no. Campos Livres Em todas as tabelas dos bancos de dados do produto Datasul-EMS 2.0, existem no mínimo 10 campos livres, sendo 2 de cada tipo de dado, conforme tabela abaixo: Campo Livre char-1 char-2 data-1 data-2 dec-1 dec-2 int-1 int-2 log-1 log-2 Lógico Inteiro Decimal Data Tipo de Dado Caracter Os antigos campos livres são para uso do cliente, como por exemplo, u-char-1, u-livre-1, não são mais implementados nas tabelas. Validações • as validações de campo simples permanecem no Field Validation (VALEXP), no dicionário de dados, entende-se por validações simples aquelas que dependam apenas do dado informado do próprio campo, não fazendo referência a outros campos da tabela. Exemplo: item.descrição-1 <> ""; todas as validações, inclusive as constantes no Field Validation dos campos atualizados na tela, devem ocorrer no momento de confirmação de gravação (botões OK, Gravar, GO of frame); • Construção de Programas utilizando os Estilos e suas Técnicas 5 • normalmente, é feita a validação em um destes locais, pi-validate, quando existirem mais de uma viewer ou na local-assign-record, quando for apenas uma; não implementar qualquer validação no evento de leave dos campos; na SmartViewer retirar as validações automáticas do UIB, para chaves estrangeiras, chamadas "XFTR-Foreing Keys"; todas as validações de eliminação constantes no Delete Validation de uma tabela no dicionário de dados devem ser transferidas para o Delete Gatilho desta tabela, assim o Delete Validation das tabelas fica vazio; também podem ser transferidas para o Delete Gatilho as validações de eliminação que estão nos programas de eliminação pois antes, não eram suportadas pelo Delete Validation. • • • • Considerações sobre o Dicionário de Dados do Datasul-HR 1.00 • a versão atual do Datasul-HR somente possui integração com o produto Datasul-EMS 2.00, e o controle do dicionário de dados é feito no DWBDDD; Datasul-HR, pode acessar tabelas do banco MGUNI e neste caso, não se deve cadastrar as tabelas do MGUNI no DWB-DDD, não sendo utilizado o conceito do DWB de base externa, uma vez que não é utilizado o módulo de construção de programas (DML) no DWB-DDD. O controle de integridade referencial, nestes casos, é feito manualmente nos gatilhos e validações; todas as validações do Datasul-HR são realizadas nos programas ou em trigger´s de write das tabelas, não existem validações no FIELDVALIDATION. • • 6 CAPÍTULO 2 Estrutura de Diretórios Definição Este capítulo relaciona e descreve os diretórios referentes ao Datasul-EMS 2.0 e o Datasul-HR 1.0. Datasul-EMS 2.0 Diretório s \ADBRW \ADGO \ADINC \ADQRY \ADVWR \ ADZOOM \ \AEP \APP \BCP \BHP \BSP \BTB \CBP \CCP Conteúdo Objetos Browsers do banco Administrativo Objetos "Vá para" do banco Administrativo Includes de campos indicadores do banco Administrativo Objetos Queries do banco Administrativo Objetos Viewers do banco Administrativo Zooms do banco Administrativo Programas do módulo Aplicações e Empréstimos Programas do módulo Contas a Pagar Programas do módulo Coleta de Dados Programas do módulo Bancos Históricos Programas do módulo Benefícios Sociais Programas do módulo Básico Programas do módulo Caixa e Bancos Programas do módulo Compras Construção de Programas utilizando os Estilos e suas Técnicas 7 \CDP \CEP \CFP \CLBRW \CLGO \CLINC \CLQRY \CLVWR \CLZOOM \CPP \CQP \CRP \CSP \ \DMAD DATABAS E \DMCL \DMDI \DMIN \DMIV \DMMP \DMPE \DMRH \DMUN \LDAD \LDCL \LDDI \LDIN \LDIV \LDMP \LDPE \LDRH \LDUN \TGAD \TAP \TCP \TDP Programas do módulo Cadastro Programas do módulo Controle de Estoque Programas do módulo Configurador Produto Objetos Browsers do banco Coletor de Dados Objetos "Vá para" do banco Coletor de Dados Includes de campos indicadores do banco Coletor de Dados Objetos Queries do banco Coletor de Dados Objetos Viewers do banco Coletor de Dados Zooms do banco Coletor de Dados Programas do módulo Controle da Produção Programas do módulo Controle de Qualidade Programas do módulo Contas a Receber Programas do módulo Custos Programas de Dump do banco MGADM Programas de Dump do banco MGLCD Programas de Dump do banco MGDIS Programas de Dump do banco MGIND Programas de Dump do banco MGINV Programas de Dump do banco MGMP Programas de Dump do banco MGPE Programas de Dump do banco MGRH Programas de Dump do banco MGUNI Programas de Dump do banco MGADM Programas de Dump do banco MGCLD Programas de Dump do banco MGDIS Programas de Dump do banco MGIND Programas de Dump do banco MGINV Programas de Dump do banco MGMP Programas de Dump do banco MGPE Programas de Dump do banco MGRH Programas de Dump do banco MGUNI Gatilhos de assign do banco MGADM Gatilhos de create do banco MGADM Gatilhos de delete do banco MGADM \TFP \TWP \TGCL \TAP \TCP \TDP \TFP \TWP \TGDI \TAP \TCP \TDP \TFP \TWP \TGIN \TAP \TCP \TDP \TFP \TWP \TGIV \TAP \TCP \TDP \TFP \TWP \TGPE \TAP \TCP \TDP \TFP \TWP \TGRH \TAP \TCP \TDP \TFP \TWP \TGUN \TAP \TCP \TDP \TFP Gatilhos de find do banco MGADM Gatilhos de write do banco MGADM Gatilhos de assign do banco MGCLD Gatilhos de create do banco MGCLD Gatilhos de delete do banco MGCLD Gatilhos de find do banco MGCLD Gatilhos de write do banco MGCLD Gatilhos de assign do banco MGDIS Gatilhos de create do banco MGDIS Gatilhos de delete do banco MGDIS Gatilhos de find do banco MGDIS Gatilhos de write do banco MGDIS Gatilhos de assign do banco MGIND Gatilhos de create do banco MGIND Gatilhos de delete do banco MGIND Gatilhos de find do banco MGIND Gatilhos de write do banco MGIND Gatilhos de assign do banco MGINV Gatilhos de create do banco MGINV Gatilhos de delete do banco MGINV Gatilhos de find do banco MGINV Gatilhos de write do banco MGINV Gatilhos de assign do banco MGPE Gatilhos de create do banco MGPE Gatilhos de delete do banco MGPE Gatilhos de find do banco MGPE Gatilhos de write do banco MGPE Gatilhos de assign do banco MGRH Gatilhos de create do banco MGRH Gatilhos de delete do banco MGRH Gatilhos de find do banco MGRH Gatilhos de write do banco MGRH Gatilhos de assign do banco MGUNI Gatilhos de create do banco MGUNI Gatilhos de delete do banco MGUNI Gatilhos de find do banco MGUNI Construção de Programas utilizando os Estilos e suas Técnicas 9 \TWP \DIBRW \DIGO \DIINC \DIQRY \DIVWR \DIZOOM \DOC \DOCAPI \DOCHLP \DOCRTF \DPP \ENP \FCP \FPP \FRP \FTP \GEP \GRP \IMAGE \IMGDIS \IMGFIN \IMGHUR \IMGMAN \IMGMAT \IMGTEC \INBRW \INCLUDE \INGO \ININC \INP \INQRY \ INTERFA Gatilhos de write do banco MGUNI Objetos Browsers do banco Distribuição Objetos "Vá para" do banco Distribuição Includes de campos indicadores do banco Distribuição Objetos Queries do banco Distribuição Objetos Viewers do banco Distribuição Zooms do banco Distribuição Módulo Documentação Documentação de API´s Documentação dos módulos em formato.hlp Documentação dos Manuais impressos (*.rtf) Programas do módulo de Desenvolvimento Produto Programas do módulo de Engenharia Programas do módulo de FASB/CMI Programas do módulo Folha de Pagamentos Programas do módulo Férias Rescisões Programas do módulo Faturamento Programas do módulo Gerencial Programas do módulo Gerador Relatórios Imagens Diretório padrão de imagens do Aplicativo Distribuição Diretório padrão de imagens do Aplicativo Financeiro Diretório padrão de imagens do Aplicativo Recursos Humanos Diretório padrão de imagens do Aplicativo Manufatura Diretório padrão de imagens do Aplicativo Materiais Diretório padrão de imagens do Aplicativo Tecnologia Objetos Browsers do banco Industrial Includes Padrões Objetos "Vá para" do banco Industrial Includes de campos indicadores do banco Industrial Programas do módulo Investimentos Objetos Queries do banco Industrial Arquivos de interfaces Produto com outros softwares C \INVWR \INZOOM \IVBRW \IVGO \IVINC \IVQRY \IVVWR \IVZOOM \LAYOUT \ MASTER S \MEN \MIP \MPBRW \MPGO \MPINC \MPP \MPQRY \MPVWR \ MPZOOM \OFP \PANEL \PCP \PDP \PEBRW \PEGO \PEINC \PEP \PEQRY \PEVWR \PEZOOM \PIP Objetos Viewers do banco Industrial Zooms do banco Industrial Objetos Browsers do banco Investimentos Objetos "Vá para" do banco Investimentos Includes de campos indicadores do banco Investimentos Objetos Queries do banco Investimentos Objetos Viewers do banco Investimentos Zooms do banco Investimentos Layout´s de Importação Masters do SmartObjects Módulo Menu Programas do módulo Manutenção Industrial Objetos Browsers do banco MultiPlanta Objetos "Vá para" do banco MultiPlanta Includes de campos indicadores do banco MultiPlanta Programas do módulo MultiPlanta Objetos Queries do banco MultiPlanta Objetos Viewers do banco MultiPlanta Zooms do banco MultiPlanta Programas do módulo Obrigações Fiscais Painéis dos SmartObjects Programas do módulo Planejamento Capacidade Programas do módulo de Pedidos Objetos Browsers do banco Ponto Eletrônico Objeto "Vá para" do banco Ponto Eletrônico Includes de campos indicadores do banco Ponto Eletrônico Programas do módulo Ponto Eletrônico Objetos Queries do banco Ponto Eletrônico Objetos Viewers do banco Ponto Eletrônico Zooms do banco Ponto Eletrônico Programas do módulo Planejamento Manutenção Industrial Construção de Programas utilizando os Estilos e suas Técnicas 11 \PLP \PMP \PTP \PVP \QOP \REP \RHBRW \RHGO \RHINC \RHQRY \RHVWR \ RHZOOM \SCRIPTS \SEC \SPOOL \SPP \SRC \ SUPPOR T \UNBRW \UNGO \UNINC \UNQRY \UNVWR \ UNZOOM \UTB \UTP \VARINC \LOCAL \XXX \DATABASE Programas do módulo Planejamento Programas do módulo Plano Mestre Programas do módulo Patrimônio Programas do módulo Previsão de Vendas Programas do módulo Cotação de Vendas Programas do módulo Recebimentos Objetos Browsers do banco Recursos Humanos Objetos "Vá para" do banco Recursos Humanos Includes de campos indicadores do banco Recursos Humanos Objetos Queries do banco Recursos Humanos Objetos Viewers do banco Recursos Humanos Zooms do banco Recursos Humanos Scripts de Carga da Aplicação Módulo Segurança Diretório default de destino dos Relatórios Programas especiais dos módulos (não será expedido) Includes Padrões PROGRESS Programas UIB customizados Objetos Browsers do banco Universal Objetos "Vá para" do banco Universal Includes de campos indicadores do banco Universal Objetos Queries do banco Universal Objetos Viewers do banco Universal Zooms do banco Universal Módulo Universal Programas Utilitários Includes de variáveis indicadores Programas que possuem localizações Prefixo do País Gatilhos do Banco de Dados do País 0 Diretório s \ \INPM DATABAS E \INPY \INTM \INUN \TGPM \TAP \TCP \TDP \TFP \TWP \TGPY \TAP \TCP \TDP \TFP \TWP \TGTM \TAP \TCP \TDP \TFP \TWP \TGUN \TAP \TCP \TDP \TFP \TWP \DOCAPI \DOCHLP \DOCRTF \IMAGE \IMGHUR \INCLUDE Conteúdo Includes de campos indicadores do banco MGPMG Includes de campos indicadores do banco MGPYC Includes de campos indicadores do banco MGTMA Includes de campos indicadores do banco MGUNI Gatilhos de assign do banco MGPMG Gatilhos de create do banco MGPMG Gatilhos de delete do banco MGPMG Gatilhos de find do banco MGPMG Gatilhos de write do banco MGPMG Gatilhos de assign do banco MGPYC Gatilhos de create do banco MGPYC Gatilhos de delete do banco MGPYC Gatilhos de find do banco MGPYC Gatilhos de write do banco MGPYC Gatilhos de assign do banco MGTMA Gatilhos de create do banco MGTMA Gatilhos de delete do banco MGTMA Gatilhos de find do banco MGTMA Gatilhos de write do banco MGTMA Gatilhos de assign do banco MGUNI Gatilhos de create do banco MGUNI Gatilhos de delete do banco MGUNI Gatilhos de find do banco MGUNI Gatilhos de write do banco MGUNI Documentação de API´s Documentação dos Módulo em formato .hlp Documentação de Manuais Impressos (*.rtf) Imagens Diretório padrão de imagens do Aplicativo Recursos Humanos Includes Padrões .Datasul-HR 1. do Banco MGPYC Objetos Queries do banco MGPYC Objetos "Vá para" do banco MGPYC Objetos Viewers do banco MGPYC Zoom do banco MGPYC Browsers do Banco MGTMA Filtros...Construção de Programas utilizando os Estilos e suas Técnicas 13 \ INTERFA C \LAYOUT \ MASTER S \MEN \OBJECT \SOPM \BRW DIALOG \QRY \GO \VWR \ZOOM \SOPY \BRW DIALOG \QRY \GO \VWR \ZOOM \SOTM \BRW DIALOG \QRY \GO \VWR \ZOOM * \SOUN \BRW DIALOG \QRY \GO \VWR \ZOOM \PANEL \PGHUR \ATP \BSP \CAP \DSP Arquivos de interfaces do Produto com outros softwares Layout´s de importação Masters do SmartObjects Módulo Menu Browsers do Banco MGPMG Filtros. narrativas. etc .. etc .. etc .. do Banco MGPMG Objetos Queries do banco MGPMG Objetos "Vá para" do banco MGPMG Objetos Viewers do banco MGPMG Zoom do banco MGPMG Browsers do Banco MGPYC Filtros. etc .. narrativas. narrativas. narrativas. do Banco MGUNI Objetos Queries do banco MGUNI Objetos "Vá para" do banco MGUNI Objetos Viewers do banco MGUNI Zoom do banco MGUNI Painéis dos SmartObjects Programas do módulo Administração de Treinamento Programas do módulo Benefícios Programas do módulo Cargos e Salários Programas do módulo Desenvolvimento de Pessoal ... do Banco MGTMA Objetos Queries do banco MGTMA Objetos "Vá para" do banco MGTMA Objetos Viewers do banco MGTMA Zoom do banco MGTMA Browsers do Banco MGUNI Filtros. \FPP \FRP \PEP *\PRGTE C \BTB \DOC \MEN \SEC \SCRIPTS \SPOOL \SRC \ SUPPOR T \UTB \UTP \VARINC Programas do módulo Folha de Pagamento Programas do módulo Férias e Rescisões Programas do módulo Ponto Eletrônico Módulo Básico Módulo Documentação Módulo Menu Módulo Segurança Scripts de Carga da Aplicação Diretório default de destino dos Relatórios Includes Padrões PROGRESS Programas UIB customizados Módulo Universal Programas Utilitários Includes de variáveis indicadores * Diretórios em implementação . 00. nome de objetos como zoom e browsers.00 e Datasul-HR 1. Sigla de bancos de dados Descrição Para cada banco de dados do Datasul-EMS 2. Esta sigla serve para compor o dump-name das tabelas. foi determinada uma sigla de dois caracteres.00 e Datasul-HR 1.00. Banco de Dados do Datasul-EMS 2.15 CAPÍTULO 3 Nomenclatura Definição O objetivo deste capítulo é descrever as regras de nomenclatura para os objetos dentro do Datasul-EMS 2.00 Banco Administrativ o Coletor de Dados Distribuição Industrial MultiPlanta Ponto Eletrônico Recursos Humanos Sigl a AD CL DI IN MP PE RH Nome lógico MGADM MGCLD MGDIS MGIND MGINV MGMP MGPE MGRH Investimentos IV . nome do diretório de gatilhos. Banco Personal Management (Administração de Pessoal) Payroll (Folha de Pagamento Time and Attendence (Controle de Freqüência) Universal (Universal) Sigl a PM PY TA UN Nome lógico DTHRPMG DTHRPYC DTHRTMA MGUNI Siglas de módulos do produto Cada módulo do produto possui uma sigla para ser utilizada na definição dos nomes de seus programas e diretórios.Universal UN MGUNI Banco de Dados do Datasul-HR 1.00 deve-se utilizar nomes e abreviaturas no idioma inglês. Módulos do Datasul-EMS 2.00 No Datasul-HR 1.00 Módulo Aplicações e Empréstimos Benefícios Sociais Caixas e Bancos Coleta de Dados Coletor de Dados Compras Configurador Produto Contabilidade Contas a Pagar Contas a Receber Controle Contratos Controle de Estoque Controle de Produção Controle de Qualidade Cotação de Vendas Custos Desenvolvimento Produto Sigla AE BS CB BC CL CC CF CT AP CR CN CE CP CQ QO CS DP . Construção de Programas utilizando os Estilos e suas Técnicas 17 EDI Engenharia FASB/CMI Faturamento Férias Rescisões Folha de Pagamento Gerencial Investimentos Manutenção Industrial MultiPlanta Obrigações Fiscais Patrimônio Pedidos Planejamento Planejamento Capacidade Planejamento Manutenção Industrial Plano Mestre Ponto Eletrônico Recebimento Recebimento Internacional ED EN FC FT FR FP GE IN MI MP OF PT PD PL PC PI PM PE RE RI Módulos do Datasul-HR 1.00 Módulo Administração de Treinamento Benefícios Cargos e Salários Desenvolvimento de Pessoal Férias e Rescisões Folha de Pagamento Ponto Eletrônico Sigla AT BS CA DS FR FP PE . >>>.>>9 >>>>>>9 cb1 Código de Barra Tipo 1 cb2 Código de Barra Tipo 2 cb3 Código de Barra Tipo 3 cdd Código .Numérico cod Código dat dsl hra idi log mm p no m nu m qtd qti rec so m val vid vli wg h Data Descrição .>>9 >>>.>>>.Tipos de Atributos Tipos de Atributos são classificadores para os tipos de informações que são gravadas.9999 >>>.Inteira Recid Som Valor Vídeo Valor-inteiro Widget-Handle des Descrição Img Imagem raw Raw row Rowid .Decimal cdn Código .>>9 ->>>>.>>9 X(8) 99/99/9999 X(40) X(15000) 99:99:99 9 X(08) Sim/Não X(8) X(30) >>>>. Segue abaixo.Longa Hora Indicador .>>>.Inteiro Lógico Memory pointer Nome Número Quantidade Quantidade .99 X(40) >>>. uma lista de todos os tipos de atributos. Tip o Descrição Tipo de Dado Integer Integer Character Decimal Integer Character Date Character Character Character Integer Character Logical MenPtr Character Integer Decimal Integer Character Recid Rowid Character Decimal Character Integer Widget-Handle Formato Default >>>>>>>9 >>>>>>>>>>>9 X(20) >>>.>>9.>>9.>>9 X(15000) >>>>>>9 X(20) X(40) ->>. descrições e tipos de dados. p²2 Exemplos para a tabela "item" database/tgint/tcp/tcin172.p database/tgin/twin172. não podem ter o mesmo nome de arquivo. e 999 é um número seqüencial único dentro do banco de dados. nomes de diretórios. ambos tem o mesmo nome do arquivo com extensão .p database/tgin/tap/ta002242.i*.Construção de Programas utilizando os Estilos e suas Técnicas 19 Dump-name de tabelas O Dump-name de uma tabela. assim a parte 999999. quando não. porque na geração do executável . Assim. a tabela é armazenada. isto é.sejam programas com extensão . Basta acrescentar uma unidade ao último número já utilizado. no padrão.p Programas A nomenclatura de um programa é determinada em função do seu tipo/estilo.0.p.r. onde "xx" é a sigla do banco de dados do produto. se possuir interface e . Todos os arquivos . includes com extensão . O gatilhos de assign do campo obedece a nomenclatura diferenciada pois podemos ter mais de um gatilho assign por tabela. Gatilhos do dicionário de dados Gatilho Create da tabela Delete da tabela Find da tabela Write da tabela Assign de campo Nomenclatura tcxx999.w. e a sua extensão é . é um número seqüencial de campos em todo o DatasulEMS 2. a tabela "item" que está no banco de dados industrial tem o dump-name "in172". etc. tem o formato "xx999". imagens.p database/tgin/tdp/tdin172.r. deverão obedecer a regra imposta pelo DOS para o seu nome.p.p database/tgin/tfin172.p tfxx999.p twxx999.p TA999999. no qual. Não existe processo automático para determinar o número seqüencial para a tabela no banco de dados.p1 tdxx999. mesmo se tiverem extensões diferentes. o tamanho máximo do arquivo 1 2 "xx999" é o dump-name da tabela. Entretanto dois programas. .. É importante utilizar letras minúsculas para a sigla da base de dados. conforme tabela a seguir: Numeração 0000 à 0099 Tipo de Programas Manutenções Cadastrais 3 4 "xx" é a sigla do banco de dados da tabela principal do objeto.p.p 6 Exemplos cep/ceapi001.w g99xx999.p • para programas do produto Datasul-HR 1. .p cep/ce0401a.w z99xx999.w cep/ce0401rp. sendo então.p Exemplos para a tabela "item" bo01in172. "99" é um número seqüencial de objetos de um determinado tipo para uma tabela e "xx999" e dump-name desta tabela.w g01in172.w v99xx999.00 deve ser observado um controle na criação da numeração do nome do programa.00. Também.p xx9999zz. 5 "xx" indica a sigla do módulo e "zz" caracteres de diferenciação entre programas e subprogramas.w z01in172. todos os nomes de arquivo dos programas devem estar em letras minúsculas.w v01in172.w q01in172. sem interface ou ainda API´s.w • para os programas que estão ligados a um módulo do Datasul-EMS 2.w4 d99xx999. containers ou programas .w5 xx9999rp. Para os programas que são objetos (SmartObjects) e estão ligados a uma tabela adota-se a nomenclatura abaixo: Tipo do Objeto Browser Dialog Go (Vá para) Query Viewer Zoom (Pesquisa) Diretório destino xxbrw3 xxdialog xxgo xxqry xxvwr xxzoom Nomencla tura b99xx999. 6 Os caracteres "rp" são fixos para nomenclatura deste tipo de subprograma construído através dos Estilos relatório e importação/exportação. adota-se a nomenclatura abaixo.deve ter 8 caracteres e o tamanho máximo para a extensão deve ter 3 caracteres no máximo. sendo que o diretório destino do programa é sempre o diretório do módulo: Tipo API Container Subprograma de relatório Subprograma qualquer sem interface Nomencla tura xxapi999.p xx9999zz.p cep/ce0401.w d01in172.w q99xx999. w ou advwr/v01ad102.i ou . 7 "999999" é um número seqüencial de includes dentro do diretório "varinc".i7 Exemplos varinc/var00002. Include com view-as de campos para o dicionário de dados São includes que incorporam a definição do view-as de campos indicadores com tipo de dado inteiro. Exemplo: cdp/cd0206.Construção de Programas utilizando os Estilos e suas Técnicas 21 0100 à 0199 0200 à 0299 0300 à 0399 0400 à 0499 0500 à 0699 0700 à 0799 0800 à 0899 0900 à 0999 Manutenções Gerais Consultas Cadastrais Consultas Complexas/Relacionamento Listagens Cadastrais Relatórios Tarefas Especiais/Gráficos Utilitários Os programas CADASTRAIS tem sempre uma numeração concordante. conforme o objetivo do include. conforme exemplo: Cadastro: AT0017 Consulta: AT0217 Relatório: AT0417. As extensões dos includes devem ser sempre .i9. obedecem a algumas regras de nomenclatura.i9.i para cdp/cd0206. i1. Estes includes são fundamentais para a tradução do produto.i para advwr/v01ad102. . e também. o nome deste include é igual ao do programa.. devem ter seus nomes de arquivo em letras minúsculas.i2.i. Diretório destino varinc Nomencla tura var99999. . também.w. Includes Da mesma maneira que os programas. .i1 a . os includes.. apenas com a extensão .i Includes de programas A nomenclatura destes includes é dada em função do seu grau de reutilização: Quando um include é apenas utilizado por um mesmo programa/procedimento. e . geralmente acima de 9000. pois dificilmente são realizados tratamentos nos programas para este tipo de widget.i. A tabela de prefixo é apresentada a seguir: Widget Botão Browse Combobox Fill-in Retângul o Selection -list Slider Togglebox Prefi xo btbrcbfirtls sl tb Exemplo bt-ok br-zoom cb-tipo-conta fi-texto rs-modo-execucao rt-moldura ls-estados sl-percentual tb-ativo Radio-set rs- Observação O padrão para nome de retângulo não é importante. Exemplo:cdp/cd9500. . o nome deste include é a sigla do módulo mais um número seqüencial. Widgets O padrão de nomenclatura adotado é um prefixo que identifique o widget mais um nome significativo.i. e o seu nome de arquivo iniciar por "i-" mais um nome significativo. Exemplo: include/i-rpini.Quando um include é utilizado por vários programas de um mesmo módulo. o nome deste include é 'cd' mais um número seqüencial. Exemplo: cep/ce9000.i. Quando um include é utilizado por vários programas de vários módulos. Includes padrões Os includes padrões dos Estilos devem ser depositados no diretório include. que indique o estilo ou a função. Construção de Programas utilizando os Estilos e suas Técnicas 23 Variáveis Datasul-EMS 2.00 Quando uma variável não for um widget o seu tipo de dados determina o prefixo que deve ser utilizado para nomear as variáveis.3 Qualificador Nome que qualifica a variável Exemplo V_cod_fornec Outros componentes da linguagem Progress Component e Buffer de Tabela Frame Parâmetro Stream Temporaryt able Prefi xo bfpsttExemplo b-item f-cad p-rw-emitente s-import tt-param . conforme tabela a seguir: Tipo de dado Caracter Inteiro Data Decimal Handle Lógico Raw Rowid Widgethandle Prefi xo cidadehlrawrwwhExemplo c-conta i-contador da-atualizacao de-total-geral h-acomp l-ativo raw-param rwwh-botao Datasul-HR 1.00 A nomenclatura de variável é formada de acordo com a seguinte regra: v_tipo de atributo_qualificador Tipo de Atributo Conforme tabela no item 4. nos programas de Zoom (z99xx999). Nestes casos. temos todas as posições (oito) tomadas pelo próprio nome do arquivo. narrativas.Siglas de países Siglas de três letras seguindo padrão internacional que é utilizado para designar objetos e diretórios criados para localização dos produtos nos países: País África do sul Argentina Bahamas Barbados Belize Bolívia Brasil Canadá Chile Colômbia Costa-rica Cuba El Salvador Equador Estados Unidos Granada Guatemala Guiana Prefi xo saf arg bah bar bel bol bra can chi col cos cub sal ecu usa gra gua gui País Guiana Francesa Haiti Honduras Jamaica México Nicarágua Panamá Paraguai Peru Porto Rico República Dominicana San Vicente Santa Lucia Suriname Trinindad-Tobago Uruguai Venezuela Prefi xo guf hai hon jam mex nic pan par per por rep vic luc sur tri uru ven Nomenclatura para Caixas de diálogos em programas de Zoom e SmartBrowser Principalmente. Não lemos como criar um subprograma para o programa de Zoom. quando necessitamos janelas para filtros.Sigla do Módulo . onde: XX . Nestes programas. estes subprogramas devem ter a seguinte nomenclatura: XX9NNN. etc.W. p .2 dígitos][inteiro seqüencial . Adapters A estrutura de diretórios e o nome dos adapters devem ser definidos com o seguinte padrão: Diretórios: adapters/[nome do parceiro]/[cicla do módulo – 3 dígitos].Construção de Programas utilizando os Estilos e suas Técnicas 25 9 . Nome: a[sigla do parceiro .p Exemplo: adapters/neogrid/ccp/anecc102.Número seqüencial dentro do Módulo.adapter Neogrid do módulo de compras .3 números].2 dígitos][sigla módulo .Fixo NNN . Estes subprogramas podem ser reutilizados. Exemplo: Programa de Cálculo do Preço Médio. Como diferenciação. . uma régua de botões no topo da janela que disponibilizam as funções existentes naquele programa. não possuem moldura (resize = no). Estas janelas não possuem menu de barra e a régua de botões fica na parte de baixo da tela.00. a idéia é simular a visualização de um dialog-box. Janela Detalhe São consideradas janelas detalhe ou filhas aquelas que são chamadas a partir de janelas mestre para realização de funções de um programa. Exemplo: Tela de um programa de cadastro. sendo que se caracterizam pela existência de um menu de barra. Caixas de Diálogo Caixas de diálogo são utilizadas em funções onde é imprescindível que a interface seja modal. Exemplo: Tela de um programa de zoom. normalmente em funções de grande risco aos sistemas. e possuem moldura (resizeable). Nestas caixas existe uma régua de botões disposta na parte de baixo da caixa.26 CAPÍTULO 4 Layout de Telas Tipos de Telas (janelas) Janela Mestre São consideradas janelas mestre aquelas que são a base dos programas chamados a partir do menu do Datasul-EMS 2. Fill-in´s • Frames(Telas) • . título das telas é feito a partir do UT-9000. é possível que o menu da Window seja copiado para a Dialog eliminando-o.. os botões de 'Sair' e 'Ajuda' devem estar sempre no canto superior direito nas janelas pai. emoldurar itens de radio-set e emoldurar editores que necessitem de label. agrupar campos de um mesmo assunto.00 unidade de caracter.Construção de Programas utilizando os Estilos e suas Técnicas 27 Observação Não é aconselhável salvar uma Dialog com uma Window aberta. 15 ou 20 unidades de caracter. Eliminar . Quando isto é feito.00 unidade de caracter. Exemplo: Cancelar.. os campos e variáveis view-as combo-box tem a altura de 1. botão 'Cancelar' não confirma a ação e sai da tela corrente. Modificar. largura: 10. quando representarem ações e possuírem labels estes termos devem ser verbos no infinitivo. botão 'Ajuda' sempre é disposto no canto inferior direito nas janelas detalhe e caixas de diálogo. os campos e variáveis view-as fill-in devem ter altura de 0.88 unidade de caracter. excepcionalmente. Objetos Combo-boxes Ver capítulo Como implementar campos indicadores com view-as combo-box nas telas.i. não necessitando intervenção do programador. Incluir. Botões • os botões com label devem ter: • • • • • • • altura: 1. botão 'OK' sempre confirma a ação e sai da tela corrente. Retângulos São utilizados para agrupar a chave de acesso das telas. Caso isto aconteça é necessário recriar a Dialog e o menu da Window.. devido à limitações do UIB. as mesmas dimensões devem ser utilizadas para as propriedades MAX-WIDTH-CHARS e MIN-WIDTHCHARS (altura máxima e mínima) e MAX-HEIGHT-CHARS e MINHEIGHT-CHARS (largura máxima e mínima) (isto deve ficar num include padrão).• as telas podem ter no máximo 90 colunas. padrão do Progress. não podem possuir label. definida a altura e largura de uma janela. Editores • • . sendo que maiores que 7 itens devem ser combo-boxes. Ver capítulo: Como implementar labels em retângulos utilizando o dicionário de dados. então quando a tabela possui apenas um editor. Caso contrário. que é um fonte fixo. emoldurá-lo com um retângulo e dispor uma literal para identificá-lo. por 17 linhas. sendo que este tamanho é sempre fixo. nos campos "Width" e "Height". Estas dimensões devem ser informadas na "Property Sheet" da janela no UIB. prevalecendo o modo vertical quando o número de itens for maior que 4. mas sempre em número inteiro. estas dimensões acompanham o limite para VGA. devido ao UIB. atribuir ou utilizar as seguintes propriedades (Property Sheet): RETURN-INSERTED. já este tamanho pode ser variável para menos. O include WIN-SIZE. não deve ser colocado qualquer literal ou texto para identificá-lo. deve-se no UIB. em View-as Editor. e o fonte deve ser escolhido o "2". Exemplo: • Radio-Sets • • podem ser horizontais ou verticais. não podem possuir label.I faz estas atribuições. Com isso as janelas podem possuir a moldura dada pela propriedade RESIZEABLE. que represente comentário ou narrativa. que é o próprio label. por isso devem ser emoldurados por um retângulo com uma literal para identificá-lo. Um SmartViewer tipicamente preenche registros da base de dados desde um SmartQuery ou SmartBrowser. SmartQuery SmartQuery é uma procedure object que contém uma base de dados query. o qual. . como mesmo nome no formato GIF (. Observação: O identificador :T no início de alguns comentários.bmp). utilizando um browse. visualiza os campos da base de dados. Assim sendo todos as telas que utilizam imagens. Um SmartQuery preenche tipicamente registros para outro SmartObjects. é usado para a tradução dos fontes dos templates para outros idiomas. Durante a montagem. pois o WebEnabler sendo um produto voltado para a Web só irá suportar os padrões da mesma quanto as imagens. normalmente no formato Bitmap (.gif). também devem possuir a mesma imagem. como o Internet Explorer. em "Options". O nome padrão do Browse não deve ser modificado. Recomendaç ões Na tela de características da "Query Builder". tal como um SmartViewer ou SmartBrowser. O SmartViewer deve ter um distanciamento de uma linha após e uma linha antes de outros objetos na sua localização. o campo "Returned" deve ser alterado de "All Fields" para "Fields Used". EMS 5 e HR através de um Web Browser.Construção de Programas utilizando os Estilos e suas Técnicas 29 Considerações sobre os SmartObjects SmartBrowser SmartBrowser é um objeto Procedure que recupera e visualiza dados. Este identificador não afeta em nada a funcionalidade do programa. SmartViewer SmartViewer é uma procedure object.º de campos. Um SmartQuery pode também responder a pedido de navegação de um SmartPanel. Considerações sobre as Imagens WebEnabler WebEnabler é um produto que disponibiliza o DATASUL EMS 2. o tamanho do SmartBrowser deve ser mantido padrão não importando o n. passando por todos os campos de uma coluna para depois passar para a outra coluna. a tabulação deve ser de cima para baixo nos campos. os campos devem estar alinhados pelo colon e formando colunas. o menu de barra da janela contém todas as opções disponíveis através dos botões dispostos na tela. com exceção do zoom e do 'vá para'. .30 CAPÍTULO 5 Estilos Cadastro Simples Característic as • • • • todas as funções. são realizadas na própria tela base do programa. não é permitida a alteração da chave da tabela através da função 'Alterar'. quanto aos botões é sugerido que sejam dispostos junto à régua de botões no topo da janela (antes do botão de 'Consultas Relacionadas'). a função 'Eliminar' deve pedir confirmação. que não estejam contempladas na palette padrão de navegação e atualização devem ser representadas por botões e itens no menu de barra. menu de barra tem a seguinte configuração: Arquiv o Primeiro Anterior Próximo Último Vá Para Pesquisa Incluir Copiar Alterar Eliminar Desfazer Cancelar Salvar Imprimir Sair Ctrl-Home Ctrl-Left Ctrl-Right Ctrl-End Ctrl-T Ctrl-F5 Ctrl-Ins Ctrl-C Ctrl-A Ctrl-Del Ctrl-U Ctrl-F4 Ctrl-S Ctrl-P Ctrl-X Ajuda Conteúdo Sobre • • • .Construção de Programas utilizando os Estilos e suas Técnicas 31 • novas funções. Cadastro Complexo Característic as • menu de barra tem a mesma configuração demonstrada na tela de Cadastro Simples. deve ser usado sempre que o número de campos de uma tabela não couberem em uma única viewer. Possui porém. folders que permitem a utilização de mais de uma viewer. Quando utilizar o Cadastro Complexo • . . 'Copiar'. 'Eliminar'. como disposto no Cadastro Simples. sem as funções de 'Incluir'.Atualiza Característic as • o menu de barra da janela contém apenas as opções para Atualizar.Construção de Programas utilizando os Estilos e suas Técnicas 33 Cadastro Simples . Cadastro Complexo . porém possui mais de uma viewer e está disposto em folders.Atualiza.Atualiza Característic as • tem as mesmas características do Cadastro Simples . . Incluir. selecionar browsers de tabelas filho. as opções 'Incluir' e 'Modificar'. quanto aos botões é sugerido que sejam dispostos junto à régua de botões no topo da janela (antes do botão de 'Consultas Relacionadas').Atualiza Filho É feita a navegação na tabela pai e a manutenção é executada somente no campo selecionado da tabela filho.Construção de Programas utilizando os Estilos e suas Técnicas 35 Pai x Filhos . chamam janelas semelhantes ao Cadastro Simples ou Complexo (sem a régua). o menu de barra da janela contém todas as opções disponíveis através dos botões dispostos na tela. novas funções. passando por todos os campos de uma coluna para depois passar para a outra coluna. Modificar e Eliminar serve apenas para manutenção da(s) tabela(s) filho. .Atualiza Filho Característic as • • • • os campos devem estar alinhados pelo colon e formando colunas. a tabulação deve ser de cima para baixo nos campos. • • Quando utilizar Pai x Filhos . que não estejam contempladas no palette padrão de navegação e atualização devem ser representadas por botões e itens no menu de barra. o 'Folder' tem como objetivo. para modificação pode se selecionar 'Modificar' para abrir uma janela. cancela apenas a última inclusão ou a última alteração. ou seja. o botão 'Cancelar'. 'Cancelar' e 'Ajuda'. podendo possuir ou não folders de acordo com a necessidade. 'Salvar'. possui função de salvar o registro corrente e criar um registro novo. a janela é a mesma tanto para inclusão quanto para alteração. é chamada a partir de um programa Pai x Filho. anula qualquer mudança feita no registro corrente do programa. o botão de 'Salvar'. para inclusão. quando o programa é chamado para inclusão.Manutenção de Filhos Característic as • é uma janela sem painéis. o botão 'Ajuda' é responsável por chamar o help do programa. quanto para modificação. o botão de 'Ok' tem função igual tanto para chamada do programa. • • • • • . a janela possui quatro botões: 'Ok'. Incluir. chamam janelas semelhantes ao Cadastro Simples ou Complexo (sem a régua). Modificar. devem ser representadas por botões e itens no menu de barra.Atualiza Ambos Caraterística • s • • tem as mesmas características da tela Pai x Filho . as opções 'Incluir'. quanto aos botões é sugerido que sejam dispostos junto à régua de botões no topo da janela (antes do botão de 'Consultas Relacionadas'). o menu de barra da janela contém todas as opções disponíveis através dos botões dispostos na tela. Modificar e Eliminar serve para manutenção da(s) tabela(s) filho.Atualiza Filho. Eliminar e Copiar serve apenas para manutenção da tabela pai. que não estejam contempladas na palette padrão de navegação e atualização. • • • .Construção de Programas utilizando os Estilos e suas Técnicas 37 Pai x Filhos . 'Modificar' e 'Copiar. as opções 'Incluir' e o 'Modificar'. novas funções. Incluir. além de que a atualização não só é feita no Folder como no registro pai. chamam janelas semelhantes ao Cadastro Simples ou Complexo (sem a régua). o botão 'Salvar'. quando o programa é chamado para inclusão. 'Cancelar' e 'Ajuda'. o botão 'Ajuda' é responsável por chamar o help do programa. 'Salvar'. de acordo com a necessidade. possui função de salvar o registro corrente e criar um registro novo. podendo possuir ou não folders. a janela é a mesma tanto para inclusão quanto para alteração ou cópia. é chamada a partir de um programa Pai x Filho. o botão de 'Ok' tem função igual tanto para chamada do programa. a janela possui quatro botões: 'Ok'. . para inclusão. quanto para modificação.Manutenção de Pais Caraterística • s • • • • é uma janela sem painéis. apenas para consulta. o menu de barra da janela contém as opções disponíveis através dos botões dispostos na tela. são realizadas na própria tela base do programa. .Construção de Programas utilizando os Estilos e suas Técnicas 39 Consulta Cadastral Simples Característic as • • as funções com exceção do zoom e do 'Vá para'. Consulta Cadastral Complexa Característic as • • • além das mesmas características da tela de Consulta Cadastral Simples. são realizadas na própria tela base do programa. apenas para Consulta. . além do botão de 'Relacionamento'. as funções. tem um 'Folder'. com exceção do zoom e do 'Vá para'. com o objetivo de selecionar as demais viewers da tabela. o menu de barra da janela contém as opções disponíveis através dos botões dispostos na tela. o evento default-action sobre estes browsers. em cada página do folder é apresentado um relacionamento (tabela filho) da tabela.Construção de Programas utilizando os Estilos e suas Técnicas 41 Consulta Relacionamento Característic as • • • o objetivo é apresentar os relacionamentos de uma determinada tabela. cuja função é chamar a consulta cadastral da tabela filho. 'Vá para' e 'Pesquisa' se aplicam sobre a tabela pai. • • • . denominada tabela pai. a chave primária e alguma descrição). posicionando-se no registro corrente no browser. menu de barra da janela contém todas as opções disponíveis na barra de botões disposta no topo da tela. acima do folder. as funções de navegação. é um atalho para botão 'Detalhar'. onde um browser apresenta os registros relacionados da tabela filho com o corrente registro da tabela pai. ficam dispostos os principais campos da tabela pai (normalmente. isolados por um retângulo. cada browser de apresentação dos relacionamentos deve possuir um botão 'Detalhar'. representado por um duplo clique ou por um pressionar na barra de espaços. Cálculos. Fechamentos .Relatórios. Seleção: tudo que é faixa. as outras informações que o usuário digita. isto é. o 'Fechar' do frame sai da tela. estão demonstrados os folders de Seleção. o botão 'Ajuda' é responsável por chamar o help do programa. o botão 'Executar' tem como função executar toda a parametrização realizada nos Folders. simulando uma caixa de diálogo. sem menu de barra emoldura. Parâmetros e Digitação: . A seguir. Classificação. Classificação: Radio-se com as opções. Digitação: browse updatable. Parâmetros: com exceção da faixa.Construção de Programas utilizando os Estilos e suas Técnicas 43 Característic as • • • • • • • • é uma janela do tipo detalhe. . Construção de Programas utilizando os Estilos e suas Técnicas 45 . sem menu de barra e moldura. Exemplo: Parâmetros por estabelecimento.Parâmetros Únicos Característic as • • • • • é uma janela do tipo detalhe. que confirma a escolha do usuário. o default-button do frame é o botão de 'Ok'. o botão 'Ajuda' é responsável por chamar o help do programa. o botão 'Imprimir' é responsável por chamar o browse dos relatórios relacionados. o cancel-button do frame é o botão de 'Cancelar' que sai da tela. dependendo do número de campos. isto é. simulando uma caixa de diálogo. Parâmetros Múltiplos Seguir as mesmas regras dos Cadastros Simples ou Complexo. . . o menu de barra da janela contém todas as opções disponíveis através dos botões dispostos na tela. os campos devem estar alinhados pelo colon e formando colunas. o botão 'Deletar' . novas funções.Construção de Programas utilizando os Estilos e suas Técnicas 47 Formação Característic as • este estilo de formação possui o palette de navegação. • • • • • • o botão 'Modifica' chama o programa de atualização dos atributos. portanto o programa é independente. que não estejam contempladas na palette padrão de navegação e atualização devem estar representadas por botões e itens no menu de barra. remove dados do Browse de formação. que é uma janela semelhante ao Cadastro Simples ou Complexo (sem a régua). adiciona no Browse de formação os dados de . não sendo necessário um programa principal para sua chamada. o botão 'Incluir' outras 2 tabelas. quanto aos botões é sugerido que sejam dispostos junto à régua de botões no topo da janela ao lado esquerdo do botão 'Consultas Relacionadas'. botão de 'Deletar' . botão de 'Incluir' outras 2 tabelas. portanto o programa é dependente.Formação sem Navegação Característic as • este estilo de formação não possui o palette de navegação. . novas funções. quanto aos botões é sugerido que sejam dispostos junto à régua de botões no topo da janela ao lado esquerdo do botão 'Consultas Relacionadas'. adiciona no Browse de formação os dados de . menu de barra da janela contém todas as opções disponíveis através dos botões dispostos na tela. os campos devem estar alinhados pelo colon e formando colunas. remove dados do Browse de formação. • • • • • • botão 'Modifica' chama o programa de atualização dos atributos. que não estejam contempladas na palette padrão de navegação e atualização deve estar representadas por botões e itens no menu de barra. sendo que ele deve ser chamado por um programa que possua um Browser Formação. Seleção. sem menu de barra e moldura.Construção de Programas utilizando os Estilos e suas Técnicas 49 Importação Característic as • • • • • • • • é uma janela do tipo detalhe. o botão 'Editar Layout' permite que seja editado o arquivo de layout através de um editor de texto. simulando uma caixa de diálogo. no folder de "Parâmetros" é determinado o nome do arquivo de entrada contendo registros a serem importados no formato do Layout. no folder de "Seleção" é determinada a faixa dos registros que são importados. contém ainda a determinação do modo de execução do mesmo. no folder de "Layout" é mostrado o layout do arquivo a ser importado. isto é. na página de "Log" é determinado o nome do arquivo de saída que deve gerar uma lista com todos os registros que forem importados ou somente os rejeitados. Parâmetros e Log. o botão 'Executar' tem como função disparar a importação que foi parametrizada nos folders. . possui quatro folders: Layout. A seguir estão demonstrados os folders de Layout. Seleção e Parâmetros: . Construção de Programas utilizando os Estilos e suas Técnicas 51 Exportação . Característic as • • • • • • • • é uma janela do tipo detalhe. A seguir são mostrados os folders de Layout. sem menu de barra e moldura. o botão 'Editar Layout' permite que seja editado o arquivo de layout através de um editor de texto. Parâmetros e Log. a página de "Log" contém a determinação de modo de execução do mesmo. simulando uma caixa de diálogo. Seleção. isto é. o botão 'Executar' tem como função disparar a exportação que foi parametrizada nos folders. possui quatro folders: Layout. no folder de "Seleção" é determinada a faixa dos registros que serão exportados. no folder de Layout é mostrado o layout do arquivo a ser exportado. no folder de "Parâmetros" é determinado o nome do arquivo de saída que é exportado no formato do Layout. Seleção e Parâmetros: . Construção de Programas utilizando os Estilos e suas Técnicas 53 . .. normalmente estes botões chamam caixas de diálogo. que pode estar desativado dependendo do programa chamador. cancel-button do frame é o botão de 'Cancelar' que sai da tela. Texto Livre. o botão é responsável pela aplicação do valor inicial e final definido pelo usuário sobre a query apresentada no browse. por exemplo: Narrativa. Filtro. • • . ao lado do botão 'Implantar' que é padrão. retornando ao programa chamador porém sem retornar um registro escolhido. simulando uma caixa de diálogo. o botão 'Implantar' é responsável por chamar o programa de cadastro da tabela.Zoom de Tabelas Característic as • • • • • é uma janela do tipo detalhe. isto é. que confirma a escolha do usuário.. cada folder representa uma opção de classificação disponível no zoom. devem ser colocados os botões específicos de cada programa de zoom. default-button do frame é o botão de 'OK'. sem menu de barra e moldura. etc. . sendo que o botão de 'Ok' é o default-button.. Caso isto aconteça é necessário recriar a Dialog e o menu da Window... usar o para acessar.. • • • Observação Não é aconselhável salvar uma Dialog com uma Window aberta. é possível que o menu da Window seja copiado para a Dialog eliminando-o... independentemente do número de campos para a faixa: .. Label do campo: [valor inicial] • não devem ser utilizadas literais em tela para denominar inicial e final. Quando isto é feito. • para utilizar o 'Pesquisa'.. o que possibilita ao usuário digitar a chave e apenas teclar "Enter" para confirmar a tela. é aberta uma pequena caixa de diálogo com os botões de 'Ok' e 'Cancelar' e 'Ajuda'. Observação Verificar se cada folder tem um browser diferente ou não. O Zoom não tem os botões de INÍCIO e de FIM (como no MAGNUS antigo). para substituir as características destas funções.Construção de Programas utilizando os Estilos e suas Técnicas 55 • os iniciais e finais devem ser apresentados no formato. evitando que o usuário tenha que navegar sobre os registros ou acionar o zoom... logo se utiliza o teclado: "HOME" e "END".. quando o usuário tem o conhecimento da chave do registro.. se isto for necessário inverter a ordem dos campos. não tem possibilidade zoom. conforme a classificação. . usar o para acessá-la. Vá Para Característic as • o objetivo é permitir um reposicionamento rápido do registro corrente no cadastro.. para utilizar esta tabela. [valor final]. isto é. simulando uma caixa de diálogo. default-button do frame é o botão 'Ok'. que efetiva a transação. Painéis Estes são os painéis padrão mais utilizados para navegação. .Digitação Rápida Característic as • • • • • é uma janela do tipo detalhe. a última página é reservada para o browser. as páginas iniciais são reservadas para as informações genéricas. sem menu de barra e moldura. cancel-button do frame é o botão 'Cancelar' que sai da tela sem considerar as informações. Para utilizar a função de "Relatórios Relacionados". o botão 'Executar'. para acessar. o botão 'Executar'. usar o . usar o Consultas Relacionadas Característic as • • chama um Browser que lista todas as consultas relacionadas ao programa que está sendo executado. chama a consulta selecionada no browser. chama o relatório selecionado no browser. para acessar. Para utilizar a função de "Consultas Relacionadas".Construção de Programas utilizando os Estilos e suas Técnicas 57 Funções Relatórios Relacionados Característic as • • chama um Browser que lista todos os relatórios relacionados ao programa que está sendo executado. {utp/ut-field. column-label.I Objetivo Utilização Retornar propriedades dos campos do dicionário de dados.i <banco> <tabela> <campo> <propriedade>} Onde: <banco>: nome lógico do banco de dados que contém o campo <tabela>: nome da tabela que contém o campo <campo>: nome do campo <propriedade>: número que identifica a propriedade conforme tabela a seguir: Núme ro 1 2 3 4 5 6 7 Propriedad e Label Column-Label Help Format Initial Description Data Type O retorno é obtido através do return-value.. etc. como label. Exemplo: .58 CAPÍTULO 6 Includes e Utilitários Padrão UT-FIELD. tem-se: .i mgadm conta natureza text-1} UT-RUN. como por exemplo um programa de impressão de relatórios xxp/xx9999rp. a partir de um outro programa (.Construção de Programas utilizando os Estilos e suas Técnicas 59 def var c-tipo as character no-undo.p). UT-RTLBL. {utp/ut-rtlbl.p).p). para definição de variáveis e funções. já está rodando no servidor (Application Server) e não é necessário iniciar um novo servidor. Deve executar apenas programas (. Sempre que for chamado algum programa sem interface a partir de um .i} e {btb/btb008za. Nota Para utilizar os includes é necessário relacionar ao programa os includes {utp/utglob.p).i <banco> <tabela> <campo> <widget fill-in>} Onde: <banco>: nome lógico do banco de dados que contém o campo <tabela>: nome da tabela que contém o campo <campo>: nome do campo <widget fill-in>: fill-in view-as text colocado na tela Exemplo: {utp/ut-rtlbl. Não deve chamar um programa (.i mgadm conta tipo 1} assign c-tipo:label in browse br-table = return-value.W e que este programa seja candidato para ser executado via RPC. através do recurso de RPC (Remote Procedure Call).io} no main-block. porque o programa chamador (.p). literais utilizados em telas para substituir labels. chamados a partir de programas (.I Objetivo Utilização Permitir a utilização de literais para colar labels em retângulos na tela minimizando os problemas de internacionalização. Utilização Formato Para a chamada de rotinas via RPC. • • Formato campos view-as radio-set ou editor.p.I Objetivo Seu objetivo é executar programas que não possuam interface (. {utp/ut-field. onde seja necessário emoldurá-lo com retângulo com um label para identificá-lo.w). i2 {1} {2} {3}} .i cep/ceapi001.i1 {1} {2} {3}} Onde: {1} = nome externo do programa {2} = mostra mensagem de acompanhamento {3} = servidor de RPC determinado {btb/btb008za. quando solicitada ({3} = yes).i {1} {2} {3} {4}} Onde: {1}: nome externo do programa {2}: parâmetros do programa {3}:mostra mensagem de acompanhamento [Opcional] {4}: servidor de RPC determinado [Opcional] Nota Para informar parâmetros em branco ou literal. input yes "" ' '} Modelo Aberto Includes {btb/btb008za. encerra a conexão e elimina a instância. mostra mensagem se ocorrer um erro (por exemplo.Modelo Simplificado Include {utp/ut-run. Funções • • • • solicita a conexão e cria a instância do servidor. Exemplo: "" ' '. input-output table tt-erro. Não sendo informados os parâmetros opcionais estes receberão "yes" e "" ' ' respectivamente. conforme servidor do aplicativo ou parâmetro.p "input-output table ttmvto. de conexão). dispara a execução do programa no servidor. Exemplo: {utp/ut-run. Aplicações Quando o programa API será disparado uma única vez para realizar todo o processo. utilize aspas duplas ("") com aspas simples (''). p "input tt_movto. {btb/btb008za.Construção de Programas utilizando os Estilos e suas Técnicas 61 Onde: {1} = nome externo do programa {2} = parâmetros do programa {3} = nome da variável do tipo "handle" para executar o programa persistente [Opcional] {btb/btb008za. dispara a execução do programa.i2 cep/ceapi001. Exemplo def var h-handle as handle no-undo. será utilizado o servidor RPC Gerai definido no aplicativo do programa. porém distribuídas em três includes: • • • solicita a conexão e cria a instância do servidor..). output tt_erro" "h-handle"} end.i1 cep/ceapi001. s . Considerações Caso não seja informado nenhum servidor RPC. for each.p "h-handle"} Nota Existe a API BTAPI008 que possui funções que podem ser utilizadas no desenvolvimento.p yes "rpc-test"} for each cta_ctbl no-lock: /* Prepara tt_movto */ {btb/btb008za.i3 cep/ceapi001. {btb/ btb008za.i3 {1} {2}} Onde: {1} = nome externo do programa {2} = nome da variável do tipo "handle" utilizada para eliminar a procedure persistente [Opcional] Funções Idênticas ao Modelo Simplificado.. encerra a conexão e elimina a instância. Aplicações Quando o programa API é disparado n vezes dentro de um laço (repeat. Se o processo estiver sendo executado via RPW e o servidor RPC não foi informado o programa será executado On-line.i3. <handle_application_server>) Parâmetros X Programa Com porta Inexistente ment o Inexistente Existe e Executa RPC =no Existe e Executa RPC =no Existe e Executa RPC =no Existe e Servidor RPC Mensag em Yes No Yes Comportamento Exibe mensagem 3045(*) via PI_STATUS_ERROR. por exemplo). ao final da execução. deve-se tomar dois cuidados: Primeiro. Ocorrendo erros na tentativa de execução do programa (faltou passar parâmetros. Retorna mensagem 3045(*) Exibe mensagem 16431(*) via PI_STATUS_ERROR. esta variável deve estar previamente definida no programa. empresa do usuário. estes serão retornados juntamente com a mensagem 16435 (*). Quando informado valor parar servidor RPC.p (<versão_integração>.i2... grupos de segurança em que o usuário se encontra. estarão disponíveis na sessão remota. as informações como usuário corrente. E segundo. Logo. Quando for informada a variável do tipo "handle" para a include btb/btb008za. Dados: Nome Programa: btb/btb923za. Retorna mensagem 16431(*) Informado No Não Informado No Executa ON-LINE Informado e Yes Exibe mensagem 16433(*) via .p Sintaxe: run btb/btb923za. deve-se eliminar o programa persistent passando o nome da variável para a include btb008za. Existe a API que transporta o conteúdo das variáveis de ambiente do Datasul_EMS da sessão client para a sessão do application server (remota) quando o programa solicita a execução de determinado programa via RPC (Remote Procedure Call). caso ocorra algum erro não será possível a execução On-line. Existe e Disponível Não Informado.Programa não cadastrado no menu ! 6160 .Não foi possível encontrar servidor RPC para programa '&1' ! 16433 . Existe e Disponível Não Informado.Não foi possível executar o programa via RPC ! 16431 .Servidor RPC não cadastrado 16434 . Existe e Disponível No Exibe mensagem 16432(*) via PIA_STATUS_ERROR. Existe e Não disponível Não Informado.Servidor RPC não disponível 164 35 . Existe e Disponível Informado. Existe e Não disponível Informado.Construção de Programas utilizando os Estilos e suas Técnicas 63 Executa RPC =yes Existe e Executa RPC =yes Existe e Executa RPC =yes Existe e Executa RPC =yes Existe e Executa RPC =yes Existe e Executa RPC =yes Existe e Executa RPC =yes Existe e Executa RPC =yes Existe e Executa RPC =yes Existe e Executa RPC =yes Existe e Executa RPC =yes Inexistente Informado e Inexistente No PI_STATUS_ERROR. será executado ON-LINE (*) Mensagens: 3045 .Não foi possível executar programa ! .Programa não pode ser executado via RPC 16432 . Retorna mensagem 16433(*) Não Informado e Yes Inexistente Não Informado e No Inexistente Informado. Executa ON_LINE Retorna mensagem 16434(*) Yes Exibe as mensagens 16434(*) via PI_STATUS_ERROR Executa ON-LINE No Yes Executa via RPC (**) No Executa via RPC (***) Yes Executa via RPC (**) No Executa VIA RPC Observação Ocorrendo erro na conexão do Servidor RPC. Existe e Não disponível Não Informado. P Objetivo Apresentar para o usuário uma mensagem previamente cadastrada. Formato run utp/ut-msgs. conforme a tabela a seguir: Ação show msg help type Resultado Apresenta a mensagem. Informação ou Questão) . com texto de ajuda no padrão do produto Retorna o texto da mensagem Retorna o texto de ajuda Retorna o tipo da mensagem (Erro. estes serão retornados juntamente com a mensagem 6160. Exemplo: Advertência: (134) . antes da exibição da mensagem substituta. onde 134 seria a mensagem exibida e 354 a mensagem original. será verificado se esta também. UT-MSGS. (***) Ocorrendo erros na conexão do servidor RPC. quando da exibição de mensagens substitutas.(**) Ocorrendo erros na conexão do servidor RPC. advertência ou questionamentos ao usuário. através do botão “trace”. ou ainda.p (input <ação> input <número da mensagem> input <parâmetros>). Advertência. seu número vai ser exibido na barra de título da caixa de diálogo. impressão de mensagens em log´s.(354). apresentação da pilha de execução dos programas até o ponto de chamada da ut-msgs.: Pergunta: (10). no Sistema de Mensagens. a mensagem substituta será exibida ao invés da original. Ex. Notas: • • ao ser exibida uma mensagem. retornar para o programa propriedades desta mensagem. se houver. informação. antes da exibição de qualquer mensagem. juntamente com o tipo de mensagem. Da mesma forma. será verificado se ela possui uma substituta. possui uma mensagem substituta e assim por diante. os números da mensagem original e da mensagem substituta serão exibidos na barra de títulos da caixa de diálogo. Onde: <ação>: ação desejada. • Utilização • • • apresentação de mensagens de erro. estes serão exibidos em tela juntamente com a mensagem 6160. input repres. Em seguida você pode acessar o Sistema pelo endereço: X:\Atalhos\SistTec\Mensagem. Para acessar o Sistema de Mensagens. IND11-50. Informação IND01-10.val-minimo). Observações A manutenção do cadastro das mensagens. Nos includes de dicionário de dados criados para cada campo indicador. Mensagem não Cadastrada. 2.p (input "show".I. <parâmetros>: são os campos. conforme tabela abaixo: .i {1} {2}} Onde: {1}: indica a função a ser realizada.I E IND51500. Cada um dos parâmetros deve ser separado por "~~" como por exemplo: input "campo~~" + variável + "~~tabela". tabelas e outras palavras que se deseja colocar na mensagem no momento de sua utilização. assim como a inclusão de novas mensagens só pode ser realizada pela Datasul. Mensagem de Advertência 3. Pergunta 4. Exemplo run utp/ut-msgs.I Objetivo Utilização Formato Viabilizar a utilização de combo-boxe´s e radio-set´s com representação para campos inteiros do tipo indicador. Mensagem de Erro. input 1235. você deve primeiro entrar em contato com a equipe de ADF e solicitar a criação de um usuário no Sistema de Mensagens.cod-regiao + "~~" + string(regiao.Construção de Programas utilizando os Estilos e suas Técnicas 65 codty pe Retorna o código do tipo da mensagem <número da mensagem>: número da mensagem desejada. Para clientes e parceiros é autorizada somente a utilização das mensagens já cadastradas. Quando a opção codtype é usada o retorno pode ser: 0.cod-repres + "~~" + regiao. 1. {include/ind01-10. i} &IF "{&LANGUAGE-CODE}" = "POR" &THEN &global val1 Erro &global val2 Advertência &global val3 Pergunta &global val4 Informação &ENDIF &IF "{&LANGUAGE-CODE}" = "ESP" &THEN &global val1 Erro &global val2 Advertencia &global val3 Pregunta &global val4 Información &ENDIF &IF "{&LANGUAGE-CODE}" = "ING" &THEN &global val1 Error &global val2 Warning &global val3 Question &global val4 Information &ENDIF {include/ind01-10.i * Campo: tipo-cod-situacao *******************************/ {include/i-lgcode. nas opções 04 e 06. Exemplo /****************************** * Include: i01un001. isto é.Funçã Objetivo o 01 02 03 04 n 05 06 item 07 define view-as combo-box define view-as radio-set lista com os itens separados por vírgula Retorna o item n da lista Retorna o número de itens da lista retorna a posição do item (número) retorna valores para a propriedade radio-buttons {2}: utilizado quando a função necessita de um segundo parâmetro.i {01} {02}} /* Fim */ . Utilização Formato {utp/ut-liter.i mgadm conta 1} assign c-tipo:label in browse br-table = return-value.Construção de Programas utilizando os Estilos e suas Técnicas 67 UT-TABLE.I Objetivo Utilizar o cadastro de literais do Datasul-EMS. cadastrando automaticamente as literais utilizadas no programa e retornando a tradução da literal no idioma corrente do banco de dados. Exemplo: def var c-tipo as character no-undo.i <banco> <tabela> <propriedade>} Onde: <banco>: nome lógico do banco de dados que contém o campo <tabela>: nome da tabela que contém o campo <propriedade>: número que identifica a propriedade conforme tabela abaixo: Núme ro 1 2 3 Proprieda de File-Label Dump_Name Desc O retorno é obtido através do return-value. {utp/ut-table. • • Formato nos SmartBrowsers ou Browsers para por label em campos calculados.I Objetivo Utilização Retornar propriedades das tabelas do dicionário de dados. • em todos os lugares onde literais passíveis de tradução forem apresentadas na interface do programa. para utilização de literais ou textos nas telas com função de label.i <literal> <modulo contexto> <alinhamento>} Onde: <literal>: Literal a ser utilizada na tela com os espaços substituídos por "_" (undescore) <módulo contexto>: parâmetro opcional que define o contexto de tradução da . UT-LITER. {utp/ut-table. como no retângulo que envolve o radio-set. <formato>). cálculos. Assign c-conta-ini = return-value. conforme tabela abaixo.p (input <opção>. que é representado pelo valor * (asterisco) <alinhamento>: parâmetro opcional que define onde é incrementado o espaço extra para tradução. Na seleção de relatórios. UT-LIMIT. run utp/ut-limit. run utp/ut-limit. atualizações e zooms que tenham faixas de seleção sobre campos caracter com formato variável. {utp/ut-liter. se omitido a literal deve ter o contexto universal de tradução. se omitido deve reservar o espaço à esquerda da literal: Tip o L C R Alinhame nto A esquerda Centralizado A direita O retorno é obtido através do return-value.i Lista_Narrativa MCE R} assign l-lista-narra:label in frame {&frame-name} = return-value. MIN = Mínimo e MAX = Máximo <formato>: formato do campo caracter O retorno é obtido através do return-value. find first param-global no-lock no-error. input param-global. formato-conta-contabil). como por exemplo a conta-contábil. Exemplo: def var l-lista-narra as character no-undo.P Objetivo Utilização Formato Determinar o valor inicial e final de campos caracter. . este contexto é um módulo do Datasul-EMS.p (input "MIN".literal. Onde: <opção>: indica o limite desejado. Exemplo def var c-conta-ini as char no-undo. cujo formato é variável. output <cancelado>). display fn-free-accent("<string>").p (input <título>. i-ep-codigo-usuario: contém a empresa corrente do usuário. UT-DIR.I Objetivo Utilização Converter strings acentuadas e caracteres especiais para strings não acentuadas e caracteres simples. Já está definido dentro dos SmartObjects.i} Onde: <variável>: variável que irá armazenar o valor do retorno da função fn-freeaccent <string>: string acentuada a ser convertida. Importação. assign <variável> = fn-free-accent("<string>"). Exportação e em pontos específicos que necessitem que a saída de dados (impressora/arquivo/tela) seja feita sem acentuação. . • nos Templates de Relatório. Formato {include/i-freeac.I Objetivo Formato Define as variáveis globais. run utp/ut-dir.Construção de Programas utilizando os Estilos e suas Técnicas 69 UT-GLOB. para habilitar o botão implanta. Exemplo {include/i-freeac. defin idas I-FREEAC. assign c-texto = fn-free-accent ("ÁÀÃÂÄ-ÉÈÊË-ÍÌÎÏ-ÓÒÔÕÖ-ÚÙÛÜ-ÝŸÇ-Ñ").i} define var c-texto as char no-undo. output <pasta>.P Objetivo Formato Este utilitário deve ser usado sempre que o usuário tiver que informar um diretório. Exemplo de variá l-implanta: variável lógica usada no Zoom. message fn-free-accent("áàãâä-éèêë-~íìîï-óòõôö-úùûü-y´¨y-ç-ñ") chr(10) c-texto view-as alert-box. veis c-seg-usuario: contém o nome do usuário corrente logado no menu. Onde: <título>: título para a caixa de diálogo para selecionar diretórios <pasta>: variável do tipo caracter onde será retornada a pasta selecionada <cancelado>: uma variável do tipo lógica onde deve ser retornado se a caixa de diálogo foi cancelada ou não Exemplo: run utp/ut-dir.p (input "Escolha um diretório". output <cancelado>). . output cancelado). BTB917ZX. output pasta. output <pasta>.p (input "Escolha um diretório. Onde: <título>: título para a caixa de diálogo para selecionar diretórios <pasta>: variável do tipo caracter onde será retornada a pasta selecionada <cancelado>: uma variável do tipo lógica onde deve retornado se a caixa de diálogo foi cancelada ou não Exemplo: run utp/ut-dir.P Objetivo Permitir a execução de sons do tipo MID e WAV. wmf.EXE.EXE.dib). é preciso que este OCX esteja registrado e instalado na máquina que deve ser utilizado. BTB917ZY.wav"). Gif Images (*. Para fazer esta instalação proceda da seguinte forma: • • executar o SETUP. clicar em 'Ok' para terminar. *.jpg). quando for solicitado. Icons (*. Formato run btb/btb917zx.p (input <som>).bmp) devem possuir um correspondente de mesmo nome no formato GIF (. . clicar no botão de 'Ok'.gif) devido a uma restrição do WebEnabler Instalação Como este programa utiliza os recursos de OCX. *. clicar no botão de 'OK'. JPEG Images (*. Metafiles (*.p (input "c:\windows\media\start.gif). Onde: <som>: caminho completo do arquivo de som a ser executado Exemplo: run btb/btb917zx.cur). que se encontra no diretório \INTERFAC\SOM\. que se encontra no diretório \INTERFAC\IMAGEM\.ico.emf).P Objetivo Permitir a visualização dos seguintes tipos de imagens: • • • • • Bitmaps (*. Para fazer esta instalação proceda da seguinte forma: • • • • executar o SETUP. Nota As imagens em formato Bitmap (.Construção de Programas utilizando os Estilos e suas Técnicas 71 Instalação Como este programa utiliza os recursos de OCX.bmp. *. é preciso que este OCX esteja registrado e instalado na máquina que deve ser utilizado. quando for solicitado. clicar no botão . clicar em 'Ok'. que se encontra no diretório \INTERFAC\VIDEO\DISK1. Como este programa utiliza os recursos de OCX.p (input <imagem>). para terminar.EXE.p (input "c:\windows\egito.P Objetivo Instalação Permitir a visualização de vídeos do tipo AVI. BTB917ZZ. é preciso que este OCX esteja registrado e instalado na máquina que deve ser utilizado. Onde: <imagem>: caminho completo da imagem a ser visualizada Exemplo: run btb/btb917zy. .• • Formato clicar no botão: . Para fazer esta instalação proceda da seguinte forma: • executar o SETUP. run btb/btb917zy.bmp"). Construção de Programas utilizando os Estilos e suas Técnicas 73 • • • Formato clicar no botão de 'Ok'. input <acomp>. clicar em 'Ok'.p (input <arquivo>. Onde: <arquivo>: variável do tipo caracter que irá conter o nome do arquivo compilado a ser analisado <acomp>: variável do tipo lógica que irá definir se a pesquisa deve apresentar a tela de acompanhamento ou não <versao>: variável do tipo caracter que irá receber a versão do programa passado como parâmetro Exemplo: .p (input <video>) Onde: <vídeo>: caminho completo do vídeo a ser apresentado Exemplo: run btb/btb917zz. output <versao>).p (input "c:\windows\help\explorer. para terminar.R).P Objetivo Formato Este utilitário pode ser usado sempre que for necessário saber a versão de um programa compilado (. UT-VRBIN.avi"). run btb/btb917zz. quando for solicitado. clicar no botão: . run utp/ut-vrbin. • programa não possui a versão internamente. .p (input <arquivo>. run utp/ut-finfo. output <hora>. se o retorno da versão for "?". • programa não está dentro das técnicas e templates do DatasulEMS 2.A. output <tamanho>). Observações • programa só conseguirá buscar a versão dos programas que foram construídos conforme os padrões de desenvolvimento da Datasul S. mas em compensação. output d-data.run utp/ut-vrbin. output c-versao).r". e que utilizem as Técnicas e Templates do Datasul-EMS 2. deixa o usuário informado do que está ocorrendo naquele momento. Onde: <arquivo>: variável do tipo caracter que deve conter o nome do arquivo a ser analisado <data>: variável do tipo data que deve receber a data do arquivo que está sendo analisado <hora>: variável do tipo caracter que deve receber a hora do arquivo que está sendo analisado <tamanho>: variável do tipo inteira que deve receber o tamanho do arquivo que está sendo analisado Exemplo run utp/ut-finfo. o programa não conseguiu obter a versão. pois faz interações com tela.0.0. a tela de acompanhamento deixa o programa sensivelmente mais lento.p (input "c:\autoexec.bat". • • UT-FINFO.P Objetivo Formato Este utilitário pode ser usado sempre que for necessário saber a data. a hora ou o tamanho de um arquivo no Windows. input no. Os principais motivos disto são: • programa a ser pesquisado não for encontrado.p (input "c:\tmp\cd0101. output <data>. output <build>.. se houver. a versão do Windows <release>: variável do tipo inteira que irá receber. se houver. na data e "00:00:00". Onde: <linha-comando>: variável do tipo caracter que irá receber a linha de comando usada para abrir a sessão corrente Exemplo: run utp/ut-cmdln.P Objetivo Formato Esta técnica pode ser usada sempre que for necessário saber informações mais detalhadas sobre o Sistema Operacional (somente para Windows). na hora. Esta função pode ser muito útil quando se deseja obter os valores dos parâmetros da sessão (ini.. inp. UT-OSVER.).p (output <linha-comando>).Construção de Programas utilizando os Estilos e suas Técnicas 75 output c-hora.p (output c-linha-comando). se houver.p (ouput <plataforma>. output <versao>. output i-tam). UT-CMDLN. o utilitário irá retornar "?". Formato run utp/ut-cmdln. o "build" do .P Objetivo Este utilitário pode ser usado sempre que for necessário saber informações mais detalhadas sobre a linha de comando usada para abrir a sessão corrente. etc . Onde: <plataforma>: variável do tipo caracter que irá receber o tipo plataforma windows (Windows NT ou Windows 95/98) <versao>: variável do tipo inteira que irá receber. Observações Caso o programa não se encontra. output <extrainfo>). run utp/ut-osver. a "release" do Windows <build>: variável do tipo inteira que irá receber. basekey. output <release>. isto é. 15). c-extrainfo).) Exemplo run utp/ut-osver.I Objetivo Utilização Descobrir a quantidade de registros numa tabela de acordo a condição passada.p (output output output output output c-plataforma. <banco>: banco de dados onde a tabela se encontra. <condição> e <tabela> devem estar entre aspas. {include/i-countds. quando o banco de dados é acessado através do DataServer (veja o item “Como contar a quantidade de registros numa tabela” no cap. Observações • • Utilize apenas se o banco de dados não for PROGRESS. etc .i &BANCO=mgadm &TABELA="cheque-pend" &COND="WHERE cod-banco > 20" &DEST=iCount} message iCount view-as alert-box.i &BANCO=mgadm Onde: <variável>: variável que irá armazenar o resultado da consulta. • Quando é necessário determinar a quantidade de registros numa tabela.. i-build. evitando que o OWNER seja incluído antes do nome da tabela no programa compilado. i-versao. <condição>: cláusa where que deve ser usada na consulta. for acessado através do DataServer. <tabela>: tabela que deve ter o número de registros contados. &TABELA=<tabela> &COND=<condição> &DEST=<variável> } Formato {include/i-countds. I-COUNTDS. Exemplo DEF VAR iCount AS INT NO-UNDO. .Windows <extrainfo>: variável do tipo caracter que irá receber informações extras sobre o Windows (Versão do Service Pack. Opcional. i-release.. Construção de Programas utilizando os Estilos e suas Técnicas 77 UT-WIN. Abaixo segue algumas das procedures definidas na include: • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • CreateProcess{&A} GetComputerName{&A} GetEnvironmentVariable{&A} GetLastError GetProfileString{&A} GetSystemDirectory{&A} GetWindowsDirectory{&A} LoadLibrary{&A} SetEnvironmentVariable{&A} WinExec GetCurrentDirectory{&A} FindExecutable{&A} ShellExecute{&A} AdjustWindowRect ClientToScreen CreateModal DeleteMenu DrawMenuBar FlashWindow GetClientRect GetMenuItemCount GetParent GetSystemMenu GetWindowLong{&A} GetWindowRect InvalidateRect RemoveMenu SetCursorPos SetWindowContextHelpId SetWindowLong{&A} SetWindowPos ShowScrollBar .I define procedures para acesso a funções externas de API’s do Windows.I Objetivo Procedures A UT-WIN. OUTPUT iResult). RUN RemoveMenu (INPUT iMenu. &SCOPED-DEFINE SC_MOVE 61456 &SCOPED-DEFINE MF_BYCOMMAND 0 &SCOPED-DEFINE MF_DELETE 512 DEFINE VARIABLE iHWND AS INTEGER INITIAL 0 NO-UNDO. OUTPUT iHWND).• • • ShowWindow SystemParametersInfo{&A} GetUserName{&A} Exemplo 1 Ver nome do usuário logado. ASSIGN chrUserID = FILL(' '. RUN GetUserName{&A} (INPUT-OUTPUT chrUserID. . RUN GetParent (INPUT windowHandle:HWND. RUN DrawMenuBar (INPUT iHWND.256) intSize = 255. Exemplo 2 Bloquear arraste de janela. OUTPUT iResult). MESSAGE TRIM(chrUserID) VIEW-AS ALERT-BOX. DEFINE VARIABLE iResult AS INTEGER INITIAL 0 NO-UNDO. Parameters: windowHandle – window que não poderá mais ser arrastada ----------------------------------------------------------------------*/ DEFINE INPUT PARAMETER windowHandle AS WIDGET-HANDLE NO-UNDO. INPUT {&MF_BYCOMMAND} + {&MF_DELETE}. RUN GetSystemMenu (INPUT iHWND. PROCEDURE SupressWindowMove: /*---------------------------------------------------------------------Purpose: Disable the MOVE option of the window object. INPUT-OUTPUT intSize). OUTPUT iMenu). INPUT {&SC_MOVE}. INPUT 0. DEFINE VARIABLE intSize AS INTEGER NO-UNDO. DEFINE VARIABLE chrUserID AS CHARACTER NO-UNDO. DEFINE VARIABLE iMenu AS INTEGER INITIAL 0 NO-UNDO. END PROCEDURE. PROCEDURE RemoveSystemMenuItem: /*---------------------------------------------------------------------Purpose: Remove a SystemMenuItem Parameters: windowHandle – window que terá os itens removidos itemId . INPUT {&MF_BYPOSITION} + {&MF_REMOVE}. RUN DrawMenuBar (INPUT viWinHWND. END PROCEDURE. DEFINE VARIABLE intResult AS INTEGER NO-UNDO. INPUT "SOME-VALUE". IF viWinHWND = 0 THEN RUN GetParent (windowHandle:HWND. ELSE MESSAGE "Function Failed.5 close 3 maximize 2 minimize ----------------------------------------------------------------------*/ DEFINE INPUT PARAMETER windowHandle AS WIDGET-HANDLE NO-UNDO. OUTPUT viRetCode). OUTPUT viSysMenu). Exemplo 4 Definir variável de ambiente. .Construção de Programas utilizando os Estilos e suas Técnicas 79 Exemplo 3 Remover botões do sistema (maximizar. DEFINE VARIABLE viRetCode AS INTEGER INITIAL 0 NO-UNDO. OUTPUT viWinHWND). RUN RemoveMenu (INPUT viSysMenu. minimizar. OUTPUT viRetCode). OUTPUT intResult). INPUT 0. fechar). DEFINE VARIABLE viSysMenu AS INTEGER INITIAL 0 NO-UNDO. INPUT itemId. DEFINE INPUT PARAMETER itemId AS INTEGER NO-UNDO. IF intResult = 1 THEN MESSAGE "Environment Variable Has Been Changed" VIEW-AS ALERT-BOX. &SCOPED-DEFINE MF_BYPOSITION 1024 &SCOPED-DEFINE MF_REMOVE 4096 DEFINE VARIABLE viWinHWND AS INTEGER INITIAL 0 NO-UNDO. Not Sure Why" VIEW-AS ALERT-BOX. RUN GetSystemMenu (INPUT viWinHWND. RUN SetEnvironmentVariableA (INPUT "DUMMYVAR". Utilização Formato Exemplo . É semelhante ao stack trace do Progress. É necessário incluir no programa a include utp/ut-trace.p PERSISTENT SET h-trace. RUN utp/ut-trace. disponível nas mensagens de erro.i e rodar o utilitário de forma persistente. RUN pi-monta-trace IN h-trace (OUTPUT TABLE tt-trace). com a vantagem que o desenvolvedor pode escolher o ponto do programa para exibição da pilha de execução. Lembrando que para isto é necessário criar uma variável do tipo handle (h-trace abaixo) e limpar o handle do programa na variável após a execução.UT-TRACE. independente do programa ser Smart ou Thin Template. RUN utp/trace.P Objetivo Exibir em tela toda a lista de programas e procedures internas executadas até o ponto de execução deste aplicativo.w (INPUT TABLE tt-trace). Pode ser utilizado em qualquer template da datasul. I. Acima destas releases deve ser utilizada a técnica multi-idiomas especificada no próximo item neste documento.07. Tradução de variáveis com view-as nas telas View-as Radi o-Set Quanto à tradução dos 'radio-buttons' da variável view-as radio-set deve-se utilizar o include XXINC/I99XX999. Quando um desenvolvedor cria um novo include de dicionário de dados. deve criá-lo no layout a seguir. conforme exemplo: /******************************************************* ** ** i01ad047. deve-se utilizar a técnica Como implementar labels em retângulos. Estes includes (XXINC e VARINC) precisam ser multidioma.Construção de Programas utilizando os Estilos e suas Técnicas 81 CAPÍTULO 7 Tradução TRADUÇÃO MONO-IDIOMAS Este modelo é utilizado até as versões EMS 2.Devedora/Credora ** ********************************************************/ {include/i-lgcode.04 e HR 2. Para o label do retângulo que emoldura o radio-set e dá significado ao mesmo.i} &IF "{&LANGUAGE-CODE}" = "POR" &THEN &glob val1 Devedora &glob val2 Credora &ENDIF &IF "{&LANGUAGE-CODE}" = "ESP" &THEN &glob val1 .i campo natureza (conta) . i var10001. criar uma include que deve ter como padrão de nomenclatura um prefixo "var" e uma seqüência que vai de 10000 até 19999.w .i 3.i Variável: cb-xxx Programa:xxp/xx9999. var19999. 2. .0. é possível utilizar o radio-set como view-as de variáveis independentes de campos do dicionário de dados. Exemplos: var10000.i} {1} {2}} /* fim */ Observação Foi incorporada uma chamada para um include i-lgcode. através da utilização de includes padrões. SmartViewer) e definir o seu 'radio-buttons' com valores 'brancos'. Seguir a nomenclatura abaixo para a include que é utilizada para tradução: Para o Datasul-EMS 2. de acordo com o roteiro abaixo: 1.i var00002.&glob val2 &ENDIF &IF "{&LANGUAGE-CODE}" = "ING" &THEN &glob val1 &glob val2 &ENDIF {include/ind01-10. Colocar um radio-set na tela (por exemplo. Mas.i Para o Datasul-HR 1.i . Exemplos: var00001.00: Dentro do diretório VARINC-RH. cujo objetivo é determinar qual o idioma da instalação do Datasul-EMS 2.00: Dentro do diretório VARINC.i . var09999. Este include tem o seguinte conteúdo: /**************************************************** ** ** var99999. . criar uma include que tem como padrão de nomenclatura um prefixo "var" e uma seqüência que vai de 000001 até 09999.i. Inicialmente. próprios para este fim.Devedora/Credora ** ************************************************************/ {include/i-lgcode. bem como seu valor inicial (screen-value): assign rs-xxx:radio-buttons in frame {&frame-name} = {varinc/var99999.i 07} rs-xxx:screen-value in frame {&frame-name} = "1":U. a sua utilização deve estar limitada à representação de campos indicadores do dicionário de dados. Os includes de dicionário de dados (XXINC e VARINC) precisam ser multidioma.i} {1} /* fim */ "POR" &THEN "ESP" &THEN "ING" &THEN {2}} 4.i} &IF "{&LANGUAGE-CODE}" = &glob val1 Devedora &glob val2 Credora &ENDIF &IF "{&LANGUAGE-CODE}" = &glob val1 &glob val2 &ENDIF &IF "{&LANGUAGE-CODE}" = &glob val1 &glob val2 &ENDIF {include/ind01-10. ou em momento próprio.i} &IF "{&LANGUAGE-CODE}" = "POR" &THEN &glob val1 Devedora &glob val2 Credora &ENDIF &IF "{&LANGUAGE-CODE}" = "ESP" &THEN . Quando um desenvolvedor cria um novo include de dicionário de dados. No 'local-initialize'.Construção de Programas utilizando os Estilos e suas Técnicas 83 ** *****************************************************/ {include/i-lgcode. deve criá-lo no layout a seguir: Exemplo /*********************************************************** ** ** i01ad047.I. deve-se carregar o 'radio-buttons' deste radio-set. em seu programa.i campo natureza (conta) . e através dos includes box XXINC/I99XX999. View-as Combo. foi incorporada uma chamada para um include i-lgcode. criar uma include que tem como padrão de nomenclatura um prefixo "var" e uma seqüência que vai de 00001 até 09999.00: Dentro do diretório VARINC-RH.i var10001. 2. Seguir a nomenclatura abaixo para a include que é utilizada para tradução: Para o Datasul-EMS 2.i Para o Datasul-HR 1. Colocar um combo-box na tela (por exemplo. Exemplos: var10000. . criar uma include que deve ter como padrão de nomenclatura um prefixo "var" e uma seqüência que vai de 10000 até 19999. var19999. é possível utilizar o combo-box. através da utilização de includes padrões. Este include tem o seguinte conteúdo: .i.i . de acordo com o roteiro a seguir: 1. var09999.i} {1} {2}} /* fim */ Observação Como se pode observar. como view-as de variáveis independentes de campos do dicionário de dados. cujo objetivo é determinar qual o idioma da instalação do Datasul-EMS 2.i var00002. .i . SmartViewer) e não definir o seu 'list-items' e 'initial'. Exemplos: var00001.i 3.00: Dentro do diretório VARINC.&glob val1 &glob val2 &ENDIF &IF "{&LANGUAGE-CODE}" = "ING" &THEN &glob val1 &glob val2 &ENDIF {include/ind01-10. Mas.0. ainda resta a tradução do label..i Variável: cb-xxx Programa:xxp/xx9999. No 'local-initialize'. CERTO: if cb-tipo:screen-value in frame {&frame-name} = {varinc\var99999. deve-se carregar o 'list-items' deste combo-box. ou ainda.i} {1} /* fim */ "POR" &THEN "ESP" &THEN "ING" &THEN {2}} 4. em seu programa. então no 'MainBlock'. ou 'Local-initialize'.i 04 2} then . Exemplo: ERRADO: if cb-tipo:screen-value in frame {&frame-name} = "Passivo" then.i 03} cb-xxx:screen-value in frame {&frame-name} = {varinc\var99999. ou em momento próprio. 5.Construção de Programas utilizando os Estilos e suas Técnicas 85 /**************************************************** ** ** var99999. não podem existir referências diretas na forma de string ("") aos itens do combo-box no fonte. isto é..i} &IF "{&LANGUAGE-CODE}" = &glob val1 Devedora &glob val2 Credora &ENDIF &IF "{&LANGUAGE-CODE}" = &glob val1 &glob val2 &ENDIF &IF "{&LANGUAGE-CODE}" = &glob val1 &glob val2 &ENDIF {include/ind01-10. bem como seu valor inicial (screen-value): assign cb-xxx:list-items in frame {&frame-name} = {varinc/var99999.w ** *****************************************************/ {include/i-lgcode.. qualquer ponto onde o programa .i. Toda codificação que precisar referenciar o valor de um item do combobox..i 04 1}. deve ser realizada através do include var99999. Em ambas as utilizações. View-as No caso dos toggle-boxes e fill-in´s é necessário preparar a tradução dos Toggl labels.i <literal> <modulo> <alinhamento>} assign <variavel>:help in frame {&frame-name} = returnvalue. deve-se implementar lógica que altere o label do combo-box: {utp/ut-field. conforme o exemplo: {utp/ut-liter. Espaço Extra para tradução em relatórios Column-Labels • o tamanho de uma coluna em um layout (down frame) está limitada ao tamanho do formato do campo ou do label Brasil do mesmo.i quando se tratar de uma e-Box variável like ou ainda o include utp/ut-liter.Utilizando utp/ut-field. este deve ter a preparação para tradução através do include utp/liter.i <banco> <tabela> <campo> <propriedade>} Fill-in assign <variável>:label in frame {&frame-name} = returnvalue. não é necessário preocupar-se com o espaço extra para tradução.i. Utilizando utp/ut-liter.i <banco> <tabela> <campo> <propriedade>} assign <var-combo-box>:label in frame {&frame-name} = return-value.i para aproveitar o cadastro de literais. os espaços extras para tradução foram recalculados para column-labels dos campos no dicionário de dados. e View.execute antes da realização do frame. • Exemplo: {utp/ut-liter Total_Pedidos} assign de-total-pedidos:label in frame f-relat = trim{returnvalue}. Help Sempre que estas variáveis possuam 'help'. o que for maior. na utilização de literais para compor column-labels de variáveis.i: as {utp/ut-field. . e para isto pode-se usar o include utp/ut-field.i <literal> <modulo> <alinhamento>} assign <variável>:label in frame {&frame-name} = returnvalue. entretanto não se deve esquecer da possibilidade de tradução.i: {utp/ut-liter. Com base nisto. 99 ____Total Geral: >>.99 Side-Labels • deve existir o tratamento do espaço extra para tradução.>>>. e está definida na ISO639-1.99 >>>>>9 XXXXXXXXXXXXXXXX >.>>>. {utp/ut-liter ____Total_Geral} assign de-total-geral:label in frame f-total = return-value. Nomenclatura Padrão e Características do modelo A nova técnica de tradução definiu uma nomenclatura para os dialetos a serem utilizados no produto. Esta nomenclatura segue um padrão de mercado já utilizado por outras empresas de mercado.>>9.>>9.>>9.08 ou superiores. Cliente Descrição Total Pedidos ------------------------------------->>>>>9 XXXXXXXXXXXXXXXX >.>>>.99 >>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>>. Segue abaixo uma tabela exemplificando as definições de cada sigla para os dialetos suportados pela Datasul: .Construção de Programas utilizando os Estilos e suas Técnicas 87 Cliente Descrição Total Pedidos ------------------------------------->>>>>9 XXXXXXXXXXXXXXXX >.>>>.05 e HR 2.>>9.99 >>>>>9 XXXXXXXXXXXXXXXX >.>>9.99 >>>>>9 XXXXXXXXXXXXXXXX >.99 TRADUÇÃO MULTI-IDIOMAS Este modelo é utilizado a partir das versões EMS 2.>>>.>>9.>>9. que deve ser reservado sempre à esquerda do label. e que estas customizações podem ser tratadas pelo cliente/distribuidor na forma como estes julgarem conveniente para sua aplicação. sendo possível com isto em uma mesma instalação do produto vários usuários acessando com um idioma/dialeto diferente.Dialeto Nome idioma/Dialeto en-US es-AR pt-BR English . basta defini-la conforme segue abaixo: define new global shared var v_cod_dialet_corren as char noundo. e pr-nr é filho de pt. es e pt. podendo este ser filho de qualquer dialeto padrão.Brazil Sendo que as siglas US. AR e BR já são consideradas customizações do dialeto principal expedido pela Datasul ou ainda um dialeto secundário. Caso queira-se tratar/consultar esta variável de alguma forma em algum programa.d presentes na pasta \univdata abaixo do diretório do produto. que atualmente são en. . Importante Para que o produto saiba que dialeto trabalhar na sessão corrente. Podemos dizer aqui então que o pt-nr-fm é filho de pr-nr. Qualquer outro dialeto criado pelo usuário/distribuidor é considerado dialeto secundário ou customizado. existe na tabela de usuários um campo chamado cod_dialeto que irá armazenar a informação do dialeto do usuário. na forma de três arquivos .United States Spanish . Quando se comenta em dialeto padrão. ou ainda o dialeto que é expedido pela própria Datasul. ou ainda de algum outro dialeto que já é filho de um dialeto padrão. que mantém uma relação com o dialeto padrão através da própria tabela de dialetos do produto.Português Nordestino das indústrias farmacêuticas.Argentina Portuguese . uma variável global é populada com o valor armazenado no campo cod_dialeto da tabela usuar_mestre. e a partir deste momento toda e qualquer tradução no produto toma como referência o valor armazenado nesta variável. sendo obrigatório como padrão validado apenas as duas primeiras letras do código do idioma/dialeto. Quando o usuário realiza o login no EMS/HR. Ex: pt-nr-fm . este pode ser considerado o próprio idioma. ou ainda um dialeto qualquer do usuário. e assim sucessivamente de acordo com a necessidade definida. podendo ser definido qualquer tipo de semântica que se julgue necessário para o módulo/programa do produto que se está trabalhando.Construção de Programas utilizando os Estilos e suas Técnicas 89 Pontos de tradução No modelo de tradução Multi-Idiomas. para os programas que possuem telas. foi adicionado um conceito de contexto de tradução. como labels. não é necessário que seja realizado nenhum tipo de intervenção manual. etc. nestes pontos. este programa irá disponibilizar um contexto automático para o cliente/usuário em tempo de . durante a análise para a construção do programa. identifica todos as propriedades destes objetos que são passíveis de tradução. Este contexto pode ser usado de forma idêntica ao utilizado na versão anterior do ut-liter. Os pontos de tradução são: • • SmartObjects – Procedure Adm-initialize ThinTemplates – Procedure InitializeInterface Contextos de tradução No modelo de tradução Multi-Idiomas. este deverá ser trabalhado para que se inclua uma chamada ao utilitário ut-liter. mesmo passando-se o caracter "*" para o utilitário de tradução ut-liter em tempo de desenvolvimento. Tudo o que está em tela e que está antes deste ponto de tradução. sejam estes SmartObjects ou ThinTemplates. ou seja.p e posterior atribuição ao atributo em questão pelo valor retornado através do return-value. foram criados o que chamamos de pontos de tradução. através da sigla do módulo. e realiza uma chamada automática ao ut-liter para sua posterior atribuição ao valor retornado. Caso tenha-se alguma atribuição em tela para atributos de objetos passíveis de tradução após estes pontos. Caso. seja verificado que não existe a necessidade da criação de uma nova contextualização de Strings. help's. mas não fica necessariamente limitado a esta contextualização. Estes pontos de tradução nada mais são do que os locais onde foram realizadas as chamadas aos tradutores automáticos de telas. um utilitário é chamado e este identifica todos os objetos dispostos em tela. tooltip's. sendo estes dois últimos campos definidos como segue: ID Item de Tradução Origem String Descrição 1 aplicat_dtsul des_aplicat_dtsul Tabela que armazena os aplicativo s Datasul . Após este cadastro. seu ID e a Origem String. Itens de Tradução Para a técnica de tradução Multi-Idiomas. onde cada um destes itens possui uma característica que deve ser levada em consideração no momento da inclusão de novas strings.execução. Estes itens estão todos armazenados dentro de uma tabela chamada string_ext_produt. e codificação dentro da tabela de strings externas estão descritos a seguir neste documento. contexto. Nota Ver sobre seqüência de busca a seguir neste documento O caracter "*" é considerado para fins de tradução. sem que haja a necessidade de alteração do programa para que o contexto seja passado de forma correta. bastando ao usuário cadastrar a String corretamente através do programa btb016aa. sendo sua chave composta pelo dialeto. bem como no momento da customização dos termos em telas do produto.p. caso julgar necessário. o contexto genérico das strings. a funcionalidade de tradução irá levar em consideração a sequência de busca e trazer o termo correto no ponto do módulo onde a string foi customizada. foi criado um conceito de itens de tradução. suas características. Isto para que o cliente/distribuidor possa realizar suas customizações. sendo que estes itens. Hoje existem 9 itens de tradução. este contexto automático disponibilizado é pela sigla do módulo. Com esta chave você encontra a tradução no dialeto desejado para a descrição da tabela cad-literal no banco . descrições dos campos e tabelas.tabela. como labels. etc. e também todas as strings presentes nos bancos de dados do produto.desc . como títulos dos programas em todos os idiomas. a chave buscada sempre seguirá a seguinte forma: Para Tabela: banco.propriedade Ex: mguni.Construção de Programas utilizando os Estilos e suas Técnicas 91 2 modul_dtsul des_modul_dtsul 3 procedimento des_proced Tabela que armazena os módulos Datasul Tabela que armazena os procedimentos Datasul Tabela que armazena os produtos Datasul Tabela que armazena as rotinas Datasul Tabela que armazena os sistemas Datasul Tabela que armazena as sub-rotinas Datasul Tabela que armazena as mensagens dos produtos Datasul Tabela que armazena as Literais dos produtos Datasul* 4 5 6 7 produt_dtsul rot_dtsul sist_dtsul sub_rot_dtsul des_produt_dtsul des_rot_dtsul des_sist_dtsul des_sub_rot_dtsul 8 cad-msgs cd-msg 9 cad-literal cod-literal * Os registros com este último indicador ainda armazenam mais algumas informações relevantes para o produto. Sendo que para as strings em bancos. help's.cad-literal. ut-msgs. que será abordado ainda neste documento. Esta chave é utilizada pelo utilitário utfield. que será abordado ainda neste documento. quando se passa uma Literal/Mensagem/String/Item de Menu para qualquer um dos utilitários que realizam a busca na tabela de strings Externas (ut-liter. contextos e strings no intuito de facilitar a customização e o entendimento por parte dos usuários e desenvolvedores da funcionalidade. ut-ltmnu). Esta chave é utilizada pelo utilitário ut-table. os pontos de tradução dentro dos programas. dentro dos módulos dos produtos Datasul.cod-literal. é necessário que se consiga visualizar como isto irá funcionar de forma prática dentro dos programas. na tabela cad-literal no banco mguni. Com isso.tabela. Sequência de busca Após verificarmos alguns conceitos sobre o modelo de tradução MultiIdiomas. Para Campo: banco.Com esta chave você encontra a tradução no dialeto desejado para o label do campo cod-literal.label . o que são contextos dentro deste novo processo.p.p.cad-literal. e os itens de tradução que estão englobados por esta técnica. a sequência de busca utilizada é a que segue: Seqüência 1 2 3 4 Dialeto Padrão X X √ √ Dialeto Usuário √ √ X X Contexto Contexto informado/módulo Contexto Genérico (“*”) Contexto informado/módulo Contexto Genérico (“*”) .campo. Para isto.propriedade Ex: mguni. desde sua nomenclatura. foi definida uma sequência de busca que visa disponibilizar uma hierarquia de Dialetos.mguni. estaremos explicando abaixo o que cada um dos utilitários criados para este processo realizam bem como algumas situações em programas que devem ser analisadas para que sejam evitadas inclusões de novos problemas em relação à tradução nos produtos Datasul. seja por região geográfica. É utilizado nos dois pontos de tradução dentro das templates: • • InitializeInterface nas ThinTemplates Adm-Initialize nos Smart Objects quando existe container definido. ou qualquer outro tipo de separação de termos que julgar conveniente. Utilização Caso exista uma window que não seja de uma template padrão Datasul.p para que sejam feitas as devidas traduções da interface. UT-TRCAMPOS. este utilitário poderá ser chamado antes do view principal da frame do programa para que a tradução automática passe a ser realizada. Ex: run utp/ut-trcampos.p.Construção de Programas utilizando os Estilos e suas Técnicas 93 Através desta hierarquia de busca. Este utilitário reconhece todas as frames que são filhas da window. e realizar a chamada ao utilitário ut-liter.P Objetivo Realizar tradução automática de telas. e deve ser chamado diretamente através do fonte. A seguir neste documento descrição destes programas/situações com o objetivo de facilitar/tornar sua implementação o mais simples possível. é possível o cliente/distribuidor fazer qualquer tipo de customização de termos de negócio que julgar necessário. por departamento funcional. Este programa tem a função de pesquisar todos os objetos de uma tela Progress baseado em sua Window. por segmentação de mercado. . Com as funcionalidades deste modelo de tradução abordado. e traduz todas os objetos presentes nestas frames automaticamente. através da hierarquia existente. Este programa não espera nenhum parâmetro de entrada. p).p (input-output cLista). converter valor de LIST-ITEMS para LIST-ITEM-PAIRS. dependendo da estrutura do programa. Deverá ser utilizado sempre quando da necessidade de uma conversão de valores de um objeto Progress não indexado para valores indexados. UT-LSTIT.p (input frame f-parametros:handle).p e posterior atribuição do valor traduzido retornado à estes objetos. ou ainda.i ou i-rpcab. de forma automática. Tem o objetivo de facilitar a programação dentro da técnica de tradução Multi-Idiomas minimizando a necessidade de realizar tal tarefa diretamente no fonte do programa em questão.UT-TRFRRP. Utilização Onde cLista deve ser uma lista separada por ". frames de relatório. Utilização Obs: Quando o programa for um relatório." provinda de uma das seguintes situações: . apenas. antes da include i-rpout.P Objetivo Difere do anterior porque realiza tradução automática de uma única frame. buscando os objetos passíveis de tradução e realizando então a chamada ao ut-liter. ou qualquer outra frame que se julgue necessário. Sua utilização deve ser da seguinte forma: Sintaxe: run utp/ut-lstit. Pode ser utilizado para traduzir Dialog-frames. Deve ser altamente utilizado para evitar alto nível de trabalho quando da necessidade de tradução de frames de relatórios devido a não existência de uma window que seja o pai destas frames nestes tipos de programas. ou seja. Busca os itens de tradução apenas na hierarquia da frame que foi passada como parâmetro. Ex: run utp/ut-trfrrp.P Objetivo Converter uma String não indexada proveniente de um objeto Progress e retorna seu conteúdo indexado e já traduzido no dialeto do usuário. esta será feita de forma automática para todas as frames do relatório antes do ponto padrão de leitura de registros desta template ou da definição do cabeçalho do mesmo.i respectivamente. não podendo nestes casos ser utilizado o utilitário anterior (ut-trcampos. para que possa ser utilizado no programa chamador. existe um filtro no RTB que caso o programa não possua nenhuma chamada a este utilitário. List-items de um campo (Este apenas caso ainda não tenha passado pelos pontos de tradução. tudo o que antes era LISTITEMS. deverão ser retrabalhados para tratar a partir de agora. Este sofreu alterações para contemplar as novas funcionalidades do modelo de tradução Multi-Idiomas. como novo conceito de contextualização. • • O programa irá retornar na mesma variável informada os valores já indexados e traduzidos. Qualquer fonte que gere uma lista separada por vírgula e que este será utilizada em algum objeto Progress não-indexado (Combo-Box. Valor populado de um for each. .solteiro” Podendo a atribuição ao objeto Progress indexado ser realizada da seguinte forma: assign combo-box:list-item-pairs = cLista.single. verificar o item abaixo que trata sobre LIST-ITEMS. Sub-programa. /* para combo-box */ assign select-list:list-item-pairs Selection-Lits */ = cLista. qualquer referência a LIST-ITEMS destes campos após os pontos de tradução.casado. com isso. é automaticamente convertido para LIST-ITEM-PAIRS nos pontos de tradução pelos programas já mencionados.Construção de Programas utilizando os Estilos e suas Técnicas 95 • • • Include de domínio.solteiro” Valor cLista depois: “married. tendo este utilitário como facilitador para esta implementação. LIST-ITEM-PAIRS. UT-LITER.P Objetivo Utilitário já existente em releases anteriores dos produtos EMS 2 e HR. /* para Importante Com a técnica de tradução Multi-Idiomas. Qualquer dúvida adicional. conforme exemplo abaixo: Valor cLista antes: “casado. SelectionList). hierarquia de busca e dialetos das Strings. ou já tenha passado e necessita ser repopulado devido a uma lógica de negócio). Sintaxe: {utp/ut-liter. Importante No modelo de tradução Multi-Idiomas.i <Literal> <Contexto> <Alinhamento>} Sendo que nesta nova ut-liter. Para manter compatilidade com o legado existente nos produtos. utilizado para apresentar as mensagens dos produtos Datasul. Outra regra importante é que strings que possuem espaços em branco. Este utilitário também sofreu alterações para contemplar as novas funcionalidades descritas e possui a característica da busca por mensagens baseando-se no dialeto e no contexto cadastrado para a mensagem. sua sintaxe foi mantida inalterada.i Teste_agora *} UT-MSGS. Ex: {utp/ut-liter. conforme exemplos abaixo: Ex: run utp/ut-liter. o alinhamento não irá gerar nenhum tipo de diferença no comportamento da string de retorno. sendo este considerado o contexto genérico. sempre passá-lo com valor em branco ("") caso utilizando o programa . mantida apenas para fins de compatibilidade.”*”. não sendo passado nada para o terceiro parâmetro.p.P Objetivo Utilitário já existente em releases anteriores dos produtos EMS 2 e HR. e "*" é o contexto. mantendo o padrão já conhecido e definido neste manual. caso utilizando a include.Utilização Para que não fosse gerado nenhum tipo de impacto sobre todo o legado de programas com o antigo modelo do ut-liter. considerado então como branco.p (input <ação> input <número da mensagem> input <parâmetros>). ou simplesmente não passar. Utilização Onde: . que seria o alinhamento. Para evitar problemas com este parâmetro. estes espaços devem ser convertidos para "_" antes da chamada a ut-liter.p.p (input “Teste”. seu forma de chamada e parâmetros não foram alterados. nenhuma string de destino pode ser maior que a string de origem. conforme regra que já vinha sendo utilizado no processo de tradução de fontes. conforme segue abaixo: Sintaxe: run utp/ut-msgs.””). {utp/ut-liter Teste *} Onde “Teste” é a literal sendo passada. Utilizado para retornar valores das propriedades dos campos do dicionário de dados. podendo ser "show" para mostrar. <número da mensagem> é o número da mensagem <parâmetros> São os parâmetros a serem substituídos na mensagem Maiores detalhes podem ser consultados na referência geral deste utilitário neste documento.propriedade. mas pode ser totalmente substituído pelo ut-liter.i banco tabela campo propriedade} Utilização onde propriedade pode ser: Propriedade 1 2 3 4 5 6 Descrição Label ColumnLabel Help Format Initial Description Observaçã o Continua buscando do banco Continua buscando do banco .campo. O que difere esta versão do modelo de tradução Multi-Idiomas para a versão anterior é que a busca não é mais realizada sobre o próprio dicionário. description. devido sua maior facilidade de identificação e customização futura pelo usuário. sendo ainda: {utp/ut-field. como label. baseando-se na chave banco. "msg" para retornar a mensagem. Foi mantido basicamente para não gerar incompatibilidade com o legado existente nos produtos. e "help" para retornar o help da mensagem. UT-FIELD. conforme mencionado em itens de tradução neste documento. Sua sintaxe não foi alteradada. e sim diretamente na tabela de strings externas do produto.Construção de Programas utilizando os Estilos e suas Técnicas 97 <ação> é a ação que será tomada pelo programa.tabela.P Objetivo Utilitário já existente em releases anteriores dos produtos EMS 2 e HR. etc. sendo ainda: {utp/ut-table.propriedade. devido sua maior facilidade de identificação e customização futura pelo usuário. O que difere esta versão do modelo de tradução Multi-Idiomas para a versão anterior é que a busca não é mais realizada sobre o próprio dicionário. conforme citado em itens de tradução neste documento. UT-TABLE. mas pode ser totalmente substituído pelo ut-liter. Foi mantido basicamente para não gerar incompatibilidade com o legado existente nos produtos. etc. Nota Onde Existe a frase “Continua buscando do banco”.Ex: {utp/ut-field. baseando-se na chave banco. Sua sintaxe não foi alteradada.P Objetivo Utilitário já existente em releases anteriores dos produtos EMS 2 e HR. como desc. Utilizado para retornar valores de propridades das tabelas do dicionário de dados.i mgadm conta tipo 1} Este exemplo irá retornar o label do campo tipo da tabela conta do banco mgadm no dialeto do usuário.tabela. label. mantendo a mesma funcionalidade da implementação anterior. e sim diretamente na tabela de strings externas do produto. significa que o comportamento do utilitário não foi alterado. .i <banco> <tabela> <propriedade>} Utilização onde propriedade é: Propriedade 1 2 3 Descrição File-Label Dump_nam e Desc Observaçã o Continua buscando do banco Ex: {utp/ut-table magadm conta 1} Este exemplo irá retornar o label da tabela conta do banco mgadm no dialeto do usuário. Este identificador tem o objetivo de indicar qual a string que o desenvolvedor requer que seja retornado pelo utilitário." ". dos respectivos itens de menu. como a versão anterior já realizava.Para os itens de menu.p (input r replace(<des_item_menu>."_"). Identificador String de retorno .Construção de Programas utilizando os Estilos e suas Técnicas 99 Nota Quando comentado "Continua buscando do banco". Input <Identificador>. normalmente "*" (Contexto Genérico) Identificador da String (Os itens de menu estão entre 1 e 7). tendo para este parâmetro dois possíveis valores: Parâmetro 1 2 Retorno Utilização Descrição do Item de Menu Traduzido Descrição do nome de menu do item de menu traduzido.P Objetivo Novo utilitário criado para a tradução de todos os itens de menu (Itens de tradução de 1 a 7). sendo estes: • • • • Origem String substituindo os espaçõs em branco por "_". isto quer dizer que o programa não está buscando o valor das strings externas.p (input replace(des_modul_dtsul. Input <IndStringRetorno>). Este utilitário realiza a busca na tabela de strings externas. Sintaxe: run utp/ut-ltmnu. e sim continua buscando do schema do banco atual que está conectado a sessão. UT-LTMNU. Neste caso. Contexto desejado. e retorna sua tradução para o programa chamador. Ex: utp/ut-ltmnu. existe nestas tabelas além das descrições dos respectivos itens nos dialetos suportados. . Input <contexto>. também o nome de menu utilizado para que estes itens sejam apresentados no produto. Para este programa é passado como parâmetro 4 valores. como selection-list's e combo-box's." ".p explicado acima neste documento para realizar o devido tratamento e sua troca de listitems para list-item-pairs. 1). deverá ser utilizado o utilitário ut-lstit. isto não é obrigatório devido aos tradutores automáticos de telas já realizarem esta tradução de forma automática. Caso um destes objetos Progress não-indexados for referenciado via LIST-ITEMS após estes pontos de tradução. nos pontos de tradução acima citados através da uttrcampos (InitializeInterface e Adm-Initialize). e ainda para não gerar muitos impactos sobre o modelo de tradução mono-idiomas. OBJETOS PROGRESS NÃO-INDEXADOS Para uma melhor adequação da nova técnica de tradução ao modelo existente anteriormente de objetos Progress não indexados. "*". todos os objetos que utilizavam LIST-ITEMS nos programas passaram a ser automaticamente convertidos para LIST-ITEM-PAIRS. Radi pode-se utilizar a técnica Como implementar labels em retângulos. Mas no o-Set caso da funcionalidade multi-idiomas. fazendo com que esta alteração não gere maiores impactos sobre lógicas de negócio utilizadas nos programas. Neste caso. será apresentada uma mensagem Progress de erro que evidencia a necessidade de troca de LIST-ITEMS para LIST-ITEM-PAIRS (Erro 7454). Este exemplo irá retornar a descrição do respectivo módulo Datasul no dialeto do usuário através do RETURN-VALUE. Tradução de variáveis com view-as nas telas View-as Para o label do retângulo que emoldura o radio-set e dá significado ao mesmo. indexando este objeto sempre pelo seu valor original normalmente em Português. 2. ."_"). Estes includes (XXINC e VARINC) precisam ser idioma Português. através da utilização de includes padrões.05: Dentro do diretório VARINC. pois nesta tem-se uma única instalação com suporte a multi-idiomas.i var00002. devido ao modelo de tradução Multi-Idiomas contemplar sua tradução de forma automática em tela. é possível utilizar o radio-set como view-as de variáveis independentes de campos do dicionário de dados. criar uma include que tem como padrão de nomenclatura um prefixo "var" e uma seqüência que vai de 000001 até 09999. conforme exemplo: /******************************************************* ** ** i01ad047.i} {1} {2}} /* fim */ Observação Na versão anterior a multi-idiomas.I mas não necessariamente.Construção de Programas utilizando os Estilos e suas Técnicas 101 Para popular o valor de ‘radio-buttons’ da variável view-as radio-set pode-se utilizar o include XXINC/I99XX999. 2. Seguir a nomenclatura abaixo para a include que é utilizada para popular o campo em Português para tradução em Multi-idiomas: Para o Datasul-EMS 2. . Mas.Devedora/Credora ** ********************************************************/ &glob val1 Devedora &glob val2 Credora {include/ind01-10.i . var09999.i . podendo estes serem realizados diretamente com os valores em Português. Neste novo modelo tal referência não é mais necessária.i campo natureza (conta) . deve criá-lo no layout a seguir. Colocar um radio-set na tela (por exemplo. de acordo com o roteiro abaixo: 1. era necessário a include i-lgcode para determinar o idioma. Exemplos: var00001. Quando um desenvolvedor cria um novo include de dicionário de dados. SmartViewer) e definir o seu 'radio-buttons' com valores 'brancos'. i Variável: cb-xxx Programa:xxp/xx9999.I.i 07} rs-xxx:screen-value in frame {&frame-name} = "1":U. Os includes de dicionário de dados (XXINC e VARINC) precisam ser sempre em Português. bem como seu valor inicial (screen-value): assign rs-xxx:radio-buttons in frame {&frame-name} = {varinc/var99999.i . Este include tem o seguinte conteúdo: /**************************************************** ** ** var99999. .w ** *****************************************************/ &glob val1 Devedora &glob val2 Credora {include/ind01-10. deve criá-lo no layout a seguir: Exemplo /*********************************************************** ** ** i01ad047. Exemplos: var10000. a sua utilização deve estar limitada à representação de campos indicadores do dicionário de dados. var19999.Inicialmente. View-as Combo.i} {1} {2}} .i} {1} {2}} /* fim */ 4. criar uma include que deve ter como padrão de nomenclatura um prefixo "var" e uma seqüência que vai de 10000 até 19999.i 3. No 'local-initialize' antes do dispatch da ADM deve-se carregar o 'radiobuttons' deste radio-set.Para o Datasul-HR 2. Quando um desenvolvedor cria um novo include de dicionário de dados.08: Dentro do diretório VARINC-RH. e através dos includes box XXINC/I99XX999.i campo natureza (conta) .Devedora/Credora ** ************************************************************/ &glob val1 Devedora &glob val2 Credora {include/ind01-10.i var10001. próprios para este fim. i .i Para o Datasul-HR 2. . Exemplos: var00001. é possível utilizar o combo-box.08: Dentro do diretório VARINC-RH. Colocar um combo-box na tela (por exemplo.Construção de Programas utilizando os Estilos e suas Técnicas 103 /* fim */ Observação Na versão anterior a multi-idiomas.i . através da utilização de includes padrões. pois nesta tem-se uma única instalação com suporte a multi-idiomas. criar uma include que tem como padrão de nomenclatura um prefixo "var" e uma seqüência que vai de 00001 até 09999. .05: Dentro do diretório VARINC. 2. Seguir a nomenclatura abaixo para a include que é utilizada para tradução: Para o Datasul-EMS 2. Exemplos: var10000.w ** *****************************************************/ &glob val1 Devedora &glob val2 Credora {include/ind01-10. Mas. Este include tem o seguinte conteúdo: /**************************************************** ** ** var99999.i var00002. var09999.i 3. criar uma include que deve ter como padrão de nomenclatura um prefixo "var" e uma seqüência que vai de 10000 até 19999.i} {1} {2}} /* fim */ .i Variável: cb-xxx Programa:xxp/xx9999. como view-as de variáveis independentes de campos do dicionário de dados. SmartViewer) e não definir o seu 'list-items' e 'initial'. Neste novo modelo tal referência não é mais necessária. var19999.i var10001. era necessário a include i-lgcode para determinar o idioma. de acordo com o roteiro a seguir: 1. deve-se carregar o 'list-items' deste combo-box. O seu label será automaticamente tratado pelo tradutor automático de telas presente nas templates. na utilização de literais para compor column-labels de variáveis não é necessário preocupar-se com o espaço extra para tradução. No 'local-initialize' antes do dispatch do método ADM. Toda codificação que precisar referenciar o valor de um item do combobox. Espaço Extra para tradução em relatórios Column-Labels • tamanho de uma coluna num layout (down frame) está limitada ao tamanho do formato do campo ou do label do mesmo.. bem como seu valor inicial (screen-value): assign cb-xxx:list-items in frame {&frame-name} = {varinc/var99999. CERTO: if cb-tipo:screen-value in frame {&frame-name} = {varinc\var99999. ou em momento posterior utilizando-se o utilitário ut-lstit.p para sua devida conversão para LIST-ITEM-PAIRS.. deve ser realizada através do include var99999. • .4. 5. isto é. Importante Apenas antes do método DISPATCH do procedure Adm-Initialize é possível implementação com LIST-ITEMS. Com base nisto. Após este ponto. Exemplo: ERRADO: if cb-tipo:screen-value in frame {&frame-name} = "Passivo" then. não podem haver referências diretas na forma de string ("") aos itens do combo-box no fonte.i 04 1}. em seu programa..p.. não gerando problemas com lógica de negócio. os espaços extras para tradução foram recalculados para column-labels dos campos no dicionário de dados. entretanto não se deve esquecer da possibilidade de tradução. o que for maior. e o valor será a referência em Português presente na include.i 04 2} then . é necessário a utilização do utilitário ut-lstit.i.i 03} cb-xxx:screen-value in frame {&frame-name} = {varinc\var99999. >>9. que deve ser reservado sempre à esquerda do label.99 Side-Labels • deve existir o tratamento do espaço extra para tradução.99 >>>>>9 XXXXXXXXXXXXXXXX >.>>9.>>9.>>>.>>9.>>>.>>>. Cliente Descrição Total Pedidos ------------------------------------->>>>>9 XXXXXXXXXXXXXXXX >.>>>. . Abaixo segue demonstração de alguns casos práticos onde será possível identificar algumas das principais diferenças na forma de programar para a técnica de tradução Multi-Idiomas em relação ao modelo anterior.>>>.99 >>>>>9 XXXXXXXXXXXXXXXX >. {utp/ut-liter. Cliente Descrição Total Pedidos ------------------------------------->>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>>.Construção de Programas utilizando os Estilos e suas Técnicas 105 Exemplo: {utp/ut-liter Total_Pedidos} assign de-total-pedidos:label in frame f-relat = trim{returnvalue}.99 >>>>>9 XXXXXXXXXXXXXXXX >.99 ____Total Geral: >>.i Total_Geral} assign de-total-geral:label in frame f-total = return-value.>>9.>>9.99 >>>>>9 XXXXXXXXXXXXXXXX >.99 PRÁTICAS PARA IMPLEMENTAÇÃO MULTIIDIOMAS Neste item estarão sendo abordados alguns casos práticos que podem ser encontrados durante a execução de uma implementação/alteração de programas para a portabilidade do produto para a nova técnica de tradução.>>9. esta mesma lógica depois de convertida para LIST-ITEM-PAIRS. será apresentada como segue: . "Retorno Beneficiamento". Se o usuário informar na tela "Remessa Consignação" gravará o valor no campo tt-natur-oper. "Reajuste Preço".p.cb-tp-oper-terc:list-items in frame fPage2.cbtp-oper-terc:list-items in frame fPage2. "Drawback" .tp-oper-terc = lookup(cb-tp-oper-terc.".". ASSIGN tt-natur-oper. "Faturamento Consignação". Se o campo tt-natur-oper. e algumas observações: assign cb-tp-oper-terc:list-items in frame fPage1 = "Remessa Beneficiamento". ASSIGN cb-tp-oper-terc:screen-value in frame fPage2 = entry(ttnatur-oper.tp-oper-terc.tp-oper-terc como 3.tp-oper-terc ter o valor 2 trará com SCREENVALUE "Retorno Beneficiamento". Agora. ”Remessa Consignação". seja esta conversão feita de forma direta no programa ou através do utilitário ut-lstit. A seguir uma lógica que era antes realizada com LIST-ITEMS. "Devolução Consignação".").").Caso Prático Diferenças LIST-ITEMS para LISTITEM-PAIRS Este primeiro caso prático está relacionado com a utilização de LIST-ITEMPAIRS e suas diferenças em relação à utilização com LIST-ITEMS. Neste caso. Se o campo tt-natur-oper. Manter a lógica da temp-table e fazer algumas implementações que fariam que o número retornado para a tp-oper-terc seja como se estivesse sendo tratado um LIST-ITEMS. "Drawback"."Drawback" ."Faturamento Consignação".cb-tp-oper-terc:list-items in frame fPage2. que é o valor indexador do campo. ASSIGN cb-tp-oper-terc:screen-value in frame fPage2 = entry(tt-natur-oper."."Retorno Beneficiamento".")."."Remessa Beneficiamento". será necessário acresce-lo em 1 unidade. "Faturamento Consignação".tp-oper-terc como 6. que alteraria de 3 para 6 no primeiro caso.tp-oper-terc = lookup(cb-tp-operterc. Caso seja retornado o valor impar. ASSIGN tt-natur-oper."Remessa Consignação". "Remessa Consignação". principalmente em sessões que estão executando em Português.tp-oper-terc é populada."Devolução Consignação". A questão principal neste trecho é a necessidade de analisar onde a tt-naturoper.Construção de Programas utilizando os Estilos e suas Técnicas 107 assign cb-tp-oper-terc:LIST-ITEM-PAIRS in frame fPage1 = "Remessa Beneficiamento".tp-oper-terc ter o valor 2 trará com SCREENVALUE "Remessa Beneficiamento"."). "Retorno Beneficiamento"."Reajuste Preço". devido este estar repetido. "Devolução Consignação".tp-oper-terc. é necessário realizar • .cb-tp-oper-terc:LIST-ITEM-PAIRS in frame fPage2. "Re ajuste Preço". Se o usuário informar na tela "Remessa Consignação" gravará o valor no campo tt-natur-oper. no caso 3. Apenas tomar o cuidado de sempre gravar o valor par. e então com isso pode-se levantar duas alternativas: • Alterar a lógica de onde esta temp-table é populada para contemplar a localização do item de negócio dentro do combo. Reajuste Preço. utilizar a lógica com gravação do valor da temp-table ainda tomando como base o valor não-indexado. Deixamos como sugestão. trabalhar direto na lógica de negócio da temp-table */ ASSIGN cb-tp-oper-terc:screen-value in frame fPage1 = entry(tp-oper-terc * 2.") mod 2 <> 0 Then ASSIGN tp-oper-terc = (lookup(cb-tp-oper-terc:screenvalue.tp-oper-terc sempre estará armazenando os valores como não indexados.Devolução Consignação. /* Valor arbitrado para fins de demonstração */ define variable cb-tp-oper-terc as char format "x(30)" view-as combo-box list-items "".cb-tp-oper-terc:list-item-pairs in frame fPage1.cb-tp-oper-terc:LISTITEM-PAIRS in frame fPage1. update cb-tp-oper-terc with frame fPage1.Remessa Beneficiamento.cb-tp-oper-terc:LIST-ITEM-PAIRS in frame fPage1. ainda utilizando list-items para a sua gravação.".cb-tp-oper-terc:LIST-ITEM-PAIRS in frame fPage1. If lookup(cb-tp-oper-terc:screen-value.Retorno Beneficiamento. conforme abaixo: define variable tp-oper-terc as int init 2. assign cb-tp-oper-terc:LIST-ITEM-PAIRS in frame fPage1 = "Remessa Beneficiamento. Para estes casos é necessário definir qual a melhor forma de implementação realizando uma análise do caso.Faturamento Consignação. evitando assim erros com .Retorno Beneficiamento.". ou seja.Drawback.alguns tratamentos para contemplar qualquer idioma sendo executado pelo produto.") + 1) / 2. /* Considerando que esta temp-table tt-natur-oper. else ASSIGN tp-oper-terc = lookup(cb-tp-oper-terc:screenvalue.". caso contrário.") / 2.Drawback".Devolução Consignação."."). analisando-se o fato que as manutenções estarão sendo realizadas em WorkSpaces de releases que já estão no mercado.Faturamento Consignação.Remessa Consignação.Reajuste Preço. define frame fPage1 cb-tp-oper-terc.Remessa Consignação. Importante Esta alteração direta de LIST-ITEMS para LIST-ITEM-PAIRS somente é necessária caso a referência ao campo esteja depois dos pontos de tradução (Ver item pontos de tradução neste documento). Caso conversão de List-items para LIST-ITEMPAIRS Quando da necessidade de atribuir valores a algum objeto Progress nãoindexado em tela após os pontos de tradução.i 04 02} &endif Onde "{&FNC_MULTI_IDIOMA}" é o pré-processador que indica que a função de tradução em multi-idiomas está habilitada. run utp/ut-lstit.Construção de Programas utilizando os Estilos e suas Técnicas 109 lógicas de negócio deste mesmo programa sendo utilizado em releases anteriores.p (input-output cLista).i 04 02} Depois: &if "{&FNC_MULTI_IDIOMA}" = "Yes" &then assign cLista = {varinc/var00002. &else assign cb-combo:list-items = {varinc/var00002.i 04 02}. . seguir o modelo de construção abaixo: Antes: assign cb-combo:list-items = {varinc/var00002. mantendo inclusive a lógica anterior no sentido de não gerar impacto sobre releases já liberadas comercialmente. assign cb-combo:list-item-pairs = cLista. Para isto. deverá realizar sua chamada ou imediatamente após a definição da frame ou antes da realização do display da frame.arquivo colon 60 "-" no-label format "x(30)" no-label colon 55 format "zzzzzzzzz9" no-label format "zzzzzzzzz9" colon 60 "|< no-label colon 55 with side-label stream-io width 132 frame f-fim. &ENDIF . &IF "{&FNC_MULTI_IDIOMA}" = "Yes" &THEN Run utp/ut-trfrrp. deve ser chamado diretamente o utilitário que realiza a tradução através dos handles dos objetos presentes na relatório frame em questão. Segue abaixo um exemplo de sua aplicação: form skip(2) c-lit-selecao skip(1) tt-param.Tradução automática em frame de relatório Para este caso.tp-etiq-ini >|" tt-param.tp-etiq-fim skip(1) c-lit-impressao skip(1) c-destino tt-param.p (input Frame f-fim:Handle). Importante Sempre passar valores fixos e de variáveis substituindo-se o " " (Branco) por "_" (underline).i são utilizadas para definição da lista de valores e utilizam outra include para realizar o tratamento do tipo de retorno escolhido pelo usuário. valores para RADIO-BUTTON. Todas as includes da nomenclatura varinc/var99999." ". O retorno dos valores é montado através de pré-processadores e o valor destes são retornados todos de uma única vez para uma variável no .000 caracteres para uma única atribuição de valores."_").""). disp c-destino. (135) na compilação de programas que incorporam includes de tradução para uma lista muito longa de valores. é necessário utilizar o programa .i 03})). um único elemento da lista. além de mudar a estrutura das includes responsáveis pelo retorno."*". Para evitar isso foi desenvolvida esta técnica que modifica a forma de chamada das includes varinc.i.Construção de Programas utilizando os Estilos e suas Técnicas 111 Traduzir valor armazenado em uma variável Para tradução de valores em variáveis. assign c-destino = return-value. As includes da pasta VARINC geralmente são utilizadas dessa forma: ASSIGN c-lista-retencao = ENTRY(1.TRIM({varinc/var00137. Segue exemplo abaixo: define variable c-destino as char init "Destino Impressão" noundo.p (input replace(c-destino. que pode ser um list-items de COMBO-BOX. ao invés de utilizar a include ut-liter. O erro 135 do Progress é devido ao limite de 32. run utp/ut-liter.p associado a esta include. Tratando lista enorme de tradução em includes Objetivo Evitar a ocorrência do erro ** More than 32000 characters in a single statement--use -inp parm. Esta é a situação na qual ocorre o erro 135 quando a lista de valores é enorme e ultrapassa o limite de caracteres para uma atribuição. entre outros. val-item = "{&val1}" tt-list-items. Retorna o numero de itens da lista 6. o trabalho de manipulação dos valores para retorno diminui. Implementaç As includes de retorno trabalham com 7 tipos de retorno atualmente: ão 1. . ASSIGN tt-list-items. Para tal. porque ao invés de ficar concatenando uma lista enorme de pré-processadores basta apenas fazer FOR EACH ou FIND na temp-table conforme a opção de retorno desejada.posicao = 1. Lista com os itens separados por virgula 4. View-as radio-set 3. Valores para a propriedade Radio-Buttons de uma Radio-Set Para cada um desses tipos de retorno. porque é necessário popular a tabela com os valores. Retorna o item n da lista 5. é necessário ler a temp-table que contém os valores da lista. View-as combo-box 2. sendo necessário incluí-los um a um. As alterações desta técnica exigem um grande trabalho para adequar a include de retorno na proposta das temp-table. a temp-table deve ser populada com os valores dos préprocessadores: CREATE tt-list-items. Sendo assim é necessário alterar a include de retorno para gravar na variável desejada os valores um por vez. é necessário gravar os valores dos pré-processadores da lista em uma temp-table e realizar um FOR EACH nesta temp-table para gravar os valores um por vez. a cada iteração do FOR EACH ou fazer um FIND diretamente no item desejado. Esta temp-table deve ser definida dessa forma: DEFINE TEMP-TABLE tt-list-items NO-UNDO FIELD posicao AS INT. Em compensação.programa que incorpora a include. Retorna a posição do item (número) 7. FIELD val-item AS CHAR Em seguida. ASSIGN l-log = TRUE.Construção de Programas utilizando os Estilos e suas Técnicas 113 CREATE tt-list-items. END. trabalhando cada tipo de retorno: • Tratamento para o retorno do tipo View-as Combo-box ou Lista com os itens separados por virgula: É necessário ler a temp-table através de FOR EACH e ir concatenando os valores em uma variável caracter (c-lista neste exemplo) separando os elementos por virgula. ASSIGN tt-list-items. ASSIGN c-lista = tt-list-items. Abaixo segue lista de tarefas para implementação da técnica. Neste tipo de retorno o programa precisa estar preparado para ler a variável c-lista. . . . ELSE ASSIGN c-lista = c-lista + ".val-item.val-item. CREATE tt-list-items. DEF VAR l-log AS LOG INITIAL FALSE NO-UNDO.val-item. . FOR EACH tt-list-items BY posicao: IF l-log = NO THEN DO: ASSIGN c-lista = tt-list-items.posicao = 250.val-item = "{&val250}" tt-list-items. . END. ASSIGN tt-list-items.posicao = 2.val-item = "{&val2}" tt-list-items." + tt-listitems. • Tratamento para o retorno do item n da lista: FIND LAST tt-list-items WHERE posicao = {2}. . posicao). . END. ASSIGN c-chave = "{2}". IF AVAIL tt-list-items THEN ASSIGN c-lista = STRING(tt-list-items. ASSIGN c-lista = STRING(tt-list-items. FIND FIRST tt-list-items WHERE val-item = c-chave NO-LOCK NO-ERROR. sendo que dessa vez o parâmetro irá conter o próprio item. Neste tratamento também utilizamos o parâmetro {2} para localizar o item na temp-table.posicao. ELSE ASSIGN c-lista = ?. • Tratamento para retonar valores para a propriedade Radio-Buttons de uma Radio-Set: DEF VAR l-log AS LOG INITIAL FALSE NO-UNDO. basta ler o campo posição do ultimo registro da temp-table para saber o número total de itens. Como a temp-table que armazena os itens possui um campo chamado “posicao”. sendo os valores gravados em ordem seqüencial. ASSIGN l-log = TRUE. • Tratamento para retornar a posição de um item na lista: DEF VAR c-chave AS CHAR NO-UNDO.posicao). Uma vez localizado esse item podemos pegar a posição dele na lista com o campo tt-list-items." + STRING(tt-list-items. • Tratamento para retornar o número total de itens na lista: FIND LAST tt-list-items. FOR EACH tt-list-items BY posicao: IF l-log = NO THEN DO: ASSIGN c-lista = tt-list-items.posicao).O parametro {2} utilizado contém o indice do item desejado e é passado como parâmetro para a include de retorno.val-item + ". . END. • Alterar o ponto de chamada da include VARINC nos programas que a utilizam: Devido as mudanças propostas pela técnica." + tt-listitems.TRIM({varinc/var00137.posicao). É necessário colocar a include em uma linha isolada. Neste caso é feito tratamento semelhante para o retorno para view-as combo-box só invertendo a ordem de um item e sua respectiva posição na string final armazenada em c-lista. de preferência logo após a definição de variáveis do programa.val-item + ". não é possível fazer mais este tipo de atribuição: ASSIGN c-lista-retencao = ENTRY(1.i 03}))." + STRING(tt-list-items.Construção de Programas utilizando os Estilos e suas Técnicas 115 ELSE ASSIGN c-lista = c-lista + ". de acordo com o tipo de Cadastro Simples que se deseja construir.CAPÍTULO 8 Construção de Programas utilizando os Estilos e suas Técnicas Como construir um Cadastro Simples Estilo Usado Cadastro Simples Cadastro Simples -Alteração Cadastro Simples Inclusão Nome Físico Masters/w-cadsim. • . Caso não exista. selecionar um dos estilos relacionados acima.w Masters/w-cadsi3. criar uma nova utilizando o estilo CustomQuery Wizard. instanciar a SmartQuery na página 0 da Window Cadastro Simples e aceitar as sugestões de SmartLinks do Wizard. • verificar se já existe uma SmartQuery para a tabela que se deseja construir um Cadastro Simples.w Implementaç • ão em Arquivo | Novo.w Masters/w-cadsi2. criar uma nova SmartViewer utilizando o estilo CustomViewer com Auto-Field. Observação Para os campos do tipo fill-in’s. tendo Source: p-exihel e como Target: SmartQuery. Caso o fill-in se encaixe em uma das opções acima. ou que possuírem um botão de zoom na sua direita.Construção de Programas utilizando os Estilos e suas Técnicas 117 • verificar se já existe um programa de vá para e um programa de pesquisa para a tabela que se deseja construir um Cadastro Simples. Portanto não é necessário efetuar o registro para esses fill-ins. Caso não exista. verificar se já existe uma SmartViewer com os atributos da tabela que devem ser editados. acessar os atributos de instância da SmartQuery e informar no atributo "Programa Pesquisa" o nome do programa de pesquisa da tabela e no atributo "Programa Vá para" o nome do programa de Vá para da tabela. Caso não existam. criar um SmartLink do tipo STATE. . eles devem ser criados. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. • instanciar a SmartViewer na página 0 da SmartWindow e aceitar as sugestões de SmartLink do Wizard. deve ser efetuado o registro para o WebEnabler. tendo como Source: p-navega e como Target: SmartQuery. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. ou possua trigger de "ENTRY". • • • • criar um SmartLink do tipo STATE. Source h_pcadsim h_pcadsim h_pnavega h_pnavega h_query h_pexihel Link Type STATE TABLEIO NAVIGATION STATE RECORD STATE target h_p-exihel h_viewer h_query h_query h_viewer h_query • Lista de Links: Como construir um Cadastro Complexo Estilo Usado Cadastro Complexo Cadastro Complexo . instanciar a SmartQuery na página 0 da SmartWindow e aceitar as sugestões de SmartLink do Wizard. • . salvar a SmartWindow com o nome definido para o Cadastro Simples. criar uma nova utilizando o estilo CustomQuery Wizard.Atualiza Nome Físico Masters/w-cadcom. de acordo com o tipo de Cadastro Complexo que se deseja construir. Ter o cuidado para que a SmartViewer fique centralizada na SmartWindow.• redimensionar a SmartWindow de acordo com os objetivos que foram colocados nela. Caso não exista. • verificar se já existe uma SmartQuery para a tabela que se deseja construir um Cadastro Complexo.w Masters/w-cadcon2.w Implementaç • ão selecionar um dos estilos relacionados na tabela acima. • • • • criar um SmartLink do tipo STATE. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. deve ser efetuado o registro para o WebEnabler. criar um SmartLink do tipo STATE. ou seja. Caso o fill-in se encaixe em uma das opções acima. ou possua trigger de "ENTRY". verificar se já existe uma SmartViewer com os atributos da tabela que devem estar expostos na parte principal da SmartWindow. • instanciar a SmartViewer na página 0 da SmartWindow. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. tendo como Source: p-exihel e como Target: SmartQuery. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita.Construção de Programas utilizando os Estilos e suas Técnicas 119 • verificar se já existe um programa de Vá para e um programa de pesquisa para a tabela que se deseja construir um Cadastro Complexo. ou que possuírem um botão de zoom na sua direita. criar uma nova SmartViewer utilizando o estilo CustomViewer com Auto-Field. e aceitar as sugestões de SmartLink do Wizard. Caso não existam eles devem ser criados. acessar os atributos de instância da SmartQuery e informar no atributo "Programa Pesquisa" o nome do programa de pesquisa da tabela e no atributo "Programa Vá para" o nome do programa de Vá para da tabela. . Portanto não é necessário efetuar o registro para esses fill-ins. Caso não exista. acima do folder. Observação Para os campos do tipo fill-in’s. acima do folder. tendo como Source: p-navega e como Target: SmartQuery. utilizando o estilo CustomViewer com Auto-Field. . ou possua trigger de "ENTRY". • instanciar a SmartViewer em determinada página do folder e aceitar as sugestões de SmartLink do Wizard. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. Portanto não é necessário efetuar o registro para esses fill-ins. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. Caso não exista. criar uma nova. Observação Para os campos do tipo fill-in’s. ou que possuírem um botão de zoom na sua direita. Caso o fill-in se encaixe em uma das opções acima.• repetir os seguintes passos para as demais SmartViewers que devem estar colocadas nas páginas do folder: • verificar se já existe uma SmartViewer com os atributos que devem estar editados na página do folder. deve ser efetuado o registro para o WebEnabler. Source h_folder h_pcadsim h_pcadsim h_pnavega h_query h_query Link Type PAGE STATE TABLEIO NAVIGATION RECORD RECORD Target THIS-PROCEDURE h_p-exihel h_viewer-l h_query h_viewer-1 h_viewer-2 Lista de Links: . tendo como Source: SmartViewer da página 0 e como Target: SmartViewer recém instanciada no folder. salvar a SmartWindow com o nome definido para o Cadastro Complexo. Ter o cuidado para que a SmartViewer fique centralizada na SmartWindow.Construção de Programas utilizando os Estilos e suas Técnicas 121 • criar um SmartLink de GROUP-ASSIGN. • • acessar as propriedades do folder e renomear os labels das páginas. • redimensionar a SmartWindow de acordo com os objetos que foram colocados nela. criar uma nova utilizando o estilo CustomQuery Wizard. Caso não existam. Caso não exista. verificar se já existe um programa de "Vá para" e um programa de pesquisa para a tabela pai. eles devem ser criados.w Implementaç • ão selecionar o estilo relacionado na tabela acima.h_query h_query h_viewer -1 h_viewer -1 h_viewer -1 h_pexihel h_pnavega RECORD RECORD GROUP-ASSIGN GROUP-ASSIGN GROUP-ASSIGN STATE STATE h_viewer-3 h_viewer-4 h_viewer-2 h_viewer-3 h_viewer-4 h_query h_query Como construir um Cadastro Pai X Filho Atualiza Filho Estilo Utilizado Window Cadastro Pai x Filho . • • • • verificar se já existe uma SmartQuery para a tabela pai. instanciar a SmartQuery na página 0 da SmartWindow e aceitar as sugestões de SmartLink do Wizard. acessar os atributos de instância da SmartQuery e informar no atributo "Programa Pesquisa" o nome do programa de pesquisa da tabela pai e no atributo "Programa VáPara" o nome do programa de Vá Para da tabela pai.Filho Nome Físico Masters/w-adf. . tendo como Source: p-exihel e como Target: SmartQuery. . tendo como Source: p-navega e como Target: SmartQuery. deve ser efetuado o registro para o WebEnabler. ou seja. Portanto não é necessário efetuar o registro para esses fill-ins. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. • instanciar a SmartViewer na página 0 da SmartWindow e aceitar as sugestões de SmartLink do Wizard. criar uma nova SmartViewer utilizando o estilo CustomViewer com Auto-Field. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. verificar se já existe uma SmartViewer com os atributos da tabela pai que devem estar expostos na página 0 da SmartWindow. Caso o fill-in se encaixe em uma das opções acima. Observação Para os campos do tipo fill-in’s. criar um SmartLink do tipo STATE. ou que possuírem um botão de zoom na sua direita. Caso não exista. acima do folder. ou possua trigger de "ENTRY".Construção de Programas utilizando os Estilos e suas Técnicas 123 • • • criar um SmartLink do tipo STATE. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. aceitando os links indicados pelo Wizard. • colocar o SmartBrowser na página correspondente do folder. . criar um novo utilizando o estilo CustomBrowser Inclui/Modifica.• repetir os seguintes passos para os SmartBrowsers que devem estar colocadas nas páginas do folder: • verificar se já existe um SmartBrowser para a tabela filho. Caso não exista. Se este programa não existir.Construção de Programas utilizando os Estilos e suas Técnicas 125 • acessar os atributos de instância do SmartBrowser e informar o nome do programa de atualização da tabela filha. . deve ser criado utilizando-se o template Cadastro Inclui/Modifica Filho. • salvar a SmartWindow com o nome definido para o Cadastro Pai x Filho. Lista de Links Source h_folder h_pexihel h_pnavega h_pnavega h_query Link Type PAGE STATE NAVIGATION STATE RECORD Target THIS-PROCEDURE THIS-PROCEDURE h_query h_query h_viewer .• criar um SmartLink de Record. • ter o cuidado para que a SmartViewer fique centralizada na SmartWindow. deve-se incluir os botões abaixo do browse. • caso seja necessário incluir botões de Seleção e/ou Parâmetros para a tabela do SmartBrowser. tendo como Source: SmartQuery e como Target: SmartBrowser recém instanciado no folder. formando um cadastro do tipo Complexo. • se os campos a serem inclusos/modificados couberem em uma única viewer. • se os campos a serem inclusos/modificados não couberem em uma única viewer. .Construção de Programas utilizando os Estilos e suas Técnicas 127 h_query h_query h_pexihel RECORD RECORD STATE h_browser1 h_browser2 h_query Como construir um Cadastro Inclui/Modifica Filho Estilo Utilizado Window Inclui/Modifica Filho Nome Físico Masters/w-incmo3. estes devem ser divididos em mais viewers que devem ser colocadas nas páginas do folder. o cadastro deve ser do tipo Simples. devendo-se eliminar o folder da SmartWindow.w Implementaç • ão selecionar o estilo relacionado na tabela acima. • • Observação Para os campos do tipo fill-in’s. criar uma nova SmartViewer utilizando o estilo CustomViewer com Auto-Field. • instanciar a SmartViewer na SmartWindow ou na página correspondente do folder no caso de um cadastro complexo. Portanto não é necessário efetuar o registro para esses fill-ins. para cada viewer a ser utilizada deve-se seguir os seguintes passos: • verificar se já existe uma SmartViewer com os atributos da tabela a serem editados. Caso não exista. • se o cadastro for do tipo complexo: . ou que possuírem um botão de zoom na sua direita. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. Caso o fill-in se encaixe em uma das opções acima. tendo como Source: THISPROCEDURE e como Target: SmartViewer recém instanciada. criar uma nova utilizando o estilo CustomQuery Wizard. instanciar a SmartQuery na página 0 (zero) da Window. Caso não exista. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler.• verificar se já existe uma SmartQuery para a tabela que se deseja construir o Cadastro Inclui/Modifica Filho. e aceitar as sugestões de SmartLinks do Wizard. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. ou possua trigger de "ENTRY". • criar um SmartLink de TABLEIO. deve ser efetuado o registro para o WebEnabler. devem ser substituídas as ocorrências de "<viewer_principal>". • incluir a seguinte linha após o Dispatch padrão na LocalInitialize: {include/i-inifld.i} • deve-se atribuir a página 1 como sendo a página inicial do programa. • na Local-Initialize da window. pelo nome da viewer que contém o(s) campo(s) chave(s) da tabela. • em Startup on Page atribuir o valor 1.Construção de Programas utilizando os Estilos e suas Técnicas 129 • criar links de group-assign entre a viewer principal (viewer que deve conter a chave da tabela) e as demais viewers (ver lista de links). Para isso é necessário: • • acessar o Procedure Properties na janela do UIB. Exemplo: . entrar em Propertie Pages. RUN dispatch IN THIS-PROCEDURE (INPUT 'create-record':U ). end. • na SmartViewer que possuir a chave da tabela.<chave pai>. Onde: <tabela pai>: deve ser substituído pelo nome da tabela pai da tabela que se está utilizando no cadastro. /* Dispatch standard ADM method. A tabela pai deve ser a mesma utilizada na query do Cadastro PaiXFilho que deve chamar este programa. Exemplo /* Code placed here will execute PRIOR to standard behavior.run pi-atualiza-parent in h_v06pd001 (input v-rowparent). /* Code placed here will execute AFTER standard behavior. if available order then assign order-line.i h_v06pd001} Exemplo: • na procedure pi-reposiciona da window. */ */ */ find order where rowid (order) = v-row-parent no-lock no-error. . • nas triggers de Choose dos botões de 'Ok' e 'Salvar'.order-num = order.order-num. <chave pai>: deve ser substituído pelo nome do campo chave da tabela pai que estabelece relacionamento com a tabela que deve estar sendo utilizada no cadastro. <tabela filho>: deve ser substituído pelo nome da tabela que deve estar sendo utilizada no cadastro. Exemplo: RUN pi-reposiciona-query IN h_q06pd001 (input v-rowtable). if available <tabela pai> then do: assign <tabela filho>. substituir a ocorrência "<queryname>" pelo nome da query utilizada no cadastro. substituir as ocorrências de "<handle da viewer principal>" pelo handle da viewer que contém o campo chave da tabela. deve ser criada uma localcreate-record e após o run dispatch deve ser inserida a seguinte lógica: find <tabela pai> where rowid (<tabela pai>) = v-rowparent no-lock no-error.<chave pai> = <tabela pai>. {include/okfil. if avail <nome buffer> then assign <tabela filho>. /* Dispatch standard ADM method. else assign <tabela filho>.<chave pai>:screen-value in frame {&frame-name} = string(<nome buffer>. <chave pai>: deve ser substituído pelo nome do campo chave da tabela pai que estabelece relacionamento com a tabela que deve estar sendo utilizada no cadastro.<chave pai>). */ */ */ def buffer b-customer for customer. e após o run dispatch deve ser inserida a seguinte lógica nas duas procedures: def buffer <nome buffer> for <tabela pai>. <tabela pai>: deve ser substituído pelo nome da tabela pai da tabela que se está utilizando no cadastro. <tabela filho>: deve ser substituído pelo nome da tabela que está sendo utilizada no cadastro.cust-num:screen-value in frame {&frame-name} = "". find <nome buffer> where rowid(<nome buffer>) = v-rowparent no-lock no-error. RUN dispatch IN THIS-PROCEDURE (INPUT 'add-record':U ).<chave pai>:screen-value in frame {&frame-name} = “”.Construção de Programas utilizando os Estilos e suas Técnicas 131 • Se desejar preencher os campos chave da tabela pai na viewer para inclusão: • Na SmartViewer que possuir a chave da tabela. Exemplo /* Code placed here will execute PRIOR to standard behavior. A tabela pai deve ser a mesma utilizada na query do Cadastro PaiXFilho que deve chamar este programa.cust-num:screen-value in frame {&frame-name} = string(b-customer. else assign order. find b-customer where rowid(b-customer) = v-row-parent no-lock no-error. /* Code placed here will execute AFTER standard behavior. deve ser criada uma local-display-fields e uma local-add-record. Onde: <nome buffer>: deve ser substituído pelo nome que se deseja dar ao buffer da tabela pai. if avail b-customer then assign order. .cust-num). order-num:screen-value in frame {&frame-name} = “1”. <tabela pai>: deve ser substituído pelo nome da tabela pai da tabela que se está utilizando no cadastro.<chave filho>:screen-value in frame {&frame-name} = string(<nome buffer>. /* Dispatch standard ADM method. . */ */ */ def buffer b-order for order.• Se desejar preencher seqüencialmente o campo chave da tabela filho para inclusão: • Na SmartViewer que possuir a chave da tabela. Exemplo /* Code placed here will execute PRIOR to standard behavior. deve ser criada uma local-add-record e após o run dispatch deve ser inserida a seguinte lógica na procedure: def buffer <nome buffer> for <tabela filho>. Onde: <nome buffer>: deve ser substituído pelo nome que se deseja dar ao buffer da tabela filho. A tabela pai deve ser a mesma utilizada na query do Cadastro PaiXFilho que deve chamar este programa. else assign <tabela filho>.<chave filho>:screen-value in frame {&frame-name} = “1”. <chave pai>: deve ser substituído pelo nome do campo chave da tabela pai que estabelece relacionamento com a tabela que deve estar sendo utilizada no cadastro. <tabela filho>: deve ser substituído pelo nome da tabela que está sendo utilizada no cadastro.cust-num nolock no-error. if avail <nome buffer> then assign <tabela filho>. RUN dispatch IN THIS-PROCEDURE (INPUT 'add-record':U ). if avail b-order then assign order.<chave filho> + 1).<chave pai> no-lock no-error. find last b-order where b-order.order-num:screen-value in frame {&frame-name} = string(b-order.<chave pai> = <tabela pai>. find last <nome buffer> where <nome buffer>.order-num + 1). /* Code placed here will execute AFTER standard behavior.cust-num = customer. else assign order. caso não exista. criar uma nova utilizando o estilo CustomQuery Wizard. • • • verificar se já existe uma SmartQuery para a tabela pai.Ambos Nome Físico Masters/w-paiamb. instanciar a SmartQuery na página 0 da SmartWindow e aceitar as sugestões de SmartLink do Wizard. para isso utilizar o template Cadastro Inclui/Modifica Pai. .w Implementaç • ão selecionar o estilo relacionado na tabela acima. verificar se já existe um programa de Cadastro Inclui/Modifica Pai para manutenção da tabela Pai. Caso não exista. deve ser criado.Construção de Programas utilizando os Estilos e suas Técnicas 133 Lista de Links (Uma Viewer): Source THISPROCEDURE h_query Link Type TABLEIO RECORD Target h_viewer h_viewer Target h_viewer1 h_viewer1 h_viewer2 h_viewer3 h_viewer2 h_browser3 Lista de Links (Mais de uma Viewer): Source h_query THISPROCEDURE h_viewer1 h_viewer1 h_query h_query Link Type RECORD TABLEIO GROUP-ASSIGN GROUP-ASSIGN RECORD RECORD Como construir um Cadastro Pai X Filho Atualiza Ambos Estilo Utilizado Window Cadastro Pai x Filho . eles devem ser criados. verificar se já existe uma SmartViewer com os atributos da tabela pai que estão expostos na página 0 da SmartWindow. Caso não exista. criar um SmartLink do tipo STATE. criar um SmartLink do tipo STATE. ou possua trigger de "ENTRY". • instanciar a SmartViewer na página 0 da SmartWindow e aceitar as sugestões da SmartLink do Wizard. criar uma nova SmartViewer. . acessar os atributos de instância da SmartQuery e informar o nome do programa de pesquisa da tabela pai. o nome do programa de "Vá Para" da tabela pai e o nome do programa de Inclui/Modifica/Copia da tabela pai. tendo como Source o Painel p-exihel e como Target a SmartQuery. criar um SmartLink do tipo STATE.• • verificar se já exista um programa "Vá para" e um programa de pesquisa para a tabela pai. utilizando o estilo CustomViewer com Auto-Field. ou seja. • • • • Observação Para os campos do tipo fill-in’s. tendo como Source o Painel p-cadpai e como Target a SmartQuery. Caso não existam. Caso o fill-in se encaixe em uma das opções acima. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. Portanto não é necessário efetuar o registro para esses fill-ins. deve ser efetuado o registro para o WebEnabler. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. ou que possuírem um botão de zoom na sua direita. acima do folder. tendo como Source o Painel p-navega e como Target a SmartQuery. Construção de Programas utilizando os Estilos e suas Técnicas 135 • repetir os seguintes passos para os SmartBrowsers que devem estar colocadas nas páginas do folder: • verificar se já existe um SmartBrowser para a tabela filho. • colocar o SmartBrowser na página correspondente do folder. deve ser criado utilizando-se o template Cadastro Inclui/Modifica Filho. . • acessar os atributos de instância do SmartBrowser e informar o nome do programa de atualização da tabela filha. aceitando os links indicados pelo Wizard. Caso não exista. criar um novo utilizando o estilo CustomBrowser Inclui/Modifica. Se este programa não existir. • salvar a SmartWindow com o nome definido para o Cadastro Pai x Filho. deve-se incluir os botões abaixo do browse. • caso seja necessário incluir botões de Seleção e/ou Parâmetros para a tabela do SmartBrowser.• ter o cuidado para que a SmartViewer fique centralizada na SmartWindow. Lista de Links: Source h_folder Link Type PAGE Target THIS-PROCEDURE h_viewer h_query h_query h_query h_query h_viewer h_browse1 p-cadpai TABLEIO p-cadpai STATE h_p_exih el h_pnavega h_pnavega h_query h_query STATE NAVIGATION STATE RECORD RECORD . w Implementaç ão • selecionar o estilo relacionado na tabela acima. • se os campos a serem inclusos/modificados couberem em uma única viewer. • se os campos a serem inclusos/modificados não couberem em uma única viewer. o cadastro deve ser do tipo Simples. formando um cadastro do tipo Complexo. .Construção de Programas utilizando os Estilos e suas Técnicas 137 h_query RECORD h_browse2 Como construir um Cadastro Inclui/Modifica Filho Estilo Utilizado Window Inclui/Modifica Filho Nome Físico Master/w-incmo3. estes devem ser divididos em mais viewers que devem ser colocadas nas páginas do folder. devendo-se eliminar o folder da SmartWindow. e aceitar as sugestões de SmartLinks do Wizard. • se o cadastro for do tipo complexo: • criar links de group-assign entre a viewer principal (viewer que conterá a chave da tabela) e as demais viewers (ver lista de links). instanciar a SmartQuery na página 0 (zero) da Window. tendo como Source: THISPROCEDURE e como Target: SmartViewer recém instanciada.• verificar se já existem uma SmartQuery para a tabela que se deseja construir o Cadastro Inclui/Modifica Filho. para cada viewer a ser utilizada deve-se seguir os seguintes passos: • verificar se já existe uma SmartViewer com os atributos da tabela a serem editados. Caso o fill-in se encaixe em uma das opções acima. • instanciar a SmartViewer na SmartWindow ou na página correspondente do folder no caso de um cadastro complexo. • • Observação Para os campos do tipo fill-in’s. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. . Caso não exista. Caso não exista. • criar um SmartLink de TABLEIO. criar uma nova SmartViewer utilizando o estilo CustomViewer com Auto-Field. Portanto não é necessário efetuar o registro para esses fill-ins. ou possua trigger de "ENTRY". ou que possuírem um botão de zoom na sua direita. deve ser efetuado o registro para o WebEnabler. criar uma nova utilizando o estilo CustomQuery Wizard. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. entrar em Propertie Pages.i} • deve-se atribuir a página 1 como sendo a página inicial do programa. Exemplo: run pi-atualiza-parent in h_v06pd001 (input v-rowparent). pelo nome da viewer que contém o(s) campo(s) chave(s) da tabela. • na Local-Initialize da window. Para isso é necessário: • • acessar o Procedure Properties na janela do UIB.Construção de Programas utilizando os Estilos e suas Técnicas 139 • incluir a seguinte linha após o Dispatch padrão no LocalInitialize: {include/i-inifld. devem ser substituídas as ocorrências de "<viewer_principal>". • em Startup on Page atribuir o valor 1. . Onde: <tabela pai>: deve ser substituído pelo nome da tabela pai da tabela que se esta utilizando no cadastro.• nas triggers de Choose dos botões de 'Ok' e 'Salvar'.<chave pai>.i h_v06pd001} • na procedure pi-reposiciona da window. find <tabela pai> where rowid (<tabela pai>) = v-row-parent no-lock no-error. Ex: RUN pi-reposiciona-query IN h-q06pd001 (input v-rowtable). A tabela pai deve ser a mesma utilizada na query do Cadastro PaiXFilho que deve chamar este programa <tabela filho>: deve ser substituído pelo nome da tabela que deve estar sendo utilizada no cadastro <chave pai>: deve ser substituído pelo nome do campo chave da tabela pai que estabelece relacionamento com a tabela que deve estar sendo utilizada no cadastro Lista de Links (Uma Viewer): Source THISPROCEDURE h_query Link Type TABLEIO RECORD Target h_viewer h_viewer .<chave pai> = <tabela pai>. • na SmartViewer que possuir a chave da tabela. end. if available <tabela pai> then do: assign <tabela filho>. deve ser criada uma localcreate-record e após o run dispatch deve ser inserida a seguinte lógica: RUN dispatch IN THIS-PROCEDURE ( INPUT 'create-record':U ) . substituir as ocorrências de "<handle da viewer principal>" pelo handle da viewer que contém o campo chave da tabela. Exemplo: {include/okfil. substituir a ocorrência "<queryname>" pelo nome da query utilizada no cadastro. w Implementaç • ão selecionar o estilo relacionado na tabela acima. devendo-se eliminar o folder da SmartWindow. o cadastro deve ser do tipo Simples.Construção de Programas utilizando os Estilos e suas Técnicas 141 Lista de Links (Mais de uma Viewer): Source h_query THISPROCEDURE h_viewer1 h_viewer1 h_query h_query Link Type RECORD TABLEIO GROUP-ASSIGN GROUP-ASSIGN RECORD RECORD Target h_viewer1 h_viewer1 h_viewer2 h_viewer3 h_viewer2 h_viewer3 Como construir um Cadastro Inclui/Modifica Pai Estilo Utilizado Window IncluiModifica Pai Nome Físico Master/w-incmdp. . • se os campos a serem inclusos/modificados couberem em uma única viewer. Caso não exista. para cada viewer a ser utilizada deve-se seguir os seguintes passos: • verificar se já existe uma SmartViewer com os atributos da tabela a serem editados. formando um cadastro do tipo Complexo. criar uma nova SmartViewer utilizando o estilo CustomViewer com Auto-Field. estes devem ser divididos em mais viewers que devem ser colocadas nas páginas do folder. • verificar se já existe uma SmartQuery para a tabela que se deseja construir o Cadastro Inclui/Modifica Filho. instanciar a SmartQuery na página 0 (zero) da Window. • • .• se os campos a serem inclusos/modificados não couberem em uma única viewer. criar uma nova utilizando o estilo CustomQuery Wizard. Caso não exista. Portanto não é necessário efetuar o registro para esses fill-ins. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. entrar em Propertie Pages. • se o cadastro for do tipo complexo: • criar links do group-assign entre a viewer principal (viewer que deve conter a chave da tabela) e as demais viewers (ver lista de links). tendo como Source: THISPROCEDURE e como Target: SmartViewer recém instanciada. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. • • acessar a Procedure Properties na janela do UIB. ou possua trigger de "ENTRY".i} • deve-se atribuir a página 1 como sendo a página inicial do programa. • em Startup on Page atribuir o valor 1. • instanciar a SmartViewer na SmartWindow ou na página correspondente do folder no caso de um cadastro complexo. . • incluir a seguinte linha após o Dispatch padrão na LocalInitialize: {include/i-inifld. Caso o fill-in se encaixe em uma das opções acima.Construção de Programas utilizando os Estilos e suas Técnicas 143 Observação Para os campos do tipo fill-in’s. • criar um SmartLink de TABLEIO. e aceitar as sugestões de SmartLinks do Wizard. ou que possuírem um botão de zoom na sua direita. deve ser efetuado o registro para o WebEnabler. Para isso é necessário. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. Exemplo: {include/okpai.• nas triggers de Choose dos botões de 'Ok' e 'Salvar'.i h_v07pd002} • na procedure pi-reposiciona da window. Exemplo: RUN pi-reposiciona-query IN h_q07pd001 (input v-rowtable). substituir as ocorrências de "<handle da viewer principal>" pelo handle da viewer que contém o campo chave da tabela. Lista de Links (Uma Viewer): Source THISPROCEDURE h_query Link Type TABLEIO RECORD Target h_viewer h_viewer Target h_viewer1 h_viewer1 Lista de Links (Mais de uma Viewer): Source h_query THISLink Type RECORD TABLEIO . substituir a ocorrência "<queryname>" pelo nome da query utilizada no cadastro. • seguir os passos do Wizard. essa tabela deve ser a mesma tabela utilizada na query do Cadastro PaiXFilho em que o browser deve ser utilizado.w Inclui/Modifica Pai Implementaç • ão selecionar o estilo relacionado na tabela acima. . observando que: • deve-se indicar uma tabela externa.Construção de Programas utilizando os Estilos e suas Técnicas 145 PROCEDURE h_viewer1 h_viewer1 h_query h_query GROUP-ASSIGN GROUP-ASSIGN RECORD RECORD h_viewer2 h_viewer3 h_viewer2 h_viewer3 Como construir um CustomBrowser Inclui/Modifica Estilo Utilizado Nome Físico Window Master/w-incmdp. a coluna "Returned" do browse. deve conter o valor "Fields Used" e o toggle-box "Sort-ByPhrase" deve ser marcado. .• a query deve conter a tabela dos registros filhos que irão ser exibidos no Cadastro PaiXFilho. • em "Options". Exemplo de query do browser: • toggle-box "Indexed-Reposition" deve ser marcado. seguir os passos do Wizard observando que o browse deve exibir apenas os registros que estejam entre os limites estabelecidos pelo usuário para isso na definição da query do browse. salvar o browse de acordo com as normas de nomenclatura. deve-se obedecer aos seguintes itens: na página where.<Campo> <= fi-fin-<campo> • Onde: .<Campo> >= fi-ini-<campo> and <Tabela>.Construção de Programas utilizando os Estilos e suas Técnicas 147 • após a criação do browse com a ajuda do Wizard. Como construir um CustomBrowser Zoom Wizard Estilo Utilizado Custom Browser Zoom Wizard Nome Físico Masters/wbrwzoo.w Implementaç • ão • selecionar o estilo relacionado na tabela acima. deve-se entrar com a seguinte condição: <Tabela>. formato e tamanho dos fill-in´s para faixa de valores devem ser alterados de modo que se tornem compatíveis com os campos utilizados na condição anterior. fi-ini-campo e fi-fin-campo são os fill-ins que o usuário irá entrar com a faixa de valores Obs. • depois de concluída a definição do browse.<Campo2> >= >= >= >= fi-ini-<campo1> fi-ini-<campo1> fi-ini-<campo2> fi-ini-<campo2> and and and .<Campo2> <Tabela>. o nome.<Campo>: é o campo da tabela ao qual deseja-se estabelecer limites. tipo. e. para isso deve-se: . Exemplo: <Tabela>.: A condição pode obedecer a valores de mais campos bastando adicionála.<Tabela>.<Campo1> <Tabela>..<Campo1> <Tabela>.. . na frame f-main disposto acima do browse. em database fields deve-se indicar o campo que esta se fazendo a condição para faixa de valores. desmarcar os toogle-boxes Label e Database Variable. na dialog Dictionary Defaults.Construção de Programas utilizando os Estilos e suas Técnicas 149 • • • acessar os atributos do fill-in c-inicial. as imagens Image-1 e Image-2 devem ser copiadas e reposicionadas entre os dois novos campos. • mais campos podem ser adicionados a condição de faixa de valores. • alterar o valor inicial do fill-in de início de faixa. Exemplo: para um fill-in do tipo inteiro de formato "999. seu valor inicial deve ser "" (branco).99. • repetir os mesmos passos para o fill-in c-final.999.999.99". para um fillin do tipo caracter de formato "x(6)". Exemplo: fi-fin-cust-num. para um fill-in do tipo caracter de formato "x(6)".: se forem adicionados mais campos para a faixa de valores. para o menor valor aceito por ele. Exemplo: para um fill-in do tipo inteiro de formato "999. . conforme a faixa original. • alterar o valor inicial do fill-in de fim de faixa para o maior valor aceito por ele. seu valor inicial deve ser "ZZZZZZ" (seis letras "z" maiúsculas).999. ou inserir diretamente os campos na frame e em seguida desvinculá-los da base através de suas propriedades e alterando seus nomes.• o nome do fill-in deve ser alterado para o mesmo nome relacionado na condição da query do browse. seu valor inicial deve ser 0 (zero).99". observando que seu nome deve ser alterado para o formato fi-fin-<campo>. seu valor inicial deve ser 999. bastando que sejam adicionados os fill-in´s e que sejam seguidos os passos citados anteriormente. Exemplo: fi-ini-cust-num. no formato fi-ini<campo>. Obs. . Como construir uma Consulta Simples Estilo Utilizado Window Consulta Simples Nome Físico Masters/w-consim. • se necessário.. . criando a procedure local-initialize antes do dispatch. os fill-in´s de inicio de faixa (fi-ini-<campo>) poderão possuir labels. Para isso os fill-in´s não devem se no-labels. Como esses fill-in´s não são vinculados ao banco de dados. Para: assign input frame {&frame-name} fi-ini-cust-num fi-fin-custnum. • • alterar a procedure pi-retorna-valor. ou se houverem mais de um campo para seleção de valores. onde: <tabela>: nome da tabela do browser <campo1>: primeiro campo do browser <campo2>: segundo campo do browser <campo. do browser <campoN>: campo N do browser salvar o browse seguindo as normas de nomenclatura. selecionar o estilo relacionado acima. a atribuição do label deverá ser feita por meio do utilitário ut-field ou ut-liter.w Implementaç • ão em Arquivo | Novo. Exemplo: assign input frame {&frame-name} c-inicial c-final. Exemplo: {utp/ut-field.Construção de Programas utilizando os Estilos e suas Técnicas 151 • na trigger do botão bt-confirma. as ocorrências dadas por c-inicial e c-final devem ser alteradas para fi-ini-campo e fi-fin-campo respectivamente...i Sports Customer Cust-Num 1} assign fi-ini-Cust-Num:Label in frame {&frame-name} = return-value.>: campo . . criar uma nova utilizando o estilo CustomQuery Wizard. Caso não existam. tendo como Source: p-exihel e como Target: SmartQuery. criar uma nova SmartViewer utilizando o estilo CustomViewer com Auto-Field. Caso não exista. instanciar a SmartQuery na página 0 da Window Consulta Simples e aceitar as sugestões de SmartLinks do Wizard. criar um SmartLink do tipo STATE. eles devem ser criados. verificar se já existe uma SmartViewer com os atributos da tabela que devem ser editados. tendo como Source: p-navega e como Target: SmartQuery. • • • • • • criar um SmartLink do tipo STATE. acessar os atributos de instância da SmartQuery e informar no atributo "Programa Pesquisa" o nome do programa de pesquisa da tabela e no atributo "Programa Vá para" o nome do programa de Vá para da tabela. verificar se já existe um programa de vá para e um programa de pesquisa para a tabela que se deseja construir a Consulta Simples.• verificar se já existe uma SmartQuery para a tabela que se deseja construir a Consulta Simples. Caso não exista. criar uma nova utilizando o estilo CustomQuery Wizard. ou que possuírem um botão de zoom na sua direita. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. . • • instanciar a SmartViewer na página 0 da SmartWindow e aceitar as sugestões de SmartLink do Wizard. deve ser efetuado o registro para o WebEnabler. redimensionar a altura da SmartWindow de acordo com os objetos que foram colocados nela. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. • verificar se já existe uma SmartQuery para a tabela que se deseja construir um Cadastro Complexo. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler.Construção de Programas utilizando os Estilos e suas Técnicas 153 Observação Para os campos do tipo fill-in’s. Source h_p-navega h_p-navega h_query h_p-exihel Link Type NAVIGATION STATE RECORD STATE Target h_query h_query h_viewer h_query • Lista de Links Como construir uma Consulta Complexa Estilo Utilizado Window Consulta Complexa Nome Físico Masters/w-concom. ou possua trigger de "ENTRY". salvar a SmartWindow com o nome definido para o Cadastro Simples.w Implementaç • ão selecionar o estilo relacionado na tabela acima. Ter o cuidado para que a SmartViewer fique centralizada na SmartWindow. Portanto não é necessário efetuar o registro para esses fill-ins. Caso não exista. Caso o fill-in se encaixe em uma das opções acima. verificar se já existe um programa de Vá para e um programa de pesquisa para a tabela que se deseja construir um Cadastro Complexo. tendo como Source: p-navega e como Target: SmartQuery. e aceitar as sugestões de SmartLink do Wizard. • . criar uma nova SmartViewer utilizando o estilo Custom Viewer com Auto-Field. ou seja. Caso não existam. acima do folder. criar um SmartLink do tipo STATE. eles devem ser criados. acessar os atributos de instância da SmartQuery e informar no atributo "Programa Pesquisa" o nome do programa de pesquisa da tabela e no atributo "Programa Vá para" o nome do programa de Vá para da tabela. • • • • criar um SmartLink do tipo STATE. verificar se já existe uma SmartViewer com os atributos da tabela que devem estar expostos na parte principal da SmartWindow. tendo como Source: p-exihel e como Target: SmartQuery. acima do folder. Caso não exista.• • instanciar a SmartQuery na página 0 da SmartWindow e aceitar as sugestões de SmartLink do Wizard. instanciar a SmartViewer na página 0 da SmartWindow. Construção de Programas utilizando os Estilos e suas Técnicas 155 • repetir os seguintes passos para as demais SmartViewers que devem estar colocadas nas páginas do folder: • verificar se já existe uma SmartViewer com os atributos que devem estar dispostos na página do folder. Caso não exista. ou que possuírem um botão de zoom na sua direita. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. Caso o fill-in se encaixe em uma das opções acima. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. • criar um SmartLink de GROUP-ASSIGN. utilizando o estilo CustomViewer com Auto-Field. criar uma nova. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. ou possua trigger de "ENTRY". Observação Para os campos do tipo fill-in’s. Portanto não é necessário efetuar o registro para esses fill-ins. deve ser efetuado o registro para o WebEnabler. . tendo como Source: SmartViewer da página 0 e como Target: SmartViewer recém instanciada no folder. • instanciar a SmartViewer em determinada página do folder e aceitar as sugestões de SmartLink do Wizard. salvar a SmartWindow com o nome definido para o Cadastro Complexo. Ter o cuidado para que a SmartViewer fique centralizada na SmartWindow. • • Source ' h_folder h_pnavega h_query h_query h_query h_query h_viewer -1 h_viewer -1 h_viewer -1 h_pexihel Link Type PAGE NAVIGATION RECORD RECORD RECORD RECORD GROUP-ASSIGN GROUP-ASSIGN GROUP-ASSIGN STATE Target THIS-PROCEDURE h_query h_viewer1 h_viewer2 h_viewer3 h_viewer4 h_viewer-2 h_viewer-3 h_viewer-4 h_query . acessar as propriedades do folder e renomear os labels das páginas.• redimensionar a altura da SmartWindow de acordo com os objetos que foram colocados nela. Caso não existam.Construção de Programas utilizando os Estilos e suas Técnicas 157 h_pnavega STATE h_query Como construir uma Consulta Relacionamentos Estilo Utilizado ' Window Consulta Relacionamento Nome Físico Masters/w-conrel.w Implementaç • ão selecionar o estilo relacionado na tabela acima. • • • . eles devem ser criados. verificar se já existe um programa de Vá para e um programa de pesquisa para a tabela que se deseja construir uma Consulta Relacionamento. Caso não exista. • verificar se já existe uma SmartQuery para a tabela que se deseja construir uma Consulta Relacionamento. instanciar a SmartQuery na página 0 da SmartWindow e aceitar as sugestões de SmartLink do Wizard. acessar os atributos de instância da SmartQuery e informar no atributo "Programa Pesquisa" o nome do programa de pesquisa da tabela pai e no atributo "Programa Vá para" o nome do programa de vá para da tabela pai. criar uma nova utilizando o estilo CustomQuery Wizard. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. Caso não exista. acima do folder. .• • • criar um SmartLink do tipo STATE. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. criar uma nova SmartViewer utilizando o estilo CustomViewer com Auto-Field. • instanciar a SmartViewer na página 0 da SmartWindow e aceitar as sugestões de SmartLink do Wizard. Observação Para os campos do tipo fill-in’s. tendo como Source: p-navega e como Target: SmartQuery. deve ser efetuado o registro para o WebEnabler. tendo como Source: p-exihel e como Target: SmartQuery. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. ou que possuírem um botão de zoom na sua direita. ou seja. ou possua trigger de "ENTRY". Portanto não é necessário efetuar o registro para esses fill-ins. criar um SmartLink do tipo STATE. verificar se já existe uma SmartViewer com os atributos da tabela pai que devem estar expostos na página 0 da SmartWindow. Caso o fill-in se encaixe em uma das opções acima. O critério de escolha para esse programa deve ser o seguinte: • • • 1º Consulta cadastral do filho. Caso não exista. . 3º Consulta cadastral de uma tabela associativa ao filho. criar um novo utilizando o estilo CustomBrowser Consulta. • deve ser implantada a técnica de reposicionamento automático com base nas variáveis globais para o browser. • Acessar os atributos de instância de cada Browse e informar o nome do programa e diretório que deve ser chamado pelo botão Detalhar.Construção de Programas utilizando os Estilos e suas Técnicas 159 • repetir os seguintes passos para os SmartBrowsers que devem estar colocadas nas páginas do folder: • verificar se já existe um SmartBrowser para a tabela filho da consulta relacionamento. • botão "Detalhar" deve ser responsável por chamar um determinado programa de consulta que deve detalhar o registro selecionado no SmartBrowser. 2º Consulta relacionamento do filho. Outra diferença é que o relatório é constituído por dois programas. conforme os parâmetros passados pelo primeiro programa. pois não se utiliza de SmartObjects. Dicas Gerais . o primeiro com o nome do formato xxp/xx9999. o segundo programa. deve-se utilizar o estilo Window Relatórios/Cálculos/Fechamentos (w-relat. Source ' h_folder h_pexihel h_pnavega h_pnavega h_query h_query h_query h_pexihel Link Type PAGE STATE NAVIGATION STATE RECORD RECORD RECORD STATE Target THIS-PROCEDURE THIS-PROCEDURE h_query h_query h_viewer h_browse1 h_browse2 h_query • Lista de Links: Como construir um programa de Relatórios Para a construção de relatórios que não são gerados pelo Data Viewer. com nome de formato xxp/xx9999rp. tendo como Source: SmartQuery e como Target: SmartBrowser recém instanciado no folder.• criar um SmartLink de Record.w é o que faz a interface com o usuário apresentando todas as opções e entradas de dados necessárias à geração do relatório. Ter o cuidado para que a SmartViewer fique centralizada na SmartWindow.w). executa a geração do relatório propriamente dito. • redimensionar a SmartWindow de acordo com os objetos que foram colocados nela.p. que se apresenta um pouco diferente dos demais estilos existentes. salvar a SmartWindow com o nome definido para a Consulta Relacionamento. • neste estilo. Botão List Objects. screen-values é feito automaticamente por um include padrão do estilo. Eliminar as frames das páginas desnecessárias com base na tabela acima. se as cinco páginas forem necessárias desconsiderar as tarefas 2. 3. Preparação do Relatório . 3.Interface 1. na janela do UIB. Exceções: listitems do widget combo-box. 4 e 5. Verificar quais as páginas que devem ser necessárias ao programa. onde a página de digitação não é necessária: &GLOBAL-DEFINE &GLOBAL-DEFINE &GLOBAL-DEFINE &GLOBAL-DEFINE &GLOBAL-DEFINE PGSEL PGCLA PGPAR PGDIG PGIMP f-pg-sel f-pg-cla f-pg-par f-pg-imp . assim se está informando ao estilo que estas páginas não existem no relatório. 4. Em 'Definitions' limpar o conteúdo dos preprocessadores das páginas desnecessárias. todo trabalho de tradução de labels. onde n é o número de páginas desnecessárias.Construção de Programas utilizando os Estilos e suas Técnicas 161 • tabela de para de folder/páginas e com objetos relacionados: PáginaFolder ' Seleção Frame f-pg-sel Imagem im-pg-sel im-pg-cla im-pg-par im-pg-dig im-pg-imp Preprocess ador PGSEL PGCLA PGPAR PGDIG PGIMP Classificaç f-pg-cla ão Parâmetr f-pg-par os Digitação f-pg-dig Impressão f-pg-imp • para selecionar uma página para trabalhar. Exemplo. clicar no botão 'List Objects' que apresenta um browse com os objetos do programa. Botão to Top. helps. Eliminar n imagens com as "orelhas" mais a direita. 2. renomeando as remanescentes conforme a tabela acima. selecionar a frame desejada e então acionar o botão 'TO TOP'. no 'Main-block' do programa. Observação Para os campos do tipo fill-in’s. toggle-box. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. Observação Para os campos do tipo fill-in’s. Pagina de Parâmetros 1. Caso o fill-in se encaixe em uma das opções acima. exemplo: {include/i-rpmbl. 3. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. Se necessário adicionar mais opções de classificação. . fill-in). para cada campo que precisa de faixa.i im-pg-par} Página de Seleção 1. Corrigir os 'initial values' das variáveis de inicial e final. initial e help para as mesmas. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. definindo label. deve ser efetuado o registro para o WebEnabler. ou possua trigger de "ENTRY". Página de Classificação 1. deve ser efetuado o registro para o WebEnabler. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. Colocar os fill-in´s de inicial e final. com as opções de classificação de seu relatório. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. formatos e tamanhos do dicionário de dados. ou possua trigger de "ENTRY". ou que possuírem um botão de zoom na sua direita. Caso o fill-in se encaixe em uma das opções acima. formato. Colocar as variáveis necessárias na representação desejada (radio-set.i. Portanto não é necessário efetuar o registro para esses fill-ins. adicionando o nome da imagem associada a página que se deseja apresentar como inicial.5. Retirar possíveis queries que o UIB automaticamente queira associar a frame. Redefinir o 'list-items' do radio-set rs-classif . Se a página de seleção não existir. 2. corrigir a chamada do include i-rpmbl. 2. A sugestão é criar como 'Database Fields' e após convertê-los para variáveis para obter automaticamente os labels. Página de Digitação 1. 3.<campo> in browse br-digita do: {include/zoomvar. 'Row-entry': determina valores iniciais para os campos da temp-table na inclusão de novas linhas. ver capítulo Como implementar Zoom e campos de referência para campos de chave estrangeira. os gatilhos de 'leave' (para atributos de referência). 5.. 'Row-leave': salva as alterações feitas pelo usuário. tais gatilhos devem ser codificados "à mão". 4. estes labels devem ser fill-in´s view-as text. Caso seja necessário implementar retângulos com label. Ainda em 'Section Editor'.} END. corrigir a definição da temp-table de digitação tt-digita inserindo os campos necessários. Em 'Section Editor'. 2. no início do 'Main Block' do programa.i . Todas as validações do browse br-digita devem ser feitas na procedure piexecutar no local indicado pelo comentário. exceto quando se trata da primeira linha do browse. mas para os botões bt-inserir e bt-alterar. na linha que aplica um evento 'Entry'. Neste caso. para o objeto browse br-digita adaptar os seguintes gatilhos para a nova definição da temp-table tt-digita e outras necessidades: 'Display': define os campos da temp-table a serem apresentados e quais devem ficar habilitados. 'f5' e 'mouse-select-dblclick' (para acionamento do zoom). Em 'Definitions'. MOUSE-SELECT-DBLCLICK OF tt-digita.. para as colunas do browse podem ser necessários. Exemplo: ON F5. . adaptar os seus gatilhos de 'Choose'.Construção de Programas utilizando os Estilos e suas Técnicas 163 O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. Observação Para mais detalhes sobre esta técnica. Portanto não é necessário efetuar o registro para esses fill-ins. sobre o primeiro campo habilitado no browse. As propriedades 'Display' e 'Enable' devem ser retiradas. 2. e o seu valor deve ser informado no seu initial e private-data. Opcionalmente. ou que possuírem um botão de zoom na sua direita. return error. input 73. Relatórios no formato RTF O template está preparado para gerar a saída do relatório no formato RTF (Rich Text Format). Porém. Na procedure 'pi-executar'. no local indicado pelo comentário. apply 'mouse-select-click' to im-pg-par in frame f-relat. seguir a técnica Como implementar Parâmetros de Impressão em Relatórios. Exemplo if input frame f-pg-par i-nr-nivel > 19 then do: run utp/ut-msgs. colocando o focus no campo com problemas. Caso não deseje que o relatório possua esta funcionalidade basta seguir os procedimentos descritos abaixo para que o programa funcione corretamente: • Em definitions deve-se alterar o valor do preprocessador RTF para “NO”.Página de Impressão Na página de impressão não é necessário que se tenha qualquer função adicional para o seu correto funcionamento. input " "). 3. 4. end. Para isto não é necessário realizar nenhuma alteração no programa de interface.P' pelo programa que deve imprimir o relatório.p (input "show". colocar a lógica de gravação dos parâmetros e seleção na temp-table tt-param. Em 'Definitions' implementar os campos de parâmetros e seleção na definição da temp-table tt-param. substituir na chamada do include {include/i-rprun. lembrando que elas devem apresentar uma mensagem de erro cadastrada. Na procedure 'pi-executar'. se necessário. Ex: &GLOBAL-DEFINE RTF NO . colocar as validações necessárias às opções do usuário para execução do relatório no local indicado pelo comentário. apply 'entry' to i-nr-nivel in frame f-pg-par. Gravação e validação dos parâmetros 1. posicionar na página com problemas. 2. Ainda na procedure 'pi-executar'.i} a literal 'XXP/XX9999RP. 00 e row 4. • Também é possível passar durante a inicialização do programa um arquivo de modelo padrão para o relatório. bt-modelo-rtf e rect-rtf. retirar a chamada para o include {cdp/cd9000. 1. nenhum programa chamado a partir de um rp. Da mesma forma.1. exceto pela própria impressão/visualização do relatório e pela caixa de acompanhamento de execução (ut-acomp/ut-perc) quando necessário. Se a implementação for uma conversão de um programa originário do MAGNUS: 2. Reposicionar os componentes de execução de acordo com o especificado a seguir: text-modo para column 1.w que o chama. text-modelo-rtf. c-modelo-rtf. Para isto basta incluir no Main Block do programa.46.86 e row 4.i} e substituir as seguintes chamadas: Include Velho ' Include Novo Cdp\cd950 Include\i-rpvar. antes da chamada a procedure “enable_UI”. rect-9 para column 2.17. onde: <pasta> = sub-pasta aonde se encontra o arquivo de modelo no propath <modelo.P de Relatório O programa de execução do relatório (rp. e rs-execucao para column 2.83.p). neste caso o usuário não será obrigado a informar um modelo manualmente.Construção de Programas utilizando os Estilos e suas Técnicas 165 • Na página de impressão(f-pg-imp) é necessário remover os componentes referentes a funcionalidade de RTF. Os componentes são: text-rtf. a linha abaixo: ASSIGN c-modelo-default = SEARCH("<pasta>\<modelo.14 e row 4. Copiar a definição das temp-tables tt-param e tt-digita (esta última se houver digitação) do programa de interface (. Todas as validações ou informações com necessidade de intervenção do usuário devem ser tratadas pelo programa .p) é um programa procedural sem qualquer tipo de interface com o usuário. l-habilitaRtf.p não deve possuir qualquer tipo de interface. 2.i .W) para o programa que deve gerar o relatório (rp.rtf>").rtf> = arquivo que contém o modelo no formato rtf Dicas para criação do Programa RP. o work-file de digitação pela temp-table tt-digita.1.i Cdp\cd954 Include\i-rpclo.i. 4.i Cdp\cd950 Include\i-rpcab. ao invés de utilizar a palavra "à". 6. substituir.0.2. seleção e classificação pelos respectivos campos da temp-table tt-param. Nas seleções. 3.i.i}. Utilizar um stream padrão definido como STR-RP. Em todos os forms/frames de impressão deve-se colocar a cláusula streamio.i &stream = "stream str-rp"}.i 0.i 2.i 0.i &stream = "stream str-rp"} {include/i-rpclo.i} ou ainda {utp/ut-table.i &stream = "str-rp"} {include/i-rpc256. 5. i-rpout. com base no programa original. deve-se passar o parâmetro &stream com o nome da stream para os includes i-rpcab. Para utilizar a funcionalidade de impressão para arquivo RTF: 7. i-rpcb80. substituí-la pelos caracteres "|< >|" semelhantes as imagens utilizadas na tela de seleção.i &stream = "str-rp"} {include/i-rpcb80.i 0. Exemplo {include/i-rpcab. para dar idéia de faixa. Este número deve ser ajustado para cada relatório conforme o tamanho .i}. para impressão do relatório. as variáveis de parâmetro.2. e que não necessitam ser traduzidos.i &stream = "str-rp"} {include/i-rpout. Todos os labels que não forem do dicionário de dados e que apareçam no relatório devem ser tratados através dos includes {utp/ut-liter. {utp/utfield. caso haja opção de digitação.3. definir o préprocessador conforme abaixo: &GLOBAL-DEFINE RTF YES 7. 7.i e i-rpclo.i. substituir. i-rpc256.fl Cdp\cd952 Include\i-rpout. 2. definir o préprocessador abaixo setando o tamanho da página: &SCOPED-DEFINE pagesize N N é o número de linhas por página e por default seu valor é 42. END. Exemplo de um progr ama RP.4.3. Caso este tamanho não esteja correto ocorrerá problema na quebra da página.cust-num /* campo . VIEW STREAM str-rp FRAME f-rodape.l-habilitaRTF <> YES THEN DO: VIEW STREAM str-rp FRAME f-cabec. condicionar o VIEW das frames de cabeçalho/rodapé no início do programa.000} /* préprocessador para ativar ou não a saída para RTF */ &GLOBAL-DEFINE RTF YES /* préprocessador para setar o tamanho da página */ &SCOPED-DEFINE pagesize 42 /* definição das temp-tables para recebimento de parâmetros */ DEFINE TEMP-TABLE tt-param NO-UNDO FIELD destino FIELD arquivo FIELD usuario FIELD data-exec FIELD hora-exec FIELD classifica FIELD desc-classifica AS INTEGER AS CHARACTER FORMAT "x(35)" AS CHARACTER FORMAT "x(12)" AS DATE AS INTEGER AS INTEGER AS CHARACTER FORMAT "x(40)" FIELD modelo-rtf AS CHARACTER FORMAT "x(35)" /* arquivo modelo para RTF */ FIELD l-habilitaRtf FIELD ini-cust-num página seleção */ AS LOG LIKE customer. Segue exemplo abaixo: IF tt-param.00. 7. a definição da temp-table tt-param deve ser idêntica a definição da mesma no programa de interface. para que quando o destino for para RTF as mesmas não sejam apresentadas.i SP0014RP 1.00. 7.P de Relat ório /* include de controle de versão */ {include/i-prgvrs.Construção de Programas utilizando os Estilos e suas Técnicas 167 do modelo RTF que vai ser utilizado. Ship-Date Order. LIKE customer.cust-num LIKE salesrep.Carrier WITH FRAME f-order DOWN STREAM-IO.Promise-Date Order. /* recebimento de parâmetros */ DEFINE INPUT PARAMETER raw-param AS RAW NO-UNDO. RAW-TRANSFER raw-param TO tt-param. /* include padrão para variáveis de relatório {include/i-rpvar.Sales-Rep Order. CREATE tt-param.Order-Date Order.Cust-Num Order.i} /* definição de variáveis DEFINE VARIABLE h-acomp */ AS HANDLE NO-UNDO. DEFINE INPUT PARAMETER TABLE FOR tt-raw-digita.FIELD fim-cust-num página seleção */ FIELD sales-rep página parâmetros */ . .Order-num Order. */ /* definição de frames do relatório */ FORM /* usar ordenado por order-num */ Order.sales-rep /* campo /* campo DEFINE TEMP-TABLE tt-raw-digita NO-UNDO FIELD raw-digita AS RAW. i &STREAM="stream str-rp"} /* include com a definição da frame de cabeçalho e rodapé */ {include/i-rpcab.l-habilitaRTF <> YES THEN DO: VIEW STREAM str-rp FRAME f-cabec. END.i &STREAM="str-rp"} /* bloco principal do programa */ ASSIGN c-programa c-versao c-revisao c-empresa c-sistema c-titulo-relat = "SP0014RP" = "1.Construção de Programas utilizando os Estilos e suas Técnicas 169 FORM /* usar ordenado por cust-num */ Order.00" = ". . /* para não visualizar cabeçalho/rodapé em saída RTF */ IF tt-param.Carrier WITH FRAME f-customer DOWN stream-io.Order-Date Order.Cust-Num Order. VIEW STREAM str-rp FRAME f-rodape.Order-num Order.000" = "Empresa Teste" = "Sports" = "Listagem Order".Ship-Date Order.Promise-Date Order.00.Sales-Rep Order. /* include padrão para output de relatórios */ {include/i-rpout. /* corpo do relatório */ IF tt-param. {utp/ut-liter. DOWN STREAM str-rp WITH FRAME f-order.sales-rep = tt-param.ini-cust-num AND order. LEAVE: RUN pi-acompanhar IN h-acomp (INPUT STRING(order.ordernum)).cust-num >= tt-param.cust-num <= tt-param.Cust-Num Order.cust-num >= tt-param. END.classifica = 1 THEN DO: FOR EACH order WHERE order.Ship-Date Order./* executando de forma persistente o utilitário de acompanhamento */ RUN utp/ut-acomp.Promise-Date Order.i Imprimindo *} RUN pi-inicializar IN h-acomp (INPUT RETURN-VALUE).Order-num Order.ini-cust-num AND .sales-rep AND order.Order-Date Order. DISPLAY STREAM str-rp Order.fim-cust-num NO-LOCK ON STOP UNDO.p PERSISTENT SET h-acomp. END.sales-rep AND order. ELSE DO: FOR EACH order WHERE order.Sales-Rep Order.Carrier WITH FRAME f-order.sales-rep = tt-param. Sales-Rep Order.fim-cust-num NO-LOCK BY order. END. DISPLAY STREAM str-rp Order.Ship-Date Order. . A esta lista de programas é dado o nome de JOB (tarefa).Construção de Programas utilizando os Estilos e suas Técnicas 171 order. END.Order-num Order. foi desenvolvido com o objetivo de agilizar a execução periódica de listas de programas construídos através da template de relatório onde.ordernum)). que se encontra no menu de Tecnologia.Cust-Num Order. RETURN "OK":U.i &STREAM="stream str-rp"} RUN pi-finalizar IN h-acomp.cust-num ON STOP UNDO.Order-Date Order.Promise-Date Order. LEAVE: RUN pi-acompanhar IN h-acomp (INPUT STRING(order. alguns parâmetros devem ser alterados (geralmente datas). Preparando o Relatório para Execução no Módulo JOB EXECUTION Este módulo. DOWN STREAM str-rp WITH FRAME f-customer. /*fechamento do output do relatório*/ {include/i-rpclo.Carrier WITH FRAME f-customer.cust-num <= tt-param. a cada execução. classificação. Exemplos de parâmetros: Períodos para execução. destino (arquivo.Cadastro de Parâ metr os e Digit açõe s (JE01 01) Parâmetros Encontra-se no menu Manutenção do módulo Job Execution e seu objetivo é preparar os programas a serem utilizados em uma lista de disparo. ou quaisquer informações únicas em programas de outro tipo que serão armazenadas na tabela TT-PARAM para execução do mesmo. São as informações que constam nas pastas Seleção. intervalos diversos. Essa preparação consiste em se cadastrar os parâmetros e as digitações necessários para que sejam executados estes programas. Parâmetros e Impressão dos programas de relatórios. impressora). data e hora para execução e etc. nome de arquivo. . Classificação. será aberta a tela a seguir: Os campos da tela acima representam exatamente todas as características dos parâmetros do programa de relatório na temp-table tt-param. .Construção de Programas utilizando os Estilos e suas Técnicas 173 Cadastrando os Parâ metr os Clicando no botão Incluir ou Modificar. O preenchimento de todos os campos é obrigatório. como segue abaixo. no relatório Resumo de Ordens de Serviço. . 2 – Impressora” valor padrão a ser utilizado para o atributo e só poderá ser preenchido após ter sido informado o formato se o atributo “extent” estiver marcado. Somente programas que possuam a pasta digitações em sua execução normal deverão possuir digitações cadastradas.Seqüência: Campo: Tipo: Extent: Tamanho: Formato: Label: Ajuda: Val Default posição do que representa o parâmetro na temp-table tt-param código do atributo na temp-table tt-param tipo de dado do atributo na temp-table tt-param Indica. “Arquivo” e “Impressora”. que o atributo tem extent tamanho do extent (só pode ser informado se tiver sido marcado extent) formato do atributo da temp-table tt-param (deve respeitar os padrões Progress) label do atributo na temp-table tt-param texto de ajuda a ser apresentado ao usuário. o valor default será uma lista de valores separados por vírgulas Digitações São informações que podem ter n valores diferentes para a execução do programa. Cada ocorrência (linha) dessa digitação é chamada registro e sua quantidade é ilimitada. respectivamente. no campo Ajuda deveria ser escrito: “1 – Arquivo. na parte inferior da janela. quando assinalado. quando o cursor estiver posicionado sobre o atributo Importante: o conteúdo deve esclarecer a quem estiver utilizando o módulo qual valor o atributo precisa assumir. Por exemplo: Se o campo Destino pudesse ter os valores “1” e “2” os quais significassem. clique no botão registros e informe os valores default para cada campo em N registros.Construção de Programas utilizando os Estilos e suas Técnicas 175 Após cadastrados os campos de digitações. . . Encontra-se no menu Tarefas do módulo Job Execution e nessa opção fazemos a exportação dos parâmetros e digitações do programa que foi preparado para ser executado neste módulo. pois muitas vezes o nome do campo não expressa em detalhes o significado correto do mesmo.Consideraçõe s sobr eo cada stra ment Exportação o de JOB camp Exec os ution (JE01 04) Deve sempre ser observada o label e o valor default utilizada na tela do programa original. através do devido cadastramento de seus parâmetros e digitações. Os nomes dos arquivos serão os mesmos dos programas.: Para o programa ap0707rp.jep (parâmetros).A. localizado no diretório DOCPDF/DTSUL. os mesmos deverão ser gravados no Roundtable para que sejam expedidos normalmente pelo produto e importados na base do cliente para sua utilização no módulo JOB EXECUTION.JEP (parâmetros) dos programas. basta informar o nome do diretório onde serão gerados os arquivos .) ou para clientes que tiverem adquirido o produto. Para maiores informações referentes ao produto. selecione a pasta Lay-out.JED (digitações) e . Observação O módulo JOB EXECUTION somente estará disponível para uso interno (Datasul S.Construção de Programas utilizando os Estilos e suas Técnicas 177 Para fazer a exportação. o intervalo dos programas a serem gerados e clicar em Executar.p será gerado o ap0707rp. Caso deseje consultar o lay-out do arquivo gerado.jed (digitações e ap0707. Nela encontram-se os lay-outs dos dois arquivos gerados: parâmetros e digitações. Após a geração destes arquivos. Ex. deverá ser consultado o manual do produto. . verificar se já existe uma SmartQuery para a tabela que se deseja construir o programa de Parâmetros Únicos. instanciar a SmartQuery na página 1 da SmartWindow. devem ser criados SmartLinks de GROUP-ASSIGN. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. tendo como Source a SmartViewer da página 1 e como a Target a SmartViewer corrente. ou possua trigger de "ENTRY". criar uma nova utilizando o estilo CustomViewer com Auto-Field. Caso não exista.w Implementaç • ão • selecionar o estilo relacionado na tabela acima. • • instanciar esta e outras SmartViewers a partir da página 1 no folder e aceitar a sugestão de SmartLink do Wizard. • • Observação Para os campos do tipo fill-in’s. deve ser efetuado o registro para o WebEnabler. • . if not avail <tabela> then do: run notify in this-procedure ('add-record':U).Como construir um programa de Parâmetros Únicos Estilo Utilizado ' Window Parâmetros Únicos Nome Físico Masters/w-paruni. Caso não exista. verificar se já existe uma SmartViewer com os atributos que devem ser editados. inserir a seguinte lógica após o run-dispatch da local-initialize da SmartWindow: find first <tabela> no-lock no-error. Portanto não é necessário efetuar o registro para esses fill-ins. se existirem mais de uma SmartViewer. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. criar uma nova utilizando o estilo CustomQuery Wizard. ou que possuírem um botão de zoom na sua direita. Caso o fill-in se encaixe em uma das opções acima. end. criar um SmartLink do tipo STATE.Construção de Programas utilizando os Estilos e suas Técnicas 179 else run new-state('update-begin':U). verificar se já existe uma SmartQuery para a tabela que se deseja construir o programa de Formação. eles devem ser criados. criar uma nova SmartViewer utilizando o estilo CustomViewer com Auto-Field.w Implementaç • ão • selecionar o estilo relacionado na tabela acima. Caso não existam. run dispatch in this procedure ('enable-fields'). tendo como Source: p-navega e como Target: SmartQuery. Caso não exista. instanciar a SmartQuery na página 0 da SmartWindow e aceitar as sugestões de SmartLink do Wizard. salvar a SmartWindow com o nome definido para o programa de Parâmetros Únicos. criar uma nova utilizando o estilo CustomQuery Wizard. • • • criar um SmartLink de TABLEIO. criar um SmartLink do tipo STATE. Caso não exista. verificar se já existe uma SmartViewer com os atributos da tabela que devem ser pesquisados. Como construir um programa de Formação Estilo Utilizado ' Window Formação Nome Físico Masters/w-forma. tendo como Source THISPROCEDURE e como Target a SmartViewer da página1. redimensionar o Folder e a SmartWindow de acordo com os objetos nela instanciados. verificar se já existe um programa de Vá para e um programa de pesquisa para a tabela que se deseja construir um programa de formação. acessar os atributos de instância da SmartQuery e informar no atributo "Programa Pesquisa" o nome do programa de pesquisa da tabela e no atributo "Programa Vá Para" o nome do programa de Vá para da tabela. tendo como Source: p-exihel e como Target: SmartQuery. • • • • • • . deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita.Observação Para os campos do tipo fill-in’s. criar um novo utilizando o estilo CustomBrowser Formação. • deve ser criada uma trigger de MOUSE-SELECT-DOUBLECLICK e inserido o seguinte código: RUN NEW-STATE(INPUT 'incluir-browse':U). deve ser efetuado o registro para o WebEnabler. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. tendo como Source: o SmartBrowser fonte e como Target: THIS-PROCEDURE. ou possua trigger de "ENTRY". devem ser observados os seguintes aspectos: • deve ser definida como tabela externa. na construção desse SmartBrowser. ou que possuírem um botão de zoom na sua direita. ele deve ser redimensionado. criar um novo utilizando o estilo CustomBrowser Wizard. • retirar os comentários da Procedure PI-ADD-BROWSE e substituir pelos dados a seguir: <tabela-1>: nome da tabela que está sendo realizada a navegação <tabela-2>: nome da tabela do SmartBrowser fonte <tabela-formação>: nome da tabela do SmartBrowser formação . de modo que caiba no lado esquerdo dos botões bt-add e bt-del da window formação. deve ser observado o seguinte: • como exceção à regra. Caso não exista. verificar se já existe um SmartBrowser que contenha os dados que servem de fonte para o SmartBrowser de Formação. Portanto não é necessário efetuar o registro para esses fill-ins. • • • • instanciar o SmartBrowser que serve de fonte para o SmartBrowser de Formação no lado esquerdo da página 0 da SmartWindow. verificar se já existe um SmartBrowser com a tabela de formação. a tabela utilizada na SmartQuery do programa de Formação. criar um SmartLink do tipo STATE. Caso o fill-in se encaixe em uma das opções acima. • • instanciar a SmartViewer na página 0 da SmartWindow. Caso não exista. na construção desse SmartBrowser. O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. IF AVAIL (<tabela-formação>) THEN DO: DELETE (<tabela-formação>). tendo como Source: SmartBrowser formação e como Target: THIS-PROCEDURE. FIND <tabela-formação> WHERE ROWID (<tabela-formação>) = V-ROW no-error. RUN DISPATCH IN THIS-PROCEDURE (INPUT 'openquery':U).order-num + 1. def var i-next-line-num as integer no-undo.order-num = order.order-num = order. • inserir o seguinte código na trigger de MOUSE-SELECTCLICK: RUN PI-POSICAO-BROWSE IN THIS-PROCEDURE (OUTPUT vrow). find last order-line where order-line. acessar os atributos de instância do SmartBrowser de formação e informar no atributo "Programa Atributo" o nome do programa de modificação dos .line-num = i-next-line-num. criar um SmartLink do tipo STATE. create order-line.Construção de Programas utilizando os Estilos e suas Técnicas 181 <campo-1>: campo da <tabela-1> que deve constituir parte da chave da tabela de formação <campo-2>: campo da <tabela-2> que deve constituir parte da chave da tabela de formação • Exemplo se for necessário. find order where rowid(order) = rw-row-1 no-lock. find item where rowid(item) = rw-row-2 no-lock.order-num order-line. • • • instanciar o SmartBrowser de formação no lado direito da página 0 da SmartWindow. END. def input parameter rw-row-2 as rowid no-undo.item-num order-line. if avail order-line then assign i-next-line-num = order-line. assign order-line. def input parameter rw-row-1 as rowid no-undo.item-num = item. ajustar a lógica da Procedure PI-ADD-BROWSE de modo que atenda as necessidades do programa. else assign i-next-1 line num = 1.order-num no-lock no-error. Para criar este programa de modificação. salvar a SmartWindow com o nome definido para a Consulta Relacionamento.atributos do registro de formação. deve ser utilizado o estilo Window Inclui/Modifica Filho. • na procedure STATE-CHANGED da SmartWindow e na trigger do botão "INCLUIR(>)". retirar os comentários e substituir pelos dados a seguir: <h_browse>: handle do SmartBrowser de formação <tabela-formação>: nome da tabela de formação • redimensionar a SmartWindow de acordo com os objetos que foram colocados na tela. retirar os comentários e substituir pelos dados a seguir: <h_query>: handle da SmartQuery <h_browse>: handle do SmartBrowser fonte do SmartBrowser de formação <h_browse-formação>: handle do SmartBrowser de formação • na trigger do botão de "RETORNO(<)". • . Ter o cuidado para que a SmartViewer fique centralizada na SmartWindow. O botão "Formação" deve chamar o estilo de Formação sem Navegação. deve sempre ser chamado a partir de um CustomBrowser Formação Filho. o template utilizado para construção deste tipo de programa não utiliza SmartObjects.w Implementaç • ão • • estilo de formação sem navegação é dependente. identifique que tabelas servem como: Pai. Destino. jamais eliminar um "include" padrão mesmo que ele não possua nenhum conteúdo/lógica. Origem. ou seja. • seguir sempre a seqüência descrita neste documento pois a ordem em que as tarefas são executadas podem afetar o resultado da construção do programa (por exemplo.Construção de Programas utilizando os Estilos e suas Técnicas 183 Lista de Links: Source ' h_browseformação h_p-exihel h_p-navega h_p-navega h_query h_query THIS PROCEDURE Link Type STATE STATE NAVIGATION STATE RECORD RECORD STATE Target THIS-PROCEDURE h_query h_query h_query h_viewer h_browse-formação h_browse-fonte Como construir um programa de Formação sem Navegação Estilo Utilizado ' Window Formação sem Navegação Nome Físico Masters/w-form2. os campos da tabela pai não podem jamais ser a primeira coisa a ser colocada na tela. bem como a consulta da tabela destino deve ser feita após definirmos a consulta da tabela origem). Objetos do programa: • . Criar browse origem: • • definir query. 3. • definir query (relacionando esta com a tabela pai) para a temptable. 5. . definir campos para display. 2. Colocar campos da tabela pai. 4. Preencher pré-processor da seção de definições com o nome da tabela pai. portanto esta deve ser uma freeform query. Criar browse destino: • • criar uma temp-table (na seção definitions): colocar nesta temp-table os atributos da tabela destino. • definir campos para display. Acrescentar dentro da procedure local-initialize lógica para carregar a temp-table com os registros que já existem na tabela de destino.Seqüência 1. através da função is-create-allowed.realiza o create e o assign no browse destino (temp-table).lê os registros selecionados e para cada um deles executa regras de negócio que verificam se a eliminação é permitida (através da função is-delete-allowed) e realiza a eliminação quando permitida pela função através da procedure pidelete-from-target (elimina da temp-table). na cláusula Options.lê os registros selecionados verifica se o registro pode ser incluído.valida se o registro não existe ainda no browse destino.Construção de Programas utilizando os Estilos e suas Técnicas 185 6. • criar eliminação do browse destino: • Procedure pi-del . • criar inclusão no browse destino: • Procedure pi-ins . • Procedure pi-add-to-target . e caso a inclusão seja permitida executa a procedure pi-add-totarget. • criar uma procedure interna (pi-commit) que transfira os registros da temp-table para a tabela de destino. atentando para o seguinte: • • • • deve ser informada a tabela externa. esta procedure é chamada pelo evento choose do botão 'Ok': Como construir um Browse Formação Filho Estilo Utilizado ' CustomBrowser Formação Filho Nome Físico Masters/wbrwfrm. ou realiza outras regras de negócio que verificam se a inclusão é valida retorna um status que indica o resultado dos testes. desmarcar as opções Key-Phrase e SortBy-Phrase. . deve-se fazer as seguintes alterações: modificar na coluna Returned de All Fields para Fields Used.w Implementaç • ão utilizar o wizard. • Função is-create-allowed . Criar funções e procedures internas: • criar função para mostrar o registro da tabela pai (pi-showmaster-record). na opção. através da opção 'Rejeitados'.w). que apresenta um browse com os objetos do programa. 'Todos' ou imprimir somente os registros que apresentaram erro. • • . acionar o botão 'TO TOP'. • também. existem duas streams abertas. Exceções: list-items do widget combo-box. deve-se marcar a opção Indexed-Reposition. Botão List Objects.• o index-reposition deve ser sempre setado. todo trabalho de tradução de labels. Para tanto. neste estilo. helps. que é uma variação do estilo de relatórios. portanto sem SmartViewer e SmartFolders. Como construir um programa de Importação Para a construção de programas de importação deve-se utilizar o estilo Window Importação/Exportação (w-impor. screenvalues deve ser feito automaticamente por um include padrão do estilo. Botão To Top. uma para importação dos dados e outra para impressão do log. o log de importação pode ser completo. durante a importação. na cláusula Table. • salvar o CustomBrowse com o nome definido para Browse de Formação Filho. então sobre o frame relacionado à página. Dicas Gerais • tabela de para de folder/páginas e com objetos relacionados: PáginaFolder ' Layout Seleção Parâmetr os Log Frame f-pg-lay f-pg-sel f-pg-par f-pg-log Imagem im-pg-lay im-pg-sel im-pg-par im-pg-log Preprocess ador PGLAY PGSEL PGPAR PGLOG • para selecionar uma página para trabalhar utilizar o botão 'List-Objects'. onde o programa deve apresentar inicialmente. Em 'Definitions' limpar o conteúdo dos preprocessadores PGSEL &GLOBAL-DEFINE &GLOBAL-DEFINE &GLOBAL-DEFINE &GLOBAL-DEFINE PGLAY f-pg-lay PGSEL PGPAR f-pg-par PGLOG f-pg-log 5. A sugestão é criá-los como 'Database Fields' e após convertê-los para variáveis para obter automaticamente os labels. Exemplo: { include/i-imvrf.i}. 2. 3 e 4. . Corrigir os 'initial values' das variáveis de inicial e final. passando como parâmetro posicional a imagem da página. que possue dois parâmetros. Colocar os fill-in´s de inicial e final. Este arquivo tem o seguinte nome e path: LAYOUT/LOXX9999.i &programa=CP0406 &versãolayout=001 } Criar um arquivo que contenha o layout de importação. 3. as páginas de layout. 2.i. No 'Main Block'. 2. Eliminar a frame f-pg-sel. corrigir a chamada do include i-immbl. Eliminar a imagens im-pg-log e renomear as imagens: im-pg-par > im-pg-log im-pg-sel > im-pg-par 4. caso haja seleção desconsiderar as tarefas 2. somente a página de seleção é opcional.001. parâmetros e log são obrigatórias. Verificar quantas páginas são necessárias. formatos e tamanhos do dicionário de dados.Construção de Programas utilizando os Estilos e suas Técnicas 187 Preparação do programa 1. Se a página de seleção não existir. nos padrões do Produto Datasul-EMS. Página de Seleção 1. para cada campo que precisar de faixa. informar neste o nome do programa no formato XX9999 e a versão do layout no formato 999 (o valor inicial da versão é 001). existe a chamada para um include denominado {include/i-imvrf. exemplo: {include/i-immbl. no 'Main-block' do programa.i im-pg-par} Página de Layout 1. input " "). . Gravação e validação dos parâmetros 1.p (input "show". posicionar na página com problemas. end. apply 'entry' to i-nr-nivel in frame f-pg-par. implementar os campos de parâmetros e seleção na definição da temp-table tt-param. apply 'mouse-select-click' to im-pg-par in frame f-relat. Colocar as variáveis necessárias na representação desejada (radio-set. fill-in). Caso seja necessário implementar retângulos com label. definindo label. e o seu valor deve ser informado no seu initial e private-data. Na procedure 'pi-executar'. Exemplo DO: {include/i-imarq.xls' . Retirar possíveis queries que o UIB automaticamente queira associar a frame. estes labels devem ser fill-in´s view-as text. return error. initial e help para as mesmas. Página de Log Não existem tarefas. onde é possível passar como parâmetro os filtros que serão utilizados na sistem dialog.*'" } END. formato. colocando o focus no campo com problemas. Pagina de Parâmetros 1. input 73. Em 'Definitions'. 2. 'todos' '*. 2. Exemplo if input frame f-pg-par i-nr-nivel > 19 then do: run utp/ut-msgs.i . No on choose do bt-arquivo-entrada.i c-arquivo-entrada f-pg-par "'*. lembrando que elas devem apresentar uma mensagem de erro cadastrada. toggle-box. colocar as das páginas de parâmetros e seleção. se não for passado nada neste parâmetro a include assumira como padrão o tipo de arquivo *.3.XLS' '*. pode ser adicionado um terceiro parâmetro na include i-imarq.lst e todos os tipos de arquivos. As propriedades 'Display' e 'Enable' devem ser retiradas 3. Todas as validações ou informações com necessidade de intervenção do usuário devem ser tratadas pelo programa .i} e substituir as seguintes chamadas. Da mesma forma.Construção de Programas utilizando os Estilos e suas Técnicas 189 3. referentes a impressão do log de importação: Include Velho ' Cdp\cd950 0. exceto pela caixa de acompanhamento de execução (ut-acomp/ut-perc) quando necessário. Se a implementação for uma conversão de um programa originário do MAGNUS.i &stream = "str-rp"} .p não deve possuir qualquer tipo de interface.i.i Include Novo Include\i-rpvar. Substituir as variáveis de parâmetros e seleção pelos respectivos campos da temp-table tt-param.i Include\i-rpclo. 3.P de Importação O programa de execução do relatório (rp. 4. i-rpc256. substituir na chamada do include {include/i-imrun.P' pelo programa que deve importará os registros.i. 2. Definir uma stream para a importação. Dicas para criação do Programa RP.i Cdp\cd950 0. para impressão do log. i-rpout.fl Cdp\cd952 0.i 2.i. i-rpcb80. retirar a chamada para o include {cdp/cd9000. Na procedure 'pi-executar'. Utilizar um stream padrão definido como STR-RP.i Include\i-rpcab. 1.i &stream = "str-rp"} {include/i-rpc256. colocar a lógica de gravação dos parâmetros e seleção na temp-table tt-param.i Include\i-rpout.1.i &stream = "str-rp"} {include/i-rpcb80. nenhum programa chamado a partir de um rp. Ainda na procedure 'pi-executar'.i Cdp\cd954 0.i} a literal 'XXP/XX9999RP. Exemplo {include/i-rpcab.p) é um programa procedural sem qualquer tipo de interface com o usuário.w que o chama. deixando a stream padrão definido como STR-RP para a impressão do log.i e i-rpclo. deve-se passar o parâmetro &stream com o nome da stream para os includes i-rpcab. Em todos os forms/frames de impressão deve-se colocar a cláusula streamio. {utp/ut-field. raw-transfer.00.i &stream = "stream str-rp"}. para dar idéia de faixa.00. passar o parâmetros {&tofile}. substituí-la pelos caracteres "|< >|" semelhantes as imagens utilizadas na tela de seleção.i.i}. ao invés de utilizar a palavra "à". 4. 7.i} ou ainda {utp/ut-table. Exemplo: {include/i-rpout. Todos os labels que não forem do dicionário de dados e que apareçam no log devem ser tratados através dos includes {utp/ut-liter.i XX9999RP 1.000} /* definição das temp-tables para recebimento de parâmetros */ define temp-table tt-param field destino as field arq-destino as field arq-entrada as field todos as field usuario as field data-exec as field hora-exec as field cust-ini as field cust-fim as integer char char integer char date integer integer integer def temp-table tt-raw-digita field raw-digita as raw. Nas seleções.arq-destino} 5. e que não necessitam ser traduzidos.i}. /* recebimento de parâmetros */ def input parameter raw-param as raw no-undo. 6.raw-param to tt-param.i &stream = "stream str-rp"} {include/i-rpclo. def input parameter tabel for tt-raw-digita.P de Impo rtaçã o /* include de controle de versão */ {include/i-prgvrs.i &tofile=tt-param. Exemplo de um progr ama RP. Na chamada do include i-rpout.i} /* definição de variáveis e streams */ */ .{include/i-rpout. /* include padrão para variáveis para o log {include/i-rpvar. create tt-param. "XX0006RP" "1.cust-num = i-cust no-lock.5)).Construção de Programas utilizando os Estilos e suas Técnicas 191 def def def def stream s-imp.000" "Empresa Teste" 'Sports' = "Listagem de Erros da Importação de view stream str-rp frame f-cabec. run utp/ut-acomp. if not avail customer then do: create customer.i &STREAM="str-rp"} /* bloco principal do programa */ assign c-programa = c-versao = c-revisao = c-empresa = c-sistema = c-titulo-relat Clientes". assign customer. assign i-cust = integer(substring(c-linha.cust-num = i-cust customer. end. var i-cust as int no-undo.p persistent set h-acomp. {utp/ut-liter. . leave: import stream s-imp unformatted c-linha. view stream str-rp frame f-rodape. var h-acomp as handle no-undo.arqdestino} /* include com a definição da frame de cabeçalho e rodapé */ {include/i-rpcab.00" ". find customer where customer. /* bloco principal do programa */ repeat on stop undo. input stream s-imp close.i Importando *} run pi-inicializar in h-acomp (input RETURN-VALUE).00. /* define o arquivo de entrada informando na página de parâmetros */ input stream s-imp from value(tt-param.arq-entrada).1. run pi-acompanhar in h-acomp (input c-linha). /* definição de frames do log */ /* include padrão para output de log */ {include/i-rpout. var c-linha as char no-undo.name = substring(c-linha. end.5).i &STREAM="stream str-rp" &TOFILE=tt-param. então sobre o frame relacionado à página. Botão To Top. existem duas streams abertas. return "Ok":U. somente a página de seleção é opcional. acionar o botão 'TO TOP'. Verificar quantas páginas são necessárias. que apresenta um browse com os objetos do programa. • Preparação do programa 1./* fechamento do output do log */ {include/i-rpclo. parâmetros e log são obrigatórias. • também. neste estilo. que é uma variação do estilo de relatórios. todo trabalho de tradução de labels. durante a exportação. helps. as páginas de layout. Dicas Gerais • tabela de para de folder/páginas e com objetos relacionados: PáginaFolder ' Layout Seleção Parâmetr os Log Frame f-pg-lay f-pg-sel f-pg-par f-pg-log Imagem im-pg-lay im-pg-sel im-pg-par im-pg-log Preprocess ador PGLAY PGSEL PGPAR PGLOG • para selecionar uma página para trabalhar utilizar o botão 'List-Objects'.w). 3 e 4.i &STREAM="stream str-rp"} run pi-finalizar in h-acomp. Como construir um programa de Exportação Para a construção de programas de exportação deve-se utilizar o estilo Window Importação/Exportação (w-impor. Exceções: list-items do widget combo-box. uma para exportação dos dados e outra para impressão do log. Botão List Objects. . portanto sem SmartViewers e SmartFolders. caso haja seleção desconsiderar as tarefas 2. screenvalues deve ser feito automaticamente por um include padrão do estilo. Exemplo: { include/i-imvrf. no 'Main-block' do programa. . 2.001. nos padrões do Produto Datasul-EMS. Este arquivo tem o seguinte nome e path: LAYOUT/LOXX9999. informar neste o nome do programa no formato XX9999 e a versão do layout no formato 999 (o valor inicial da versão é 001). Eliminar a frame f-pg-sel. Corrigir os 'initial values' das variáveis de inicial e final. No 'Main Block'. Eliminar a imagens im-pg-log e renomear as imagens: im-pg-par > im-pg-log im-pg-sel > im-pg-par 4.i}. para cada campo que precisar de faixa. que possue dois parâmetros. Página de Seleção 1. onde o programa deve apresentar inicialmente. Se a página de seleção não existir.i &programa=CP0406 &versãolayout=001 } 2. Em 'Definitions' limpar o conteúdo dos preprocessadores PGSEL &GLOBAL-DEFINE &GLOBAL-DEFINE &GLOBAL-DEFINE &GLOBAL-DEFINE PGLAY f-pg-lay PGSEL PGPAR f-pg-par PGLOG f-pg-log 5. 3. corrigir a chamada do include i-immbl. Criar um arquivo que contenha o layout de importação. Colocar os fill-in´s de inicial e final. exemplo: {include/i-immbl. 3. formatos e tamanhos do dicionário de dados. passando como parâmetro posicional a imagem da página. A sugestão é criá-los como 'Database Fields' e após convertê-los para variáveis para obter automaticamente os labels.Construção de Programas utilizando os Estilos e suas Técnicas 193 2.i im-pg-par} Página de Layout 1. existe a chamada para um include denominado {include/i-imvrf.i. Página de Parâmetros 1. No on choose do bt-arquivo-entrada. . pode ser adicionado um terceiro parâmetro na include i-imarq. 4. Não esquecer do botão "Configurar Impressora". As propriedades 'Display' e 'Enable' devem ser retiradas. onde é possível passar como parâmetro os filtros que serão utilizados na sistem dialog. Colocar as variáveis necessárias na representação desejada (radio-set.i . e o seu valor deve ser informado no seu initial e private-data. 'todos' '*. toggle-box. estes labels devem ser fill-in´s view-as text. fill-in).3. Retirar possíveis queries que o UIB automaticamente queira associar a frame.xls' . 2.lst e todos os tipos de arquivos.XLS' '*. Eliminar o campo todos da temp-table tt-param. Exemplo DO: {include/i-imarq. 3. se não for passado nada neste parâmetro a include assumira como padrão o tipo de arquivo *. Gravação e validação dos parâmetros 1. Remover o retângulo.*'" } END. definindo label. Mover todos os outros objetos desta frame para cima. Em 'Definitions'. implementar os campos de parâmetros e seleção na definição da temp-table tt-param. 2.i c-arquivo-entrada f-pg-par "'*. formato. 2. initial e help para as mesmas. Caso seja necessário implementar retângulos com label. Mudar o private-data e o initial do label "Arquivo de Entrada" do retângulo para "Arquivo de Saída". o label e o radio-set com as opções "Todos" e "Rejeitados". Página de Log 1. lembrando que elas devem apresentar uma mensagem de erro cadastrada. end. return error. Na procedure 'pi-executar'. return error. end. colocar a lógica de gravação dos parâmetros e seleção na temp-table tt-param. input c-arquivo-entrada). apply 'entry' to c-arquivo-entrada in frame f-pg-par. apply 'mouse-select-click' to im-pg-log in frame fimport.p (input "show". input 73.p (input "show". substituir o código de validação do arquivo de entrada: assign file-info: file-name = input frame f-pg-par c-arquivoentrada. substituir na chamada do include {include/i-imrun. if file-info:pathname = ? then do: run utp/ut-msgs. 4. Ainda na procedure 'pi-executar'. colocar as validações das páginas de parâmetros e seleção. end. 6. Na procedure 'pi-executar'. input " ").i} a literal 'XXP/XX9999RP. if return-value = "nok" then do: run utp/ut-msgs. apply 'mouse-select-click' to im-pg-par in frame f-relat. Na procedure 'pi-executar'. apply 'entry' to c-arquivo-destino in frame f-pg-log. posicionar na página com problemas. por: run utp/ut-vlarq. return error.Construção de Programas utilizando os Estilos e suas Técnicas 195 3. input 326. input 73. apply 'entry' to i-nr-nivel in frame f-pg-par. apply 'mouse-select-click' to im-pg-par in frame f-import.p (input "show". . input "").P' pelo programa que exportará os registros. Exemplo if input frame f-pg-par i-nr-nivel > 19 then do: run utp/ut-msgs. colocando o focus no campo com problemas. 5.p (input frame f-pg-par c-arquivo-entrada). Dicas para criação do Programa RP. i-rpcb80.i &stream = "str-rp"} {include/i-rpout.i &stream = "str-rp"} {include/i-rpcb80. 1.P de Exportação O programa de execução da exportação (rp.i Include\i-rpout.i &stream = "stream str-rp"}. i-rpc256.i &stream = "stream str-rp" &tofile=ttparam. 2. i-rpout. Definir uma stream para a importação. Exemplo {include/i-rpcab. 4. deixando a stream padrão definido como STR-RP para a impressão do log.i} e substituir as seguintes chamadas.i.arq-destino} .i Cdp\cd954 0. Exemplo: {include/i-rpout.i Include Novo Include\i-rpvar. nenhum programa chamado a partir de um rp.i Cdp\cd950 0. Na chamada do include i-rpout.fl Cdp\cd952 0. deve-se passar o parâmetro &stream com o nome da stream para os includes i-rpcab.i &stream = "stream str-rp"} {include/i-rpclo. retirar a chamada para o include {cdp/cd9000.i.i 2. 3. passar o parâmetro {&tofile}. Utilizar um stream padrão definido como STR-RP.i e i-rpclo.p) é um programa procedural sem qualquer tipo de interface com o usuário.1 Substituir as variáveis de parâmetros e seleção pelos respectivos campos da temp-table tt-param. Todas as validações ou informações com necessidade de intervenção do usuário devem ser tratadas pelo programa .i.w que o chama. Da mesma forma. exceto pela caixa de acompanhamento de execução (ut-acomp/ut-perc) quando necessário.i &stream = "str-rp"} {include/i-rpc256.i Include\i-rpcab. referentes a impressão do log de exportação: Include Velho ' Cdp\cd950 0. Se a implementação for uma conversão de um programa originário do MAGNUS.i. para impressão do log.p não deve possuir qualquer tipo de interface.i Include\i-rpclo. 00. Exemplo de um progr ama RP.arqdestino} /* include com a definição da frame de cabeçalho e rodapé */ */ . ao invés de utilizar a palavra "à". para dar idéia de faixa.raw-param to tt-param. substituí-la pelos caracteres "|< >|" semelhantes as imagens utilizadas na tela de seleção.i} ou ainda {utp/ut-table. def var h-acomp as handle no-undo. raw-transfer.000} /* definição das temp-tables para recebimento de parâmetros */ define temp-table tt-param field destino as field arq-destino as field arq-entrada as field usuario as field data-exec as field hora-exec as integer char char char date integer def temp-table tt-raw-digita field raw-digita as raw. def input parameter tabel for tt-raw-digita.i}. 6.00.i}.i &STREAM="stream str-rp" &TOFILE=tt-param.P de Expo rtaçã o /* include de controle de versão */ {include/i-prgvrs. /* definição de frames do log */ /* include padrão para output de log */ {include/i-rpout. /* include padrão para variáveis para o log {include/i-rpvar.i} /* definição de variáveis e streams */ def stream s-exp. Todos os labels que não forem do dicionário de dados e que apareçam no log devem ser tratados através dos includes {utp/ut-liter. Em todos os forms/frames de impressão deve-se colocar a cláusula streamio. {utp/ut-field.i XX9999RP 1. /* recebimento de parâmetros */ def input parameter raw-param as raw no-undo. 7. e que não necessitam ser traduzidos. Nas seleções. create tt-param.Construção de Programas utilizando os Estilos e suas Técnicas 197 5. arq-entrada). /*fechamento do output do log */ {include/i-rpclo.00" ". output stream s-exp close. "99999") string(customer.i Exportando *} run pi-inicializar in h-acomp (input RETURN-VALUE).name. view stream str-rp frame f-rodape.{include/i-rpcab. end. /* define a saída para o arquivo de saída informando na página de parâmetros */ output stream s-exp from value(tt-param.i &STREAM="str-rp"} /* bloco principal do programa */ assign c-programa = c-versao = c-revisao = c-empresa = c-sistema = c-titulo-relat Clientes"."x(40)") skip. /* bloco principal do programa */ for each customer on stop undo. return "Ok":U. run utp/ut-acomp.p persistent set h-acomp. "XX0006RP" "1. Como construir um programa de Pesquisa Estilo utilizado Nome Físico .000" "Empresa Teste" 'Sports' = "Listagem de Erros da Exportação de view stream str-rp frame f-cabec.00.i &STREAM="stream str-rp"} run pi-finalizar in h-acomp.cust.custnum)). put stream s-exp unformatted string(customer. leave: run pi-acompanhar in h-acomp (input string(customer. {utp/ut-liter. criar um novo utilizando o estilo CustomBrowserZoom Wizard. onde a ordem das colunas no browser deve ser a ordem de classificação. tendo como Source o SmartBrowser recém instanciado e como Target. para todos os SmartBrowsers que devem estar colocados no programa de Pesquisa. • criar um SmartLink do tipo STATE. Caso não exista.Construção de Programas utilizando os Estilos e suas Técnicas 199 ' Window Pesquisa Masters/w-pesqui. é necessário utilizar um SmartBrowser para cada classificação do programa de Pesquisa. • instanciar o SmartBrowser no SmartFolder. THISPROCEDURE.w Implementaç • ão • selecionar o estilo relacionado na tabela acima. • recomenda-se que cada SmartBrowser das diferentes páginas do SmartFolder tenha o mesmo tamanho. seguir os seguintes passos: • verificar se já existe um SmartBrowser com os dados necessários para a pesquisa e se eles devem estar na mesma ordem da classificação desejada. . • • • redimensionar o SmartFolder e a SmartWindow de acordo com os objetos nela instanciados; alterar os labels das páginas dos folders através do Instance Atributes; salvar a SmartWindow com o nome definido para o programa pesquisa. Source ' h_browse h_folder Link Type STATE PAGE Target THIS-PROCEDURE THIS-PROCEDURE Como construir um programa "Vá Para" Estilo Utilizado ' Dialog VaPara Nome Físico Masters/d-vapara.w Implementaç • ão • em New, selecionar o template acima; escolher a tabela que o programa deverá consultar; • Escolher os campos que devem existir na tela do Vá para: Construção de Programas utilizando os Estilos e suas Técnicas 201 • • Ajustar os campos na tela; salvar o SmartDialog com o nome definido para o programa "Vá Para". Observação O template irá gerar automáticamente a TRIGGER GO da janela que faz todo o tratamento necessário para o programa Sugestão Para que os campos sejam exibidos no tamanho adequado (altura 0.88) você deve alterar as seguintes propriedades: 1. No AppBuilder Acessar Options - Preferences 2. Selecionar o folder Grid Units 3. Alterar a opção Layout Units para Pixel 4. Preencher os campos com valor 1 Ou alterar o tamanho dos campos manualmente. Como construir um programa de Digitação Rápida Estilo Utilizado ' Window Digitação Rápida Nome Físico Masters/w-digit.w Implementaç • ão • selecionar o estilo relacionado na tabela acima; verificar se já existe uma CustomViewerDigita que atenda as necessidades, caso não exista, deve ser criada uma nova, utilizando o estilo CustomViewerDigita, lembrando-se que a única condição para esta viewer é a utilização de variáveis, e não a utilização de DBFields; • • instanciar a CustomViewerDigita na página 1 da WindowDigitaçãoRápida; verificar se já existe um CustomBrowserDigita que atenda as necessidades, caso não exista, deve ser criado um novo, utilizando o estilo CustomBrowserDigita. Este browser deve utilizar uma temp-table; instanciar o CustomBrowserDigita na página 2 da WindowDigitaçãoRápida; redimensionar a WindowDigitaçãoRápida de acordo com os objetos que foram colocados nela; salvar a WindowDigitaçãoRápida com o nome definido para Janela Digitação Rápida; Estilo Utilizado ' CustomBrowserDi gita Nome Físico Masters/b-digit.w • • • Como construir um Browse de Digitação Implementaç • ão • • • selecionar o estilo relacionado na tabela acima; alterar a definição da temp-table no bloco de definitions conforme necessidade. Não eliminar o campo "line"; alterar a trigger de open_query, substituindo a cláusula <temp-table> pelo nome da temp-table definida anteriormente; alterar a trigger de display, substituindo as cláusulas <campo1> <campo2> pelos campos que devem estar no browse; após o comando enable substituir as cláusulas <campo1> <campo2> pelos campos editáveis do browse; alterar a pi-salva-rel para que esta possa gravar todos os valores do browse. Não é necessário gravar o campo "line"; na chamada da pi-buscavalor, conforme instruções na pi, informar o nome das variáveis que estão na viewer e que se deseja retornar o valor destas para o browse, os valores serão retornados por intermédio do comando return-value, a lista retornada será gravada numa variável e o usuário deve utilizar esta variável e o comando ENTRY para trabalhar com estes valores; • Construção de Programas utilizando os Estilos e suas Técnicas 203 • • colocar todas as validações na pi-salva-rel, validando assim os valores informados no browse a cada inclusão de um novo registro no browse; na pi-cria-registro deve ser feita a leitura dos registros da temp-table e criados os registros na tabela física. Esta pi é chamada no choose bo botão OK; salvar o browse com o nome definido para Browse de Digitação Rápida. • Como construir uma Query Estilo Utilizado ' Custom Query Wizard Nome Físico Masters/wquery.w Implementaç • ão em Arquivo | Novo, selecionar o estilo relacionado acima; • seguir os passos indicados pelo Wizard atentando para que, se a viewer não contiver cláusula where, em query definitions seja assinalado o toggle box Index Reposition; Como construir viewers Estilo Utilizado ' Custom Viewer com AutoField Nome Físico Masters/vieweraf.w Implementaç • ão • em Arquivo | Novo, selecionar o estilo citado acima; de acordo com os objetos a serem instanciados na viewer, seguir a técnica correspondente: • • • Padrão; Sem campos de tabela; Só com campos chave; Como definir viewer Padrão Viewer Padrão é aquela que possui ao menos um campo não chave de tabela. É necessário para uma Viewer Padrão, possuir ao menos um campo de tabela habilitado, esse campo não pode ser chave de tabela. Construção de Programas utilizando os Estilos e suas Técnicas 205 • • • • na dialog que se abrirá logo após a seleção do template, selecionar a(s) tabela(s) a serem utilizadas na viewer; na janela após a seleção da(s) tabela(s), selecionar os campos a serem utilizados; a seguir pode ou não ser apresentada uma mensagem questionando se a viewer deve suportar chaves estrangeiras, caso aconteça, clicar em Cancel; se a viewer for utilizada em um cadastro do tipo simples, no início da procedure local-assign-records é necessário substituir a linha contendo: {include/i-valid.i} por estas a seguir: if not frame {&frame-name}:validate() then return 'ASM-ERROR':U. • • alterar a altura de todos os atributos de tipo fill-in para 0.88; para os atributos que formam a chave de acesso da tabela, caso forem postos na tela: • tornar os atributos desabilitados, através de propriedades, desmarcando o toggle-box 'Enable'; • em propriedades e Advanced, marcar o toggle-box '{&ADMCREATE-FIELDS}'; • • • colocar o primeiro atributo na linha 1.17; caso exista mais de um atributo chave: colocá-los em espaçamento 1, ou seja, na linha 2.17, 3.17, etc.; • alterar a altura do retângulo rt-key para o número de atributos chave + 0.25, ou seja, 2.25, 3.23, etc.; • alterar a linha inicial do retângulo rt-mold para a altura do rtkey + 1.25; • se não forem colocados atributos chave: • • eliminar o retângulo rt-key; mover o retângulo rt-mold para a linha 1; • para os atributos que não formam a chave de acesso da tabela, caso forem postos na tela: • colocar o primeiro atributo na linha de rt-mold + 0.17 (Exemplo: 2.67); • colocar os demais atributos com um espaçamento de 1 (Exemplo: 3.67, 4.67); • alterar a altura do retângulo rt-mold de modo a apenas caber os atributos dentro; • • colocar na SmartViewer outros objetos, como por exemplo combo-box, que não estão associados aos campos no banco de dados; para os objetos não associados ao banco de dados e que devem ser atualizados pelo usuário, acessar as 'Property' e: • tornar o objeto desabilitado (em propriedades, desmarcar o toggle-box 'Enable'); • em propriedades e Advanced, marcar o toggle-box '{&ADMMODIFY-FIELDS}'; • customizar a procedure LOCAL-INITIALIZE para que as inicializações dos objetos sejam feitas. Essas inicializações das variáveis podem ser, atribuição de labels (para tradução automática), atribuição de itens para combo-boxes e radio-sets, etc., e devem ser feitas antes do dispatch padrão; Exemplo /* Code placed here will execute PRIOR to standard behavior. */ {utp/ut-liter.i Preço * R} assign fill-in_Price:label in frame {&frame-name} = returnvalue cb-country:list-items in frame {&frame-name} = {pdinc/i01pd001.i 03}. /* Dispatch standard ADM method. RUN dispatch IN THIS-PROCEDURE ( INPUT 'initialize':U ). /* Code placed here will execute AFTER standard behavior. */ • na procedure LOCAL-ENABLE-FIELDS comentar a linha que contém a ocorrência:"if-adm-new-record=yes then"; Construção de Programas utilizando os Estilos e suas Técnicas 207 • a procedure LOCAL-DISPLAY-FIELDS deve ser customizada para que o valor da variável seja exibido, para isso, antes do dispatch padrão deve-se atribuir a variável o valor a ser exibido. Exemplo /* Code placed here will execute PRIOR to standard behavior. if avail order-line then assign fill-in_Price = Order-Line.Price. else assign fill-in_price = 0. /* Dispatch standard ADM method. */ /* RUN dispatch IN THIS-PROCEDURE (INPUT 'display-fields':U).*/ /* Code placed here will execute AFTER standard behavior. */ */ • quanto à largura da SmartViewer: • se a SmartViewer for usada dentro de um folder de Cadastro Inclui/Modifica Filho, alterar a largura de rt-key e rt-mold para 76,72; • se a SmartViewer for usada dentro do Cadastro Inclui/Modifica Filho sem folder, alterar a largura de rt-key e rt-mold para 79,29; • se for usada dentro de outro folder que não seja em um Cadastro Inclui/Modifica Filho, alterar a largura de rt-key e rt-mold para 85.72; • acessar as propriedades da frame da SmartViewer, clicar em 'Tab Order' e no combo-box 'Tabbing Options' escolher a opção 'Left-to-Right By Columns'; salvar a SmartViewer com o nome definido, de acordo com os Padrões de Nomenclatura; • Como definir viewer sem campos de tabela: Viewer sem campos de tabela é aquela que possui apenas objetos (widgets) não vinculados a uma base de dados, ou seja, são variáveis dispostas na tela de modos que o usuário possa alterar os seus valores em tempo de execução. • • cancelar a tela de seleção de tabelas exibida após a escolha da template; se a viewer for utilizada em um cadastro do tipo simples, no início da local-assign-records é necessário substituir a linha: {include/i-valid.i} combo-boxes. deve-se colocar os campos nos preprocessadores de acordo com a tabela abaixo: Preprocessador Adm-create-fields Finalidade Habilitados somente na criação de um novo registro.i. COPY e MODIFY. etc) na viewer. • • • • • definir no Method-Library a include i-auxtab. Habilitados nas operações de ADD. esses objetos não podem ser campos de tabelas. desabilitar todos os objetos da tela que não devam ser mostrados habilitados. radio-sets. Para isso. definir ao menos uma tabela externa. retângulos. deve ser a primeira da lista. • Tipo de Objetos Chaves (variáveis que representam chaves) Outras variáveis Adm-modify-fields Adm-assign-fields .por estas a seguir: if not frame {&frame-name}:validate() then return 'ADM-ERROR':U. inserir os objetos (fill-in´s. Atenção: o controle de habilitação/desabilitação de campos deve ser feito pelo usuário. */ Exemplo /* Code placed here will execute PRIOR to standard behavior. Essas inicializações das variáveis podem ser. etc.Construção de Programas utilizando os Estilos e suas Técnicas 209 • customizar a procedure LOCAL-INITIALIZE para que as inicializações dos objetos sejam feitas.i País * L} assign cb-country:label in frame {&frame-name} = return-value cb-country:list-items in frame {&frame-name} = {pdinc/i01pd001. /* Code placed here will execute AFTER standard behavior. sendo que é nessa procedure que os valores dos objetos serão exibidos: . /* Dispatch standard ADM method.. */ RUN dispatch IN THIS-PROCEDURE (INPUT 'initialize':U).i Preço * R} padrão assign fill-in_Price:Label in frame {&frame-name} = returnvalue. {utp/ut-liter.i 03}.r value. {utp/ut-liter. */ • customizar a procedure LOCAL-DISPLAY-FIELDS.i Quantidade * R} Comenta assign fill-in_Qty:label in frame {&frame-name} = return. atribuição de itens para combo-boxes e radio-sets. chamada {utp/ut-liter. atribuição de labels (preparação para tradução). Price Order-Line.Item-num Order-Line. sendo que é nessa procedure que os objetos são habilitados: • comentar o dispatch padrão. • inserir os comandos para que os valores dos objetos sejam exibidos. Exemplo /* Code placed here will execute PRIOR to standard behavior. */ Comenta /* Dispatch standard ADM method. */ chamada padrão /* Code placed here will execute AFTER standard behavior. GROUP-ASSIGN-TARGET':U).chamada */ padrão /* Code placed here will execute AFTER standard behavior.Line-num Order-Line. */ r /* RUN dispatch IN THIS-PROCEDURE (INPUT 'initialize':U). &endif Caso seja uma viewer principal.• comentar o dispatch padrão. • customizar a procedure LOCAL-DISABLE-FIELDS. • comentar a linha em que consta a seguinte sentença: if admnew-record then. */ /* if adm-new-record = yes then */ &if defined(ADM-MODIFY-FIELDS) &then enable {&ADM-MODIFY-FIELDS} with frame {&frame-name}. */ DISPLAY Order-Line Qty Order-Line. */ Comenta /* Dispatch standard ADM method.Discount WITH FRAME {&FRAME-NAME} @ @ @ @ @ @ fill-in_Qty fill-in_Price fill-in_order-num fill-in_line-num fill-in_item-num fill-in_Discount • customizar a procedure LOCAL-ENABLE-FIELDS. inserir as seguintes linhas: . */ r /* RUN dispatch IN THIS-PROCEDURE (INPUT 'initialize':U).Order-num Order-Line. sendo que é nessa procedure que os objetos são desabilitados: • • comentar o dispatch padrão. incluir: RUN notify ('enable-fields. Exemplo /* Code placed here will execute PRIOR to standard behavior. */ r /* RUN dispatch IN THIS-PROCEDURE (INPUT 'disable-fields':U).Order-num = FILL-IN_Order-num when admnew-record = yes order-line. */ Exemplo /* Code placed here will execute PRIOR to standard behavior. &endif Exemplo /* Code placed here will execute PRIOR to standard behavior. • customizar a procedure LOCAL-ASSIGN-STANTEMENT. &endif &if defined {ADM-MODIFY-FIELDS} &THEN disable {&ADM-MODIFY-FIELDS} with frame {&frame-name}. .Qty = FILL-IN_Qty NO-ERROR. • alterar a altura de todos os atributos para 0. */ Comenta /* Dispatch standard ADM method.Price = FILL-IN_Price order-line.Discount = FILL-IN_Discount order-line. ASSIGN order-line. sendo que é nessa procedure que os objetos terão seus valores salvos: • • comentar o dispatch padrão. */ Comenta /* RUN dispatch IN THIS-PROCEDURE (INPUT 'assign-statement':U). END.Construção de Programas utilizando os Estilos e suas Técnicas 211 &if defined(ADM-CREATE-FIELDS) &then disable {&ADM-CREATE-FIELDS} with frame {&frame-name}. */ chamada /* Code placed here will execute AFTER standard behavior. &endif Caso seja uma viewer principal colocar: RUN notify ('disable-fields. GROUP-ASSIGN-TARGET':U). r */ chamada /* Code placed here will execute AFTER standard behavior.88.Item-num = FILL-IN_Item-num order-line. /* Dispatch standard ADM method. IF ERROR-STATUS:ERROR THEN RUN dispatch IN THIS-PROCEDURE ('show-erros':U). */padrão &if defined(ADM-CREATE-FIELDS) &then disable {&ADM-CREATE-FIELDS} with frame {&frame-name}.Line-num = FILL-IN_Line-num order-line. inserir a lógica de gravação dos valores das variáveis. */ padrão DO WITH FRAME {&FRAME-NAME} ON ERROR UNDO. RETURN "ADM-ERROR": ASSIGN {&ADM-CREATE-FIELDS}{&ADM-MODIFY-FIELDS}. 67). 3.• para os atributos que representam a chave de acesso a tabelas. quanto à largura da SmartViewer: • se a SmartViewer for usada dentro de um folder de Cadastro Inclui/Modifica. • alterar a altura do retângulo rt-key para o número de atributos chave + 0. etc. etc.72. • alterar a altura do retângulo rt-mold de modo a apenas caber os atributos dentro. • • se não forem colocados atributos não chave. ou seja. na linha 2.17 (Exemplo: 2.17 caso existam mais de um atributo que represente uma chave: • colocá-los com espaçamento 1.17. retirar o retângulo rt-mold.17.67. • para os atributos que não formam a chave de acesso da tabela.25 • se não forem colocados atributos que representem chaves: • • eliminar o retângulo rt-key.25. • se a SmartViewer for usada dentro do Cadastro Inclui/Modifica sem folder. • colocar os demais atributos com um espaçamento de 1 (Exemplo: 3. • alterar a linha inicial do retângulo rt-mold para a altura do rtkey + 1. 4.67).29. caso forem postos na tela: • • colocar o primeiro atributo na linha 1.23.25. mover o retângulo rt-mold para a linha 1. ou seja. alterar a largura de rt-key e rt-mold para 76. caso forem postos na tela: • colocar o primeiro atributo na linha de rt-mold + 0. 2. alterar a largura de rt-key e rt-mold para 79. . 3. • Como definir viewers só com campos chave: Viewer só com campos chave é aquela que não possui campos não chave dispostos na tela.i. alterar a largura de rt-key e rt-mold para 85. selecionar a(s) tabela(s) a serem utilizadas na viewer. definir no Method-Library a include i-auxtab. selecionar os campos a serem utilizados.72. na janela após a seleção da(s) tabela(s). • • • • na dialog que se abrirá logo após a seleção do template. clicar em 'Tab Order' e no combo-box 'Tabbing Option' escolher a opção 'Left-to-Right By Columns'. clicar em Cancel. caso aconteça. • acessar as propriedades da frame da SmartViewer. Essa viewer poderá conter variáveis dispostas para entrada de dados pelo usuário. pode ou não ser apresentada uma mensagem questionando se a viewer deve suportar chaves estrangeiras. de acordo com os Padrões de Nomenclatura. . salvar a SmartViewer com o nome definido. deve ser a primeira da lista. a seguir.Construção de Programas utilizando os Estilos e suas Técnicas 213 • se for usada dentro de outro folder que não seja em um Cadastro Inclui/Modifica. . atribuição de itens para combo-boxes e radio-sets. Observe que índices de tabelas não podem ser alterados. • customizar a procedure LOCAL-INITIALIZE para que as inicializações dos objetos sejam feitas.• desabilitar todos os campos da tela. Essas inicializações podem ser. */ . atribuição de labels (preparação para tradução). Mais instruções a seguir: • colocar os campos nos preprocessadores de acordo com a tabela abaixo: Preprocessad Finalidade or Adm-createfields Adm-assignfields Adm-modifyfields Habilitados somente na criação de um novo registro Exemplo: operações de ADD e COPY Devem ser marcados os objetos que serão habilitados para alteração de uma ocorrência na tabela. Exemplo /* Code placed here will execute PRIOR to standard behavior. etc. Atenção: o controle de habilitação/desabilitação de campos deve ser feito pelo usuário. i País * L} assign cb-country:label in frame {*frame-name} = return-value {pdinc/i01pd001. {utp/ut-liter. /* Dispatch standard ADM method. &endif */ Caso seja uma viewer principal. */ */ • caso existam na viewer objetos não vinculados ao banco de dados (variáveis).Price:label in frame {&frame-name} = return-value. */ Exemplo /* Code placed here will execute PRIOR to standard behavior. */ /* Dispatch standard ADM method.Qty order-line. = fill-in_Qty = fill-in_Price • customizar a procedure LOCAL-ENABLE-FIELDS: • comentar o dispatch padrão. {utp/ut-liter. RUN dispatch IN THIS-PROCEDURE ( INPUT 'initialize':U ). customizar a procedure LOCAL-DISPLAY-FIELDS para que seus valores sejam exibidos.i Preço * R} assign Order-line.Construção de Programas utilizando os Estilos e suas Técnicas 215 {utp/ut-liter. incluir: .i Quantidade * R} assign fill-in_Qty:label in frame {&frame-name} = returnvalue. /* Code placed here will execute AFTER standard behavior. */ /* Code placed here will execute AFTER standard behavior /*if adm-new-record = yes then */ &if defined(ADM-MODIFY-FIELDS) &then enable {&ADM-MODIFY FIELDS} with frame {&frame-name}. */ if avail Order-Line then DISLPAY order-line. */ /* RUN dispatch IN THIS-PROCEDURE (INPUT 'enable-fields':U). • comentado a linha em que apareça a sentença: if adm-newrecord = yes then. /* Dispatch standard ADM method.Price WITH FRAME {&FRAME-NAME}. Exemplo /* Code placed here will execute PRIOR to standard behavior. /* Code placed here will execute AFTER standard behavior. */ RUN dispatch IN THIS-PROCEDURE (INPUT 'display-fields':U).i 03}. GROUP-ASSIGN-TARGET':U)..88.) /* Dispatch standard ADM method. 3.RUN notify ('enable-fields. &endif &if defined(ADM-MODIFY-FIELDS) &then assign {&ADM-MODIFY-FIELDS}. /* Todos os assign´s não feitos pelo assign-record devem ser feitos aqui */ assign order-line. etc. ou seja. • inserir o seguinte código após o dispatch padrão: do with frame {&frame-name} on error undo.. • • • • alterar a altura de todos os atributos para 0. &endif end. 3.25.23. return "ADMERROR": &if defined(ADM-CREATE-FIELDS) &then if ADM-NEW-RECORD then assign {&ADM-CREATE-FIELDS}.17. ou seja.25.17. caso exista mais de um atributo chave: • colocá-los com espaçamento 1. • caso existam na viewer objetos não vinculados ao banco de dados (variáveis).qty = fi-3.17. • para os atributos que não formam a chave de acesso da tabela. • alterar a altura do retângulo rt-key para o número de atributos chave + 0. etc. caso forem postos na tela: . customizar a procedure LOCAL-ASSIGN-RECORD para que seus valores sejam salvos.25. na linha 2. para os atributos que formam a chave de acesso da tabela: colocar o primeiro atributo na linha 1. • alterar a linha inicial do retângulo rt-mold para altura do rt-key + 1. RUN dispatch IN THIS-PROCEDURE (INPUT 'assign-record':U ).. 2. Exemplo: (. • criar e customizar a procedure LOCAL-ASSIGN-STATEMENT.. salvar a SmartViewer com o nome definido.29.67). • se a SmartViewer for usada dentro do Cadastro Inclui/Modifica sem folder. marcar o toggle-box '{&ADMMODIFY-FIELDS}'. acessar as 'Property' e: • tornar o objeto desabilitado (em propriedades. • acessar as propriedades da frame da SmartViewer. Obs.67.17 (Exemplo: 2. desmarcar o toggle-box 'Enable'). • se for usada dentro do outro folder que não seja em um Cadastro Inclui/Modifica. clicar em 'Tab Order' e no combo-box 'Tabbing Options' escolher a opção 'Left-to-Right By Columns'. • em propriedades e Advanced.Construção de Programas utilizando os Estilos e suas Técnicas 217 • colocar o primeiro atributo na linha de rt-mold + 0. para os objetos não associados ao banco de dados e que devem ser atualizados pelo usuário. 72. • • colocar na SmartViewer outros objetos. • . que não estão associados ao banco de dados.: apesar da viewer só com campos chave não conter outros campos. • quanto à largura da SmartViewer: • se a SmartViewer for usada dentro de um folder de Cadastro Inclui/Modifica. de acordo com os Padrões de Nomenclatura. poderá conter variáveis.67). alterar a largura de rt-key e rt-mold para 76.72. alterar a largura de rt-key e rt-mold para 79. como por exemplo combo-box. • se não forem colocados atributos não chave. alterar a largura de rt-key e rt-mold para 85. retirar o retângulo rt-mold. 4. • colocar os demais atributos com um espaçamento de 1 (Exemplo: 3. • alterar a altura do retângulo rt-mold de modo a apenas caber os atributos dentro. Observação Para os campos do tipo fill-in’s. . ou possua trigger de "ENTRY". O WebEnabler já registra automaticamente o evento de "LEAVE" para TODOS os fill-ins que possuírem a lupa como cursor do mouse. conforme técnica Como registrar campo do tipo Fill-in para o WebEnabler. deve ser observado se o mesmo possue trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita. Portanto não é necessário efetuar o registro para esses fill-ins. ou que possuírem um botão de zoom na sua direita. deve ser efetuado o registro para o WebEnabler. Caso o fill-in se encaixe em uma das opções acima. Este caso aplica-se para executar uma função qualquer como apresentar uma mensagem informativa ao usuário referindo-se àquele registro ou desabilitar o botão de alteração ou cópia. Deve-se ter cuidado com esse tipo de validação.2). . de modo que estejam condizentes com o que o programa pede e que não sejam passadas informações errôneas de modo a prejudicar o andamento correto das operações. porém em alguns desses casos a validação pode ser complexa e demorada. Validações na Navegação de Registro Em certos casos é necessário validar um registro assim que é acessado através da navegação na tabela. consequentemente prejudicial a performance do programa.Construção de Programas utilizando os Estilos e suas Técnicas 219 CAPÍTULO 9 Validações Validações de Tela As validações têm o objetivo de conferir as entradas de dados fornecidas pelo usuário a um programa. Para que o botão de Modificação seja habilitado deve ser seguida a técnica Como habilitar ou desabilitar Botões em Painéis. a validação será feita podendo prejudicar a performance do programa. Validações Antes da Alteração Da mesma forma que nas Validações na Navegação de Registro (item X. existem casos em que é necessário validar um registro para permitir ou não a sua alteração. pois cada vez que o usuário navegar na tabela. Para evitar que a validação acabe afetando a performance do programa. <mensagem>. OUTPUT c-p-cadsim). Validações em Entrada de Dados As validações feitas para valores de entradas de dados devem ser feitas sempre no momento de sua confirmação. Onde: <tabela>: a tabela que está sendo utilizada na manutenção <condição>: uma condição qualquer que indica que o registro não pode ser alterado <mensagem>: uma mensagem a ser apresentada ao usuário informando impossibilidade da alteração para o registro. INPUT "TableIO-Source". end. . de modo que na ocorrência de alguma inconformidade em qualquer dos valores requisitados pelo programa. contradizendo a função do botão. Validações em Cadastro Simples As validações em um Cadastro Simples devem ser feitas antes do dispatch da procedure Local-assign-record da Viewer. este deverá apresentar uma mensagem de erro através do utilitário ut-msgs. pois o usuário verá o botão de alteração habilitado e ao tentar alterar o registro a mensagem irá interrompê-lo. incluindo o código a seguir antes do dispatch padrão da procedure Local-Enable-Fields: define variable c-p-cadsim as character no-undo. if not adm-new-record and available <tabela> then do: if <condição> then do: RUN get-link-handle IN adm-broker-hdl (INPUT THIS-PROCEDURE. return "ADM-ERROR":U. Observação Essa técnica deve ser evitada. if valid-handle(widget-handle(c-p-cadsim)) then do: RUN pi-cancelar IN widget-handle(c-pcadsim).p e posicionar o foco no campo em que ocorreu o problema para que o usuário possa corrigi-lo. end. end. devese fazer a validação apenas quando houver a tentativa de alteração. Porém. Validação da Página de Impressão A página de impressão não precisa sofrer qualquer tipo de validação.Construção de Programas utilizando os Estilos e suas Técnicas 221 Validações em Cadastro Complexo O cadastro complexo possui mais de uma Viewer por isso tem uma forma diferente de fazer as validações para suas entradas de valores. já que esse tipo de validação não pode retornar informações do problema ocorrido para que seja tratado conforme necessário. As validações dos dados de entrada em um Cadastro Complexo são feitas nas procedures pi-validate das Viewers que compõem o cadastro. isso não acontece para os campos que não pertencem originalmente ao Template. por isso não são indicadas. Porém as validações de dicionário de dados podem acarretar o mau funcionamento nos Templates. Validações para Window Relatório Pelo fato da Window Relatório ser um Template não composto por SmartObjects. após o comentário: /* Coloque aqui as validações das outras páginas. . Seleção e Classificação Os valores dessas páginas são validados dentro da procedure pi-executar. lembrando que elas devem apresentar uma mensagem de erro cadastrada. a validação de seus valores tem as seguintes características: Validações das páginas de Parâmetros. que foram adicionados posteriormente. o Template se encarrega de confirmar os valores para essa página. posicionar na página com problemas e colocar o foco no campo com problemas */ Browse de Digitação Os valores do browse de digitação devem ser validados no momento que o usuário sai do registro. Validações em Triggers de Dicionário de Dados Existem casos que é imprescindível que haja validações de dicionário de dados para as tabelas de modo a assegurar que não ocorram entradas de dados que não condizem com o esperado. no evento Row-Leave do browse. Para que isso não ocorra. as validações de dicionário devem ser replicadas nos programas. fazendo com que seja possível o tratamento dos problemas que possam ocorrer no andamento das validações. nos locais indicados conforme o Template utilizado. . Importante 1. Em seguida você pode acessar o Sistema pelo endereço: X:\Atalhos\SistTec\Mensagem. Parâmetros: &1 = label da tabela Mensagens substituídas: &1 já cadastrado. Para auxiliar o cadastro e manutenção de mensagens. Para clientes e parceiros é autorizada somente a utilização das mensagens já cadastradas. mas não é necessário realizar esta alteração agora. deve-se utilizar o returnvalue do include utp/ut-table.223 CAPÍTULO 10 Mensagens Este capítulo apresenta mensagens padrões para algumas situações comuns no Datasul-EMS 2. &1 já cadastrada. 2. .i. Mensagem: &1 já existente ! Número: 1 Help: Já existe ocorrência em &1 com a chave informada.00. Quando o parâmetro solicitar o label da tabela. existe o Sistema de Mensagens. As mensagens já cadastradas e utilizadas que se encaixem nas situações abaixo devem ser alteradas. você deve primeiro entrar em contato com a equipe de ADF e solicitar a criação de um usuário no Sistema de Mensagens. Os novos programas devem utilizar estas mensagens. assim como a inclusão de novas mensagens só pode ser realizada pela Datasul. Para acessar o Sistema de Mensagens. Registro &1 já cadastrado. somente quando o programa for aberto para outras manutenções. Observações A manutenção do cadastro das mensagens. &1 já informado ! Observações: • • utiliza-se palavra 'existente'. Registro &1 não cadastrado. • • Mensagem: &1 já existente ! Número: 56 Help: Verificar se existe uma ocorrência para a(o) &1 informado em seu cadastro. A palavra 'inválido'. pois ela não possui gênero. cadastrada e cadastramento devem ser evitadas. deve ser evitada. a palavra 'registro'. &1 não cadastrada. não é necessário apresentar o conteúdo da chave da tabela. Parâmetros: &1 = label da tabela Mensagens substituídas: &1 não cadastrado. também. Observações: • • utiliza-se palavra 'existente'. deve ser evitada. pois se pode obter sentido não desejado. &1 incorreto(a) ! &1 inválido. devendo ser substituída por 'ocorrência'. Exemplo: Funcionário inválido ! Mensagem: &1 possui relacionamentos ativos com &2 ! Número: 5 Help: A corrente ocorrência de &1 possui relacionamento ativos . pois ela não possui gênero. as palavras derivadas do termo 'cadastro' como cadastrado. também. Agência não cadastrada.Agência já cadastrada. cadastrada e cadastramento devem ser evitadas. pois este está na tela. &1 inválida. as palavras derivadas do termo 'cadastro' como cadastrado. pois trata-se de um termo computacional estranho ao usuário. . Informe um código diferente de branco.. &1 possui &2 cadastrado(s).. Exemplo: O código da referência deve ser preenchido... • • As reticências podem ser utilizadas somente nos casos de uso do gerúndio. • não utilizar ponto de exclamação ou ponto final. As mesmas visam facilitar o controle das mensagens (para que não haja o acúmulo de informações que não serão utilizadas ou então repetitivas) e também. Mensagem: Não encontrado(a) &1 para chave informada ! Número: 2 Help: Não foi encontrada ocorrência em &1 com a chave informada.. Executando .. Exemplo: Eliminando cálculo antigo . portanto não pode ser eliminada. Imprimindo .. Observações: As palavras derivadas do termo 'cadastro' como cadastrado. Outros exemplos de mensagens cadastradas que não podem ocorrer: Exemplo: Calculando . a não ser que haja sentença posterior. . Banco possui Agência cadastrada.00. Parâmetros: &1 = label da tabela pai no relacionamento &2 = label da tabela filho no relacionamento Mensagens substituídas: &1 possui relacionamentos ativos. Parâmetros: &1 = label da tabela Mensagens substituídas: Chave informada não encontrada. Observações: • mensagem padrão para inclusão de ocorrências numa tabela temporária de digitação. quando esta possuir índice único. cadastrada e cadastramento devem ser evitadas. Regras para a criação de novas mensagens Estas regras devem ser seguidas por todos os programadores e analistas que estão desenvolvendo o Datasul-EMS 2. &1 possui &2 cadastrada(s).. facilitar o trabalho de tradução.Construção de Programas utilizando os Estilos e suas Técnicas 225 com a tabela &2. pois seguindo estas normas o número de mensagens criadas diminui. . • evitar repetir a mesma palavra várias vezes. Exemplos: Linha Possui Ordens Valorizadas ! Ordem de Produção Não Possui &1. Exemplo: Períodos para o ano ja cadastrados. • não utilizar letras maiúsculas no meio da frase sem que seja nome próprio. de Fim de Perídodo Confirma elimanação ? Ano fiscal já esté encerrado. Informe outra operação para este Roteiro ou cadastre a Operação &1 para o Roteiro &2. de concordância e de grafia.. Exemplo de mensagem incorreta: não utilizar ponto ao abreviar palavra. revisar possíveis erros gramaticais. .• • • • Quando o programador tiver a necessidade de ressaltar a mensagem.. Exemplo de mensagens incorretas: Serão criadas as mesmas contas para todos os grupos de clientes Informe se será irá ser executado um processo de substituição de &1 modificado em &2 registrados para &3 Permitindo somente a inclusão de três tipos de mão de obra &1 não pode ser eliminad(o)a ! . • utilizar acentuação sempre. Moeda do credito nao tem cotacao para hoje. Pagto. Eliminção inválida ! Eliminação inválida ! Exemplo de mensagem incorreta: Cond. Exemplos: Operação &1 não está cadastra para o Roteiro &2. utilizar a função "alert-box warning". • • • procurar ser formal. o Sistema de Mensagens possui o botão Pesquisa. Pagto. Exemplo: Agência não cadastrada. Exemplo: Eliminação Inválida ! Eliminação inválida! Para auxiliar esta operação. se houver algo a acrescentar. • utilizar o help da mensagem somente se necessário. Exemplo: Linha Possui Ordens Valorizadas ! Não pode alterar ! Não utilizar o tratamento VOCÊ.Construção de Programas utilizando os Estilos e suas Técnicas 227 • antes de criar uma nova mensagem verificar se não há outra similar que possa ser utilizada. utilizar somente o idioma português (com exceção de palavras técnicas específicas). • não utilizar palavras ou jargões técnicos. Não utilizar gírias. somente para repetir a mesma mensagem. ainda possui a opção de Filtro onde você informa palavras que deseja procurar dentro do sistema. Exemplo: Parámetros . Exemplos: Título já existe no browse Script do Automanager não encontrado.Help Item para debito direto. • não abreviar palavras sem necessidade (somente por questões de espaço). Não utilizá-lo. Help Agência não cadastrada! Item para debito direto . Exemplo: Cond. onde você pode buscar por Código ou pelo Texto da Mensagem. Estabelec Dt Ent Prev Cod Dest Merc Encer calc não efetuado. Além disso. . Exemplos: a nd fghfhdfh . não criar mensagem somente com letras maiúsculas. Exemplo: ** Pendencias de Credito do Cliente • não criar mensagens sem sentido.El código de grupo informado não existe ! • não utilizar sinais ortográficos ou espaços em branco ao início das mensagens. no caso de dúvidas. utilizar o help.fhdfjhdfghdf Vários Representante teteretert fadfads • • a mensagem deve ser o mais clara e sucinta possível. Qualquer necessidade de detalhamento. consultar Glossário ou demais membros da equipe de tradução. Padrões para tradução de mensagens para Inglês e Espanhol • • utilizar os mesmos padrões para criação de mensagens novas. Conversão de valores entre moedas. As procedures tratadas neste tópico diferem de outras ou mesmo de outros includes pelo fato de serem documentadas (posteriormente) em Manual Técnico do Módulo. Se forem incorporadas a programas . Rotinas de Extenso. e disponibilizadas para clientes e parceiros da DATASUL. onde: XX .w. .i. Nomenclatur A nomenclatura dos includes que contém este tipo de procedure interna deve ser a seguinte: a XXINC999. Exemplo : Cálculo do valor presente de uma cotação de preços.229 CAPÍTULO 11 Programas Reutilizáveis Procedures Internas Procedures Internas reutilizáveis são definidas em includes que devem ser incorporados aos programas. não devem fazer acesso muito grande a dados pois se isto acontecer devem ser transformadas em API(s).Seqüencial.Sigla do Módulo INC .Fixo 999 . . ). pressionar o menu Tools e em seguida o item Application Compiler. na qual se deve informar os arquivos que se deseja compilar e as opções de compilação. UIB . Procedure Editor.. exibida a janela a seguir.230 CAPÍTULO 12 Ferramentas Application Compiler O Application Compiler é uma ferramenta Progress utilizada para compilar arquivos. deve-se estar com qualquer uma das ferramentas Progress abertas (Data Dictionary. Para iniciar o Application Compiler. Sendo então. . Então. informar mais de um tipo de arquivos. 3. na qual pode-se localizar mais facilmente os arquivos desejados. Pressionar o botão 'Ok' e então o diretório e os arquivos devem ser exibidos na janela do Application Compiler. 2. também. para exibir uma caixa de diálogo padrão do Windows.Construção de Programas utilizando os Estilos e suas Técnicas 231 Selecionar arquivos a serem compilados Para selecionar os arquivos que devem ser compilados seguir os passos abaixo: 1. utilizar o botão 'Files'. deve ser exibida uma caixa de diálogo. na qual. Pode-se. . deve ser informado o diretório e/ou nome dos arquivos e/ou tipo dos arquivos a serem compilados. Pode-se. Caso os arquivos desejados estejam em diretórios diferentes pode-se adicionar mais diretórios e/ou arquivos a lista. Pressionar o botão "Add" na janela anterior. separando-os por espaço. na qual. Depois pressionar o botão 'Modify' e será exibida uma caixa de diálogo. deve ser exibida uma caixa de diálogo com todos os caminhos existentes no PROPATH do Progress. Pressionar o botão 'Propath'. Pressionar o botão esquerdo do mouse sobre o diretório e/ou arquivos da lista a ser eliminado. Pressionar o botão 'Ok'. 2. Pressionar o botão esquerdo do mouse sobre os diretórios desejados. deve-se seguir os passos abaixo: 1. Pressionar o botão esquerdo do mouse sobre o diretório e/ou arquivo da lista a ser modificado. seguir os passos abaixo: 1. Após feitas as devidas modificações pressionar o botão 'Ok'. Eliminar e Modificar a lista de arquivos a serem compilados Para modificar algum dos diretórios da lista de arquivos a serem compilados. selecionando-os. 3.E ainda. caso queira incluir a lista de arquivos a serem compilados num diretório do PROPATH do Progress. 2. deve-se seguir os passos abaixo: 1. retornando assim a janela anterior. . ficando assim selecionado. Para eliminar alguns dos diretórios da lista de arquivos a serem compilados. 3. pode-se modificar o diretório e/ou arquivos e/ou tipos de arquivos a serem compilados. r Files. para isso marcar a caixa de combinação Look in Subdirectories.para isso marcar o item de menu Show Status que se encontra no menu Options.R .R gerados . na qual.digitar o diretório e o nome do arquivo de LOG na caixa de texto Message Log File.. pode-se informar algumas opções adicionais. o Application Compiler possui outras opções de compilação. não informar nenhum diretório nesta caixa de texto. compilar arquivos existentes nos subdiretórios dos diretórios da lista de compilação. Depois pressionar o botão 'Delete'. este arquivo deve armazenar os resultados (arquivos compilados com sucesso.R devam ser gravados no mesmo diretório dos arquivos de origem.R existentes .para isso marcar o item de menu Save Settings on Exit que se encontra no menu Options. item Compiler. no qual devem ser gravados os novos arquivos .Construção de Programas utilizando os Estilos e suas Técnicas 233 2.para isso marcar a caixa de combinação Only Compile If No . • . exibir status da compilação dos arquivos . compilar somente os arquivos que não possuam . eliminar os antigos ..r File.digitar os tipos de arquivos na caixa de texto Default File Spec.. descritas abaixo: • • salvar os novos arquivos . diretório. . erros encontrados. na caixa de texto Save Into. • • • • Além das opções descritas anteriormente.para isso marcar a caixa de combinação Remove Old . caso os novos arquivos .) da compilação dos arquivos . Estas opções podem ser acessadas através do menu Options. Opções de Compilação O Application Compiler disponibiliza algumas opções de compilação. salvar as alterações realizadas nas opções de compilação .r Files. tais como: • • tipos de arquivos padrão a serem compilados .para isso marcar a caixa de combinação Save New . Será então exibida uma caixa de diálogo denominada Compiler Options. arquivo de LOG.digitar o nome do diretório onde estes arquivos devem ser gravados.R . Para a utilização do Roundtable. . veja os passos a seguir: . caso este item de menu não esteja marcado. ). Caso o item de menu Show Status esteja marcado. 2. será exibida a mesma caixa de diálogo mas. será exibida uma caixa de diálogo com informações sobre o status da compilação (arquivos compilados com sucesso. somente ao final da compilação dos arquivos. Criar uma task para poder desenvolver os programas. objetos e includes. Roundtable O Roundtable é uma ferramenta que facilita o controle de versão de programas.Iniciar Compilação Para iniciar a compilação dos arquivos deve-se pressionar o botão 'Start Compile'.. erros encontrados.. Selecionar a Workspace. deve-se seguir os passos descritos abaixo: 1. estar com a task selecionada. selecionar o objeto que se quer editar. • • • • • ir em File .Task Maintenance. 3. digitar na opção Summary a descrição da Task. digitar na opção Manager. caso o objeto já . selecionar a task que foi criada na opção Task.New Task.Construção de Programas utilizando os Estilos e suas Técnicas 235 • ir no menu Task . Após criada a task. Observação: Poderá ter mais de uma Task criada para um mesmo usuário. 4. clicar no botão 'Done'. Observação: Não há necessidade de se fazer os dois próximos itens. Como editar um objeto: • • esteja na sua task. a quem está designado (opcional). clicar no botão 'Ok'. 5.Check Object Out: Observação: Caso essa opção não esteja habilitada certifique-se que a task esteja selecionada ou se o objeto já está em uso por outra pessoa. ir em File .Edit Selected Object: Observação Com isso deve abrir o programa no Procedure Editor. Para isso.Complete Task e deve-se perguntar se deseja completar a task e deve-se responder que . Para verificar se o objeto já está em uso Ir em Folder . Se for selecionada a opção View Selected Object. Como completar uma task: • depois de feitas as devidas alterações no(s) objeto(s) é preciso completar a task para liberar o(s) objetos(s) presos a task. • • selecionar a opção Patch Level. Caso se queira abrir no Interface Builder - Abrir o Interface Builder e Ir no menu File .• ir em File .na última label Event. deve ser aberto o programa somente para leitura. que deve estar escrito 'Work in process'.Spec (que está na tela principal do Roundtable) . File . deve-se ir no menu Task .Open.Task Maintanence. clicar em Ok.Check Object In do menu. 7. Com isso. desde que estes estejam sem erros. o Roundtable deve liberar todos os objetos presos a task. 6. Como saber se todos os objetos estão associados a task: . Como liberar um único objeto: • • • • • ir no menu compile . selecionar a task desejada. ir no menu View. ir na opção File .Construção de Programas utilizando os Estilos e suas Técnicas 237 sim.Compile Object With Xref. opção Object in Task View. Esta tarefa. ou seja. é um programa que recebe parâmetros específicos para a realização de alguma tarefa. Uma API. evitando duplicidade de código e as mantendo atualizadas.238 CAPÍTULO 13 API´s O que são API´s e como construí-las Objetivo API (Application Program Interface). Característic as Com isto. • outros módulos. quando desejar fazer alguma customização. . As API´s são usadas pelos: • próprios programas do módulo. • equipes de desenvolvimento específico para customização dos módulos. pode ser desde uma atualização. não pode ser chamada diretamente. é sempre executada a partir de um outro programa. • • parceiros de desenvolvimento da DATASUL. não precisam conhecer em detalhes o modelo de dados de um módulo para criar registros. o cliente e mesmo os outros módulos. que passa os devidos parâmetros. próprio cliente. alcançando assim a independência dos aplicativos. quanto um programa que retorne informações. Visando facilitar a customização e a integração dos módulos. Logo. segue a idéia de orientação a objeto. deve ser da seguinte forma: • INPUT-OUTPUT PARAMETER TEMP-TABLE: este é a única forma de comunicação de dados com a API. Assim. podendo-se utilizar uma ou mais tabelas temporárias para fazê-la.P. através da temp-table. receba parâmetros e execute alguma ação. dados como empresa. a reutilização de código. usuário. para determinar o sucesso completo (OK) ou parcial (NOK) ou nulo (NOK) da execução. também. uma temp-table somente de retorno. se o programa API.i. parar retornar todos os erros ocorridos com determinado registro. onde: XXX . Funcionamen A API deve ser construída de forma que. Isto facilita no momento da utilização do RPC. ou seja. não deve ter tratamento com tela. definir a forma que mais se adapta ao programa a ser criado. para acessar determinado objeto. Pode ser utilizada também. o include que contém as definições das temptables de integração tem o nome externo MPAPI001. deve ficar num include de nome semelhante ao programa API. O retorno da API.I. A API. A definição das temp-tables. A entrada dos parâmetros na API.Construção de Programas utilizando os Estilos e suas Técnicas 239 Este conceito. devem ser enviados para a API. Além disto. somente um elemento preestabelecido pode efetuar tal operação. As API´s devem ter a nomenclatura: XXAPI999. deve ser sempre via troca de to parâmetros. devolvendo informações ao programa chamador.indica o nome do módulo 999 . pode ser utilizada uma temp-table. • INPUT-OUTPUT PARAMETER TEMP-TABLE: pode-se atualizar em um atributo da temp-table de entrada de dados com o código da mensagem de erro que ocorreu com o registro. tem o nome externo MPAPI001.um número seqüencial de API´s dentro do módulo. apenas com a extensão .P.I. . ou qualquer outro tipo de variável global. de forma alguma pode ser utilizado os valores das variáveis globais definidas no ut-glob. deve ocorrer das seguintes formas: • RETURN-VALUE: retornando OK ou NOK. Cabe ao projetista/programador. No caso. Retorno de Erros a mesma deve retornar no próprio registro da temp-table de entrada com problemas. deve conter as seguintes informações: . da versão de integração estiver incompatível. ou através de uma temp-table de erros de dois campos com as seguintes informações: Campo coderro descerro Descrição Número da mensagem de erro Descrição da mensagem de erro A mensagem deve estar obrigatoriamente cadastrada no cadastro de mensagens. Utilizar um campo com nome cod-versao-integracao. A documentação da API. Existe um manual para cada módulo contendo todas as suas API´s. esta versão de integração da API é diferente da versão do programa da API. deve ser feita pelo módulo responsável. Deve ser utilizado módulo de documentação do Datasul-EMS. e a descrição é o texto da mensagem. com os dados recebidos por ela. pode alterar o programa e gerar uma nova versão. devendo estar sempre atualizada. adequar seu programa às exigências impostas pela API. deve ser utilizada a mensagem de erro número 3941. Esta versão deve ser incrementada. sem que seja necessário alterar a versão de integração da API. Sempre que a API encontrar algum problema. Cabe ao responsável do programa chamador.A API deve ter um controle interno para a versão corrente de integração. Esta Versão de Integ versão é fixa no programa API. uma vez que. sempre que ocorrer alguma alteração no layout das temp-table´s. Esta documentação está contida no manual técnico do módulo. para gerar o help da documentação da API. O programa chamador deve obrigatoriamente passar esta versão como parâmetro de entrada (sempre o primeiro campo da temp-table) e a API faz a consistência. verificando se a versão em que está o programa chamador é compatível com a versão de integração da API. sendo controlada pelo programador (deve ser ração obrigatoriamente um número seqüencial). Importante lembrar que. ou na forma de passar e receber os parâmetros. Documentaçã ** Item parcialmente definido ** o A documentação da API. este deve buscar via BBS o help corrente da API.p Versão de Integração: 1 Objetivo: verificar se deve replicar transação nas máquinas remotas e por buscar código da máquina local. Exemplo Nome Físico: mmp/mpapi001. objetivo. No manual técnico do módulo deve conter uma relação com todas as API´S do módulo. Parâmetros de Entrada: Para executar a API é necessário utilizar o include {mpp/mpapi001. objetivo e nome do arquivo help.Construção de Programas utilizando os Estilos e suas Técnicas 241 • • • nome físico do programa.i} que contém a definição dos parâmetros de entrada do programa.i ** Definição das temp-tables utilizadas para verificar ** replicação das mensagens para uma planta remota . • • execução (validações e ações).Multiplanta ** *************************************************************** def temp-table tt-replic-msg field cod-versao-integracao as integer format "999" field cod-transacao as char format "x(8)" field log-replica-msg as logical field cod-erro as integer format "99999" field desc-erro as char format "x(60)" field cd-maquina-local as integer format "999". • nome do include que contém a definição das temp-tables de integração. Se o usuário precisar utilizar a API. considerações gerais. Campo Descrição . /************************************************************** ** Include: MPAPI001. versão de integração. • parâmetros de entrada e saída (o que significam os campos na(s) tabelas temporária(s)). nome físico da API. cod-transacao no-lock no-error. . else do: run utp/ut-msgs. cdtrans = tt-replic-msg. return "NOK" end.p (input "msg". else do: find first maq-dest-trans where maq-dest-trans.log-replica-msg = yes.P ** API responsável por verificar se deve replicar transação nas ** máquinas remotas e por buscar código da máquina local ** *************************************************************/ {mpp/mpapi001. find first tt-replic-msg no-lock no error.cd-maquina. input 3941.i} def input-output parameter table for tt-replic-msg. if avail tt-replic-msg then do: if tt-replic-msg. input "") assign tt-replic-msg.desc-erro = return-value. assign i-versao-integ = 001. if avail maquina then assign tt-replic-msg.tp-conexao = 1 no-lock noerror.cod-versao-integracao <> i-versao-integ then do: run utp/ut-msgs. if avail maqui-dest-trans then assign tt-replic-msg.cod-versaointegracao cod-transacao log-replica-msg cod-erro desc-erro cd-maquinalocal Número da versão de integração Código da API /************************************************************* ** Programa : MPAPI001.cod-erro = 3941 tt-replic-msg. def var i-versao-integ as integer format "999" no-undo. find first maquina where maquina.cd-maquina-local = maquina.p (input "msg". doc Existem duas API´s documentadas. Algumas recomendações no uso: .dot).01). por exemplo: Nome do programa API: cep/ceapi003. /* fim */ Como documentar API´s Foi criado um documento modelo do Microsoft Word (.00. para facilitar a documentação técnica das API´s (Application Program Interface).cd-maquina-local = 0.doc) e ser armazenado no diretório \DOCAPI\.Construção de Programas utilizando os Estilos e suas Técnicas 243 input 3942. btb917zb. end. Return "NOK". do DATASUL-EMS 2.99 (exemplo V. fonte dentro das tabelas Arial 8. O arquivo Word.desc-erro = return-value tt-replic-msg. que podem servir de exemplo: • • • • • • • btb912zb.dot". fonte padrão do documento é Arial 10. deve ter o mesmo nome da API com extensão (. end. que está no diretório \FERRAMENTAS\MANUAL. com a documentação de cada API. este documento deve ser escrito de forma mais clara possível. input ""). end. Assign tt-replic-msg. com o nome "API.p Nome do documento API: docapi/ceapi003. else return "NOK". pois deve estar disponível para clientes e parceiros comerciais.doc (API de Criação de Pedidos de Execução para o RPW).doc (API de Eliminação de Pedidos de Execução para o RPW). o nome do nosso produto é Datasul-EMS (é importante observar as letras maiúsculas e minúsculas para não confundir com o produto internacional). a versão do documento deve estar no formato V.cod-erro = 3942 tt-replic-msg. 3. que estas não sejam muito significativas e não fiquem fora do padrão. + param-global. idêntico ao resultado da antiga. sem muda nça de parâ metr os Para este tipo de evolução. pode sofrer alterações no layout.taxa = 0. if avail param-global then assign param-global. Evolução de lógic a de API.taxa = 0. Observação O resultado obtido através da nova API deve ser. find first param-global exclusive-lock no-error.3. basta alterar o código principal da API. find first param-global exclusive-lock no-error. fazendo com que as customizações feitas pelos clientes/parceiros continuem funcionando. sempre que possível. procurando destacar nomes ou aspectos importantes para o entendimento. . define input param param-2 as int no-undo. Como implementar evoluções de API´s Implementar novas funcionalidades nos programas. Exemplo /* API antiga */ define input param param-1 as char no-undo. obviamente. o documento. mas.indic.• • usar negrito e itálico de forma moderada. /* API nova */ define input param param-1 as char no-undo. define input param param-2 as int no-undo. if avail param-global then assign param-global. A API antiga deve chamar a nova API de forma persistente e roda a procedure interna EXECUTE.UTAPI001.taxa = 0. if avail param-global then assign param-global. EX. run utp/utapi001a. define input param param-2 as int no-undo. find first param-global exclusive-lock no-error. acrescida de um diferenciador. passando todos os antigos parâmetros e um valor padrão para cada um dos novos parâmetros. .P UTAPI001A.3.P */ define input param param-1 as char no-undo. run execute in h-api (input param-1. /* API antiga e alterada . input param-1. Esta nova API deve possuir uma procedure interna EXECUTE.: UTAPI001. delete procedure h-api. com muda nças de parâ metr os Para este tipo de evolução.P */ define input param param-1 as char no-undo. define input param param-2 as int no-undo. define var h-api as handle no-undo. deve ser criada uma nova API com o mesmo nome da API antiga. input yes). que receberá os novos parâmetros e uma lógica.UTAPI001. Exemplo /* API antiga .Construção de Programas utilizando os Estilos e suas Técnicas 245 Evolução de lógic a de API .P.p persistent set h-api. P */ procedure execute: define input param param-1 as char no-undo. find first param-global exclusive-lock no-error. Ex. define input param param-2 as int no-undo.: UTAPI001. chamar a nova API de forma persistente e rodar a procedure interna EXECUTE.UTAPI001.P */ define temp-table tt-clientes . A API antiga deve. com alter ação de camp os na temp table s de parâ metr os Para este tipo de evolução. if avail param-global then assign param-global. end procedure.indic.taxa = if param-3 = yes then 0. copiar todos os campos da antiga temptable para a nova. Observação Os parâmetros novos que são passados como padrão para a nova API.P. primeiramente./* API nova . Exemplo /* API antiga . define input param param-3 as log no-undo.3 else 03 + param-global. Esta nova API deve possuir uma procedure interna EXECUTE.P UTAPI001A. acrescida de um diferenciador. devem garantir que o resultado seja o mesmo da antiga API. Evolução de lógic a de API. que receberá os novos parâmetros e uma lógica. deve ser criada uma nova API com o mesmo nome da API antiga.UTAPI001A. /* API antiga . run utp/utapi001a. if avail tt-new-clientes then assign param-global. buffer-copy tt-clientes to tt-new-clientes assign tt-new-clientes. end procedure.P */ define temp-table tt-new-clientes field cliente as char field taxa as int.ult-cliente = tt-clientes. procedure execute: define input param table for tt-new-clientes. if avail param-global then do: find first tt-clientes no-lock no-error.UTAPI001. find first param-global exclusive-lock no-error. find first param-global exclusive-lock no-error. if avail tt-clientes then assign param-global. define input param table for tt-clientes. /* API antiga e alterada . .taxa = tt-new-clientes. define input param table for tt-clientes. end.taxa.cliente. delete procedure h-api.ult-cliente = tt-new-clientes.Construção de Programas utilizando os Estilos e suas Técnicas 247 field cliente as char. define var h-api as handle no-undo.p persistent set h-api.taxa = 1. define temp-table tt-new-clientes field cliente as char field taxa as int. if avail param-global then do: find first tt-new-clientes no-lock no-error.cliente param-global.UTAPI001.P */ define temp-table tt-clientes field cliente as char. run execute in h-api (input table tt-clientes). for each tt-clientes no lock: create tt-new-clientes. find first param-global exclusive-lock no-error. devem ser repassados os registros da nova temp-table para a antiga.p persistent set h-api. for each tt-clientes no-lock: create tt-new-clientes.P */ define temp-table tt-new-clientes field cliente as char field taxa as int. devem ser repassados os registros da nova temp-table para a antiga. /* API nova .UTAPI001A. procedure execute: define input param table for tt-new-clientes. end. delete procedure h-api. no retorno da API evoluída.ult-cliente = tt-new-clientes. run utp/utapi001a.taxa = tt-new-clientes. if avail param-global then do: find first tt-new-clientes no-lock no-error. if avail tt-new-clientes then assign param-global. Observação Caso a temp-table antiga seja input-output.taxa. end procedure.Observação Caso a temp-table seja input-output. run execute in h-api (input table tt-clientes).taxa= = 1. no retorno da API evoluída. buffer-copy tt-clientes to tt-new-clientes assign tt-new-clientes.cliente param-global. define input param table for tt-clientes. . define var h-api as handle no-undo. : EXECUTE EXECUTE2.taxa = 0.taxa = 0. define input param param-3 as log no-undo.UTAPI001A.P procedure execute: */ . Exemplo /* API antiga . passando todos os antigos parâmetros e um valor padrão para cada um dos novos parâmetros. Ex. acrescida de um diferenciador.3.UTAPI001A. else do: find first param-global exclusive-lock no-error. if avail param-global then assign param-global. que já foi Para este tipo de evolução. /* API antiga alterada . end procedure. end. if param-3 = yes then find first param-global exclusive-lock no-error.3 + param-global.P */ procedure execute: define input param param-1 as char no-undo. ída Esta nova procedure interna deve receber os novos parâmetros e possuir toda a lógica. if avail param-global then assign param-global. com muda nça de parâ metr os. A procedure interna antiga deve chamar a nova procedure. define input param param-2 as int no-undo.Construção de Programas utilizando os Estilos e suas Técnicas 249 Evolução de lógic a de API.indic. deve ser criada uma nova procedure interna com o evolu mesmo nome da procedure interna antiga. end. run execute2 (input input input input end procedure. int no-undo. Evolução de lógic a de API com muda nça de parâ metr os. procedure execute2: define define define define input input input input param param param param param-1 param-2 param-3 param-4 as as as as char no-undo. param-2.taxa = if paam-4 0 then 0. devem garantir que o resultado seja o mesmo da antiga procedure interna. end procedure. . if avail param-global then assign param-global. acrescida de um diferenciador. find first param-global exclusive-lock no-error. param-1. param-3. a procedure interna ou API antiga deve retornar um erro para que o programa que o chamou emita uma mensagem de erro explicando o motivo que a API não foi executada e qual o motivo da obrigatoriedade de novo parâmetro.define input param param-1 as char no-undo. define input param param-3 as log no-undo. int no-undo. Como não é possível determinar valores padrão. 0). deve ser criada uma nova procedure interna ou API com o mesmo nome da procedure interna antiga. conforme exemplificando nos itens anteriores. Para este tipo de evolução. define input param param-2 as int no-undo.3 + param-4. log no-undo. onde não é possí vel deter mina r um valor padr ão para o novo parâ metr o ou o novo parâ metr oé obrig atóri o Observação Os parâmetros novos que são passados como padrão para a nova procedure interna.3 else 0. end procedure. if avail param-global then assign param-global. else do: find first param-global exclusive-lock no-error. run execute 2 (input input input input end procedure. param-2.taxa = 0. end. param-3.UTAPI001A. 0). define input param param-3 as log no-undo. int no-undo.Construção de Programas utilizando os Estilos e suas Técnicas 251 Exemplo /* API antiga . define var h-execute as handle no-undo.taxa = 0.UTAPI001A.P */ procedure execute: define input param param-1 as char no-undo. if param-4 = 0 then find first param-global exclusive-lock no-error. define input param param-2 as int no-undo. define input param param-2 as int no-undo. input param-3. return return-value. . end procedure. procedure execute2: define define define define input input input input param param param param param-1 param-2 param-3 param-4 as as as as char no-undo. /* API nova . if avail param-global then assign param-global.P */ procedure execute: define input param param-1 as char no-undo. run execute2 (input param-1. param-1. input 0). log no-undo.3 + param-4. define input param param-3 as log no-undo. int no-undo. input param-2.3. end. if avail param-global then assign param-global. e nunca na própria API. . find first param-global exclusive-lock no-error. Esta mensagem deve apresentar um erro dizendo que esta API está desatualizada e o motivo de sua extinção.3 + param-4 * param-5 end procedure. A mensagem de que a API possui uma nova versão com parâmetro obrigatório. return "999". int no-undo. deve ser criada uma nova procedure interna ou API com o mesmo nome da procedure interna antiga. já que as API´s não devem possuir eventos de interface.taxa = 0. conforme exemplificando nos itens anteriores. end procedure. deve ser somente apresentada no programa chamador. int no-undo. log no-undo. procedure execute3: define define define define define input input input input input param param param param param param-1 param-2 param-3 param-4 param-5 as as as as as char no-undo. acrescida de um diferenciador. int no-undo. int no-undo. Observação Isto somente deve ser feito caso não exista nenhuma maneira de definir um valor padrão para o novo parâmetro ou o parâmetro seja obrigatório. log no-undo.procedure execute2: define define define define input input input input param param param param param-1 param-2 param-3 param-4 as as as as char no-undo. int no-undo. A antiga API deve retornar um erro para o programa chamador. Evolução de lógic a de API com muda nça de versã o de integ ração Para este tipo de evolução. define input param param-2 as int no-undo.UTAPI001. end procedure.Construção de Programas utilizando os Estilos e suas Técnicas 253 A nova API deve conter uma procedure interna que retorne a versão de integração para o programa chamador. Antes de rodar a nova API. if avail param-global then assign param-global.P */ procedure execute: define define define define define input input input input input param param param param param param-1 param-2 param-3 param-4 param-5 as as as as as char no-undo.P */ define input param param-1 as char no-undo. find first param-global exclusive-lock no-error.3 * param-2.3 + param-4 * param-5. Exemplo /* API antiga .UTAPI001.taxa = 0. return "999". Lembrar que. define input param param-3 as log no-undo. int no-undo. Observação Esta técnica pode ser utilizada quando as outras técnicas citadas implicarem muito na performance da API. procedure get-integration-version: define output param i-version as int no-undo. . define input param param-2 as int no-undo. int no-undo.UTAPI001A. qualquer mensagem para o usuário deve ser emitida pelo programa chamador e nunca pela API. define input param param-3 as log no-undo. o programa chamador deve rodar o método Get-Integration-Version da nova API e verificar se a versão está correta. int no-undo. if avail param-global then assign param-global. /* API nova. end procedure. /* API antiga alterada . log no-undo. find first param-global exclusive-lock no-error. assign i-version = 4.taxa = 0.P */ define input param param-1 as char no-undo. P A API utp/utapi002. um programa. não deve-se realizar nenhuma alteração pois estão sendo feitas correções nessa API.Importante Para novos programas que venham a utilizar a API utapi0001. Para os programas antigos que já utilizam essa API. que contém as definições das templates utilizadas pela própria API e pelos programas que irão utilizá-la. Importante Para novos programas que venham a utilizar esta API. e. baseados em formulários. é recomendado que seja utilizado o programa utp/utapi012 ao invés deste. UTAPI001. Maiores informações podem ser obtidas na documentação da API de Geração de Gráficos (doc-api/utapi001. Para os programas antigos que já utilizam essa API. é recomendado entrar em contato com a equipe de Suporte ao Desenvolvimento no ramal 7125 antes de utiliza-lá.doc). não deve-se realizar nenhuma alteração pois estão sendo feitas correções nessa API. para o Microsoft Word. UTAPI002. Importante Para novos programas que venham a utilizar esta API. Essa API é constituída por uma include utp/utapi001. objetos não Progress contidos em interfac/grafico que fazem parte de Datgraph (visualizador de gráficos). utp/utapi001.p.doc).i. Maiores informações podem ser obtidas na documentação da API de Integração entre PROGRESS e Microsoft Word 97 (docapi/utapi002. que é a própria API.p faz a integração entre Progress e Microsoft Word 97. . é recomendado entrar em contato com a equipe de Suporte ao Desenvolvimento no ramal 7125 antes de utiliza-lá. permitindo a criação de arquivos.P A API de geração de gráficos tem por finalidade exibir gráficos de acordo com os parâmetros a ela passados. com.br".. verificar o andamento do envio de E-Mail (UT-ACOMP). ". • • • • • • • • Exemplo run utp/utapi004. gráficos. ou seja. receber um EMail quando o destinatário tiver lido a mensagem. "". "Manual". o terceiro parâmetro é o Assunto (Subject). é recomendado que seja utilizado o programa utp/utapi013 ao invés deste. o nono e último parâmetro é o Acompanhamento. "Mensagem do manual . Importante Para novos programas que venham a utilizar esta API.0 usando o MSExchagne (OLE Automation). 2 Alto. onde 0 Baixo. "fulano@internet. Maiores informações podem ser obtidas na documentação da API de Integração entre PROGRESS e Microsoft Excel 97 (docapi/utapi003. o oitavo parâmetro é a Confirmação de Leitura.P A API utp/utapi003. permitindo a construção de planilhas e. o segundo parâmetro deve ser o E-Mail ou o número do FAX para uma "Cópia Carbono" (Cc). também.doc). o sétimo parâmetro é a Confirmação de Envio. ou seja. o sexto parâmetro é o Grau de Importância.. receber um E-Mail quando o E-Mail foi enviado.com.Construção de Programas utilizando os Estilos e suas Técnicas 255 UTAPI003. ou seja. 1 Médio. o quarto parâmetro é a mensagem.br") ou o número do FAX (Exemplo: "[FAX:9999999]"). UTAPI004.p (input input input input .P Objetivo Parâmetros Permitir o envio de E-Mail ou FAX através do EMS 2. o quinto parâmetro é o arquivo anexo (attachment). • o primeiro parâmetro deve ser endereço E-Mail do destinatário (Exemplo: "
[email protected] faz a Integração entre PROGRESS e Microsoft Excel 97. sys". o sexto parâmetro é o Assunto (Subject). UTAPI005. Configuração Para que o programa de envio de E-Mail funcione é preciso que esteja cadastrado corretamente o endereço IP do servidor de E-Mail a sua porta nos Parâmetros Globais do Sistema. yes). no.P Objetivo Parâmetros Permitir o envio de E-Mail através do EMS 2. • • • • • . Devem ser passados oito parâmetros para este programa: • o primeiro parâmetro deve ser o endereço IP do servidor de E-Mail que pode ser adquirido da tabela de Parâmetros Globais do Sistema (paramglobal serv-mail).porta-mail).input input input input input "c:\autoexec. o terceiro parâmetro deve ser o remetente (Exemplo: "fulano"). OK E-Mail enviado com sucesso.com. Retorno NPG Não existe registro na tabela de Parâmetros Globais do Sistema. c:\config.bat. o quarto parâmetro deve ser o endereço E-Mail do destinatário (Exemplo: "fulano@internet. NEX O Servidor de E-Mail não é MS-Exchange conforme os Parâmetros Globais do Sistema.br").0 usando um servidor UNIX ou qualquer outro servidor com suporte ao protocolo SMTP. NCC Destinatário da Cópia Carbono inválido. ATT O Arquivo Anexo não foi encontrado. o segundo parâmetro deve ser a porta do servidor de E-Mail. NDE Destinatário inválido. que também pode ser adquirida na tabela de Parâmetros Globais do Sistema (paramglobal. o quinto parâmetro deve ser o E-Mail para uma "Cópia Carbono" (Cc). no. 0. 25. c-cc. deve ser o diretório para a criação do SCRIPT de envio de E-Mail. o oitavo parâmetro.p (input input input input input input input input Retorno Se o retorno (return-value) desse programa for igual a Ok. c-mesg. . c-to. pode ser deixado em branco. senão. Configuração Para que o programa de envio de E-Mail funcione é preciso que esteja cadastrado corretamente o endereço IP do servidor de E-Mail e a sua porta nos Parâmetros Globais do Sistema.Construção de Programas utilizando os Estilos e suas Técnicas 257 • • o sétimo parâmetro é a mensagem.89". senão algum erro ocorreu no envio ou os parâmetros passados não estão corretos. o mail foi enviado com sucesso. Exemplo run utp/utapi004. caso esteja enviando E-Mail via UNIX. c-from. ""). "172.16. c-assunto.1. br. Instalação Interface Para que o programa de envio de E-Mail funcione.p.doc). Maiores informações podem ser obtidas na documentação da API para Uso de Funções do Excel no Progress (docapi/utapi007." (ponto e vírgula). No programa responsável por buscar os dados deve ser feita a inclusão do include: utp/utapi006. No programa responsável por usar esta API deve ser feita a inclusão do include: utp/utapi007. para retornar os resultados para um programa Progress. onde estão as definições das temp-table´s que devem ser passadas como parâmetros à API utp/utapi007. output table tt-erros). O mesmo acontece para a Cópia Carbono.br".Observação O programa permite enviar um E-Mail para várias pessoas. Maiores informações podem ser obtidas na documentação da API para Busca de Dados do Excel para o Progress (docapi/utapi006. output table tt-erros). onde estão as definições das temp-table´s que devem ser passadas como parâmetros à API utp/utapi003.i." (vírgula) ou por ".BAT. A chamada da API deve seguir o padrão abaixo: run utp/utapi006. que se encontra no diretório \INTERFAC\MAIL. UTAPI007. Este programa não possui interface. deve ser executado o arquivo INSTALA.p (input-output table tt-dados.i.p (input-output table tt-dados.doc). O assunto e a mensagem podem ser passadas em branco. Para isto devese passar cada nome separado por ". Exemplo:
[email protected] A API utp/utapi006.P A API utp/utapi007. Exemplo: ("") O remetente nunca pode conter espaços em branco.p permite o uso de funções do Excel. Apenas envia o E-Mail.com.p. . A chamada da API deve seguir o padrão abaixo: run utp/utapi007. UTAPI006.com.p permite a busca de dados de uma planilha Excel para o Progress. beltrano@internet. i . Importante Para novos programas que venham a utilizar esta API. é recomendado que seja utilizado o programa utp/utapi018 ao invés deste.doc). Importante Para novos programas que venham a utilizar esta API.i Versão de Integração: 001 Objetivo Envio de mensagens através do servidor de correio eletrônico e envio de FAX através de servidor de FAX.p Nome do Include com os Parâmetros: utp/utapi009.P Nome Físico: utp/utapi010. Maiores informações podem ser obtidas na documentação da API de Integração entre Progress e Microsoft Excel 97 (docapi/utapi008.p Nome do Include com os Parâmetros: utp/utapi008.i Versão de Integração: 001 Objetivo Atualização de arquivos para o Microsoft Excel 97 e retorno de informações para o Progress.doc).P Nome Físico: utp/utapi009. Maiores informações podem ser obtidas na documentação da API de Envio de FAX/E-mail (docapi/utapi009. é recomendado que seja utilizado o programa utp/utapi019 ao invés deste.P Nome Físico: utp/utapi008.p Nome do Include com os Parâmetros: utp/utapi010. UTAPI010. UTAPI009.Construção de Programas utilizando os Estilos e suas Técnicas 259 UTAPI008. para o Microsoft Word.doc). Sendo que os parâmetros recebidos são utilizados para preencher os campos de formulário existentes no documento.P Nome Físico: utp/utapi011.i Versão de Integração: 001 Objetivo Criação de arquivos. baseados em formulários.doc). Importante Para novos programas que venham a utilizar esta API. Maiores informações podem ser obtidas na documentação da API para Criação de Gráficos (docapi/utapi011.i Versão de Integração: 003 Objetivo A API de geração de gráficos tem por finalidade exibir gráficos de acordo com os parâmetros a ela passados.P Nome Físico: utp/utapi012. Maiores informações podem ser obtidas na documentação da API para Compartilhar Impressoras do EMS com Programas Magnus (docapi/utapi010. UTAPI011.p Nome do Include com os Parâmetros: utp/utapi012. . não deve-se realizar nenhuma alteração pois estão sendo feitas correções nessa API.Versão de Integração: 001 Objetivo Permitir que impressoras cadastradas no EMS sejam utilizadas em programas compilados contra os bancos do MAGNUS. UTAPI012. Para os programas antigos que já utilizam essa API. é recomendado entrar em contato com a equipe de Suporte ao Desenvolvimento no ramal 7125 antes de utiliza-lá.p Nome do Include com os Parâmetros: utp/utapi011. i Versão de Integração: 001 . Maiores informações podem ser obtidas na documentação da API de Integração entre Progress e Microsoft Excel (docapi/utapi018. UTAPI019.P Nome Físico: utp/utapi018.P Nome Físico: utp/utapi019.p Nome do Include com os Parâmetros: utp/utapi013.i Versão de Integração: 001 Objetivo Faz a Integração entre Progress e Microsoft Excel..p Nome do Include com os Parâmetros: utp/utapi018.doc). UTAPI018.Construção de Programas utilizando os Estilos e suas Técnicas 261 Maiores informações podem ser obtidas na documentação da API de Integração entre Progress e Microsoft Word (docapi/utapi012.p Nome do Include com os Parâmetros: utp/utapi019.i Versão de Integração: 001 Objetivo Atualização de arquivos para o Microsoft Excel e retorno de informações para o Progress. gráficos. Maiores informações podem ser obtidas na documentação da API de Integração entre Progress e Microsoft Excel (docapi/utapi013. também.P Nome Físico: utp/utapi013. UTAPI013. permitindo a construção de planilhas e.doc).doc). Objetivo Envio de mensagens através do servidor de correio eletrônico e envio de FAX através de servidor de FAX.i Versão de Integração: 001 .doc). UTAPI028. UTAPI027. sendo que a decisão de gravar ou não o documento caberá ao usuário final.p Nome do Include com os Parâmetros: utp/utapi029. Maiores informações podem ser obtidas na documentação da API de Envio de FAX/E-mail (docapi/utapi019. baseados em formulários para o Microsoft Word.P Nome Físico: utp/utapi028.P Nome Físico: utp/utapi027.doc).i Versão de Integração: 001 Objetivo Criação de documentos.doc).p Nome do Include com os Parâmetros: utp/utapi028.P Nome Físico: utp/utapi029. Maiores informações podem ser obtidas na documentação da API de Integração entre Progress e Microsoft Word (docapi/utapi027.i Versão de Integração: 001 Objetivo Envio de compromisso do tipo reunião via Microsoft Outlook. UTAPI029.p Nome do Include com os Parâmetros: utp/utapi027. Maiores informações podem ser obtidas na documentação da API de Envio de compromisso via Outlook (docapi/utapi028. APAPI009.p Nome do Include com os Parâmetros: app/apapi009. Exemplo: run utp/utapi008. Parâmetros de Entrada Temp-table tt-referencia: nesta temp-table deverão ser repassadas as informações de atualização dos pagamentos extra fornecedor. TEMP-TABLE TT-REFERENCIA Atributo i-ep-codigo c-referencia c-usuario l-vid-rel Tipo Integer Character Character Logical Formato Valor Inicial Obrigatório Sim Sim Sim Sim Sim Cod-versao-integ Integer .P Nome Físico: app/apapi009. devem ser passadas 1 (uma) temp-table de entrada e 1 (uma) de saída contendo as informações para atualização dos PF´s. Maiores informações podem ser obtidas na documentação da API de Integração com Excel Web (docapi/utapi029.doc).p (input table tt-referencia. Consideraçõe • s Gerai • s • a API funciona da seguinte forma: Recebe como parâmetro a temp-table.i Versão de Integração: 001 Objetivo Consistir os parâmetros passados e caso estejam Ok atualizar os pagamentos. faz as críticas e caso não tenha ocorrido nenhum problema atualiza os pagamentos.Construção de Programas utilizando os Estilos e suas Técnicas 263 Objetivo A API de Integração com excel tem como função gerar código javascript para gerar planilhas e gráficos no excel em programas estilo pai x filho. output table tt-erro-pef). todas as temp-tables são passadas como parâmetro através dos comandos INPUT TABLE ou OUTPUT TABLE. TEMP-TABLE TT-ERRO-PEF Atributo i-cod-erro c-desc-erro c-arquivo-erro Tipo Integer Character Character Formato 9999999 "x(70)" "x(100)" Descrição Código da mensagem de erro Descrição da mensagem de erro Informações com inconsistências Valor Inicial Obrigatório Sim Sim Não Atributo i-cod-erro c-desc-erro c-arquivo-erro Execução O programa app/apapi009.l-vid-rel=yes com o código do erro. a API abortará a execução retornando através da temp-table tt-erro-pef o código de erro 3941. Número do Erro 3941 Mensagem Versão de integração incorreta ! Ajuda Aversão de integração informada . descrição e informações dos registros com inconsistências. Caso a versão esteja incompatível.p irá primeiramente validar a versão de integração: Validação: Versão de Integração O programa irá verificar se o programa chamador está íntegro com a API. e isto ocorre através da verificação da versão de integração passada como parâmetro através da temp-table tt-referencia (campo cod-versao-integ).l-acompanha Logical Descrição Empresa do pagamento Referência a ser atualizada Versão de integração Usuário corrente Sim Atributo i-ep-codigo c-referencia cod-versao-integ c-usuario l-vid-rel l-acompanha Mostra mensagens na tela ou gera temp-table de erros Mostra acompanhamento na tela? Parâmetros de Saída Temp-table tt-erro-pef: serão gerados registros nesta temp-table quando ttreferencial. Construção de Programas utilizando os Estilos e suas Técnicas 265 através dos parâmetros internos é incompatível com a versão atual da API. Favor contatar suporte técnico. também as seguintes consistências. Número do Erro 774 8759 6280 Mensagem Empresa &1 não cadastrada Ajuda Empresa &1 não cadastrada. a seleção não será feita. . Além da versão de integração são efetuadas. Cabe ao programa de origem. Parâmetro do Contas a Pagar não Parâmetro do Contas a Pagar não cadastrado cadastrado para esta empresa Referência inexistente ! Não foram encontrado movimentos PEF/PEC pendentes cadastrados com a referência informada. Caso ocorra um dos erros acima. verificar os registros que estão com erro. não . compilados em ambiente Windows e que não tenha respeitado as regras de portabilidade. tanto explícitas como implícitas). isto não é possível. MS-Windows) and tried to run it under another (for example. podem ser executados via RPW/RPC e geralmente em ambiente Unix. Your procedure file is portable across windowing system. As três regras são: • códigos que não possuem comandos de User-Interface (especificamente. códigos que não criam frames. (4438) You have frames in your program. caso contrário. Regras para Portabilidade de RCODE Para que seja possível a portabilidade de RCODES. Cannot run without recompile. You compiled it under one windowing system (for example. três regras básicas devem ser obedecidas. é apresentado o erro 4438 como descrito a seguir: Program <program-name> was compiled under another incompatible display environment.CAPÍTULO 14 Portabilidade de RCODES Objetivo O objetivo da análise de portabilidade de RCODES é validar o funcionamento dos programas compilados em ambiente Windows e executados em ambientes Unix. Caso contrário. but you need to produce separate r-code files for each windowing system. Isto se faz necessário porque programas que respeitam as regras para portabilidade de RCODE. R-code with user interface components in it is only portable within a windowing system. existe a necessidade de recompilação do programa. tty). Ao executar programas no Unix. deve ter o mesmo tamanho de palavra e alinhamento de bytes. por algum motivo. Como exemplo. Outra solução para este problema. O comando DISPLAY cria uma FRAME impossibilitando o uso do programa compilado em ambiente Windows.Construção de Programas utilizando os Estilos e suas Técnicas 267 pertencem a nenhuma arquitetura para mostrar informações. . alguns problemas foram detectados com a descoberta de comandos que criam. estão os programas em batch (RPW). Por exemplo: output to value(c-arquivo) find emitente where emitente. Um exemplo para o problema da não compatibilidade de RCODE e sua correção.cod-emitente with stream-io. display emitente. FRAMES implícitas.cod-emitente = 10 no-lock. em um ambiente Unix ou vice-versa. put emitente. é necessário utilizar a função STREAM-IO para reformatar a saída para texto puro. sem formatação de fonte: output to value(c-arquivo) find emitente where emitente. Para solucionar este problema de incompatibilidade. é usar o comando PUT. mesma classe de plataforma de servidor. output to value(c-arquivo) find emitente where emitente.cod-emitente. display emitente. Caso em Especial A partir da regra de não utilizar comandos que criam FRAMES explícitas ou implícitas.cod-emitente = 10 no-lock. Para que o erro 4438 ocorra.cod-emitente = 10 no-lock. pois o mesmo não usa FRAME. • • mesmo tipo de banco de dados. é o uso de frames ou comandos que criam frames. é necessário compilar um programa que possui frame em ambiente Windows e tentar executar o mesmo (RCODE) em ambiente UNIX.cod-emitente. caso contrário. é necessário identificar se existe outra maneira para realizar a tarefa desejada. será necessário manter um RCODE por ambiente existente. Para os casos identificados. isto é. um RCODE para ambiente Windows e outro para ambiente Unix. Para solucionar o problema. será necessário manter RCODES para cada ambiente existente.Até o momento foi constatado o problema nos comandos CREATE SERVER e EXPORT. Para o comando CREATE SERVER. o comando EXPORT pode ser substituído por PUT ou DIPLAY (utilizando a opção STREAM-IO). . 269 CAPÍTULO 15 Técnicas Como alterar o caracter de senha Objetivo Esta técnica pode ser usada sempre quando for usado um fill-in do tipo blank, ou seja, sempre que for colocada alguma informação que não possa ser visualizada. inserir a chamada da include i-win.i, no início do bloco de definições; {include/i-win.i} Implementaç • ão • rodar o procedimento SendMessageA, passando os seguintes parâmetros: • • • • o atributo hWnd do fill-in; o valor {&EM_SetPasswordChar}; o caracter que deve ser mostrado na entrada da senha; o valor 0 (zero). run SendmessageA in hpApi (input fill-in-2:hwnd, input {&EM_SetPasswordChar}, input ASC ("*"), input 0). Como alterar o diretório corrente Objetivo Esta técnica pode ser usada quando for necessário mudar o diretório corrente em tempo de execução. Isto permite que o diretório corrente seja fixo. Implementaç • ão • • inserir a chamada da include i-win.i, no início do bloco de definições; {include/i-win.i} definir uma variável do tipo handle; def var h-prog as handle no-undo. rodar o programa ut-utils.p persistente e atribuir o seu handle para a variável que foi criada anteriormente; run utp/ut-utils.p persistent set h-prog. • rodar o procedimento SetCurrentDir que deve estar dentro do programa ututils.p passado o seguinte parâmetro: • a novo caminho do diretório corrente; run SetCurrentDir in h-prog(input "C:\WINDOWS\TEMP"). • eliminar o programa ut-utils.p que foi rodado persistente da memória. delete procedure h-prog. Observação Não esquece de executar o último procedimento descrito, pois na falta deste, o sistema pode ficar sem recursos e travar. Como alterar ou criar uma variável de ambiente Objetivo Esta técnica permite inserir ou alterar uma variável de ambiente em tempo de execução. Sempre utilizar esta técnica ao invés de usar o comando OSCOMAND SET (...), pois este fará com que a variável de ambiente fique setada apenas na sessão DOS que foi aberta. Esta técnica seta uma variável de ambiente do WINDOWS e não DOS. inserir a chamada da include i-win.i, no início do bloco de definições; {include/i-win.i} Implementaç • ão • • definir uma variável do tipo handle; def var h-prog as handle no-undo. rodar o programa ut-utils.p persistente e atribuir o seu handle para a variável que foi criada anteriormente; run utp/ut-utils.p persistent set h-prog. Construção de Programas utilizando os Estilos e suas Técnicas 271 • rodar o procedimento SetEnv que está dentro do programa ut-utils.p, passando os seguintes parâmetros: • • a variável de ambiente que deve ser criada: o valor para esta variável de ambiente; run SetEnv in h-prog(input "TEMP", input "C:\WINDOWS\TEMP"). • eliminar o programa ut-utils.p que foi rodado persistente da memória. delete procedure h-prog. Observação Não esquecer de executar o último procedimento descrito, pois na falta deste o sistema pode ficar sem recursos e travar. Como dar foco a qualquer objeto Objetivo Essa técnica deve ser utilizada quando for necessário dar foco a qualquer objeto, mesmo sendo uma janela. inserir a chamada da include i-win.i, no início do bloco de definições; {include/i-win.i} Implementaç • ão • • definir uma variável do tipo handle; def var h-prog as handle no-undo. rodar o programa ut-utils.p persistente e atribuir o seu handle para a variável que foi criada anteriormente; run utp/ut-utils.p persistent set h-prog. • rodar o procedimento ApplyFocus que está dentro do programa ut-utils.p, passando o seguinte parâmetro: • o atributo hWnd do objeto que deve receber o foco; run ApplyFocus in h-prog(input {&window-name}:hWnd). • eliminar o programa ut-utils.p que foi rodado persistente na memória. delete procedure h-prog. Observação Não esquecer de executar o último procedimento descrito, pois na falta deste, o sistema pode ficar sem recursos e travar. Como deixar uma janela sempre visível Objetivo Esta técnica pode ser usada sempre que uma janela, mesmo perdendo o foco, permaneça visível. inserir a chamada da include i-win.i, no início do bloco de definições; {include/i-win.i} Implementaç • ão • • definir uma variável do tipo handle; def var h-prog as handle no-undo rodar o programa ut-utils.p persistente e atribuir o seu handle para a variável que foi criada anteriormente; run utp/ut-utils.p persistent set h-prog. • rodar o procedimento SetTopMost que está dentro do programa ut-utils.p, passando os seguintes parâmetros: • • o atributo hWnd da window que deve ficar sempre visível; o valor yes se a janela deve ficar sempre visível; run SetTopMost in h-prog(input {&window-name}:hWnd, input yes). • eliminar o programa ut-utils.p que foi rodado persistente da memória. delete procedure h-prog. Observação Não esquecer de executar o último procedimento descrito, pois na falta deste, o sistema pode ficar sem recursos e travar. Como utilizar OCX Objetivo Permitir a construção de programas que utilizam OCX. Construção de Programas utilizando os Estilos e suas Técnicas 273 Instalação Faz-se necessário que o OCX esteja registrado na máquina onde será desenvolvido o programa. O programa para registrar e instalar cada OCX encontra-se na pasta interfac dos produtos Datasul. O diretório onde se encontra o pacote para instalação desse ActiveX é em \interfac\Estruct\ e o arquivo que possui esse componente é MSCOMCTL.ocx. O nome do componente a ser utilizado é Microsoft Treeview Control, Version 6.0. Este ActiveX Controle possui os seguintes métodos: 1. Nodes: Clear Remove todas as entradas. ChTreeView:TreeView:Nodes:Clear(). 2. Nodes: Add Adiciona um item para a estrutura. Sintaxe: TreeView:Nodes:Add(<Nivel relativo>, <Grau>, <Identificador>, <Label>) Onde: <Nivel relativo> - O pai de item a ser incluso. Caso o item seja do primeiro nível, este deve ser em branco. <Grau>- Caso o item a ser incluso seja um filho, deve ser passado 4 senão deve ser em branco. <Identificador>- Chave única para o item a ser incluso. <Label>- O label do item a ser incluso. ChTreeView:TreeView:Nodes:Add(, , "Nivel1", "Pai"). ChTreeView:TreeView:Nodes:Add("Nivel", 4, "Nivel2", "Filho"). Neste exemplo, é criado um item "Pai" com um identificador "Nivel1" e logo após é criado um item "Filho" para o "Nivel1" com um identificador "Nivel2". Para criar-se um filho deve-se utilizar o grau 4. 3. SelectedItem:Key Retona a chave do nodo selecionado na árvore. Exemplo: MESSAGE ChTreeView:TreeView:SelectedItem:KEY VIEW-AS ALERT-BOX INFO BUTTONS OK. O comando contido neste exemplo mostrará uma mensagem contendo a chave do nodo selecionado. Considerando que o nodo selecionado fosse o TreeView nodo de label “Pai” do exemplo do método Nodes:Add, o valor exibido seria “Nível1”. 4. SelectedItem:Index Retorna o indice do nodo selecionado na árvore. Exemplo: ASSIGN i-escolha = chCtrlFrame:TreeView:SelectedItem:Index. Nesse caso o indice do nodo selecionado ficará armazenado na variável iescolha. Contando que foram criados 4 (quatro) nodos Pai e um nodo filho, o valor armazenado seria 5 (cinco) caso o filho fosse o nodo selecionado. 5. SelectedItem:Text Retorna o texto do nodo selecionado na árvore. Exemplo: ChTreeView:TreeView:Nodes:Add("rh-1", 4, "rh-1-2", "Folha de Pgto "). /* Após seleção do novo nodo criado acima */ MESSAGE ChTreeView:TreeView:SelectedItem:Text VIEW-AS ALERT-BOX INFO BUTTONS OK. A mensagem desse exemplo exibira o texto “Folha de Pgto” quando o nodo criado acima for selecionado. Observação Deve-se utilizar sempre o TreeView da Microsoft (COMCTL32.OCX). Todos os programas que hoje estão construídos e utilizando o TreeView da Datasul, não precisam ser alterados. Construção de Programas utilizando os Estilos e suas Técnicas 275 ImageList Deverá ser colocado na propriedade tag do OCX (TreeView ou ListView) o nome do ImageList utilizado. Se estivermos utilizando um OCX TreeView o nome do OCX deverá ser TreeView, e se estivermos utilizando um OCX ListView o nome do OCX deverá ser ListView.. O diretório onde se encontra o pacote para instalação desse componente é em \interfac\Grafico \ e o arquivo que possui esse componente é COMCTL32.ocx. O nome do componente a ser utilizado é Microsoft ImageList Control, version 5.0. No objeto ImageList deverá ser colocado o nome do arquivo da imagem na propriedade tag de cada imagem dentro do mesmo. As imagens adicionadas no ImageList deverão ser expedidas dentro da pasta imagens do produto. Observação A utilização do ImageList é necessária para que o programa possa ser executado pelo WebEnabler. Na ausência do mesmo o programa executará sem imagens. PSTimer Este controle permite que sejam programadas execuções de uma rotina dentro de determinados intervalos de tempo. Para interagir com esse objeto você deve utilizar o evento “Tick” do mesmo. Esse evento é disparado sempre que se passar o intervalo de tempo determinado na propriedade “Interval”. Construção de Programas utilizando os Estilos e suas Técnicas 277 Esse componente já acompanha o Progress e por isso não precisa ser instalado. Tick É o evento que é disparado após cada intervalo de tempo determinado.ocx. Sintaxe: <com-handle>:Controls:Item(1):Largura. Caso o valor setado seja 0 não será disparado o evento.Informa-se o caminho da imagem desejada. O nome do componente a ser utilizado é Progress Timer Control. O nome do componente a ser utilizado é DatasulImage.Largura da área onde a imagem poderá ser exibida. chCtrlFrame:Controls:Item(1):ENABLED = TRUE. chCtrlFrame:Controls:Item(1):imagem = "c:/tmp/amostra. Sintaxe: <com-handle>:Controls:Item(1):imagem. esta propriedade é tanto de leitura quanto de escrita. o arquivo que possui esse componente é PSTIMER. o valor dessa propriedade pode ser utilizado para leitura e para escrita. Propriedades: • Imagem . sempre que for setado para true o evento Ticker será disparado após o intervalo de tempo determinado. chCtrlFrame:Controls:Item(1):Interval = 50. O diretório onde se encontra o pacote para instalação desse componente é em \interfac\imagem\ e o arquivo que possui esse componente é DATIMAGE.jpg". Propriedades • Enabled É uma propriedade do tipo Lógico (true/false). Sintaxe: <com-handle>:Controls:Item(1):ENABLED. chCtrlFrame:Controls:Item(1):Largura = 500. • Evento • Imagem A imagem é um componente OCX que permite a visualização de imagens em um programa progress.ocx. • . Largura . Sintaxe: <com-handle>:Controls:Item(1):Interval. Interval É uma propriedade do tipo Integer e nela especifica-se qual o intervalo de tempo(em milisegundos) que se quer esperar entre uma ocorrência do evento Ticker e outra.Imagem. Possui a propriedade “arquivo” que informa ou recebe o nome do arquivo está sendo executado ou que irá ser executado. • • • MediaPlayer Componente que permite a execução de filmes em aplicações progress. chCtrlFrame:Controls:Item(1):ajusta = yes.MediaPlayer.Altura da imagem. Sintaxe: <com-handle>:Controls:Item(1):AlturaFigura. Ajusta .avi" chCtrlFrame:Controls:Item(1):comando = "open" chCtrlFrame:Controls:Item(1):comando = "play". . e a propriedade comando que recebe ou informa o comando que está sendo executado.ocx. propriedade de escrita e de leitura. AlturaFigura . Sintaxe: <com-handle>:Controls:Item(1):Altura. propriedade de escrita e de leitura.• Altura . LarguraFigura . chCtrlFrame:Controls:Item(1):AlturaFigura = 500. Exemplo: ASSIGN chCtrlFrame:Controls:Item(1):arquivo = "c:/tmp/count. Sintaxe: <com-handle>:Controls:Item(1):LarguraFigura.Determina-se se a imagem irá se ajustar para ser totalmente exibida dentro da área determinada. este valor pode ser lido e alterado. ASSIGN chCtrlFrame:Controls:Item(1):comando = "stop".Altura da área onde a imagem poderá ser exibida. O nome do componente a ser utilizado é DatasulMultimedia. O diretório onde se encontra o pacote para instalação desse componente é em \interfac\video\ e o arquivo que possui esse componente é DATVIDEO. este valor pode ser acessado tanto para leitura quanto para escrita. PAUSE. chCtrlFrame:Controls:Item(1):LarguraFigura = 500. Sintaxe: <com-handle>:Controls:Item(1):ajusta. chCtrlFrame:Controls:Item(1):Altura = 500.Largura da imagem. Construção de Programas utilizando os Estilos e suas Técnicas 279 ListView O diretório onde se encontra o pacote para instalação desse componente é em \interfac\Estruct\ e o arquivo que possui esse componente é MSCOMCTL. version 6. "Item1". "Item1". <SmallIcon> .É o índice do smallicon na lista de smallicons. a Key não pode repetir nos itens da ListView. <Icon> . . Este componente funciona de maneira muito semelhante ao TreeView.É uma chave única de cada item. "indice". 3).CellView. <Text> . "indice".ocx.ocx.OCX). Onde: <Index> .0. Sintaxe: <com-handle>:ListView:ListItems:Clear. <Key>. <SmallIcon>). caso não seja necessário esse controle pode-se omitir essa informação. Sintaxe: <com-handle>: Add (<Index>. <Text>. ). chCtrlFrame: ListView:ListItems:Clear. Esse componente possibilita a visualização de células. sendo que seus métodos básicos são: • ListView:ListItems:Clear Este método elimina todas as entradas da ListView. chCtrlFrame:ListView:ListItems:Add ( 1. esse índice também é opcional. seus principais métodos e propriedades são: • CellView . <Icon>. <Key> . chCtrlFrame:ListView:ListItems:Add ( . esse índice é opcional. O diretório onde se encontra o pacote para instalação desse componente é em \interfac\Cellsvwr\ e o arquivo que possui esse componente é CELLSVWR. Observação Deve-se utilizar sempre o ListView da Microsoft (COMCTL32. . O nome do componente a ser utilizado é Microsoft ListView Control.É o índice do ícone na lista de ícones. ListView:ListItems:Add Adiciona um item à ListView. O nome do componente a ser utilizado é CellsVwr.É o texto que irá ser exibido na ListView para representar o item.É o índice do item dentro da ListView. • • • DTPicker Componente para visualização de calendário.ocx. atribuímos a data corrente do sistema operacional para o componente DTPicker. AddLink Este método é utilizado para adicionar células.OCX.Character-Text.Character-PrevToolTipText."Key1". O nome do componente a ser utilizado é Microsoft Date and Time Picker Control 6. END PROCEDURE.Character-PrevText."Item1".Click.CharacterPrevKey. Sintaxe: <com-handle>: AddLink (Integer-Level."Tip2"). Character-ToolTipText). O diretório onde se encontra o pacote para instalação desse componente é em \interfac\calendar\ e o arquivo que possui esse componente é MSCOMCT2. seu atributo mais utilizado é o Value."Tip1". Click Evento disparado quando um item. PROCEDURE CtrlFrame.Click : DEFINE INPUT PARAMETER Key AS CHARACTER. No exemplo acima. chctrlframe:CellView:CellsCount. CellsCount Propriedade apenas para leitura. Aloca_Tarefa Esse componente OCX permite a exibição de um gráfico que facilita a representação da agenda de compromissos de uma ou várias pessoas. O gráfico . Sintaxe: <com-handle>:CellsCount.0. que informa a quantidade de células existentes. Exemplo: chCtrlFrame:Controls:Item(1):value = today. Sintaxe: <control-frame>."Item2".CharacterKey. recebe um clique do usuário. que foi criado. chctrlframe:CellView:ClearCells. Sintaxe: <com-handle>:Value."Key2". chctrlframe:CellView:AddLink (0. Sintaxe: <com-handle>:ClearCells. Existe um parâmetro de entrada que é a Key do item selecionado.<control>.• ClearCells Este método limpa todas as células. todos os parâmetros são obrigatórios. Alocacoes_Tarefa_Navegar Este método faz com que o componente exiba a locação de horários das tarefas que estão na mesma data que a tarefa que estava selecionada no momento em que o método foi chamado.01. chctrlframe:Aloca_Tarefa:objetos_mostrar.Aloca_Tarefa. Sintaxe: <com-handle>:Tela_limpar. Character-tooltip_tar. chctrlframe:Aloca_Tarefa:Alocacoes_Tarefa_Navegar(). Sintaxe: <com-handle>:Alocacoes_Tarefa_Navegar(). • • • • • .ocx. O nome do componente a ser utilizado é Barras. Integer-cor_aloc ). Charactertexto_tar. Sintaxe: <com-handle>:objetos_mostrar.Construção de Programas utilizando os Estilos e suas Técnicas 281 gerado exibe a locação dos horários por tarefa cadastrada. Sintaxe: <com-handle>:Tarefa_Retorna_Id(). Character-tooltip_aloc. este valor pode se repetir mas quando isso acontecer todas as tarefas com o mesmo id serão exibidas em uma mesma linha. Onde: <tarefa_id>: É o identificador da tarefa. Date-dt_aloc. Character-hora_ini. objetos_mostrar Método que exibe no componente as tarefas que foram inseridas no mesmo. Tarefa_Retorna_Id Método que retorna um valor caracter que representa o id da tarefa que está selecionada. Seus principais métodos são: • Data_Inicial_Setar Este método informa qual a data inicial que será utilizada pelo componente. todas as tarefas que estavam sendo exibidas deixam de ser exibidas no componente. Alocar É utilizando esse método que se adiciona tarefas para o componente. Sintaxe: <com-handle>: Data_Inicial_Setar (dt-ini AS DATE). Characterhora_fim. chctrlframe:Aloca_Tarefa:Data_Inicial_Setar (DATE(01. chctrlframe:Aloca_Tarefa:Tarefa_Retorna_Id(). Tela_limpar Quando este método é invocado. chctrlframe:Aloca_Tarefa:Tela_limpar. Sintaxe: <com-handle>: Alocar ( Character-tarefa_id. O diretório onde se encontra o pacote para instalação desse componente é em \interfac\barra\ e o arquivo que possui esse componente é BARRAS_2.2004)). >>9. chctrlframe:Aloca_Tarefa:Alocar ("1".99"). <hora_fim>: Horário de término da tarefa. Sintaxe: <com-handle>:Tela_Limpar(). basta invocar o método e passar um valor inteiro para definir o estilo da linha. 3 – Tracejado."12:00". <hora_ini>: Horário de início da tarefa. Valor_Maximo_Setar Esse método permite que seja definido qual o valor máximo das colunas do gráfico. <dt_aloc>: Data em que a tarefa está sendo alocada. Linhas_Trocar_Estilo Utilizando esse método podemos alterar os estilos das linhas dos gráficos. O nome do componente a ser utilizado é PColunas51. chCtrlFrame:UColunas:Tela_Limpar().12:00 / 3 Pessoas". chCtrlFrame:UColunas:Valor_Maximo_Setar (10. <tooltip_tar>: É o tooltip do texto da tarefa."Tarefa 01". Sintaxe: <com-handle>: Valor_Maximo_Setar (Valor AS FLOAT. 2 – Pontilhado. UColunas Componente para geração de gráficos em colunas que possibilita a exibição de diversas colunas e cada coluna com no máximo mais 5 colunas. • • ."TIP .500).Character-c_format ). Os estilos de linha são: 1 – Sem linha.Tarefa 01". <tooltip_aloc>: É o tooltip da representação de locação de horário no componente. <cor_aloc>: Através desse parâmetro é possível alterar a cor de exibição da locação de horário. chCtrlFrame:UColunas:Linhas_Trocar_Estilo (4).">>>>>. sua funcionalidade é de limpar as barras que já estejam sendo exibidas.Ucolunas."01/05/2004". "08:30".<texto_tar>: Texto que é exibido no canto esquerdo do gráfico e indica qual tarefa está sendo representada naquela linha.ocx. O diretório onde se encontra o pacote para instalação desse componente é em \interfac\graf-col\ e o arquivo que possui esse componente é COLUNAS5. Seus principais métodos e atributos são: • Tela_Limpar Como o próprio nome do método sugere. Sintaxe: <com-handle>:Linhas_Trocar_Estilo (Valor AS Integer). "08:30 . 4 – Linhas. val1 AS FLOAT. O nome do componente a ser utilizado é Microsoft Communications Control. val4 AS FLOAT. <leg_x1 e leg_x2>: São as legendas que podem ser atribuídas para os grupos de colunas do componente. Handshaking Handshaking é o protocolo que é utilizado pelo hoardware para se comunicar através da porta serial. 7. "Teste1". • • MSComm O MSComm é um componente OCX produzido pela Microsoft que possibilita a comunicação da aplicação com outros dispositivos que estejam previamente configurados e aptos para realizar essa comunicação. Suas propriedades mais utilizadas são: • CommPort Com essa propriedade podemos ver ou alterar qual a porta que o componente irá utilizar para se comunicar com outros dispositivos. chCtrlFrame:UColunas:Coluna_Selecionada(). Character-leg_x2). 9. ASSIGN chComm:MSComm:CommPort =500. 10. 8. "Texto 2"). val2 AS FLOAT. 6. Character-leg_x1. <val1 – val5>: É o valor correspondente de cada coluna do grupo. Coluna_Selecionada Este método retorna uma string com o identificador + posição da coluna no grupo. Sintaxe: <com-handle>:Objetos_Mostrar(). Objetos_Mostrar Método que exibe os grupos de colunas criados na tela.0. Onde: <Id>: É o identificador de cada grupo. Essa string permite identificar unicamente cada uma das colunas. val3 AS FLOAT. val5 AS FLOAT. version 6. Sintaxe: <com-handle>:Coluna_Selecionada(). chCtrlFrame:UColunas:Objetos_Mostrar(). Exemplo: chCtrlFrame:UColunas:Colunas_Criar (1. O diretório onde se encontra o pacote para instalação desse componente é em \interfac\BCportaserial\ e o arquivo que possui esse componente é MSCOMM32.Construção de Programas utilizando os Estilos e suas Técnicas 283 • Colunas_Criar Este método permite a criação de grupos de coluna sendo que cada grupo é composto por no máximo 5 colunas. Sintaxe: <com-handle>:CommPort. Essa propriedade • . Sintaxe: <com-handle>: Colunas_Criar (Id AS SHORT.ocx. • ProgressBar Como o próprio nome sugere. e para abrir ou fechar a porta basta setar yes ou no para a porta. chComm:MSComm:PortOpen = NO. version 5. quantidade de bits e o bit de parada. Caso a proprieade seja chamada e o valor obtido for “no” significa que a porta está fechada e se o valor for “yes” significa que a porta está aberta. 1 – XonXoff. ASSIGN chComm:MSComm:Handshaking = 0.4. essas configurações são os números de bits por segundo. Todas as configurações devem ser atribuídas ao componente através de uma string que deve separar cada informação com uma “. Sintaxe: <com-handle>:Handshaking. ASSIGN chctrlframe:ProgressBar:Min = 0. Max Por meio dessa propriedade definimos qual o maior valor que a barra de progresso poderá assumir. PortOpen Com essa propriedade podemos abrir ou fechar a porta de comunicação e também podemos apenas obter qual o estado atual da porta. Sintaxe: <com-handle>:Settings. • Settings Através dessa propriedade definimos as configurações que serão utilizadas para se comunicar com o outro disposito.2.”. pois isso causa erro. O nome do componente a ser utilizado é Microsoft ProgressBar Control. a paridade. 3 – XonXoffAndRtsCts. É importante que se controle o valor da barra para que não ultrapasse o valor máximo. 2 – RtsCts.aceita apenas valores inteiros e os possíveis valores para a propriedade são: 0 – NoHandshaking.ocx.0. • Min Nessa propriedade do objeto definimos qual o valor mínimo que a barra pode assumir. ASSIGN chComm:MSComm:Settings = “5. trata-se de um componente OCX que exibe a barra de progresso de um determinado procedimento que esteja sendo executado. Sintaxe: <com-handle>:Min. • .1”. O diretório onde se encontra o pacote para instalação desse componente é em \interfac\Grafico\ e o arquivo que possui esse componente é COMCTL32. Sintaxe: <com-handle>: PortOpen. Sintaxe: <com-handle>:Count. O nome do componente a ser utilizado é Microsoft TabStrip Control. ADD Esse método é utilizado para adicionar as tabs no componente. COUNT Por meio dessa propriedade conseguimos obter a quantidade exata de tabs criadas. chCtrlFrame:TabStrip:Tabs:COUNT INDEX Essa propriedade retorna o valor do index da tab que está selecionada no instante em que se pega o valor da mesma. REMOVE Método utilizado para remover uma determinada tab do componente. version 5. Sintaxe: <com-handle>:Remove (Index BY-VARIANT-POINTER). ASSIGN chctrlframe:ProgressBar:Value = chctrlframe:ProgressBar:VALUE + 1. • • • • . ASSIGN chctrlframe:ProgressBar:Max = 10. permitindo assim que em uma mesma frame se consiga trabalhar com diversas informações de uma forma muito organizada. as tabs devem ser adicionadas uma de cada vez.. Sintaxe: <com-handle>:Value. Seus principais métodos e propriedades são: • CLEAR O método Clear do componente TabStrip faz com que sejam eliminadas todas as tabs criadas anteriormente no componente. chCtrlFrame:TabStrip:Tabs:Remove(chCtrlFrame:TabStrip:SelectedIt em:INDEX). Sintaxe: <com-handle>:Index. • Value Value é propriedade do componente onde podemos obter o valor atual que a barra está exibindo ou que podemos informar qual o novo valor que a barra deve exibir o progresso do processo.0. O diretório onde se encontra o pacote para instalação desse componente é em \interfac\Grafico\ e o arquivo que possui esse componente é COMCTL32.ocx. chCtrlFrame:TabStrip:SelectedItem:INDEX. TabStrip O TabStrip é um componente que permite que sejam criadas diversas tabulações de trabalho.Construção de Programas utilizando os Estilos e suas Técnicas 285 Sintaxe: <com-handle>:Max. Sintaxe: <com-handle>:Clear(). chCtrlFrame:TabStrip:Tabs:CLEAR(). essa informação não é obrigatória. <Caption>: Caption é o texto de exibição da tab que está criada.'vt100'). Caption BY-VARIANT-POINTER. O nome do componente a ser utilizado é Distinct Telnet ActiveX Control. Seus principais métodos e propriedades são: • CONECT O método Conect é responsável por fazer com que o componente consiga se conectar ao servidor telnet especificado. . "Teste1" BY-VARIANT-POINTER . chCtrlFrame:TabStrip:Tabs:ADD( 1 BY-VARIANT-POINTER .ocx.Sintaxe: <com-handle>:Add(Index BY-VARIANT-POINTER. <Image>: É o índice da imagem da lista de imagem que será exibida nessa tab. O diretório onde se encontra o pacote para instalação desse componente é em \interfac\Telnet\ e o arquivo que possui esse componente é D_TNET32. Onde: <Index>: É o índice da tab que está sendo adicionanda. Image BY-VARIANT-POINTER ). Esse método retorna uma variável do tipo lógico que pode ser verdadeiro no caso de ter concluído o encerramento da conexão Telnet ou falso no caso de ter ocorrido algum problema que não possibilite o encerramento da • . DTelnet DTelnet é um componente ActiveX que possibilita que programas se conectem a servidores remotos por meio de conexões Telnet e que troquem informações com esses servidores. chCtrlFrame:Connect(trim("TelnetServer"). <Tty>: É o tipo de conexão telnet que se deseja estabelecer com o servidor informado. ). Key BY-VARIANT-POINTER. esse dado não é obrigatório. Onde: <Host>: Especifica o nome do servidor Telnet ao qual se deseja conectar. Sintaxe: <com-handle>:Connect (Host as Character. <Key>: Key é o valor da tab. Tty AS Character). Esse método retorna um valor do tipo lógico que representa se o componente conseguiu se conectar ou não no servidor. DISCONNECT Esse método solicita ao servidor que seja encerrada a sessão Telnet e finaliza a conexão com o servidor. .wav". O diretório onde se encontra o pacote para instalação desse componente é em \interfac\Tree Chart\ e o arquivo que possui esse componente é TREECHART. • RECEIVE Método que recebe as informações que o servidor Telnet está enviando para o programa. Esse método retorna uma varíavel do tipo character com as informações enviadas pelo servidor. O nome do componente a ser utilizado é Tree Chart Control.ocx. Sound Componente que possibilita e execução de arquivos de sons como wav e mid em aplicações progress.ocx.Sound. Sintaxe: Get: [ Decimal-Var = ] <com-handle>:LayerDistance. ASSIGN chCtrlFrame:Controls:Item(1):comando = "sound". Set: <com-handle>:LayerDistance [ = Decimal-Var ]. Seus principais métodos e propriedades são: • LAYERDISTANCE Atrinbuto que define o tamanho das linhas verticais do diagrama. O nome do componente a ser utilizado é DatasulSound. O diretório onde se encontra o pacote para instalação desse componente é em \interfac\som\ e o arquivo que possui esse componente é DATSOUND. Exemplo: ASSIGN chCtrlFrame:Controls:Item(1):arquivo = "c:/tmp/som1. Sintaxe: <com-handle>:Disconnect ( ). chCtrlFrame:Receive. Possui a propriedade “arquivo” que informa ou recebe o nome do arquivo está sendo executado ou que irá ser executado. Tree Chart Componente OCX destinado à definição do lay-out de posicionamento das células no organograma. chCtrlFrame:Disconnect(). Sintaxe: <com-handle>:Receive.Construção de Programas utilizando os Estilos e suas Técnicas 287 conexão. e a propriedade “comando” que recebe ou informa o comando que está sendo executado. Set: <com-handle>:VertexDistance [ = Decimal-Var ]. Exemplo: chTree_Layout:VertexDistance = 300. Valores: 0 – Norte. 3 – Oeste. 2 – Sul. Sintaxe: Get: [ Decimal-Var = ] <com-handle>:VertexDistance. Sintaxe: Get: [ <user-defined>-Var = ] <com-handle>:Orientation. Sintaxe: NO-RETURN-VALUE <com-handle>: Layout ( Com-HandleControl ).Exemplo: chTree_Layout:LayerDistance = 300. Exemplo: chTree_Layout:Orientation = 0. O diretório onde se encontra o pacote para instalação desse componente é . • LAYOUT Aplica o lay-out definido no componente de diagrama definido em Com-Handle-Control. Print Chart Componente OCX destinado ao tratamento dos parâmetros de impressão para outros componentes OCX. • VERTEXDISTANCE Atrinbuto que define o tamanho das linhas horizontais do diagrama. Exemplo: no-return-value chTree_layout:Layout(chOrg). Onde chOrg é o componente que será aplicado o Layout. 1 – Leste. Set: <com-handle>:Orientation [ = <user-defined>-Var ]. • ORIENTATION Atributo que define a posição das células pai em relação às células filhas. Sintaxe: Get: [Character-Var = ] <com-handle>:DocName. Exemplo: chPrn:FitToPage = TRUE. Set: <com-handle>:FitToPage [ = Logical-Var ]. Set: <com-handle>:DocName [ = Character-Var ]. Set: <com-handle>:hWndFlow [ = Integer-Var ]. • FITTOPAGE Método utilizado para acomodar o conteúdo a ser impresso em uma única página.ocx. • DOCNAME Esse método armazena o nome do respectivo documento. Exemplo: chPrn:hWndFlow = chOrg:hwnd . Exemplo: chPrn:Preview = TRUE. Seus principais métodos e propriedades são: • HWNDFLOW Esse método é utilizado para armazenar o componente que possui os dados a serem impressos. Onde chOrg é o componente que possui os dados a serem impressos. O nome do componente a ser utilizado é Print Chart Activex Control. Sintaxe: Get: [Integer-Var =] <com-handle>:hWndFlow. Set: <com-handle>:Preview [ = Logical-Var ]. . Sintaxe: Get: [ Logical-Var = ] <com-handle>:Preview. • PREVIEW Método utilizado para apresentar a tela de preview de impressão. Sintaxe: Get: [ Logical-Var = ] <com-handle>:FitToPage.Construção de Programas utilizando os Estilos e suas Técnicas 289 em \interfac\Print Chart\ e o arquivo que possui esse componente é PRINTCHART. Exemplo: chPrn:DocName = "Nome do arquivo". Org Chart Componente OCX destinado à criação de organogramas.• PRINTERSETTINGS Método utilizado para apresentar a tela de propriedades de impressão. Exemplo: chPrn:PrintDoc. . O nome do componente a ser utilizado é Org Chart Activex Control. Set: <com-handle>:FillColor [ = Integer-Var ]. Exemplo: chPrn:PrinterSettings = true. Set: <com-handle>:PrinterSettings [ = Logical-Var ].255). O diretório onde se encontra o pacote para instalação desse componente é em \interfac\Org Chart\ e o arquivo que possui esse componente é ORGCHART. Set: <com-handle>:Orientation [ = <user-defined>-Var ]. Sintaxe: Get: [ Logical-Var = ] <com-handle>:PrinterSettings. Sintaxe: Get: [ <user-defined>-Var = ] <com-handle>:Orientation. • ORIENTATION Método utilizado para informar a orientação da folha ( Retrato ou Paisagem ). Sintaxe: NO-RETURN-VALUE <com-handle>: PrintDoc. Exemplo: chPrn:orientation = 2. Exemplo: chorg:fillcolor = rgb-value(255. Seus principais métodos e propriedades são: • FILLCOLOR Método utilizado para definir a cor das células do diagrama. Sintaxe: Get: [ Integer-Var = ] <com-handle>:FillColor.ocx. • PRINTDOC Método utilizado para imprimir o respectivo documento.255. 255. Sintaxe: NO-RETURN-VALUE <com-handle>: SaveFile ( Sintaxe: NO-RETURN-VALUE <com-handle>: SaveImage ( . Exemplo: chorg:forecolor = rgb-value(0. chOrg:FONT:SIZE = 7. Sintaxe: Get: [ Integer-Var = ] <com-handle>:ForeColor. Sintaxe: Get: [ Com-Handle-Var = ] <com-handle>:Font. Exemplo: chOrg:FONT:NAME = "Tahoma".0. Set: <com-handle>:BackColor [ = Integer-Var ]. Set: <com-handle>:Font [ = Com-Handle-Var ]. • SAVEFILE Salva um diagrama em um arquivo Character-file ).Construção de Programas utilizando os Estilos e suas Técnicas 291 • FORECOLOR Método utilizado para definir a cor dos labels do diagrama.0). Exemplo: chorg:backcolor = rgb-value(255. Integer-tymed. • BACKCOLOR Método utilizado para determinar a cor de fundo do diagrama. Character-file ). Sintaxe: Get: [ Integer-Var = ] <com-handle>:BackColor. Exemplo: no-return-value chOrg:FONT: SaveFile( name file ). Set: <com-handle>:ForeColor [ = Integer-Var ]. Integer-format.255). • FONT Método responsável pelo tratamento de fontes. • SAVEIMAGE Salva um diagrama em um formato meta-arquivo. name file). • AUTOSCROLL Através desse método pode-se determinar se o diagrama irá apresentar as barras de rolagem quando necessário. • ADD Método utilizado para adicionar novas células no diagrama. • DELETESEL Método utilizado para apagar os itens selecionados. Exemplo: chOrg:AutoScroll = true. Set: <com-handle>:AutoScroll [ = Logical-Var ]. Set: <com-handle>:Shape [ = Integer-Var ]. Onde Integer-tymed: afTypeMediumFile = 0 afTypeMediumClipboard = 1 Integer-format: afWMF = 0 afEMF = 1 • SHAPE Método utilizado para definir a figura geométrica das células do organograma. Sintaxe: NO-RETURN-VALUE <com-handle>: DeleteSel ( ). Exemplo: chOrg:DeleteSel. Sintaxe: Get: [ Logical-Var = ] <com-handle>:AutoScroll. Exemplo: chOrg:shape = 2.Exemplo: no-return-value chOrg:FONT: SaveFile( 0. • SELECTALL Método utilizado para selecionar todo o diagrama. 0. Sintaxe: Get: [ Integer-Var = ] <com-handle>:Shape. Exemplo: chOrg:SelectAll. Sintaxe: NO-RETURN-VALUE <com-handle>: SelectAll ( ). Sintaxe: [ Com-Handle-Var = ] <com-handle>: Add ( . def var chLiga as com-handle no-undo. O código abaixo mostra um exemplo da ligação das células do organograma: IF chOrg:nodes:count > 0 then do: repeat i = 1 to chOrg:nodes:count: chNodos = chOrg:nodes(i). primeiramente. Para criarmos novas células no diagrama deve-se.Construção de Programas utilizando os Estilos e suas Técnicas 293 Decimal-Left AS FLOAT. def var chNodos as com-handle no-undo. Utilizando o método “nodes” do componente OCX OrgChart. sendo que a variável “sequência” será utilizada para armazenar a seqüência na hierarquia do organograma: chNode[sequência] = chNodos:add(0. Decimal-Width AS FLOAT. definir três variáveis do tipo com-handle: def var chNode as com-handle extent 9999 no-undo. Utilizando o método “outlinks” criamos a ligação entre a célula pai e a cáelula filho.0.600). chLiga = chNode[seqüência pai]:outlinks:add(chNode[sequência]). associálo à variável chNodos: chNodos = chOrg:nodes. A variável chLiga é utilizada para montar os links entre as células. Decimal-Height AS FLOAT ). Decimal-Top AS FLOAT. A variável chNode será utilizada para armazenar as novas células criadas. repeat j = 1 to chNodos:links:count: . Onde chOrg é o nome do componente OCX OrgChart.1500. chliga:LinkStyle = 4. pois na falta deste. input ""). end. • eliminar o programa ut-utils. end.p. Observação Não esquecer de executar o último procedimento descrito. chLiga:Rigid = true.p persistent set h-prog. Como executar um aplicativo do Windows Objetivo Esta técnica deve ser usada sempre que for executado um programa externo. Implementaç • ão • • inserir a chamada da include i-win.i no início do bloco de definições. run Execute in h-prog(input "c:\windows\calc. os parâmetros para o programa a ser executado. If return-value = "Ok" then message "A operação foi feita com sucesso".p persistente e atribuir o seu handle para a variável que foi criada anteriormente. rodar o programa ut-utils.exe".i} definir uma variável do tipo handle.chliga = chNodos:links(j). Essa função substitui a antiga função WINEXEC. run utp/ut-utils. • rodar o procedimento Execute que está dentro do programa ut-utils.p que foi rodado persistente da memória. . o sistema pode ficar sem recursos e travar. • se o retorno for "Ok" a operação foi feita com sucesso. delete procedure h-prog. {include/i-win. def var h-prog as handle no-undo. passando os seguintes parâmetros: • • caminho do programa para ser executado. criar um botão e colocá-lo ao lado direito superior do Editor. definir a variável 1-control-spell em Definitions. Exemplo: define variable l-control-spell as logical no-undo init no. passando como parâmetro o nome do botão que foi criado. dependendo onde se encontra o Editor. Exemplo: . Implementaç • ão • na procedure local-display-fields da SmartViewer ou na procedure localinitialize da SmartWindow. a chamada da include i-inispl.i.Construção de Programas utilizando os Estilos e suas Técnicas 295 Como implementar Correção Ortográfica em Editores Objetivo Esta técnica tem com objetivo fazer com que seja possível executar a correção ortográfica do Word 97 para o texto que foi inserido em um determinado campo ou variável view-as editor. inserir o Help:"Corretor ortográfico" no botão para implementar o Tooltip.25 • • • • deixar o botão sem label. deve ser inserida após o Run Dispatch.00 Height: 1. alterar os atributos do tamanho do botão para: Width: 4. a imagem do botão check deve estar em vermelho. instalado na sua máquina. Após a implementação da técnica. Exemplo: {include/i-spell. Exemplo: • quando o botão for disparado. indicando que o texto do Editor ainda não passou pela correção ortográfica.i <nome-do-editor> <nome-do-botão>} É importante ressaltar que esta técnica só irá funcionar para quem possui o Word 97. e como segundo parâmetro. a Dialog de correção ortográfica do Word 97 é chamada e todos os seus recursos devem estar disponíveis: . o nome do botão que foi criado e que dispara a correção ortográfica. deve ser inserida a chamada da include i-spell. ela funciona assim: • no início.{include/i-inispl.i. passando como primeiro parâmetro o nome do Editor que sofre a correção ortográfica.i <nome-do-botão>} • no MAIN-BLOCK. run utp/ut-utils. output i-y).p persistent set h-prog. • rodar o procedimento GetMousePos que está dentro do programa ututils. {include/i-win. inserir a chamada da include i-win. Exemplo: Como obter as coordenadas do mouse Objetivo Utilizar esta técnica sempre que for necessário verificar se o mouse está dentro de uma determinada região da janela no momento do clique. output i-x. • uma variável do tipo inteiro para retornar o valor da coordenada Y. • uma variável do tipo inteiro para retornar o valor da coordenada X.i no início do bloco de definições. rodar o programa ut-utils.p persistente e atribuir o seu handle para a variável que foi criada anteriormente.i} Implementaç • ão • • definir uma variável do tipo handle. run GetMousePos in h-prog(input {&window-name}:handle.Construção de Programas utilizando os Estilos e suas Técnicas 297 • terminada a execução do corretor ortográfico. . def var h-prog as handle no-undo.p. Pode ser usado em browsers para ordenação automática com base em um clique. passando os seguintes parâmetros: • handle da window onde deve ser verificada a posição do mouse. a imagem do botão check está em verde. indicando que o texto do Editor já passou pela correção ortográfica. p. delete procedure h-prog. Observação Não esquecer de executar o último procedimento descrito.p persistente e atribuir o seu handle para a variável que foi criada anteriormente. run utp/ut-utils. passando o seguinte parâmetro: • uma variável do tipo caracter onde deve ser retornado o diretório corrente.p que foi rodado persistente da memória.• eliminar o programa ut-utils. . • eliminar o programa ut-utils. pois na falta deste. Como obter o diretório corrente Objetivo Utilizar sempre que for necessário obter o diretório corrente do aplicativo que está sendo executado. fazendo com que este retorne a coordenada do mouse no momento foi dado o clique no objeto.p que foi rodado persistente da memória. def var h-prog as handle no-undo. • rodar o procedimento GetCurrentDir que está dentro do programa ututils. Observação Não esquecer de executar o último procedimento descrito.p persistent set h-prog. rodar o programa ut-utils.i no início do bloco de definições. inserir a chamada da include i-win. {include/i-win. delete procedure h-prog. run GetCurrentDir in h-prog(output c-dir).i} Implementaç • ão • • definir uma variável do tipo handle. o sistema pode ficar sem recursos e travar. • este procedimento pode ser usado na trigger de Select-Mouse-Click de um objeto. pois na falta deste. o sistema pode ficar sem recursos e travar. Observação Não esquecer de executar o último procedimento descrito. passando o seguinte parâmetro: • uma variável do tipo caracter para retornar o caminho do diretório de sistema do windows. {include/i-win. pois na falta deste.i no início do bloco de definições. . o sistema pode ficar sem recursos e travar.i no início do bloco de definições. rodar o programa ut-utils. {include/i-win. Pode ser usada quando se deseja copiar algum arquivo para o diretório SYSTEM. delete procedure h-prog. Como obter o diretório do Windows Objetivo Utilizar esta técnica sempre que for necessário retornar o diretório do windows.p que foi rodado persistente da memória.i} Implementaç • ão • • definir uma variável do tipo handle.p.Construção de Programas utilizando os Estilos e suas Técnicas 299 Como obter o diretório de sistema do Windows Objetivo Utilizar esta técnica sempre que for necessário retornar o diretório de sistema do windows. • rodar o procedimento GetSysDir que deve estar dentro do programa ututils. inserir a chamada da include i-win.p persistente e atribuir o seu handle para a variável que foi criada anteriormente. def var h-prog as handle no-undo.p persistent set h-prog.i} Implementaç • ão • definir uma variável do tipo handle. run utp/ut-utils. • eliminar o programa ut-utils. def var h-prog as handle no-undo. Pode ser usada quando se deseja copiar algum arquivo para o diretório WINDOWS. run GetSysDir in h-prog(output c-path). inserir a chamada da include i-win. p persistent set h-prog. • rodar o procedimento GetWinDir que deve estar dentro do programa ututils. pois na falta deste. rodar o programa ut-utils. {include/i-win. passando os seguintes parâmetros: • uma variável do tipo caracter onde deve ser retornado o caminho do diretório do windows. .i no início do bloco de definições. • rodar o procedimento GetComputerName que deve estar dentro do programa ut-utils. run GetComputerName in h-prog(output c-computador).• rodar o programa ut-utils.p persistent set h-prog. o sistema pode ficar sem recursos e travar.p persistente e atribuir o seu handle para a variável que foi criada anteriormente. run utp/ut-utils. delete procedure h-prog. • eliminar o programa ut-utils.p persistente e atribuir o seu handle para a variável que foi criada anteriormente. • eliminar o programa ut-utils. delete procedure h-prog. run utp/ut-utils. passando o seguinte parâmetro: • uma variável do tipo caracter onde deve ser retornado o nome do computador.p. Observação Não esquecer de executar o último procedimento descrito.p que foi rodado persistente da memória.p que foi rodado persistente da memória.p. Como obter o nome do computador Objetivo Essa técnica deve ser usada quando for necessário obter ou até mesmo informar o nome do computador que deve estar executando a aplicação.i} Implementaç • ão • • definir uma variável do tipo handle. run GetWinDir in h-prog(output c-path). def var h-prog as handle no-undo. inserir a chamada da include i-win. i} Implementaç • ão • • definir uma variável do tipo handle.p. pois na falta deste.p persistente e atribuir o seu handle para a variável que foi criada anteriormente. Como transformar uma janela em barra de ferramentas Objetivo Esta técnica deve ser usada sempre que for necessário implementar uma janela que esteja sempre visível e que contenha funções de ferramentas. ou seja. {include/i-win. passando os seguintes parâmetros: • a variável de ambiente que deseja-se saber o valor. Como obter o valor de uma variável de ambiente Objetivo Utilizar esta técnica sempre que for necessário ler alguma variável de ambiente. • eliminar o programa ut-utils.Construção de Programas utilizando os Estilos e suas Técnicas 301 Observação Não esquecer de executar o último procedimento descrito. rodar o programa ut-utils. run utp/ut-utils. • rodar o procedimento GetEnv que deve estar dentro do programa ututils. funções que não estejam ligadas a nenhum objeto ou programa específico. • uma variável do tipo caracter para retornar o valor da variável de ambiente informada. o sistema pode ficar sem recursos e travar. output c-path). pois na falta deste.p persistent set h-prog. o sistema pode ficar sem recursos e travar.i no início do bloco de definições. Observação Não esquecer de executar o último procedimento descrito. delete procedure h-prog.p que foi rodado persistente da memória. def var h-prog as handle no-undo. run GetEnv in h-prog(input "PATH". inserir a chamada da include i-win. . o label do radio-button. muda para cada língua. run utp/ut-style. Se a barra for sempre visível.p persistent set h-prog. veja Como deixar uma janela sempre visível.i no início do bloco de definições.i} definir uma variável do tipo handle. {include/i-win. delete procedure h-prog. o que é o mais normal. • rodar o procedimento AddPaletteStyle que deve estar dentro do programa winstyle. def var h-prog as handle no-undo.p que foi rodado persistente da memória. Observação Não esquecer de executar o último procedimento descrito.p persistente e atribuir o seu handle para a variável que foi criada anteriormente. passando os seguintes parâmetros: • atributo hWnd da janela a ser transformada. run AddPaletteStyle in h-prog(input {&window-name}:hWnd).Implementaç • ão • • inserir a chamada da include i-win. visto que. iremos adotar uma técnica que utiliza a seguinte sintaxe: . pois na falta deste.p. • eliminar o programa ut-style. Entretanto essa técnica não corresponde as nossas necessidades. Para isso. Como desabilitar Radio-Buttons A sintaxe normal para desabilitar radio-buttons é: DISABLE(LABEL_DO_RADIO_BUTTON). • verificar a possibilidade de deixar a barra de ferramentas sempre visível. rodar o programa ut-style. o sistema pode ficar sem recursos e travar. Exemplo: def var h-programa as handle no-undo. Como executar programas que são janelas Objetivo Esta técnica demonstra a forma correta para execução de um programa (.transacao 1 .Construção de Programas utilizando os Estilos e suas Técnicas 303 IF nome-rs:DISABLE(ENTRY(X. .. 2.Aplicação 2 . Este número é obtido pela seguinte fórmulaX=2 * (entrada desejada)-1. Onde: Nome-rs: Nome do Radio-set X: Número que obtém a entrada desejada do radio-set.. "string". evitando a ocorrência do erro 4123 ("None of the widgets used in WAIT-FOR statement are SENSITIVE WAIT-FOR terminated.transacao:disable(entry(3.(nome-rs:RADIO-BUTTONS IN FRAME {&FRAME-NAME}))) THEN. exemplo: .w) a partir de um outro programa que já é uma janela.Empréstimo X = 2(2) -1 X=3 If tipo-modalidade.. Observação o Radio-Set Properties mostra que as strings são: "string". deve ser definida uma variável do tipo handle. tipomodalidade:radio-buttons)) in frame {&frame-name} then. então para obter a posição desejada é necessário utilizar a fórmula descrita anteriormente. (4123))" durante a sua execução. Exemplo: desabilitar o radio-button empréstimo Tipo-modalidade. 1. Implementaç • ão • o programa deve ser executado de forma persistente usando a variável handle que foi definida e a inicialização do programa deve ser feita através da execução da "initialize". por isso a execução de programa chamado deve ser de forma persistente. 11 Procedimento. Inicialização do programa chamado. podem-se executar procedimentos do mesmo. Isso pode acontecer se. If valid-handle(h-programa) then run dispatch in h-programa ('initialize'). sendo que para cada procedimento a ser executado deve-se verificar a validade do handle. Deverá sempre ser feita separadamente de outras execuções de procedimentos devido a possibilidade de a inicialização o handle tornar-se inválido. Exemplo: run xxp/xx9999. A chamada desta procedure deve ser feita dentro do local-initialize. Para executar a procedure e habilitar/desabilitar é necessário ter um link do tipo STATE. o procedimento feche o programa chamado. If valid-handle(h-programa) then run dispatch in h-programa ('initialize'). por exemplo.run xxp/xx999. se a técnica foi utilizada. 8 9 Procedure pertencente ao programa chamado executada antes de sua inicialização. 10 Validação do handle agrupando mais de uma execução de procedimentos. depois do run-dispatch. Como habilitar ou desabilitar botões em painéis Foram criados procedures internas. O conceito GUI / MS Windows / Progress indica que uma janela deve rodar como um objeto independente. na Window. • logo após a execução persistente do programa.w persistent set h-programa. para habilitar ou desabilitar todos os botões dos painéis de Cadastro e Alteração. Quando for encerrada a "janela chamada" o erro não deve ocorrer. . entre o painel e a Window (THIS-PROCEDURE). contido em um bloco com mais procedimentos. Isso pode ser feito desde que a inicialização do programa não esteja no mesmo bloco da condição e que nenhum dos procedimentos contidos no bloco possam ocasionar a perda da validade do handle. If valid-handle(h-programa) then run pi-seta-parametros in h-programa (input "teste"). run pi-reposiciona-tabela2 in h-programa (input 456).9 If valid-handle(h-programa) then do:10 run pi-reposiciona-tabela1 in h-programa (input 123). nas masters. 11 8 Para verificar se a implementação foi realizada de forma correta. End. se necessário. basta fechar a "janela chamadora" antes de fechar a "janela chamada". que não tem possiblidade de ocasionar a invalidade do handle.w persistent set h-programa. antes ou depois de sua inicialização. inserir a lógica abaixo: if .. você deve proceder da seguinte maneira: • • • Executar a procedure habilitar/desabilitar no state-changed. Onde: <função-do-botão>: Função específica do botão a ser trabalhado <handle-do-painel>: Handle do painel. else run new-state("nao-habilitar":U).. tendo como Source a Viewer ou Browser e como Target a SmartWindow(this-procedure). onde "yes" habilita e "no" desabilita. na Windows. validação qualquer . inserir a lógica abaixo: . onde o link é source <logical>: Variável em fator lógico. • na state-changed da Window. do tipo state. Criar um Smart-link..Construção de Programas utilizando os Estilos e suas Técnicas 305 A sintaxe desta procedure é: RUN enable-<função-do-botão> in <handle do painel> (Input <logical>). conforme alguma validação existente em uma viewer ou em um browser. then run new-state("habilitar":U). Funções Inclui Elimina Modifica Copia Cancela Desfaz Salva Va-para Zoom Relacionamento Relatório Caso você queira desabilitar os botões do painel. conforme necessidade do usuário.. da Viewer ou do Browser. Na procedure local-row-available ou outro local. . pois nesta procedure passam vários outros state ´s. end.*/ DEFINE INPUT PARAMETER p-issuer-hdl AS HANDLE DEFINE INPUT PARAMETER p-state CASE p-state: when "no-record-available":U then assign bt-name:SENSITIVE in frame {&FRAME-NAME} = no. Como habilitar ou desabilitar botões específicos em Browse Inclui/Modifica Objetivo Esta técnica pode ser usada quando for necessário desabilitar/habilitar outros botões em Browse Inclui/Modifica conforme a existência ou não de registro no Browse. na procedure STATE-CHANGED do Browse Inclui/Modifica. Implementaç • ão PROCEDURE state-changed: /* --------------------------------------------------------Purpose: Parameters: <none> Notes: ----------------------------------------------------. Observação Não utilize a opção "else". inserir o código. AS CHARACTER NO-UNDO. NO-UNDO. em destaque.if p-state = "nao-habilitar":U then do: run enable-<função-do-botão> in <handle do painel> (Input <logical>). end. if p-state = "habilitar":U then do: run enable-<função-do-botão> in <handle do painel> (Input <logical>). nos códigos abaixo: XX: sigla do banco de dados XXINC/I99XX999. when "record-available":U then assign bt-name:SENSITIVE in frame {&FRAME-NAME} = yes. Nas propriedades avançadas deste combo-box. conforme o tipo de SmartViewer: Viewers de Cadastro Simples ADM-CREATE-FIELDS ADM-ASSIGN-FIELDS ADM-MODIFY-FIELDS ADM-MODIFY-FIELDS Viewers de Folders . Colocar um combo-box na tela com formato maior que o tamanho do maior elemento do list-items deste campo indicador.I: include do dicionário de dados para o campo indicador <variável-combo-box>: nome da variável view-as combo-box que na tela representa o campo indicador <tabela>: tabela que possui o campo tipo indicador <campo>: campo tipo indicador representado pelo combo-box 1. */ {src/adm/template/bstates. ainda. Como implementar campos indicadores com view-as combo-box nas telas Os campos indicadores podem ser representados nas telas com view-as combo-box e para isto deve-se seguir os passos. Observações Não elimine o código existente na procedure STATE-CHANGED.i} END CASE.Construção de Programas utilizando os Estilos e suas Técnicas 307 when "no-external-record-available":U then assign bt-name:SENSITIVE in frame {&FRAME-NAME} = no. marcar os 'Custom lists'. E. os botões de Modifica/Eliminar são desabilitados automaticamente. p-state). END PROCEDURE. run pi-trata-state (p-issuer-hdl. /* Object instance CASEs can go here to replace standard behavior or add new cases. end. após o run dispatch. end.2. Retirar a propriedade Enable do combo-box. Na procedure "local-display-fields" implementar. implementar a seguinte lógica após o "run dispatch da local-assign-statement": assign input frame {&frame-name} <variável-combo-box> <tabela>. e este campo não fizer parte da chave primária. else assign <variavel-combo-box>:screen-value in frame {&frame-name} = {XXINC/I99XX999. uma lógica que apresente o valor caracter correspondente ao valor inteiro do campo indicador: /* Dispatch standard ADM method. 4. para atualizá-lo deve ser criada a local-assign- .I 06 <variávelcombo-box>}. implementar a seguinte lógica após o "run dispatch da local-assign-record": assign <tabela>. Para gravação do conteúdo do combo-box.<campo> = {XXINC/I99XX999. 5. comentar a lógica abaixo: /* if adm-new-record = yes then */ Observação Quando da utilização de campos indicadores com view-as combo-box. 3. RUN dispatch IN THIS-PROCEDURE (INPUT 'display-fields':U).I 06 <variável-combobox>}. */ RUN dispatch IN THIS-PROCEDURE (INPUT 'initialize':U). /* Dispatch standard ADM method. uma lógica que prepare o "list-items" da variável combo-box: assign <variavel-combo-box>:list-items in frame {&frame-name} = {XXINC/I99XX999. Na procedure "local-initialize" implementar. 6.I 04 <tabela>. /* Code placed here will execute AFTER standard behavior. Na procedure local-enable-fields. b) Quando for um Cadastro Complexo. antes do run dispatch.I 03}.<campo>}.<campo> = {XXINC/I99XX999. na base de dados: a) Quando for um Cadastro Simples.I 04 1}. */ if avail <tabela> then assign <variavel-combo-box>:screen-value in frame {&framename} = {XXINC/I99XX999. Definir as seguintes variáveis no bloco de Definitions da viewer: define variable c-lista as character no-undo. define variable i-cont as integer no-undo. end.". também após o run dispatch. o assign deve ser feito na local-create-record.I: include do dicionário de dados para o campo indicador <variável-radio-set>: nome da variável view-as radio-set que na tela representa o campo indicador <tabela>: tabela que possui o campo tipo indicador <campo>: campo tipo indicador representado pelo radio-set 1.1. uma lógica que prepare o "list-items" da variável radio-set: do i-cont = 1 to num-entries({XXINC/I99XX999. Na procedure "local-initialize" implementar. 3. . marcar os 'Custom lists'. antes do run dispatch.Construção de Programas utilizando os Estilos e suas Técnicas 309 record e após o run dispatch fazer o assign da variável para o campo da tabela. Retirar a propriedade Enable do radio-set. Como implementar campos indicadores com view-as radio-set nas telas Os campos indicadores podem ser representados nas telas com view-as radioset e para isto deve-se seguir os passos. conforme o tipo de SmartViewer: Viewers de Cadastro Simples ADM-CREATE-FIELDS ADM-ASSIGN-FIELDS ADM-MODIFY-FIELDS ADM-MODIFY-FIELDS Viewers de Folders 2. nos códigos abaixo: XX : sigla do banco de dados XXINC/I99XX999.1).I 03}): assign c-lista = c-lista + entry(i. 4.I 03}) + ". Colocar um radio-set na tela com formato maior que o tamanho do maior elemento do list-items deste campo indicador e do tipo caracter. assign c-lista = substring(c-lista.lenght(c-lista) . Caso este campo faça parte da chave." + string(i-cont) + ". Nas propriedades avançadas deste radio-set.{XXINC/I99XX999. <campo> = {XXINC/I99XX999. também após o run dispatch.<campo> = {XXINC/I99XX999. 7. b) Quando for um Cadastro Complexo. na base de dados: a) Quando for um Cadastro Simples. /* Code placed here will execute AFTER standard behavior. com view-as radio-set.<campo>}. end. somente a descrição correspondente ao valor . uma lógica que apresente o valor caracter correspondente ao valor inteiro do campo indicador: /* Dispatch standard ADM method. o assign deve ser feito na local-create-record. deve ser mostrado num fill-in. end. implementar a seguinte lógica após o "run dispatch da local-assign-statement": assign input frame {&frame-name} <variável-radio-set> <tabela>.assign <variavel-radio-set>:radio-buttons in frame {&framename} = c-lista.I 04 1}. else assign <variavel-radio-set>:screen-value in frame {&frame-name} = {XXINC/I99XX999. e este campo não fizer parte da chave primária. 6. Para gravação do conteúdo do radio-set. Quando for mostrar o campo indicador. em consulta. implementar a seguinte lógica após o "run dispatch da local-assign-record": assign <tabela>. RUN dispatch IN THIS-PROCEDURE (INPUT 'display-fields':U). comentar a lógica abaixo: /* if adm-new-record = yes then */ Observação Quando da utilização de campos indicadores com view-as radio-set. */ if avail <tabela> then assign <variavel-radio-set>:screen-value in frame {&framename} = {XXINC/I99XX999.I 06 <variável-radioset>}. para atualizá-lo deve ser criada a local-assign-record e após o run dispatch fazer o assign da variável para o campo da tabela. Na procedure local-enable-fields. */ RUN dispatch IN THIS-PROCEDURE (INPUT 'initialize':U). após o run dispatch. Caso este campo faça parte da chave. 5.I 04 <tabela>. /* Dispatch standard ADM method.I 06 <variávelradio-set>}. Na procedure "local-display-fields" implementar. uma conter o seu 'label' e ser a coluna do campo calculado no browse e outra character para conter o seu 'list-items'. radio-set ou combo-box) num SmartBrowser é necessário utilizar um campo calculado ("Calculate Field") e neste implementar uma lógica com o comando entry para apresentar o conteúdo do campo significativo para o usuário. No Main-Block do SmartBrowser deve-se preparar o conteúdo da variável com o 'list-items' e buscar o label do dicionário de dados.Receita. Como implementar campos indicadores num SmartBrowser Quando se precisar colocar um campo do tipo indicador (view-as. deve ser dado um assign no fillin utilizando a include do dicionário conforme exemplo abaixo: assign <variavel-fill-in>:screen-value in frame <framename> = {XXINC/I99XX999.i 03} */ Onde: {03}:indica a função a ser realizada. /* busca o list-items conforme o include padrão assign c-lista-tipo = {adind/i02ad049.Construção de Programas utilizando os Estilos e suas Técnicas 311 cadastrado. /* coluna no browse */ def var c-lista-tipo as character no-undo.Título") @ c-tipo 1.Vendas. Exemplo /* include que retornará o label do campo {utp/ut-field. conforme a tabela abaixo: Funçã Objetivo o 01 define view-as Combo-Box . Exemplo: def var c-tipo as character no-undo.Despesa.I 04 <tabela-campo>}. Exemplo: entry(conta. Na procedure local-display-fields.i mgadm conta tipo 1} */ /* acerta o column-label no browse */ assign c-tipo:label in browse br-table = return-value. /* list-items */ 2.Passivo. Em Definitions do SmartBrowser definir duas novas variáveis para o campo indicador."Ativo.tipo. porque estes campos indicadores são inteiros e deve ser apresentado o valor caracter correspondente. nas suas propriedades defini-lo como 'view-as text'. Colocar na tela um fill-in. Exemplo: . após a chamada do ADM Method 'display-fields' que aplica um clear no frame desejado. ao invés de um text. como label do retângulo.i para definir o screen-value deste fill-in.i para redefinir o screen-value deste fill-in na inclusão. c-lista-tipo) @ c-tipo Como implementar labels em retângulos utilizando o dicionário de dados Quando se precisar colocar um campo (view-as. Na Local-Display-Fields da SmartViewer também fazer a chamada do include ut-rtlbl.02 03 04 n 05 06 item define view-as Radio-Set lista com os itens separados por vírgula retorna o item n da lista retorna o número de itens da lista retorna a posição do item (número) 3. Exemplo: 1. assinalar a propriedade 'display' e retirar a propriedade 'enable'. Exemplo: {utp/ut-rtlbl. Exemplo: entry(conta. O problema é que este 'text' deveria conter o label do dicionário de dados para o campo. No Local-Initialize da SmartViewer fazer a chamada do include ut-rtlbl.i mgadm conta natureza text-1} 3. Nas propriedades do SmartBrowser colocar um Calculate Field (campo calculado) que retorna a entrada no 'list-items' de acordo com o conteúdo do registro. Exemplo: 2. 'no-label'.tipo. radio-set ou editor) num SmartViewer é necessário (opcionalmente para o editor) seja emoldurado com um retângulo e colocar um 'text' sobre o mesmo para identificar o campo. quando o SmartViewer estiver rodando. descreve-se abaixo algumas técnicas para sua utilização. input ""). 2. o radio-set fica assim: Como implementar mensagens para o usuário A partir da utilização do programa utilitário UTP/UT-MSGS.. . pode ser utilizado o passo 3 desta técnica. Mensagem de Erro/Advertência/Informação sem Parâmetros 1.P para apresentação de mensagens ou retorno de propriedades.p (input "show". Observação As mensagens padrões estão descritas no capítulo "Mensagens". Para quem está desenvolvendo específicos e precisa utilizar mensagens que não estão cadastradas. pode-se utilizar o comando Progress MESSAGE. incluir {utp/ut-rtlbl. Se a mensagem já existir.i mgadm conta natureza text-1} 4.. Para apresentar a mensagem. input 1234. depois do RUN dispatch IN THIS-PROCEDURE (input 'Add_Record:U'). Este aplicativo é de uso exclusivo da Datasul. com texto de help. Exemplo: Número: 1234 Mensagem: Data de conversão inválida ! Tipo: Erro Help: Data de conversão não pode ser menor que a data de . Chamar o programa utp/ut-cdmsg. Na Local-Add-Record da SmartViewer.i mgadm conta natureza text-1} Após. Exemplo: run utp/ut-msgs. {utp/ut-rtlbl.p e criar a mensagem.Construção de Programas utilizando os Estilos e suas Técnicas 313 RUN dispatch IN THIS-PROCEDURE (input 'display-fields'). p (input "show". pode-se utilizar o comando Progress MESSAGE. Exemplo run utp/ut-msgs. input ""). display return-value @ c-erro with frame f-log. Este aplicativo é de uso exclusivo da Datasul. com texto de help. (ou help) input 1234. input 1235. para utilizar alguma propriedade da mesma.val-minimo).p (input "msg". Mensagens com Questionamento ao Usuário 1.p (input "msgs". Ou. Este aplicativo é de uso exclusivo da Datasul.p e criar a mensagem. pode ser utilizado o passo 3 desta técnica. 2. pode-se utilizar o comando Progress MESSAGE.cod-repres + "~~" + regiao. Para quem está desenvolvendo específicos e precisa utilizar mensagens que não estão cadastradas. (ou help) input 1235. Chamar o programa utp/ut-cdmsg. Mensagem de Erro/Advertência/Informação com Parâmetros 1. Para quem está desenvolvendo específicos e precisa utilizar mensagens que não estão cadastradas. Chamar o programa utp/ut-cdmsg. Exemplo run utp/ut-msgs.cod-repres + "~~" + regiao. Se a mensagem já existir. 3.codregiao + "~~" + string(regiao. Ou. para utilizar alguma propriedade da mesma.3. input repres. display return-value @ c-erro with frame f-log. Exemplo: .codregiao + "~~" + string(regiao. input repres. esta técnica pode ser utilizada normalmente.val-minimo). Exemplo: Número: 1235 Mensagem: &1 não pode ser representante na região &2 nesta situação Tipo: Erro Help: O representante &1 não está habilitado para operar na região &2 para valores inferiores a &3. Exemplo: run utp/ut-msgs. Se a mensagem já existir. Para apresentar a mensagem.p e criar a mensagem com texto de help. esta técnica demonstra como deve ser feita essa implementação. Como pode ser verificado. estando os dados preparados para atualização 2.Construção de Programas utilizando os Estilos e suas Técnicas 315 Número: 1236 Mensagem: Verificação completa. para informar o help de um botão.. Para apresentar a mensagem.i} foi alterada para copiar o help para o tooltip em todos os botões de todas as telas. pois a include padrão {src/adm/method/smart. input ""). else if return-value = "yes" then message "Aguarde.p (input "show". os botões padrões (aqueles que formam os painéis) já passaram a apresentar tooltips durante a execução dos programas. Exemplo run utp/ut-msgs.". em Processamento . pois os estilo fazem a tradução automaticamente dos help´s e label´s de botões. todos os botões criados num determinado programa também devem contar com Tooltip e. Implementaç • ão para que um botão não padrão apresente seu tooltip é necessário que o mesmo possua help. não sendo necessário qualquer tratamento para tradução. para tanto. Confirma atualização ? Tipo: Questão Help: A verificação dos dados foi completada.. input 1236. if return-value = "no" then return. Contudo. deve-se no UIB editar as propriedades avançadas deste botão e informar a propriedades avançadas deste botão e informar a propriedade help em idioma português. Como implementar Tooltip em um determinado botão O tooltip é um help que é apresentado ao usuário sempre que o ponteiro do mouse permanece por alguns instantes sobre um botão. Exemplo: • . p persistent set h-prog. • rodar o procedimento pi-inicializar que deve estar dentro do programa utperc. Como implementar uma barra de progresso Objetivo Utilizar esta técnica sempre que for executado um processo longo e que se deseja manter o usuário informado sobre o andamento do mesmo. . for each item no-lock: assign i-tot = i-tot + 1. definir uma variável do tipo handle. def var h-prog as handle no-undo. Implementaç • ão • rodar o programa ut/ut-perc. passando os seguintes parâmetros: • • título da janela da barra de processo. número total de iterações que a barra deve acompanhar.Em tempo: não informar a propriedade tooltip.p persistente e atribuir o seu handle para a variável que foi criada anteriormente. run utp/ut-perc.p. leave: run pi-acompanhar in h-prog. 500). • rodar o procedimento pi-finalizar. • rodar o procedimento pi-acompanhar. logo após a saída da iteração: run pi-finalizar in h-prog. que está dentro do programa ut-perc. run pi-desabilita-cancela in h-prog. deve-se rodar os procedimentos pi-desabilita-cancela e pi-habilita-cancela logo após a piinicializar: run pi-inicializar in h-prog(input "Importando arquivos".it-codigo)). i-tot).Construção de Programas utilizando os Estilos e suas Técnicas 317 end. end. OK Caso o procedimento tenha sido executado até o fim. passando como parâmetro. deve-se rodar o procedimento pi-registro logo após a pi-acompanhar. leave: run pi-acompanhar in h-prog. • para verificar se o processo foi cancelado. run pi-retorna-status in h-prog (output c-status). . que está dentro do programa utperc. • para desabilitar ou habilitar o botão cancela. deve-se apenas rodar o procedimento pi-returna-status antes da pi-finalizar e este retornará uma das seguintes informações: • • NOK Caso o procedimento tenha sido cancelado. • para que seja visualizado o registro que está sendo processado no momento (na barra de título). run pi-registro in h-prog (input string(item. run pi-inicializar in h-prog(input "Importando arquivos".p para cada iteração: for each item no-lock on stop undo. uma string que irá identificar o registro processado: for each item no-lock on stop undo.p. end. que está dentro do programa utacomp. for each item no-lock on stop undo. • rodar o procedimento pi-finalizar. logo após a saída da iteração: run pi-finalizar in h-prog. que está dentro do programa utacomp. passando os seguintes parâmetros: • título da janela da barra de processo. deve-se rodar os procedimentos pi-desabilita-cancela e pi-habilita-cancela logo após a piinicializar: . • para setar o título da janela de barra de processo é necessário rodar o procedimento pi-seta-titulo passando o seguinte parâmetro: • título da janela da barra de processo. Implementaç • ão • rodar o programa ut/ut-acomp. run pi-seta-titulo in h-prog(input "Exportando Arquivos"). definir uma variável do tipo handle.p.p.p persistente e atribuir o seu handle para a variável que foi criada anteriormente.Como implementar acompanhamento (UTACOMP) Objetivo Utilizar esta técnica sempre quando executar um processo longo e que se deseje manter o usuário informado sobre o andamento do mesmo. leave: run pi-acompanhar in h-prog(input string(item. • para desabilitar ou habilitar o botão cancela. Esta técnica deve ser utilizada sempre que não for conhecido o número total de registros a serem processados. run pi-inicializar in h-prog(input "Importando arquivos"). def var h-prog as handle no-undo. end.p para cada iteração.p persistent set h-prog. run utp/ut-acomp. • rodar o procedimento pi-acompanhar. • rodar o procedimento pi-inicializar que deve estar dentro do programa utacomp. passando o seguinte parâmetro: • o texto a ser visualizado pelo usuário.it-codigo)). o utilitário somente exibirá qual é o registro corrente a cada 60 segundos. OK Caso o procedimento tenha sido executado até o fim. deve-se rodar os procedimentos pi-desabilita-cancela e pi-habilita-cancela logo após a piinicializar: run pi-inicializar in h-prog(input "Importando arquivos". run pi-desabilita-cancela in h-prog. deve-se incluir no arquivo . • para desabilitar ou habilitar o botão cancela. Exemplo: [Datasul_EMS2] Show-Report-Program=notepad. 500). • para verificar se o processo foi cancelado. run pi-desabilita-cancela in h-prog. 500). o utilitário continuará tendo o comportamento padrão de exibir cada registro processado. Caso não seja informado nenhum valor para “TimeAComp” ou ela nem mesmo existir no arquivo . run pi-retorna-status in h-prog (output c-status). deve-se apenas rodar o procedimento pi-returna-status antes da pi-finalizar e este retornará uma das seguintes informações: • • NOK Caso o procedimento tenha sido cancelado.ini utilizado pelo EMS uma nova chave nomeada “TimeAComp” com o valor do tempo desejado em segundos no bloco de definições Datasul_EMS2.exe TimeAComp=60 Neste exemplo.Construção de Programas utilizando os Estilos e suas Técnicas 319 run pi-inicializar in h-prog(input "Importando arquivos".ini. • para determinar um intervalo de tempo para a exibição do registro corrente do processamento. . Exemplo if available customer then do: find state where state. deve ser inserida uma lógica para carregar o valor inicial da variável para o campo de referência. Passos: 1.state = customer. 3. além de apresentar campos de referência no retorno do zoom ou na saída do campo chave estrangeira devem ser feitas as seguintes alterações quando da criação da viewer do programa que chama o zoom: Observação Nos exemplos de código abaixo.state = input frame {&frame-name} customer.statename else "":U. customer é a tabela que possui uma chave estrangeira no campo state. Deve ser criada uma variável do tipo caracter view-as fill-in. antes do run dispatch. assign c-state-name = if avail state then state. end.state no-lock noerror. Acessar as propriedades deste campo e retirar a propriedade 'Enable'. relacionando-a com a tabela state e o campo state-name é o campo de referência para o usuário. na qual é armazenado o campo de referência da chave estrangeira e deve ser colocada ao lado do campo que tem zoom. Exemplo {include/leave. Exemplo: Para o campo de referência state-name temos a variável c-statename.i &tabela=state &atributo-ref=state-name &variavel-ref=c-state-name &where="state.state"} Onde: . 2. Criar a procedure local-display-fields e nela.Como implementar Zoom e campos de referência para campos chave estrangeira Para implementar o zoom em campos chave estrangeira. No gatilho de leave do campo que possui zoom deve ser inserida uma lógica para determinar o valor do campo de referência com base no que o usuário digitou no campo que possui zoom. • a partir de um campo chave estrangeira de uma tabela cujo nome não coincide com o nome do campo no browse de pesquisa. . não deve ser informado o nome da tabela <frame>: parâmetro opcional utilizado quando o frame onde está o campo que possui zoom é diferente de {&frame-name} <browse>: parâmetro opcional utilizado quando o zoom é acionado a partir de uma coluna de um browse updateable. que atende as seguintes situações de acesso ao zoom. 4. e no browse o campo chama-se it-codigo. <where>: cláusula where para localizar o registro na tabela de referência.I é padronizada a chamada do zoom para os campos que são chave estrangeira. simplesmente comum em tabelas com auto-relacionamento). deve ser especificado no formato tabela.]} Onde: <prog-zoom>: é o nome do programa de zoom <campo>: é o campo/variável na viewer ou frame onde está sendo colocado o zoom.i &prog-zoom=diretório/programa &campo=variavel/tabela. <variavel-ref>: variável criada para receber o campo de referência. Todas estas situações com a possibilidade de passagem de parâmetros para o programa de zoom. de onde o valor será buscado (Exemplo: Na viewer o campo chama-se itcodigo-pai. Sintaxe: {include/zoomvar.campo <campozoom>: é o campo no SmartBrowser do zoom de onde o valor é buscado. sendo um campo de tabela. • • a partir de um campo chave estrangeira de uma tabela.Construção de Programas utilizando os Estilos e suas Técnicas 321 <tabela>: tabela que possui a chave estrangeira.atributo &campozoom=nome-atributo [&frame=nome-frame] [&browse=nome-browse] [¶metros="run pi-procedure in whpesquisa". <atributo-ref>: recebe o campo de referência da tabela da chave estrangeira. a partir de uma variável. • a partir de uma coluna num browse. Através do include ZOOMVAR. b) chamada do zoom para mais de um atributo de um frame: ON F5 OF det-rateio.ct-final &campozoom=ct-codigo &campo2=det-rateio. Deve conter um valor do tipo: ¶metros="run pi-procedure in wh-pesquisa(input 'inicio'.it-codigo in frame {&FRAME-NAME} DO: {include/zoomvar.it-codigo &campozoom=it-codigo} END. que recebe os parâmetros.w &campo=tt-digita.i &prog-zoom=inzoom/z01in172.it-codigo in browse {&BROWSE-NAME} DO: {include/zoomvar.it-codigo in frame {&FRAME-NAME} OR MOUSE-SELECT-DBLCLICK OF ord-prod. input 'fim').".i &prog-zoom=inzoom/z01in172.it-codigo . Exemplos: a) chamada de zoom para atributos em um frame: ON F5 OF ord-prod.i &prog-zoom=inzoom/z01in172. Observação Esta mesma sintaxe deve ser utilizada para colocar zoom em atributos cujo nome na viewer difere no nome do atributo no browse da pesquisa.ct-codigo in frame {&FRAME-NAME} OR MOUSE-SELECT-DBLCLICK OF det-rateio.it-codigo in frame {&FRAME-NAME} DO: {include/zoomvar.ct-codigo in frame {&FRAME-NAME} DO: {include/zoomvar.w &campo=det-rateio.i &prog-zoom=adzoom/z01ad049.w &campo=ord-prod.w &campo=c-item-pai &campozoom=it-codigo} END. d) chamada de zoom para colunas de um browse updateable: ON F5 OF tt-digita.it-codigo in browse {&browse-NAME} OR MOUSE-SELECT-DBLCLICK OF tt-digita.it-codigo in frame {&FRAME-NAME} OR MOUSE-SELECT-DBLCLICK OF ord-prod. c) chamada do zoom para variáveis em um frame: ON F5 OF ord-prod.<parâmetros>: chama uma procedure dentro da Window do programa de zoom.sc-final &campozoom2=sc-codigo} END. it-codigo <= c-item-fim and item. • passagem para o include de zoom dos parâmetros através de ¶metros.i &prog-zoom=inzoom/z01in172.Construção de Programas utilizando os Estilos e suas Técnicas 323 &campozoom=it-codigo &browse=br-digita} END. que recebe o nome do browse onde o campo/variável se encontra. e) chamada de zoom para telas com mais de uma frame (estilo de relatórios): ON F5 OF c-item-pai in frame f-pg-par OR MOUSE-SELECT-DBLCLICK OF c-item-pai in frame f-pg-par DO: {include/zoomvar. e transfere o conteúdo para variáveis que influenciarão a abertura da query: define input parameter p-tipo-contr as char no-undo. . • criação nos browses do zoom de uma procedure que recebe os parâmetros recebidos da Window de zoom.tipo-contr = p-tipo-contr. run pi-seta-inicial in h_b26in172 (input p-tipo-contr). f) chamada de zoom com passagem de parâmetros: • criação na Window do programa de zoom de uma procedure que recebe e trata os parâmetros e os repassa para os browses do zoom: define input parameter p-tipo-contr as char no-undo. run pi-seta-inicial in h_b25in172 (input p-tipo-contr). assign c-tipo-contr = p-tipo-contr. • código do open query de cada browser que compõe o zoom: open query br-table for each item where item. Observação A única diferença está na utilização do parâmetro &browse.w &campo=c-item-pai &campozoom=it-codigo &frame=f-frame} END. Observação A única diferença está na utilização do parâmetro &frame.it-codigo >= c-item-ini and item. que recebe o nome da frame onde o atributo se encontra. ON F5 OF c-item-pai in frame f-pg-par OR MOUSE-SELECT-DBLCLICK OF c-item-pai in frame f-pg-par DO: {include/zoomvar.i &prog-zoom=inzoom/z01in172.w &campo=item.it-codigo &campozoom=c-item-pai ¶metros="run pi-seta-inicial in wh-pesquisa (input param-cp.tipo-contr)."} END. Observação Quando o zoom é chamado, executa o conteúdo de &parâmetros. Este, no exemplo, chama a procedure pi-seta-inicial, localizada dentro da Window do programa de zoom (representada pela variável wh-pesquisa), passando para esta procedure como parâmetro um valor de sistema (param-cp.tipo-contr). A procedure pi-seta-inicial, na Window do zoom, recebe o parâmetro e o envia para o browse, através do chamado da procedure pi-seta-inicial, dentro do browse, recebe o valor e atribui à variável de filtro (c-tipo-contr) utilizada para abrir a query. Por fim, para todos os campos em frames (não é possível para colunas de browsers) que possuem zoom é necessário alterar o ponteiro do mouse, através do método load-mouse-pointer, normalmente isto é realizado no main-block do programa. Exemplo: c-item-pai:load-mouse-pointer ("image/lupa.cur") in frame {&frame-name}. Observação Utilizar sempre a sintaxe acima, no início do Main Block. 5. Criar o gatilho de Mouse-Select-DblClick o campo que possui o zoom com o seguinte código: apply 'F5' to self. 6. No Main-block, deve-se alterar o ponteiro do mouse para o campo chave estrangeira. No exemplo: costumer.state:load-mouse-pointer ("image/lupa.cur") in frame {&frame-name}. Como implementar ThinZoom e campos de referência para campos chave estrangeira em SmartObjects Para implementar o ThinZoom em campos chave estrangeira, além de apresentar campos de referência no retorno do zoom ou na saída do campo Construção de Programas utilizando os Estilos e suas Técnicas 325 chave estrangeira devem ser feitas as seguintes alterações quando da criação da viewer do programa que chama o zoom: Observação Nos exemplos de código abaixo, customer é a tabela que possui uma chave estrangeira no campo state, relacionando-a com a tabela state e o campo state-name é o campo de referência para o usuário. Passos: 1. Deve ser criada uma variável do tipo caracter view-as fill-in, na qual é armazenado o campo de referência da chave estrangeira e deve ser colocada ao lado do campo que tem zoom. Acessar as propriedades deste campo e retirar a propriedade 'Enable'. Deve também ser definida na seção definitions uma variável do tipo Handle chamada hProgramZoom. Exemplo: Para o campo de referência state-name temos a variável c-statename. DEFINE VARIABLE hProgramZoom AS HANDLE NO-UNDO 2. Criar a procedure local-display-fields e nela, antes do run dispatch, deve ser inserida uma lógica para carregar o valor inicial da variável para o campo de referência. Exemplo if available customer then do: find state where state.state = customer.state no-lock noerror. assign c-state-name = if avail state then state.statename else "":U. end. 3. No gatilho de leave do campo que possui zoom deve ser inserida uma lógica para determinar o valor do campo de referência com base no que o usuário digitou no campo que possui zoom. Exemplo {include/leave.i &tabela=state &atributo-ref=state-name &variavel-ref=c-state-name &where="state.state = input frame {&frame-name} customer.state"} Onde: <tabela>: tabela que possui a chave estrangeira; <atributo-ref>: recebe o campo de referência da tabela da chave estrangeira; <variavel-ref>: variável criada para receber o campo de referência; <where>: cláusula where para localizar o registro na tabela de referência; 4. Através do include ZoomFields.i é padronizada a chamada do zoom para os campos que são chave estrangeira, que atende as seguintes situações de acesso ao zoom; • • • a partir de um campo chave estrangeira de uma tabela; a partir de uma variável; a partir de um campo chave estrangeira de uma tabela cujo nome não coincide com o nome do campo no browse de pesquisa, de onde o valor será buscado (Exemplo: Na viewer o campo chama-se it-codigo-pai, e no browse o campo chama-se it-codigo, simplesmente - comum em tabelas com auto-relacionamento); Sintaxe: {method/ZoomFields.i &ProgramZoom="nome do programa" &FieldZoomN="nome do campo que retorna" &FieldScreenN="nome do campo ou variável" &FrameN="frame" &RunMethod="run procedure in hProgramZoom" &EnableImplant="yes/no"} Onde: <ProgramZoom>: Nome do programa de Pesquisa a ser executado; <FieldZoomN>: Indica o nome do campo que deve ser retornado pelo programa de Pesquisa, N indica um número que pode variar de 1 até 10; <FieldScreenN>: Indica o nome do campo (variável) que deve receber o valor retornado pelo programa de pesquisa, N indica um número que pode variar de 1 até 10; <FrameN>: Indica o nome da frame na qual está o campo (variável) que deve receber o valor retornado pelo programa de pesquisa, N indica um número que pode variar de 1 até 10; <RunMethod>: Indica a linha de comando, que contém a chamada a um método do programa de pesquisa. A variável hProgramZoom contém o handle do programa de pesquisa; <EnabledImplant>: Os valores YES e NO indicam se o botão Implantar será habilitado ou não; Exemplos: Construção de Programas utilizando os Estilos e suas Técnicas 327 a) chamada de zoom para atributos em um frame: ON F5 OF ttcustomer.sales-rep in frame fPage2 OR MOUSE-SELECT-DBLCLICK OF ttcustomer.sales-rep in frame fPage2 DO: {method/ZoomFields.i &ProgramZoom="spp/spzoom.w" &FieldZoom1="Sales-Rep" &FieldScreen1="ttCustomer.Sales-Rep" &Frame1="fPage2" &RunMethod="RUN setaVariable IN hProgramZoom (INPUT 'Representante')." &EnableImplant="NO"} END. b) chamada do zoom para mais de um atributo de um frame: ON F5 OF ttcustomer.sales-rep in frame fPage2 OR MOUSE-SELECT-DBLCLICK OF ttcustomer.sales-rep in frame fPage2 DO: {method/ZoomFields.i &ProgramZoom="spp/spzoom.w" &FieldZoom1="Sales-Rep" &FieldScreen1="ttCustomer.Sales-Rep" &Frame1="fPage2" &FieldZoom2="Rep-Name" &FieldScreen2="fiRepName" &Frame2="fPage2" &RunMethod="RUN setaVariable IN hProgramZoom (INPUT 'Representante')." &EnableImplant="NO"} END. c) chamada do zoom para variáveis em um frame: ON F5 OF ttcustomer.sales-rep in frame fPage2 OR MOUSE-SELECT-DBLCLICK OF ttcustomer.sales-rep in frame fPage2 DO: {method/ZoomFields.i &ProgramZoom="spp/spzoom.w" &FieldZoom1="Sales-Rep" &FieldScreen1="cRepresentante" &Frame1="fPage2" &RunMethod="RUN setaVariable IN hProgramZoom (INPUT 'Representante')." &EnableImplant="NO"} END. Observação Esta mesma sintaxe deve ser utilizada para colocar zoom em atributos cujo nome na viewer difere no nome do atributo no browse da pesquisa. Por fim, para todos os campos em frames que possuem zoom é necessário alterar o ponteiro do mouse, através do método load-mouse-pointer, normalmente isto é realizado no main-block do programa. Exemplo: c-item-pai:load-mouse-pointer ("image/lupa.cur") in frame {&frame-name}. Observação Utilizar sempre a sintaxe acima, no início do Main Block. 5. Criar o gatilho de Mouse-Select-DblClick no campo que possui o zoom com o seguinte código: apply 'F5' to self. 6. No Main-block, deve-se alterar o ponteiro do mouse para o campo chave estrangeira. No exemplo: costumer.state:load-mouse-pointer ("image/lupa.cur") in frame {&frame-name}. Como imprimir campos editores nos relatórios Para imprimir campos com view-as editor, deve-se seguir os passos abaixo: 1. Na área de definições do programa implementar a chamada para o include tt-edit.i, que define uma temp-table chamada tt-editor. {include/tt-edit.i} 2. Não incluir o campo editor na definição do form de impressão, ele deve ser impresso num form separado. Incluir o campo tt-editor.conteudo num novo form vazio, determinando o formato ocupado no layout do relatório. Exemplo: form item.it-codigo /* item.narrativa */ with stream-io width 132 frame f-imp. Construção de Programas utilizando os Estilos e suas Técnicas 329 form tt-editor.conteudo format "x(50)" no-label with stream-io width 132 frame f-imp. 3. No final do programa de impressão, na área de procedures internas, implementar a chamada para o include pi-edit.i, que define a procedure interna pi-print-editor. {include/pi-edit.i} 4. Na impressão do campo editor, deve-se chamar a procedure interna piprint-editor: for each item no-lock: run pi-print-editor (item.narrativa, 50). find first tt-editor no-erro. disp item.it-codigo with frame f-imp. down with frame f-imp. for each tt-editor: disp tt-editor.conteudo with frame f-imp. down with frame f-imp. end. end. Como totalizar colunas de um browse Para totalizar colunas (valores) de um browse numa consulta ou outro programa é necessário seguir alguns passos: 1. Estes totais devem ser apresentados em variáveis view-as fill-in, pois não é possível que se apresentem como a última linha do browse. a) Nos programas de consulta, a recomendação é que sejam apresentados numa caixa de diálogo (utilizar CustomDialog) que é acionada por um botão na régua de botões. Este botão utiliza como imagem "image/imtotal.bmp" e como imagem insensitive "image/ii-total.bmp". b) No caso de caixa de diálogo, é necessário criar um novo programa para que se apresente, seu nome externo é igual a de um subprograma (.w) deste programa. 2. No gatilho de choose deste botão deve-se implementar uma lógica para totalizar os campos, com o objetivo de não reler a base de dados, pois, na maioria dos casos, os registros já estão na query. Exemplo DO: /* desvincula a query do browse */ ASSIGN br-browse:REFRESHABLE IN FRAME {&frame-name}= no. ASSIGN de-tot-debito = 0 de-tot-credito = 0. GET FIRST br-browse. DO WHILE AVAIL tabela: /* tabela da query */ ASSIGN de-tot-debito = de-tot-debito + tabela.val-debito de-tot-credito = de-tot-credito + tabela.valcredito. GET NEXT br-browse. END. /* vincula a query no browse e torna disponível o registro corrente */ ASSIGN br-browse:REFRESHABLE IN FRAME {&frame-name} = yes. If br-browse:FETCH-SELECTED-ROW(1) in frame {&frame-name} then. /* chama o programa da caixa de diálogo RUN XXP/XX999X.W (input de-tot-debito, input de-tot-credito). END. */ Como adaptar a procedure pi-retorna-valor no Custom Browser Zoom Wizard Quando desenvolvemos um Custom Browser Zoom Wizard, uma procedure interna denominada pi-retorna-valor é gerada automaticamente, no momento em que é salvo o programa. Esta procedure interna é responsável por retornar ao campo chamador do zoom o valor escolhido pelo usuário. Inicialmente, ela é gerada para devolver campos da tabela principal do browse, ou seja, a primeira a ser referenciada em sua criação. Desta forma, o zoom de chave estrangeira fica restrito a campos desta tabela denominada principal. Entretanto, surgiram duas outras situações em que há necessidade do zoom retornar outros campos ou variáveis que compõe o browse de zoom. Diante Construção de Programas utilizando os Estilos e suas Técnicas 331 disso, implementamos a possibilidade do programador interferir na geração desta procedure interna. Para interferir, basta marcar o toggle-box "Manutenção Manual da PIRETORNA-VALOR", na tela que é apresentada, quando o SmartObject é gravado. A partir de então ela só pode ser modificada pelo programador e não vai ser gerada pelo estilo como até então. Situações necessárias • campo de outra tabela: Para campos de uma tabela além da tabela da principal, o desenvolvedor deve alterar a pi-retorna-valor, para que devolva o campo desejado. Exemplo /********************************/ /* PI-RETORNA-VALOR **/ /*******************************/ DEFINE input parameter p-campo as character no-undo. DEFINE variable p-valor as char initial "" no-undo. if avail mguni.proced_consult_proced then do: case p-campo: when "cond_proced" then assign p-valor = string(proced_consult_proced.cod_proced). when "des_prog_dtsul" then assign p-valor = prog_dtsul.des_prog_dtsul. end case. end. return p-valor. No caso, o Custom Browser Zoom Wizard por default criou a procedure piretorna-valor para o campo cod_proced que pertence a tabela principal do browse, como o desejado é que o mesmo retorne a descrição do programa (des_prog_dtsul) então, foi acrescentado o código: when "des_prog_dtsul" then assign p_valor = prog_dtsul.des_prog_dtsul. • variáveis / campos calculados: Para esta situação, o desenvolvedor deve alterar a procedure pi-retorna-valor para que esta devolva a variável / campo calculado desejado. Exemplo /********************************/ /* PI-RETORNA-VALOR **/ /*******************************/ DEFINE input parameter p-campo as character no-undo. DEFINE variable p-valor as char initial "" no-undo. if avail proced_consult_proced then do: case p-campo: when "cond_proced" then assign p-valor = string(proced_consult_proced. when "c-descricao" then assign p-valor = c-descricao.i. com as propriedades abaixo: . end. No frame f-pg-imp. return p-valor. Neste caso. do tipo logical. coloca-se o nome da variável. na definição da Temp-Table tt-param. define temp-table tt-param field destino as integer field arquivo as char field usuário as char field data-exec as date field hora-exec as integer field classifica as integer field desc-classifica as char format "x(40)" field parametro as logical. na chamada do zoomvar. como o desejado é que o mesmo retorne a descrição que está gravada em uma variável e esta variável consta no browse foi acrescentado o código: when "c-descricao" then assign p-valor = c-descricao. end case.cod_proced). em vez do nome do campo da tabela que se deseja retornar. o Custom Browser Zoom Wizard criou automaticamente a pi-retornavalor para o campo cod_proced que pertence a tabela principal do browse. No caso. Como implementar Parâmetros de Impressão em Relatórios Caso haja a necessidade de implementar Parâmetros de Impressão em Relatórios devem ser seguidos os passos abaixo: Impressão Página de Parâmetros: 1. inserir um objeto rectangle. Na área de Definições do Programa incluir o campo parâmetro. 2. 63 Width: 46. alterar a lógica de assign da Temp-table ttparam para gravar o campo parametro . inserir um objeto toggle-box.00 Row: 8.71 3. inserir um objeto fill-in.29 Row: 8.67 Display: não selecionado Enable: não selecionado View-as-Text: selecionado Initial Value: Parâmetros de Impressão Private Data: Parâmetros de Impressão 4.20 Row: 9. com as propriedades abaixo: • • • • • • • • Object: tb-parametro Label: Imprimir Página de Parâmetros No-Label: não selecionado Column: 3. Na procedure pi-executar.29 Height: 1.72 Height: 0.00 Height: 0.Construção de Programas utilizando os Estilos e suas Técnicas 333 Column: 2.83 Initial Value: no 5. com as propriedades a seguir: • • • • • • • • • • • Object: text-parametro No-Label: selecionado Column: 1.00 Width: 32.25 Width: 24. Na frame f-pg-imp. Na frame f-pg-imp. usuario = c-seg-usuario tt-param.arquivo tt-param.00 Row: 8.hora-exec = time tt-param.assign tt-param. 2. realizar o tratamento do valor do campo parametro. Formato de Impressão (80 colunas ou 132 colunas): 1. para imprimir ou não a Página de Parâmetro.data-exec = today tt-param. do tipo integer. incluir o campo formato. display c-parametro c-impressao c-destino tt-param. Na frame f-pg-imp.desc-classifica = entry((ttparam.parametro = if input frame f-pg-imp tbparametro = "yes" then yes else no. rs-classif:radio-buttons in frame f-pg-cla) tt-param. down with frame f-parametros.classifica .63 . 6. Exemplo if parametro = yes then do: page. na definição da Temp-Table tt-param. end. No programa RP.1) * 2 + 1. define field field field field field field field field temp-table tt-param destino as integer arquivo as char usuario as char format "x(12)" data-exec as date hora-exec as integer classifica as char format "x(40)" desc-classifica as char format "x(40)" formato as integer.classifica = input frame f-pg-imp rsdestino tt-param. Na área de Definições do Programa.P.usuario with frame f-parametros. com as propriedades abaixo: • • Column: 2. inserir um objeto rectangle.destino = input frame f-pg-imp rsdestino tt-param. 00 ou 10.25 Width: 31. Na frame f-pg-imp.Construção de Programas utilizando os Estilos e suas Técnicas 335 • • • • • • • • • • Width: 46.00 Height: 0.79 (caso exista o objeto tb-parametro) Object: text-parametro No-Label: selecionado Column: 1.29 Row: 8.29 Height: 1. Na frame f-pg-imp. 1. "132 colunas".08 (caso exista o objeto tb-parametro) Width: 32. Na procedure pi-executar. inserir um objeto fill-in.83 Horizontal: selecionado Initial Value: 2 Help: Formato de Impressão 5.71 ou 2. 2 • • • • • • • Column: 3 Row: 9. com as propriedades abaixo: 4. inserir um objeto radio-set. com as propriedades abaixo: • • Object: rs-formato Buttons: "80 colunas".92 Initial Value: Parâmetros de Impressão Private Data: Parâmetros de Impressão 3.00 Height: 0. alterar a lógica de assign da Temp-table ttparam para gravar o campo formato . 7.assign tt-param. end.desc-classifica = entry((tt-param.formato e utilizar uma frame ou outro frame. view frame f-rodape-80. mas possui a definição de form´s de cabeçalho e rodapé de 80 colunas. No momento de realizar o display dos campos. enviar uma mensagem de notify (open query) para a Window. 6. Exemplo if tt-param. Como implementar Botão de Filtro em Zoom Quando for necessário reabrir as querys do browse.i que é idêntico ao anterior.formato = 1 then do: {include/i-rpcb80.1) * 2 + 1. pode ser consultado como exemplo.classifica .hora-exec = time tt-param. conforme comando abaixo: RUN notify IN this-procedure ('open-query. No programa RP. definir form´s de 132 colunas e 80 colunas para o relatório. 8. else do: {include/i-rpcab. exemplo: if tt-param. . rs-classif:radio-buttons in frame f-pg-cla) tt-param.formato = if input frame f-pg-imp rs-formato = "1" then 1 else 2.W. No programa RP.P. O Zoom Z02IN172. Para tanto. else do: view frame f-cabec.i} end.P.classifica = input frame f-pg-cla rs-classif tt-param.i} end. verificar qual o valor do campo tt-param.usuario = c-seg-usuario tt-param.i deve ser incluído o include: include/i-rpcb80. além de incluir o include: include/i-rpcab. deve ser alterado o posicionamento dos campos no form e a propriedade width.data-exec = today tt-param. deve-se no choose do botão. a partir de seleções efetuadas (Exemplo: Botão do FILTRO). end. view frame f-rodape.destino = input frame f-pg-imp rs-destino tt-param.formato = 1 then do: view frame f-cabec-80. após a chamada da tela de filtro. containertarget':U). este programa inicia posicionado no registro X. ELSE RUN dispatch IN h_<nome-query> (INPUT "get-first":U)..i <nome-tabela>} Na VIEWER. que deve conter o rowid do último registro acessado na sua tabela. deve ser incluso o código a seguir após o RUN DISPATCH .. Programa chamado: Variável global deve ser definida em DEFINITIONS da Window.i" conforme é mostrado a seguir: {include/i-vrtab. Este código é implementado depois do RUN DISPATCH .. Definição da Variável Global A variável global deve ser definida na área de DEFINITIONS da Window e da Viewer.Construção de Programas utilizando os Estilos e suas Técnicas 337 Como implementar reposicionamento de registro com base nas variáveis globais Toda tabela deve possuir no produto uma variável global do tipo rowid. ao chamar outro programa que utilize a mesma tabela para navegação. IF gr-<nome-tabela> <> ? THEN RUN pi-reposiciona-query IN h_<nome-query> (INPUT gr-<nome-tabela>).. Assim. Para definir esta variável. em todas as consultas e nos cadastros em que for usado. se o usuário acessar um programa qualquer e através da navegação estiver posicionado num registro X de uma tabela t. É criado a PROCEDURE LOCAL-INITIALIZE e inserir o código a seguir antes do RUN DISPATCH . Além disso. . é criada a procedure LOCAL-ROW-AVAILABLE com o código: if avail <nome-tabela> then assign gr-<nome-tabela> = rowid(<nome-tabela>)... RUN set-attribute-list IN h_<home-query> (INPUT "Reposition-Pending=YES":U). deve-se utilizar o include "i-vrtab.. Para que seja evitado este problema. com o código antes do RUN DISPATCH: ASSIGN rw-<nome-tabela> = gr-<nome-tabela>. fazer em todos os programas onde são utilizadas. uma variável LOCAL como ROWID: def var rw-<nome-tabela> as rowid no-undo. ASSIGN gr-<nome-tabela> = rw-<nome-tabela>. isto é: IF rw-<nome-tabela> <> ? THEN RUN pi-reposiciona-query IN h_<nome-query> (INPUT rw-<nome-tabela>). sendo que o <nome-tabela>. ELSE RUN dispatch IN h_<nome-query> (INPUT "get-first":U). da Window do programa chamado. Reposicionamento Automático do Browser de Zoom Observação Somente implementar a técnica nas variáveis INICIAL de faixa. então passa a ser a tabela do browse. a variável global é zerada. • editar os SmartBrowsers que compõe o programa de zoom e selecionar a variável inicial de faixa (no exemplo c-inicial). colocar o mesmo código do LOCALROW-AVAILABLE. na área de DEFINITIONS. RUN set-attribute-list IN h_<nome-query> (INPUT "Reposition-Pending=YES":U). se o programa chamador for do tipo Consulta-Relacionamento. . • atualizar a procedure LOCAL-INITIALIZE. Observação Em caso de posicionamento de Browser. com Browse.Ao utilizar uma mesma viewer em dois programas e um deles é consulta do outro. ou seja. no Gatilho VALUE-CHANGED do Browse. na Window do programa chamado. faça o seguinte: • criar. cujo tipo de dado for CARACTER ou INTEIRO. Para prevenir programas posteriores. • após o RUN DISPATCH substituir a variável global pela local. i. existe o preprocessador &variavel que deve conter o nome da variável inicial de faixa: .i.Construção de Programas utilizando os Estilos e suas Técnicas 339 • criar um gatilho para o evento ANY-KEY destas variáveis com a chamada do include i-anykey. existe o preprocessador &variavel que deve conter o nome da variável inicial de faixa: • criar um gatilho para o evento BACK-TAB destas variáveis com a chamada do include i-tab. existe o preprocessador &variavel que deve conter o nome da variável inicial de faixa: • criar um gatilho para o evento TAB destas variáveis com a chamada do include i-tab. Se você estiver numa versão 9 ou superior clique no botão “V8 call”. Como validar campos em viewers diferentes Abra a viewer que você deseja fazer a validação. conforme a necessidade) e entre no menu Inserir. mas pode-se fazer em qualquer outra procedure interna.• salvar e fechar o SmartBrowser. Retorna a seguinte lógica: . em Show Procedures escolha Methods e nos methods procure por Get-Field-Screen-Value. entre na procedure de validação (normalmente a pi-validade. No combo-box Object escolha adm-broker-hdl. depois em procedure call. código do gatilho. definição do gatilho. definição da variável de versão do gatilho. Em <handle atual> deve ser colocado o nome da variável handle. Neste caso. pois senão o programa não encontra o campo. Como construir gatilhos de dicionários de dados São apresentados a seguir. Por exemplo. INPUT “name”). INPUT <campo a ser validado>).name. pois com ela você estará passando o handle da viewer que você estiver trabalhando. . O <campo a ser validado> vai utilizar o nome do campo que deve ser buscado o valor. modelos de cada tipo de gatilho de dicionário de dados. if RETURN-VALUE = “” then do: /*insira aqui o tratamento do erro*/ return ‘ADM-ERROR’:U. Esses modelos que servem de exemplo para construção dos gatilhos são compostos por: • • • • cabeçalho. Vale lembrar que não se deve passar o handle da viewer onde estiver o campo a ser procurado. a partir da qual deve ser procurado o valor do campo. tem que ser como parâmetro <name>. se quiser validar um campo a partir do customer. utilize sempre a variável de programa this-procedure. Ex: RUN Get-Field-Screen-Value IN adm-broker-hdl (INPUT this-procedure.Construção de Programas utilizando os Estilos e suas Técnicas 341 RUN Get-Field-Screen-Value IN adm-broker-hdl (INPUT <handle atual>. end. /** Definição da variável que indica a versão do gatilho def var c-versao-mg97 as char init "01. sua ** reprodução parcial ou total por qualquer meio.00" no-undo.... (1997) ** Todos os Direitos Reservados.00..A.A.. só poderá ser ** feita mediante autorização expressa.: XX/XX/XXXX ** *********************************************************/ TRIGGER PROCEDURE FOR DELETE OF <nome-da-tabela>. só poderá ser ** feita mediante autorização expressa.. /** Definição da variável que indica a versão do gatilho def var c-versao-mg97 as char init "01.. /************************************************************* ** Copyright DATASUL S. ** ** Este fonte é de propriedade exclusiva da DATASUL. ** ** Gatilho de Dicionário. ** ** Este fonte é de propriedade exclusiva da DATASUL.• Gatilho de Creat e include para chamada da EPC. (1997) Write .A.00.: XX/XX/XXXX ** ***************************************************************/ TRIGGER PROCEDURE FOR CREATE OF <nome-da-tabela>.i <nome-da-tabela>} /************************************************************* Gatilho de ** Copyright DATASUL S. sua ** reprodução parcial ou total por qualquer meio.. (1997) ** Todos os Direitos Reservados. ** ** Gatilho de Dicionário.: CREATE/<nome-da-tabela> ** Data de Criação.. /** Validações de eliminação **/ **/ /** Include para chamada de EPC /** Eliminação em cascata **/ **/ {include/i-epc102..00" no-undo. /** Código do gatilho de Create /** Fim de Include **/ **/ **/ Gatilho de Delet e /************************************************************* ** ** Copyright DATASUL S.: DELETE/<nome-da-tabela> ** Data de Criação. sendo que este só ocorre nos gatilhos de WRITE e DELETE.. . includes. 2. ** ** Este fonte é de propriedade exclusiva da DATASUL. os objetos para localização para a Argentina ficam armazenados no diretório local/arg.. Por exemplo. abaixo do diretório de instalação do Datasul-EMS.<campo> then do: Código desejado no gatilho de assign. só poderá ser ** feita mediante autorização expressa. bancos. end. Todos os arquivos (programas.00" no-undo. que identifica o país da localização.Construção de Programas utilizando os Estilos e suas Técnicas 343 ** Todos os Direitos Reservados.: WRITE/<nome-da-tabela> ** Data de Criação..00. /** Código do gatilho de Write **/ **/ /** Include para chamada da EPC **/ {include/i-epc101.. Gatilho de Find Não é recomendada a utilização do gatilho de Assign. sua ** reprodução parcial ou total por qualquer meio. Todos os objetos que compoem a localização para um determinado país tem na composição do seu nome uma sigla de três letras. Como implementar localizações Objetivando viabilizar a administração de localizações do Datasul-EMS 2. E todas as triggers criadas são . Ver subcapítulo Siglas de países. é adotado um padrão para sua implementação. ** ** Gatilho de Dicionário. /** Definição da variável que indica a versão do gatilho def var c-versao-mg97 as char init "01. utilizando a seguinte lógica no gatilho de Write: n if new <nome-da-tabela> or <nome-da-tabela>.i <nome-da-tabela> <b-old-nome-da-tabela>} Não é recomendada a utilização do gatilho de Find.. para atender as necessidades de um determinado país.<campo> <> <b-old-nome-databela>. etc) criados para a localização de um país são armazenados num subdiretório.00. sendo que este pode ser Gatilho de Assig substituído. que identifica o país dentro do diretório local. conforme segue: 1.: XX/XX/XXXX ** ***************************************************************/ TRIGGER PROCEDURE FOR WRITE OF <nome-da-tabela> OLD BUFFER <bold-nome-da-tabela>. w(browser) xxxq999.w(viewer usab999.il usa9999a. Para a construção de programas podem ser utilizados os mesmo estilos.p(write da tabela) tgarg999.w(browser) argq999.w(vá para) usai999.i1 arg9999a.o(delete da tabela) tfarg999.db usa9999. País Padrão Base de Dados lcxxx.w arg9999.p xxx9999a.p(create da tabela) tdarg999.i1 Estados Unidos (exempl o) lcusa. 3.i xxx9999.w xxx9999.il xxx9999a.w usa9999. 4.w(browser) usaq999.db na (exempl o) arg9999.p(find da tabela twarg999. local/arg/database.i usa9999.é a sigla do país.w(vá para) xxxi999.w(zoom) usag999.i(include de dicionários) usav999.w (viewer) xxxb999. Na nomenclatura destes programas. por exemplo.w(query) argz999(zoom) argi999. com a mesma dinâmica utilizada e que pode permitir a integração com outros programas implementados. sempre no padrão 'lcxxx'. e os três primeiros 999 .i(include de dicionários) Argenti lcarg.db Objetos xxx9999.armazenadas dentro de um subdiretório do diretório do próprio país numa pasta chamada database.il argv999.p usa9999a. Casa País deve ter uma base de dados própria.w(query) xxxz999. . demonstrados no Capítulo 5.é o número Dump-name da tabela.i arg9999.w(viewer) argb999.w(query) usaz999. conforme a nomenclatura demonstrada na tabela acima.w(zoom) xxxg999. adotar o padrão a seguir: Onde: XXX .p arg9999a.i1 xxxv999.i(include de dicionários) tcarg999.p(assign de campo) Triggers 5. como no Exemplo: Campos da tabela: tipo-tax cod-tax descrição tax-perc tributados ct-tax tipo sc-tax conta-tax ind-data-base ct-percepcao sc-percepcao conta-percepcao sc-retencao ct-retencao conta-retencao perc-percepcao cod-esp serie incidencia-impto Índices da tabela tipo-tax: Flag IndexNa s me pu ch-tipo-tax Cnt Field Name 1 + cod-tax Campos da tabela ext-tipo-tax cod-tax cod-sicore Índices da tabela ext-tipo-tax: Flag IndexNa Cnt Field . Cada base de dados contém a extensão dos arquivos necessários para a localização.Construção de Programas utilizando os Estilos e suas Técnicas 345 6. se o valor for "yes" os objetos ficam um pouco maiores (em pixels). deve-se utilizar a técnica de construção de APPC . é informar ao usuário que determina área na interface é um campo ou variável do sistema. definindo-se a permissão para cada um. Implementaç Existem dois parâmetros no progress.ini que afetam diretamente a interface dos programas: ão • • Use-3D-Size Keep3DfillinBorder O parâmetro Keep3DfillinBorder é de menor importância. assim deve haver situações onde um programa foi desenvolvido com Use-3D-Size=no e não roda onde use-3dsize=yes. na prática determina se o efeito 3D é para fora ou para dentro das dimensões do objeto. No módulo de Segurança são administradas as informações do produto Datasul-EMS 2. Para a localização de programas do Datasul-EMS. uma parcela dos desenvolvedores está com o parâmetro Use-3D-Size como "yes" e outra parcela como "no". O valor padrão é NO. Já o parâmetro Use-3D-Sizen determina se os objetos devem usar uma dimensão 3D ou não. evitar problemas como programas que foram construídos com determinados parâmetros e depois são executados com outros. ou o inverso. Então. onde não é realizada a substituição completa do mesmo. Padronização dos parâmetros do progress. conceder automaticamente a mesma permissão para todos os usuários que fazem parte deste país. A vantagem de manter a borda.00. a sua função é determinar se os fill-in´s irão manter a borda 3D quando desabilitados.ini Objetivo Padronizar os parâmetros de que influem no tamanho dos objetos no UIB.0. 8. e portanto. Como não houve um padrão no início do desenvolvimento do Datasul-EMS 2.s pu me cg-tipo-tax Name 1 + cod-tax 7. para com isso. . mas o valor padrão para o mesmo é YES. e não um adereço da interface.Application Partner Program Call (ainda não documentada). através da implementação de níveis de segurança a um determinado país. Porém. Implementaç • ão ao entrar em section functions do UIB.2 do Progress. após gravar um novo registro não é habilitada a tela para uma próxima inclusão. após gravar um novo registro é habilitada a tela para uma próxima inclusão. O valor default para esta propriedade é Multiple.) é possível que a solução seja recompilar o objeto ou então editar o objeto (aumentando as dimensões do frame. Caso alguns programas passem a não rodar (erro: **Cannot fit <objeto> in frame . quando o valor é Multiple. Para nome da função foi determinado que é utilizado o seguinte padrão: fn-"nome que qualifica a .ini. é indispensável que sejam padronizados esses dois parâmetros nos arquivos progress. Onde: <handle-panel>: variável que contenha o valor do handle do panel <valor>: valor para a propriedade que pode ser: Simple ou Multiple Como utilizar "functions" no UIB Desde o início da utilização da versão 8. Ou seja. é questionado o nome da nova função e o tipo de dado que é retornado por ela. normalmente a distância do topo do frame e o primeiro objeto).w) existe uma propriedade.. conforme exposto acima. Como setar os modos de inclusão (Simple/Multiple) Para os panels de Inclusão (panel/p-cadsim. A sintaxe a ser utilizada para setar esta propriedade é: RUN set-attribute-list IN <handle-panel> (INPUT "AddFunction=<valor>":U). quando esta propriedade está setada como o valor Simple.. foi possível notar uma nova section no UIB.w e panel/p-cadsi4. A section functions veio para facilitar a implementação de rotinas de cálculo que antes eram confusas de serem utilizadas e esta técnica deve demonstrar este recurso. utilizada para setar o modo de inclusão do papel. chamada AddFunction.Construção de Programas utilizando os Estilos e suas Técnicas 347 Contudo. conforme exemplo abaixo. Antes era necessário utilizar ON-FIND TABELA no MAIN-BLOCK do programa para calcular o valor de um campo que possuía uma lógica mais complexa (Exemplo: pesquisa em outras tabelas). lógica da função Return de-valor. devem ser retiradas as "" do comando RETURN e acrescentado no seu lugar o nome da variável que possui o valor a ser retornado para quem chamou a função. Agora basta seguir a seguinte sintaxe: fn-nome da função (valor a ser transferido) na expressão de um calculated field para utilizar uma função e atribuir o valor retornado a uma outra variável do browser. Esta função é muito útil para os campos calculados de browsers. Quanto ao retorno da função. Exemplo RETURNS DECIMAL (input de-valor as decimal): valor transferido /*-----------------------------------------------------------Purpose: Notes: -------------------------------------------------------------*/ assign de-valor = (de valor + 1000). Para que a função retorne o valor calculado por ela. deve ser colocado o tipo de dado que a função retorna no final de sua execução. Exemplo: Depois de ter criado a função. valor retornado da função END FUNCTION. deve ser declarado os valores a serem transferidos para ela. Exemplo: .função". Conforme a expressão do calculated field. o valor retornado da função é mostrado na variável de soma-aplic do browser. • rodar o procedimento IsRegistered que deve estar dentro do programa ututils. a utilização de tabelas temporárias dentro de funções está causando SYSTEM ERROR (130). temos que a função "fn-valor" está sendo acionada utilizando o valor do campo banco.Construção de Programas utilizando os Estilos e suas Técnicas 349 Neste exemplo. Como verificar o registro de um OCX Objetivo Esta técnica deve ser usada sempre que for utilizado um OCX no programa. definir uma variável do tipo handle. Observação Recomenda-se que não sejam utilizadas temp-tables. def var h-prog as handle no-undo.p persistent set h-prog. Implementaç • ão • rodar o programa ut-utils. passando o seguinte parâmetro: . Ela consiste basicamente em verificar se o OCX está registrado corretamente na máquina para que não seja disparado um erro PROGRESS.2A do Progress.p persistente e atribuir o seu handle para a variável que foi criada anteriormente. run utp/ut-utils.p.vl-lim-aplic. Na versão 8. 1 CtWAVE.OCX CIMAIL.OCX MIDIFL32. antes que o PROGRESS dispare o erro.OCX COMCTL32.CellsView CIMAIL. if return-value <> "Ok" then do: run utp/ut-msgs.p que foi rodado persistente da memória.l ").Midifile Ctl MCI.OCX CELLSVWR. pois na falta deste. Observação Não esquecer de executar o último procedimento descrito.TreeView DatasulImage.l Microsoft TreeView Control Microsoft Common Dialog Control .OCX Nome Barras. return.CISMTPCtrl.OCX DATIMAGE. • Caso o return-value seja diferente de "Ok" mostrar a mensagem padrão de inexistência de OCX e fechar o programa: • passar como parâmetro para a mensagem o nome do OCX. • eliminar o programa ut-utils. delete procedure h-prog.OCX DATVIDEO.ctWaveCtrl.OCX TREEVIEW.MediaPlayer Mabry.Imagem DatasulSound. input 16808. • procurar rodar este procedimento no início do Main-Block.Aloca_Tarefa Communications Control CellsVwr. input "TreeView"). Nome de OCX homologados no Datasul EMS 2.OCX CTWAVE32.OCX MSCOMM32.OCX MSCOMCT2.MMControl. run IsRegistered in h-prog(input " COMCTL.OCX MCI32.OCX DATSOUND.0 OCX BARRAS_2.• nome do OCX a ser verificado. o sistema pode ficar sem recursos e travar.TreeCtrl.p (input "show".l Date and Time Picker Control DatTreeView. end.OCX COMDLG32.Sound DatasulMultimedia. City:READ-ONLY IN BROWSE {&BROWSE-NAME} = TRUE.Name:READ-ONLY IN BROWSE {&BROWSE-NAME} = TRUE Customer. Implementaç • ão • inicializar o atributo READ-ONLY de todos os campos que serão utilizados para ordenação como YES: ASSIGN Customer. • marcar o atributo column-searching do browse. .Construção de Programas utilizando os Estilos e suas Técnicas 351 Como construir um browse com ordenação por coluna Objetivo Esta técnica deve ser usada sempre que for preciso construir um browse que terá ordenação por coluna. criar um browse e definir todos os campos que serão utilizados para ordenação com a propriedade enable marcada. Name.• na trigger START-SEARCH do browse inserir o seguinte: DEFINE VARIABLE columnHandle AS HANDLE NO-UNDO. ASSIGN columnHandle = {&BROWSE-NAME}:CURRENT-COLUMN. APPLY 'END-SEARCH' TO {&BROWSE-NAME}. END CASE. . WHEN 'City' THEN OPEN QUERY {&BROWSE-NAME} FOR EACH Customer NO-LOCK BY Customer.City. CASE columnHandle:NAME: WHEN 'Name' THEN OPEN QUERY {&BROWSE-NAME} FOR EACH Customer NO-LOCK BY Customer. a linha geral de codificação é semelhante para todos os tipos. &ELSEIF. fazer a utilização dos pré-processadores necessários através das diretivas de pré-processadores: &IF. &ELSE e &ENDIF.i. seguindo as regras a seguir: • • inserir a chamada ao include de especificação dos pré-processadores de mini-flexibilização. MiniFlexi biliza ção para Tipo de Banc o de Dado s Esta técnica oferece possibilidade para o desenvolvimento de implementações específicas para determinados tipos de bancos de dados. podendo ser utilizada para atender as mais diversas situações Independentemente do tipo de mini-flexibilização. para implementar funcionalidades ou características específicas para uma versão do produto ou um tipo específico de banco de dados. conforme seu tipo. Oracle e MS SQL-Server. &THEN. A chamada ao include torna disponível uma série de pré-processadores. Para tanto se deve saber qual o tipo de mini-flexibilização desejada. . Contendo como valor a sigla do banco de dados utilizado no produto (no ambiente específico de desenvolvimento e expedição do produto corrente). Para tanto devem ser seguidas algumas regras. por exemplo. chamado include/i_dbtype.Construção de Programas utilizando os Estilos e suas Técnicas 353 Mini-Flexibilização Em muitas situações faz-se necessária a implementação de mini-flexibilização. descritas a seguir: • Inserir a chamada ao include de especificação dos pré-processadores de mini-flexibilização para tipos de banco de dados. que são: Tipo Descrição Tipo de Banco de Mini-flexibilização visando atender necessidades de Dados implementações específicas a um determinado tipo de banco de dados Versão de Banco de Mini-flexibilização visando atender necessidades de Dados implementações específicas a uma determinada versão ou release do banco de dados Especifica Mini-flexibilização visando atender necessidades de implementações específicas a um determinado módulo ou funções. para cada um dos bancos de dados dos produtos Datasul. a saber: Progress. ou seja.Os valores. ficando assim disponíveis em todo o escopo do programa. as siglas suportadas pelo include estão apresentadas a seguir: Banco de Dados Progress Oracle MS SQL-Server Sigla progress oracle mss Outro fato relacionado a inserção da chamada ao include é que esta deve ser feita uma única vez em todo o programa. E os pré-processadores disponíveis para utilização estão listados a seguir: Nome do pré-processador ems_dbtype Produto EMS 5 emsbas_dbtype emsedi_dbtype emsfin_dbtype emsuni_dbtype Produto EMS 2 mgadm_dbtype mgdis_dbtype mgind_dbtype mguni_dbtype mgcld_dbtype mginv_dbtype mgsws_dbtype mgmrp_dbtype mgven_dbtype mgcex_dbtype mgmp_dbtype mgmfg_dbtype mgsop_dbtype lcarg_dbtype movadm_dbtype movdis_dbtype movind_dbtype movmnt_dbtype . Isto se deve ao fato dos pré-processadores definidos no include terem escopo global. e mais especificamente no início do programa. &ELSE e &ENDIF. na maioria das vezes visa implementar soluções para contornar ou diminuir as deficiências e/ou limitações de bancos de dados não-Progress.i} &IF "{&ems_dbtype}":U = "progress":U &THEN GET LAST {&QueryName} NO-LOCK. &ENDIF Exemplo 2: {include/i_dbtype. A utilização dos pré-processadores. &ELSE MESSAGE "Função não disponível!" VIEW-AS ALERT-BOX. A seguir veja dois exemplos de utilização de pré-processadores de miniflexibilização para banco de dados: Exemplo 1: {include/i_dbtype.. &ELSEIF. &ENDIF IF customer.name = "Bob Song". ASSIGN customer. . &IF "{&ems_dbtype}":U <> "progress":U &THEN VALIDATE customer.i} CREATE customer. em conjunto com as diretivas de préprocessadores. Isto faz com que o uso dos pré-processadores utilize uma estrutura simples que consiste em: caso o banco de dados seja Progress é executada uma lógica senão é executada outra lógica.credit-limit > 1000 THEN .cust-num = 1000 customer. &THEN.Construção de Programas utilizando os Estilos e suas Técnicas 355 Nome do pré-processador movmfg_dbtype Produto HR dthrpyc_dbtype dthrpmg_dbtype dthrtma_dbtype • Fazer a utilização dos pré-processadores disponíveis no include através das diretivas de pré-processadores: &IF.. podendo assumir os valores. Mini- Esta técnica oferece possibilidade para o desenvolvimento de implementações Flexi específicas para determinadas versões de bancos de dados. A seguir veja um exemplo de utilização de pré-processador de miniflexibilização para banco de dados: Exemplo 1: PROCEDURE afterNewRecord: &IF "{&DBType}":U = "PROGRESS":U &THEN GET LAST {&QueryName} NO-LOCK. &ENDIF END PROCEDURE. a saber: Progress. descritas a seguir: ção • Inserir a chamada ao include de especificação dos pré-processadores para de mini-flexibilização para versão de banco de dados. ão de Banc o de Dado s . Para tanto devem ser seguidas algumas regras.MiniFlexi biliza ção para Tipo de Banc o de Dado s em DBOs Esta técnica oferece possibilidade para o desenvolvimento de implementações específicas em DBOs para determinados tipos de bancos de dados. Oracle e MS SQL-Server. as siglas suportadas para especificar o tipo de banco de dados. Sendo que os valores/siglas permitidos são: Banco de Dados Progress Oracle MS SQL-Server Sigla progress oracle mss A utilização do pré-processador.i. &ELSE e &ENDIF. Para tanto devem biliza ser seguidas algumas regras. &THEN. &ELSEIF. na maioria das vezes visa implementar soluções para contornar ou diminuir as deficiências e/ou limitações de bancos de dados não-Progress. Isto faz com que o uso do pré-processador utilize uma estrutura simples que consiste em: caso o banco de dados seja Progress é executada uma lógica senão é executada outra lógica. em conjunto com as diretivas de préprocessadores. pré-existente nos DBOs. através das diretivas de préprocessadores: &IF. ou seja. O pré-processador existente chama-se DBType. chamado Vers include/i_dbvers. descritas a seguir: • Fazer a utilização do pré-processadore disponíveis no include de serviço. e mais especificamente no início do programa.Construção de Programas utilizando os Estilos e suas Técnicas 357 A chamada ao include torna disponível uma série de pré-processadores. Contendo como valor a versão do banco de dados utilizado (no ambiente específico de desenvolvimento e expedição do produto corrente). E os pré-processadores disponíveis para utilização estão listados a seguir: Nome do pré-processador Produto EMS 5 emsbas_version emsedi_version emsfin_version emsuni_version Produto EMS 2 mgadm_version mgdis_version mgind_version mguni_version mgcld_version mginv_version mgsws_version mgmrp_version mgven_version mgcex_version mgmp_version mgmfg_version mgsop_version lcarg_version movadm_version movdis_version movind_version movmnt_version movmfg_version mgrac_version movrac_version Produto HR dthrpyc_version . Isto se deve ao fato dos pré-processadores definidos no include terem escopo global. para cada um dos bancos de dados dos produtos Datasul. ficando assim disponíveis em todo o escopo do programa. Outro fato relacionado a inserção da chamada ao include é que esta deve ser feita uma única vez em todo o programa. &ELSE ASSIGN customer. descritas a seguir: ção • Criar o include de especificação dos pré-processadores específicos.Nome do pré-processador dthrpmg_version dthrtma_version • Fazer a utilização dos pré-processadores disponíveis no include através das diretivas de pré-processadores: &IF. . &ELSEIF.credit-limit = 1500. &THEN.dec-1 = 1500. deve-se então apenas alterá-lo (ou seja. A utilização dos pré-processadores.cust-num = 1000 customer. &ELSE e &ENDIF. ASSIGN customer. A seguir veja um exemplo de utilização de pré-processadores de miniflexibilização para versão de produto: Exemplo 1: {include/i_dbvers. visa implementar características e funcionalidades disponíveis para uma versão (ou a partir de uma versão) específica do banco de dados. Então caso o include de mini-flexibilização específica já esteja criado para um determinado módulo. E assim devese ter apenas um include para cada um dos módulos dos produtos. Isto faz com que o uso dos pré-processadores utilize uma estrutura simples que consiste em: caso a versão do banco de dados seja maior ou igual a um valor específico então é executada uma lógica senão é executada outra lógica. Espe cífica O include de mini-flexibilização específica visa atender as necessidades de implementações de cada um dos módulos dos produtos Datasul.name = "Bob Song". acrescentar novos pré-processadores). Para tanto devem biliza ser seguidas algumas regras. &ENDIF Mini- Esta técnica oferece possibilidade para o desenvolvimento de implementações Flexi específicas para as mais diversas necessidades e situações.04":U &THEN ASSIGN customer.i} CREATE customer. &IF "{&mgadm_version}":U >= "2. em conjunto com as diretivas de préprocessadores. A utilização dos pré-processadores. .Construção de Programas utilizando os Estilos e suas Técnicas 359 A nomenclatura e localização dos arquivos de mini-flexibilização específica devem seguir o padrão: <diretório_do_módulo>/cfg<sigla_do_módulo>. visam as mais diversas necessidades e situações. • Fazer a utilização dos pré-processadores disponíveis no include através das diretivas de pré-processadores: &IF. • Inserir a chamada ao include de especificação dos pré-processadores de mini-flexibilização específica. &ELSE e &ENDIF e função de pré-processador DEFINED. facilitando a utilização dos mesmos. Um exemplo de include de mini-flexibilização específica pode ser visto a seguir: Exemplo 1: &IF DEFINED(include_sports) = 0 &THEN /* Verificação de * definição do * include */ &GLOBAL-DEFINE fn-calculo-lambda &ENDIF Quanto aos nomes dos pré-processadores. preocupem-se apenas em verificar a existência ou inexistência destes. podendo ser ou não definidos. Isto se deve ao fato dos pré-processadores definidos no include terem escopo global. em conjunto com as diretivas e funções de pré-processadores. Outro fato relacionado a inserção da chamada ao include é que esta deve ser feita uma única vez em todo o programa. Geralmente pode-se optar pela não definição de valor para os préprocessadores. &THEN. consistindo em: verificação de redefinição do include no escopo e definição de pré-processadores de escopo global. conforme módulo do produto associado ao programa no qual deseja-se implementar a mini-flexibilização. E em relação ao valor dos pré-processadores não há um padrão.i O modelo de estrutura do include é simples. ficando assim disponíveis em todo o escopo do programa. e mais especificamente no início do programa. Pois isto permite que os programas que fazem uso destes pré-processadores. deve-se seguir a padronização de nomenclatura definida para os produtos Datasul. &ELSEIF. credit-limit = fn-credit-limit-default(). &IF DEFINED(fn-calculo-lambda) > 0 &THEN ASSIGN customer. &ENDIF Neste tipo de mini-flexibilização pode-se optar por apenas inserir lógica somente quando o pré-processador estiver definido. consistindo em: caso o préprocessador esteja definido então é executada uma lógica senão é executada outra lógica.name = "Bob Song". sua estrutura de utilização em geral é simples. ASSIGN customer. &ENDIF Como registrar campo do tipo Fill-in para o WebEnabler Objetivo Esta técnica deve ser utilizada somente para os campos do tipo fill-in que possua uma trigger de "LEAVE"/"VALUE-CHANGED" e não tenha lupa como cursor do mouse ou um botão de zoom na sua direita.i} CREATE customer.credit-limit = 1500. Desta forma o exemplo anterior ficará da seguinte forma: Exemplo 2: {<diretório_do_modulo>/cfg<sigla_do_modulo>. A seguir veja um exemplo de utilização de pré-processadore de miniflexibilização específica: Exemplo 1: {<diretório_do_modulo>/cfg<sigla_do_modulo>.Embora o uso dos pré-processadores seja para as mais diversas necessidades.name = "Bob Song".cust-num = 1000 customer.i} CREATE customer. .credit-limit = fn-credit-limit-default(). ou possua uma trigger de "ENTRY". &ELSE ASSIGN customer. &IF DEFINED(fn-calculo-lambda) > 0 &THEN ASSIGN customer.cust-num = 1000 customer. ASSIGN customer. dat_term_contrat_trab &field6=funcionario. Caso esse limite seja excedido o programador deverá definir uma nova chamada da include passando os demais campos.i &field1=FILL-IN-1 &event1="leave" &field2=FILL-IN-2 &event2="entry" &field3=FILL-IN-4 &event3="focus-gained" &field4=FILL-IN-4 &event4="focus-lost"}.qti_dias_contrat_trab &event4="leave" &field5=funcionario. Exemplo {include/i-wenrgm.i &field1=v_num_pessoa_fisic &event1="leave" &field2=funcionario.i no Main Block.Construção de Programas utilizando os Estilos e suas Técnicas 361 Implementaç Colocar a chamada da include i-wenrgm.cdn_vinc_empregat &event6="leave"}.dat_admis_func &event2="leave" &field3=funcionario.qti_meses_trab_ant &event3="leave" &field4=funcionario. usando uma condição (cláusula WHERE) ou não. Observação: Existe um limite de 10 campos a serem utilizados em cada chamada da include. . {include/i-wenrgm. conforme ão exemplo abaixo. Como contar a quantidade de registros numa tabela Objetivo Esta técnica deve ser utilizada quando for necessário contar a quantidade de registros numa tabela. passando como parâmetro o nome do campo e o evento que deseja habilitar. descrito no item ICOUNTDS. “Pesquisa”. Implementaç ão Quando um programa janela é chamado a partir de uma transação de inclusão de registro – dentro de local-assign-record. acessado através do DataServer. Se o programa chamado estiver cadastrado com outro template. Exemplo {include/i_dbtype. “Janela Detalhe”.i &BANCO=mgadm &TABELA="cheque-pend" &COND="where cod-banco > 20" &DEST=iCount} &ENDIF Como chamar um programa que é janela a partir de uma transação Objetivo Esta técnica deve ser utilizada quando for necessário chamar um programa que é janela a partir de uma transação de inclusão / modificação de registros. Primeiro você deve verificar com que template o programa chamado está cadastrado no EMS. “Inclui/Modifica Filho”. Exemplo . você desabilitar a janela pai manualmente. uma vez que o próprio template do programa trata de desabilitar a janela pai.I do cap. 6 deste manual. Para os outros bancos use o include “include/i-count.Implementaç Primeiramente define-se a variável que receberá a quantidades de registros. não é necessário nenhum código adicional. Se o cadastro indicar um dos seguintes tipos: “Inclui/Modifica Pai”.p”. &ELSE {include/i-countds. Depois a técnica de mini-flexibilização para o tipo de banco de dados é usada ão para separar o código para banco PROGRESS do código para banco ORACLE ou SQL Server. por exemplo – é necessário que a janela pai seja desabilitada enquanto a nova não for fechada. “Formação sem Navegação” ou “Estrutura”. &IF "{&mgadm_dbtype}" = "progress" &THEN SELECT COUNT(*) INTO iCount FROM cheque-pend WHERE cod-banco > 20. Para banco PROGRESS o comando é: SELECT COUNT(*) INTO <var> FROM <tabela> WHERE <condição>.i} DEFINE VARIABLE iCount AS INTEGER NO-UNDO. i e verificar o valor da variável v_log_eai_habilit. */ END. através dos programas WEN0001 e WEN0006. . Como descobrir se o EAI está habilitado Objetivo Implementaç ão Esta técnica deve ser utilizada quando for necessário descobrir se o EAI está habilitado e configurado. Implementaç • ão definir a variável global do tipo handle que contém o endereço da API WebEnabler na memória. habilitando assim a integração. Exemplo Como enviar gráficos ou documentos office para o WebEnabler Objetivo Esta técnica permite enviar informações para o WebEnabler visando à construção de gráficos ou a abertura de documentos office nos programas que não utilizam as apis UTAPI011. Para isso deve-se incluir a include i_dbeai. ASSIGN {&WINDOW-NAME}:SENSITIVE = TRUE. pronto para download.w. UTAPI013. Nos programas que possuem integração através do EAI. a informação de que existe um novo arquivo no servidor. Para o caso da abertura de documentos office. Durante o login o valor dessa variável é alterado para YES se o EAI estiver configurado. antes da chamada dos adapters é necessário verificar se o EAI está configurado. RUN xxx/xxNNNN. Após o download o client do WebEnabler se encarregará de abrir o arquivo.i} IF v_log_eai_habilit THEN DO: /* Chamada do adapter. {include/i_dbeai. Ao receber essas informações o client WebEnabler irá gerar o gráfico utilizando o Datasul ChartViewer. o objetivo é enviar ao lado client do WebEnabler. Para o caso da construção de gráficos o objetivo é enviar ao client WebEnabler as informações para a construção do dataset que gerará o gráfico através dos mesmos programas citados acima. UTAPI012.Construção de Programas utilizando os Estilos e suas Técnicas 363 ASSIGN {&WINDOW-NAME}:SENSITIVE = NO. DEFINE SHARED VARIABLE hWenController AS HANDLE NO-UNDO. Em Definitions. mesmo que sejam enviadas diversas informações. acrescentar após &GLOBAL-DEFINE PGIMP: &GLOBAL-DEFINE RTF YES Implementaç • ão . • rodar a procedure requestRemoteAction da API WebEnabler visando passar as informações para o client deste. para o caso da criação de gráficos utilizar os valores referentes as parâmetros criados – maiores informações ver documentação DatGraph) Observação Não esquecer que a execução do segundo procedimento é única. Parâmetros: Tipo de Ação Remota – Os tipos de ação que devem ser utilizados são: chartviewer (para criação de gráficos) e opendocument (para a abertura de documentos office). RUN setRemoteActionSequence IN hWenController. Nome do Parâmetro – Nome dado ao parâmetro (para o caso de abertura de documentos office utilizar "file".<Nome do Parametro>. para o caso da criação de gráficos ver documentação DatGraph). ou seja. Como migrar relatórios antigos para RTF Objetivo Esta técnica permite gerar a saída do relatório em um arquivo RTF nos programas que foram criados antes da alteração que incluiu esta funcionalidae no template.<Valor do Parâmetro>). este comando deve ser executado uma única vez por ação. • rodar a procedure setRemoteActionSequence da API WebEnabler visando incrementar a sequência de ações remotas. antes de enviar a solicitação de abertura de arquivo ou de enviar os dados para geração do gráfico. RUN requestRemoteAction IN hWenController(<Tipo de Ação Remota>. Este procedimento deve ser executado somente uma vez para cada tipo de ação remota. Valor do Parâmetro – Valor dado ao parâmetro (para o caso de abertura de documentos office utlizar o nome do arquivo – sem o path. como no caso da criação de um gráfico. 86 BY . .63 NO-UNDO.88 BGCOLOR 15 NO-UNDO. acrescente os campos: field modelo-rtf field l-habilitaRtf as char format "x(35)" as LOG. DEFINE SHARED VARIABLE hWenController AS HANDLE NO-UNDO. • Após a definição da variável c-arquivo(“DEFINE VARIABLE c-arquivo AS CHARACTER”) inserir o seguinte código: DEFINE VARIABLE c-modelo-rtf AS CHARACTER VIEW-AS EDITOR MAX-CHARS 256 SIZE 40 BY . • Após a definição da variável text-destino(“DEFINE VARIABLE text-destino AS CHARACTER”) inserir o seguinte código: DEFINE VARIABLE text-modelo-rtf AS CHARACTER FORMAT "X(256)":U INITIAL "Modelo:" VIEW-AS TEXT SIZE 10. • Inclua após a definição da variável local c-terminal: def var c-rtf def var c-modelo-default as char as char no-undo. • Para criar os componentes utilizados pela funcionalidade de RTF é necessário abrir o programa que está sendo alterado no procedure editor e executar os passos abaixo: • Após a definição do botão bt-config-impr(“DEFINE BUTTON bt-config-impr”) inserir o seguinte código: DEFINE BUTTON bt-modelo-rtf IMAGE-UP FILE "image\im-sea":U IMAGE-INSENSITIVE FILE "image\ii-sea":U LABEL "" SIZE 4 BY 1.Construção de Programas utilizando os Estilos e suas Técnicas 365 • Na definição da temp-table tt-param. no-undo. 83 COL 3.75 COL 3.• Após a definição da variável text-modo(“DEFINE VARIABLE text-modo AS CHARACTER”) inserir o seguinte código: DEFINE VARIABLE text-rtf AS CHARACTER FORMAT "X(256)":U INITIAL "Rich Text Format(RTF)" VIEW-AS TEXT SIZE 20.71 COL 43.63 COL 3 HELP "Nome do arquivo de modelo do relatório" NO-LABEL bt-modelo-rtf AT ROW 6.29 BY 3.14 COLON-ALIGNED NO-LABEL text-modelo-rtf AT ROW 5.71 COL 43. Alterar a definição da frame f-pg-imp (“DEFINE FRAME f-pg-imp”) para: DEFINE FRAME f-pg-imp rs-destino AT ROW 1.29 HELP "Destino de Impressão do Relatório" NO-LABEL bt-config-impr AT ROW 2.63 NO-UNDO.88 COL 2. • Após a definição do retângulo rect-9 (“DEFINE RECTANGLE RECT-9”) inserir o seguinte código: DEFINE RECTANGLE rect-rtf EDGE-PIXELS 2 GRAPHIC-EDGE NO-FILL SIZE 46. DEFINE VARIABLE l-habilitaRtf AS LOGICAL INITIAL no LABEL "RTF" VIEW-AS TOGGLE-BOX SIZE 44 BY 1.86 BY .86 HELP "Modo de Execução" NO-LABEL text-destino AT ROW 1.96 COL 1.54.29 HELP "Configuração da impressora" bt-arquivo AT ROW 2.17 COL 1.63 COL 3.14 COLON-ALIGNED NO- .08 NO-UNDO.29 HELP "Nome do arquivo de destino do relatório" NO-LABEL l-habilitaRtf AT ROW 4.86 NO-LABEL text-rtf AT ROW 4.29 HELP "Escolha do nome do arquivo" c-arquivo AT ROW 2.29 c-modelo-rtf AT ROW 6.04 COL 3.63 COL 43 HELP "Escolha do nome do arquivo" rs-execucao AT ROW 8. 72 BY 10. colocando o seguinte código: DO: &IF "{&RTF}":U = "YES":U &THEN RUN pi-habilitaRtf.14 RECT-9 AT ROW 8.33 COL 2 WITH 1 DOWN NO-BOX KEEP-TAB-ORDER OVERLAY SIDE-LABELS NO-UNDERLINE THREE-D AT COL 3 ROW 3 SIZE 73.14 COLON-ALIGNED NOLABEL rect-rtf AT ROW 4. • Substituir o código da trigger de “VALUE-CHANGED” do componente rs-destino pelo código abaixo: DO: do with frame f-pg-imp: case self:screen-value: when "1" then do: assign c-arquivo:sensitive bt-arquivo:visible = no = no bt-config-impr:visible = YES &IF "{&RTF}":U = "YES":U &THEN l-habilitaRtf:sensitive = NO .13 COL 1. &endif END.33 COL 2.5. • Abrir o programa no AppBuilder e alterar a trigger de “VALUE_CHANGED” do componente l-habilitaRTF.46 COL 2 RECT-7 AT ROW 1.Construção de Programas utilizando os Estilos e suas Técnicas 367 LABEL text-modo AT ROW 8. end.l-habilitaRtf:SCREEN-VALUE IN FRAME f-pgimp = "No" l-habilitaRtf = NO &endif . end. &endif end. END. when "2" then do: assign c-arquivo:sensitive bt-arquivo:visible bt-config-impr:visible l-habilitaRtf:sensitive &endif . = NO l-habilitaRtf:SCREEN-VALUE IN FRAME f= no = no = no = YES = yes = yes = NO = YES &IF "{&RTF}":U = "YES":U &THEN &IF "{&RTF}":U = "YES":U &THEN . when "3" then do: assign c-arquivo:sensitive bt-arquivo:visible bt-config-impr:visible l-habilitaRtf:sensitive &endif . &IF "{&RTF}":U = "YES":U &THEN IF VALID-HANDLE(hWenController) THEN DO: ASSIGN l-habilitaRtf:sensitive pg-imp = "No" l-habilitaRtf = NO. l-ok = yes then assign c-modelo-rtf:screen-value in frame {&frame= replace(c-arq-conv. assign c-modelo-rtf = replace(input frame {&frame-name} c-modelo-rtf. • Na procedure pi-executar após o bloco de teste de validação do arquivo informado(“if input frame f-pg-imp rs-destino = 2 and input frame f-pgimp rs-execucao = 1 then do:”) inserir o código abaixo que é responsável por validar o modelo informado: .*" DEFAULT-EXTENSION "rtf" INITIAL-DIR "modelos" MUST-EXIST USE-FILENAME UPDATE l-ok. "/". def var l-ok as logical no-undo. &IF "{&RTF}":U = "YES":U &THEN RUN pi-habilitaRtf. "\". if name} END. • Alterar a trigger de “CHOOSE” do botão bt-modelo-rtf para o seguinte código: DO: def var c-arq-conv as char no-undo. end. "/").rtf".*" "*. "\"). &endif END.rtf" "*.Construção de Programas utilizando os Estilos e suas Técnicas 369 end case. SYSTEM-DIALOG GET-FILE c-arq-conv FILTERS "*. "*. END. apply "MOUSE-SELECT-CLICK":U to im-pg-imp in frame frelat.p (input "show":U. return error. input "").i o pré-processador: &GLOBAL-DEFINE RTF YES 2. Na definição da temp-table tt-param. ao criar o registro na tt-param. Acrescentar após include/i-prgvrs.l-habilitaRtf habilitaRtf &endif = INPUT FRAME f-pg-imp c-modelo= INPUT FRAME f-pg-imp l- • Alterações no Programa RP: 1. input 73. .modelo-rtf rtf tt-param. &endif • Na procedure pi-executar. acrescente o seguinte trecho de código no comando assign: &IF "{&RTF}":U = "YES":U &THEN tt-param.&IF "{&RTF}":U = "YES":U &THEN IF ( INPUT FRAME f-pg-imp c-modelo-rtf = "" AND INPUT FRAME f-pg-imp l-habilitaRtf = "Yes" ) OR ( SEARCH(INPUT FRAME f-pg-imp c-modelo-rtf) = ? AND input frame f-pg-imp rs-execucao = 1 AND INPUT FRAME f-pg-imp l-habilitaRtf = "Yes" ) THEN DO: run utp/ut-msgs. acrescente os campos field modelo-rtf field l-habilitaRtf as char format "x(35)" as LOG. Esta conversão de for each para send-sql-statement tem que estar perfeitamente correta antes de se passar para a próxima atividade. Deve-se observar o banco das tabelas. Para: SELECT cod_estabel. Implementaç • ão • Este comando select será passado como parâmetro para o send-sqlstatement. nome_abrev FROM ped_venda P WHERE P.cod_estabel = c-cod-estabel AND P.Construção de Programas utilizando os Estilos e suas Técnicas 371 3. montando cuidadosamente o comando de consulta. Então as tabelas que tem – (traço) no nome. . VIEW STREAM str-rp FRAME f-rodape. END. O comando select pode conter apenas tabelas de um mesmo banco. Esta é a fase mais crítica da conversão. Condicionar o VIEW das FRAMES no início do programa: IF tt-param. Deve-se prestar atenção nos nomes dos campos.nome_abrev = c-nome-abrev. pois em Oracle não permite que seja utilizado – (traço) no nome de campos e tabelas. realizando as conversões de tipos de dados entre Progress e Oracle necessárias. então ele deve ser montado numa variável CHAR. Como converter consultas For Each para SendSQL-Statement Objetivo Esta técnica deve ser utilizada apenas para revisar programas de relatório que apresentam problemas em Oracle.l-habilitaRTF <> YES THEN DO: VIEW STREAM str-rp FRAME f-cabec. Aqui podem ser gerados erros que acarretarão diferenças no resultado. Transformar a consulta de for each (ou eachs encadeados) em um ou mais de um comando select. no Oracle tem um _ (underline): FOR EACH ped-venda FIELDS(cod-estabel nome-abrev) WHERE cod-estabel = c-cod-estabel AND nome-abrev = c-nome-abrev: END. No exemplo abaixo. onde todos os valores de cada linha são concatenados. Caso seja necessário rodar uma stored-procedure já existente na base de dados. É necessário separá-los em vários campos.Certifique-se que as duas consultas retornam o mesmo resultado antes de passar para a próxima fase. chamado proc-text. • Uma vez que o comando SQL foi definido. podemos passar o nome dela no lugar de sendsql-statement. Este handle será usado posteriormente para leitura do resultado da consulta. Neste caso a PROC-HANDLE tem a função de passar parâmetros para a stored-procedure. A temp-table de retorno tem um nome padrão. No exemplo. É importante salientar que cada campo ocupa.cod_estabel = " + p2oCharacter(c-cod-estabel) + CHR(10) + "P. foram criadas algumas funções que estão disponíveis na include utp/ut-oraFunConv. Como a consulta é montada dentro do próprio programa Progress. Existem nesta include funções para campos do tipo CHAR. executamos o comando SELECT montado (contido na variável cComandoSQL neste exemplo) através do comando RUN STOREDPROCEDURE. iHandle1 = PROC- • O resultado da execução do comando SELECT é retornado pelo progress numa temp-table que tem apenas um campo CHAR. Em ambas as situações.i. Essa temp-table tem apenas um campo. Abaixo um exemplo de como ler essa temp-table e desmembrar os valores retornados. Primeiramente. na string concatenada. a função PROC-HANDLE retorna o handle (no formato Integer) que referencia aquela consulta no buffer. nome_abrev FROM ped_venda P" + CHR(10) + "WHERE" + CHR(10) + "P. conforme a consulta. utilizamos a variável chamada iHandle1: RUN STORED-PROCEDURE send-sql-statement HANDLE(oracleCommand). Para conversão dos tipos de dados entre Progress e Oracle.nome_abrev = " + p20Character(c-nome-abrev) . que é proc-text-buffer. É necessário definir uma variável INT para receber esse valor. INTEGER ou DATE. podemos notar a utilização de algumas dessas funções: ASSIGN cComandoSQL = "SELECT cod_estabel. e a conversão pode ser feita do Progress para Oracle (usando as funções que começam com p2o) ou do Oracle para o Progress (usando as funções que começam com o2p). passamos "send-sql-statement" como parâmetro do RUN STORED-PROCEDURE (este é um nome padrão para a stored-procedure a ser executada). o exato espaço de . o próximo passo é executar o comando RUN STORED-PROCEDURE no Progress. formando uma string única. Isso ficará mais fácil de entender no exemplo abaixo. 4. é necessário criar uma temp-table com os campos que foram consultados. Algumas funções recebem 2 parâmetros: o buffer e a posição a partir de onde se deseja ler. END. Para aproveitar a lógica já existente do relatório. Após este comando . a definição dessa temp-table deve seguir alguns padrões.cod-estabel => pedVenda_codEstabel.pedVenda_nomeAbrev = o2pGetString(proctext.i) que retornam conforme o tipo de dado. a string concatenada teria 40 posição.nome-abrev. outras recebem 3 parâmetros: o buffer. por exemplo. ASSIGN oracleLine. Para pegar os valores. 1.nome-abrev => pedVenda_nomeAbrev.cod-estabel FIELD pedVenda_nomeAbrev like ped-venda. ****** DEFINE TEMP-TABLE oracleLine FIELD pedVenda_codEstabel like ped-venda.Construção de Programas utilizando os Estilos e suas Técnicas 373 seu tamanho no banco. convertidos para o nome padrão na temp-table. a temp-table pode ter um nome qualquer. então numa consulta com 2 campos. existem funções (definidas na include utp/ut-oraFunConv. 3) oracleLine. os registros não estarão mais disponíveis no proc-text-buffer: . e depois uma definição da temp-table e também a leitura da proc-text-buffer: ped-venda. primeiramente vemos alguns campos. onde o primeiro tem 10 de tamanho e o segundo tem 30.pedVenda_codEstabel = o2pGetString(proc-text. entretanto o nome dos campos deve ser formado por: nomeTabela_nomeCampo. ped-venda. a posição e o tamanho a ser importado. • Por fim. Para receber os valores. FOR EACH proc-text-buffer WHERE PROC-HANDLE = iHandle1: CREATE oracleLine. 12). executa-se o comando CLOSE STORED-PROCEDURE para terminar o uso daquela consulta. Deve-se então fazer um search e replace para cada campo.nome-abrev Replace: oracleLine. deve-se agora substituir o(s) for each (ou eachs) na tabela do banco por um for each simples na(s) temp-table(s) de resultados que acabamos de popular. Programa com a técnica: DEFINE VAR oracleCommand AS CHAR NO-UNDO.order-num order. fazendo a modificação que definimos anteriormente. • Exemplo de programa convertido: Programa atual: FOR EACH order WHERE order-num >= 100 AND order-num <= 900 AND sales-rep >= c-sales-rep-ini AND sales-rep <= c-sales-rep-fim AND promise-date >= da-entrega-ini AND promise-date <= da-entrega-fim BY order-num NO-LOCK: DISPLAY STREAM str-rp order.cod-estabel Replace: oracleLine. . Afim de aproveitar as lógicas préexistentes de negócio no relatório. como no exemplo: Search: ped-venda.cust-num order. END.Sales-Rep WITH FRAME f-pedido.CLOSE STORED-PROCEDURE send-sql-statement WHERE PROC-HANDLE = handle1. Search: ped-venda.Promise-Date order. DEFINE VAR handle1 AS HANDLE NO-UNDO. • Agora os dados já foram consultados.pedVenda_codEstabel.pedVenda_nomeAbrev. {utp/ut-oraFunConv.order-num. RUN STORED-PROCEDURE send-sql-statement handle1 = PROCHANDLE(oracleCommand). END. 60). ASSIGN oracleLine. 30) oracleLine. 80. . FOR EACH proc-text-buffer WHERE PROC-HANDLE = handle1: CREATE oracleLine.order_custNum = o2pGetNumber(proc-text.Sales-Rep " + CHR(10) + "FROM order " + CHR(10) + "WHERE" + CHR(10) + " order.Promise-Date BETWEEN " + p2oDate(da-entregaini) + " AND " + p2oDate(da-entrega-fim) + ")) ". order. 1). oracleLine.order_promiseDate = o2pGetDate(proctext.promise-date FIELDS order_salesRep like order.order-num <= 900 AND" + CHR(10) + " (order.order_orderNum = o2pGetNumber(proctext.sales-rep BETWEEN UPPER(" + p2oCharacter(csales-rep-ini) + ") AND LOWER(" + p2oCharacter(c-sales-repfim) + ")) AND" + CHR(10) + " (order.Construção de Programas utilizando os Estilos e suas Técnicas 375 DEFINE TEMP-TABLE oracleLine FIELDS order_orderNum like order.order-num >= 100 AND" + CHR(10) + " order. oracleLine.order-num FIELDS order_custNum like order.Promise-Date. 8). " + CHR(10) + " order.cust-num FIELDS order_promiseDate like order.i } ASSIGN oracleCommand = "SELECT" + " order.order_salesRep = o2pGetString(proctext.cust-num. CLOSE STORED-PROCEDURE send-sql-statement WHERE PROC-HANDLE = handle1.sales-rep. order. p ao banco de dados. gerando perda de performance se comparamos processos executados utilizando banco Progress e banco Oracle. Para implementar tal processo o desenvolvedor fará uso de dois utilitários que são: • O programa ut-select.i: Include responsável pelo envio do comando SQL criado pela ut-select.order_salesRep WITH FRAME f-pedido. . ficando à cargo do DataServer a interface entre os comandos Progress e SQL. Importante: compatível com Ansi SQL.order_custNum oracleLine.FOR EACH oracleLine BY order-num: DISPLAY STREAM str-rp oracleLine. Implementaç • Definir uma variável do tipo handle. A include ut-send-sql. ão define variable utSelect as handle no-undo. • O desenvolvedor irá desmembrar o comando FOR EACH em partes.order_orderNum oracleLine. Nem sempre os comandos convertidos pelo DataServer são os mais eficazes.order_promiseDate oracleLine. END. que serão repassados ao programa ut-select. tal código deverá ser enviado à include utsend-sql.i que irá retornar ao programa executor uma temp-table contendo o resultado da consulta.p: Permite ao programador montar o comando SQL conforme a necessidade. Atualmente o acesso à bases Oracle é feito de maneira transparente ao desenvolvedor. Utilitário para Geração de Comandos SQL Objetivo Esta técnica tem por objetivo apresentar uma alternativa para efetuar consultas em bases Oracle. • Rodar o programa ut-select. Parâmetros: INPUT inAbreParenteses: número de parênteses que serão abertos para esta linha.address LIKE customer. • O programa ut-select. A temp-table deverá conter todos os campos retornados da consulta.p persistente e atribuir o seu handle para a variável que foi criada anteriormente.p disponibiliza procedures auxiliares para a criação do comando SQL.campo1 = tabela1_campo1 tabela1. INPUT inCampoBanco: Nome do campo da tabela a ser referenciado pela cláusula BETWEEN. seguindo o seguinte modelo: tabela1. tais campos deverão ser definidos na mesma temp-table. são elas: • adicionarBetween: Adiciona ao comando SQL a cláusula BETWEEN.qty LIKE customer.price LIKE order-line.cod_campo2 = tabela1_codCampo2 tabela1.Address2 LIKE customer. se a consulta compreender campos de mais de uma tabela do mesmo banco.campo3_campo = tabela1_campo3Campo DEFINE FIELD FIELD FIELD FIELD FIELD FIELD FIELD FIELD FIELD FIELD FIELD FIELD TEMP-TABLE oracleLine customer_cust-num customer_name customer_address customer_address2 customer_city customer_country customer_credit-limit order_order-num item_item-num item_price order-line_qty customer_comments NO-UNDO LIKE customer. Convencionamos que os campos da temp-table de retorno seguirão a nomenclatura dos campos da tabela.credit-limit LIKE order.name LIKE customer.city LIKE customer.cust-num LIKE customer.item-num LIKE item.p persistent set utSelect.country LIKE customer. O operador Between pode ser usado para especificar um critério de seleção. run utp/ut-select.comments.Construção de Programas utilizando os Estilos e suas Técnicas 377 • Definir uma temp-table que será utilizada para armazenar o resultado da consulta realizada no banco de dados.order-num LIKE item. . : INPUT STRING(i-qty-ini) INPUT STRING(180) INPUT inAte: Valor final do intervalo a ser pesquisado. deve-se utilizar " para a passagem do parâmetro. Ex. decimal. deve-se utilizar STRING(x). INPUT STRING(i-qty-ini). Ex. Ex.qty BETWEEN i-qty-ini AND i-qty-fim” executar o código abaixo: RUN adicionarBetween IN utSelect(INPUT 0.INPUT inDe: Valor inicial do intervalo a ser pesquisado. Exemplo: Para incluir a cláusula BETWEEN: “sports. INPUT inOperadorLogico: Define a condição lógica a ser aplicada para essa linha. deve-se utilizar STRING(x).qty" Para a passagem de variáveis ou valores. Para campos de tabela. INPUT ""). Para campos de tabela.order-line. Pode ser integer. date ou field. INPUT STRING(i-qty-fim). INPUT inFechaParenteses: número de parênteses que serão fechados nesta linha.qty" Para a passagem de variáveis ou valores.: INPUT STRING(i-qty-ini) INPUT STRING(180) INPUT inTipoDado: Tipo de dado do campo a ser referenciado.: INPUT "order-line.qty". OR ou “”. character. . Ex. deve-se utilizar " para a passagem do parâmetro. Será sempre incluído antes do operador lógico. INPUT "order-line. INPUT 0. INPUT "Integer".: INPUT "order-line. logical. pode se AND. INPUT ">". character . INPUT 0.price".: INPUT STRING(i-qty-ini) INPUT STRING(180) INPUT inTipoDado: Tipo de dado do campo a ser referenciado. INPUT "integer". INPUT STRING(18). Para campos de tabela. INPUT inOperador: Nome do operador de comparação a ser utilizado. pode ser ‘=’. Pode ser integer. INPUT inFechaParenteses: número de parênteses que serão fechados nesta linha. INPUT inValor: parâmetro destinado a informação do campo ou valor a ser comparado na cláusula Where. INPUT inOperadorLogico: Define a condição lógica a ser aplicada para essa linha. decimal. logical.price > 18” executar o código abaixo: RUN adicionarWhere IN utSelect(INPUT 0. INPUT inCampo: Nome do campo da tabela a ser referenciado pela cláusula Where. ‘>’ ou ‘<’ ou ‘<>’. deve-se utilizar " para a passagem do parâmetro. INPUT "item. Exemplo: Para incluir a cláusula Where: “AND sports. OR ou “”.qty" Para a passagem de variáveis ou valores. deve-se utilizar STRING(x). pode se AND. date ou field.: INPUT "order-line.item.Construção de Programas utilizando os Estilos e suas Técnicas 379 • adicionarWhere: Adiciona ao comando SQL uma cláusula WHERE. Ex. Ex. . Parâmetros: INPUT inAbreParenteses: número de parênteses que serão abertos para esta linha. order-num AND order-line. Utiliza as informações passadas pelas procedures ‘adicionarBetween’ e ‘adicionarWhere’ para gerar o comando SELECT retornando o mesmo para o programa executor através parâmetro ‘comando’.qty.Address2 . • gerarSelect: Gera o comando SELECT propriamente dito. customer. Customer. order-line.Credit-Limit. item.NAME. Customer. order.address.item-num. INPUT Tabelas: Informa as tabelas que serão utilizadas no comando SELECT.cust-num = order.qty BETWEEN i-qty-ini AND i-qty-fim Executar os procedimentos apresentados anteriormente para criação das cláusulas BETWEEN e Where juntamente com o código abaixo: .cust-num AND order. item.City.item-num AND item. OUTPUT Comando: Retorna ao programa executor o comando SELECT gerado.Comments FROM Customer.order-num. Parâmetros: INPUT Campos: Informa os campos que serão retornados pelo comando SELECT.price. Customer. Customer. Customer. order-line.Country.item-num = ITEM.INPUT ""). item WHERE customer.order-num = order-line. order. Exemplo: Para obtermos o comando: SELECT customer.cust-num. Formarão a cláusula FROM do comando SELECT. customer.price > 18 AND order-line. utilizando a temp-table retornada pela include. OUTPUT oracleCommand). Customer. • Ao final do processo. order.i. a temp-table que será retornada pela include e o nome do banco envolvido na consulta: Importante: A include não permite a utilização de tabelas em bancos diferentes.p.i. A primeira será utilizar a include para cada banco. " + " customer.order-num. item ".Address2. Os demais bancos seriam tratados com comandos FOR EACH. INPUT " Customer. • É necessário eliminar o buffer da tabela de consulta o qual é criado pela include ut-send-sql. gerando duas temp-tables.Credit-Limit. order.qty. item. .item-num. Customer. " + " Customer. passando o comando retornado pelo programa ut-select. • Para enviar o comando gerado pelo programa ut-select.price.p ao banco de dados utiliza-se a include ut-send-sql. " + " order-line. order-line. customer.Construção de Programas utilizando os Estilos e suas Técnicas 381 RUN gerarSelect IN utSelect (INPUT " customer.address.City. Importante Para campos CHAR deverá ser feito a seguinte verificação no código INPUT IF <campo> = ? THEN “INTEGER” ELSE “CHARACTER”. " + " Customer. A outra seria identificar o banco mais crítico e utilizar a include apenas nesse banco. O código que deverá ser acrescentado no programa que esta utilizando a técnica ut-select é: delete object send-sql-bh.Comments " . delete object utSelect. Customer.NAME. deve-se eliminar o objeto persistente.cust-num. " + " item.Country. {utp\ut-send-sql.i oracleCommand oracleLine mgmov} Observação Para tabelas em bancos diferentes pode-se optar por duas alternativas. DEFINE TEMP-TABLE tt-raw-digita NO-UNDO FIELD raw-digita AS RAW.00.025} /* prÚprocessador para ativar ou nÒo a saÝda para RTF */ &GLOBAL-DEFINE RTF YES /* prÚprocessador para setar o tamanho da pßgina */ &SCOPED-DEFINE pagesize 42 /* definiþÒo das temp-tables para recebimento de parÔmetros */ DEFINE TEMP-TABLE tt-param NO-UNDO FIELD destino FIELD arquivo FIELD usuario FIELD data-exec FIELD hora-exec FIELD classifica FIELD desc-classifica AS INTEGER AS CHARACTER FORMAT "x(35)" AS CHARACTER FORMAT "x(12)" AS DATE AS INTEGER AS INTEGER AS CHARACTER FORMAT "x(40)" FIELD modelo-rtf AS CHARACTER FORMAT "x(35)" /* arquivo modelo para RTF */ FIELD l-habilitaRtf FIELD sel-inicial FIELD sel-final AS LOG AS INTEGER AS INTEGER.i TESTE2RP 2. .• Exemplo de programa convertido: /* include de controle de versÒo */ {include/i-prgvrs. NO-UNDO.00. &IF "{&EMS_DBTYPE}" = "Oracle" &THEN DEFINE VARIABLE oracleCommand DEFINE VARIABLE utSelect AS CHARACTER AS HANDLE NO-UNDO. orderLine_qty OracleLine.orderLine_OrderNum OracleLine.discount FIELD orderLine_extendedPrice LIKE order-line.orderLine_price OracleLine.Order-num LIKE order-line. /* include padrÒo para varißveis de relat¾rio {include/i-rpvar.orderLine_extendedPrice WITH FRAME f-order-line DOWN STREAM-IO.orderLine_lineNum OracleLine.Construção de Programas utilizando os Estilos e suas Técnicas 383 DEFINE TEMP-TABLE OracleLine NO-UNDO FIELD orderLine_OrderNum FIELD orderLine_lineNum FIELD orderLine_itemNum FIELD orderLine_price FIELD orderLine_qty FIELD orderLine_discount LIKE order-line.price LIKE order-line.extendedprice.line-num LIKE order-line. DEFINE INPUT PARAMETER TABLE FOR tt-raw-digita.orderLine_discount OracleLine. */ /* definiþÒo de frames do relat¾rio */ &IF "{&EMS_DBTYPE}" = "Oracle" &THEN FORM OracleLine.orderLine_itemNum OracleLine. &endif /* recebimento de parÔmetros */ DEFINE INPUT PARAMETER raw-param AS RAW NO-UNDO. CREATE tt-param. RAW-TRANSFER raw-param TO tt-param. &ELSE IF .i} /* definiþÒo de varißveis DEFINE VARIABLE h-acomp */ AS HANDLE NO-UNDO.qty LIKE order-line.item-num LIKE order-line. orderLine_OrderNum OracleLine.i &STREAM="str-rp"} /* bloco principal do programa */ ASSIGN c-programa c-versao c-revisao c-empresa c-sistema c-titulo-relat = "SMARTRP" = "1. END.orderLine_price OracleLine.orderLine_discount OracleLine.orderLine_extendedPrice WITH FRAME f-order-line DOWN STREAM-IO.orderLine_lineNum OracleLine.i &STREAM="stream str-rp"} /* include com a definiþÒo da frame de cabeþalho e rodapÚ */ {include/i-rpcab.00" = ".FORM OracleLine.000" = "Empresa Teste" = "Sports" = "Listagem Order-Line". /* para nÒo visualizar cabeþalho/rodapÚ em saÝda RTF */ IF tt-param. .l-habilitaRTF <> YES THEN DO: VIEW STREAM str-rp FRAME f-cabec. &endif /* include padrÒo para output de relat¾rios */ {include/i-rpout.00.orderLine_qty OracleLine.orderLine_itemNum OracleLine. VIEW STREAM str-rp FRAME f-rodape. order-line. INPUT "order-line". INPUT STRING(tt-param.i Imprimindo *} RUN pi-inicializar IN h-acomp (INPUT RETURN-VALUE).qty.order-num".Construção de Programas utilizando os Estilos e suas Técnicas 385 /* executando de forma persistente o utilitßrio de acompanhamento */ RUN utp/ut-acomp.extended-price ".line-num. {utp\ut-send-sql. /* corpo do relat¾rio */ &IF "{&EMS_DBTYPE}" = "Oracle" &THEN RUN utp/ut-select.price. " + " order-line. {utp/ut-liter. RUN adicionarBetween IN utSelect(INPUT 0.sel-final). INPUT "Integer". INPUT "order-line. INPUT ""). INPUT 0. DELETE OBJECT utSelect. INPUT STRING(tt-param. FOR EACH OracleLine WHERE . " + " order-line.item-num. order-line.Order-num.p PERSISTENT SET h-acomp.sel-inicial).p PERSISTENT SET utSelect.discount. RUN gerarSelect IN utSelect (INPUT "order-line. " + " order-line." + " order-line.i oracleCommand OracleLine Sports} DELETE OBJECT send-sql-bh. OUTPUT oracleCommand). sel-final NO-LOCK ON STOP UNDO.orderLine_extendedPrice WITH FRAME f-orderline.orderLine_price OracleLine. DISPLAY STREAM str-rp OracleLine.orderLine_lineNum OracleLine.orderLine_OrderNum OracleLine.orderLine_orderNum <= tt-param.orderLine_extendedPrice WITH FRAME forder-line.orderLine_orderNum >= tt-param.sel-inicial AND OracleLine.orderLine_OrderNum)).orderLine_orderNum <= tt-param. END. .orderLine_qty OracleLine.orderLine_OrderNum OracleLine.orderLine_discount OracleLine.orderLine_discount OracleLine. DISPLAY STREAM str-rp OracleLine. LEAVE: RUN pi-acompanhar IN h-acomp (INPUT STRING(OracleLine.orderLine_itemNum OracleLine.orderLine_price OracleLine.orderLine_orderNum)).sel-final NO-LOCK ON STOP UNDO.orderLine_lineNum OracleLine.orderLine_itemNum OracleLine. DOWN STREAM str-rp WITH FRAME f-order-line. &Else IF FOR EACH OracleLine WHERE OracleLine.orderLine_orderNum >= tt-param.OracleLine.sel-inicial AND OracleLine. LEAVE: RUN pi-acompanhar IN h-acomp (INPUT STRING(OracleLine.orderLine_qty OracleLine. &endif /*END.*/ /*fechamento do output do relat¾rio*/ {include/i-rpclo. Desfazer a query da frame. Na efetivação desta ação aparecerá a questão abaixo que deve ser respondida com “Sim”: • . Conversão de Query em Frame para SmartQuery Objetivo O objetivo desta técnica é converter os programas que possuem queries definidas na frame do programa para que utilizem SmartQueries. criar uma nova utilizando o estilo CustomQuery Wizard. END.Construção de Programas utilizando os Estilos e suas Técnicas 387 DOWN STREAM str-rp WITH FRAME f-order-line. Caso contrário estes programas não poderão ser beneficiados com as melhorias realizadas no template de SmartQuery que melhoraram as performance dos programas em ambiente ORACLE. RETURN "OK":U.i &STREAM="stream str-rp"} RUN pi-finalizar IN h-acomp. Caso não exista. Caso seja necessário converter algum programa de outro estilo consulte a equipe de Suporte ao Desenvolvimento. As tarefas para conversão de um programa Inclui/Modifica Filho são: • Verificar se já existe uma SmartQuery para a consulta existente na query da Frame do Programa. Esta técnica prevê tarefas para conversão de um programa estilo Inclui/Modifica Filho. Não se pode converter programas do template de Relatório porque não é possível instanciar uma SmartQuery neste tipo de programa uma vez que eles não possuem uma SmartWindow como container. • • Remover o SmartLink do tipo RECORD que tem como source THISPROCEDURE e target a viewer do programa. devem ser comentados e/ou retirados. Instanciar a Smart Query e aceitar a sugestão de SmartLink do tipo RECORD do Wizard. Caso existe outros comandos que façam procedimento semelhante. Este comando deve ser o único existente na procedure para fazer posicionamento na query. Como por exemplo o trecho de código abaixo: . que tem coom source a Query e target a Viewer do Programa: • Editar a procedure pi-reposiciona substituir a ocorrência "<queryname>" na linha de comando abaixo pelo nome da SmartQuery instanciada: IN h_<query-name> (input v-row- RUN pi-reposiciona-query table). Construção de Programas utilizando os Estilos e suas Técnicas 389 find {&first-table-in-query-{&frame-name}} where rowid({&first-table-in-query-{&frame-name}}) = v-row-table no-lock no-wait no-error. . if available ({&first-table-in-query-{&frame-name}}) then run notify In this-procedure ("row-available":U). r) ou então deve-se inserir a senha de acesso num . buffers e tabelas). quando uma base de dados possui configurada a segurança de banco. Já objetos dinâmicos são aqueles que são criados em tempo de execução.r já criado. No Progress existem dois tipos de objetos: os estáticos e os dinâmicos. ou seja. os mesmos devem. Na Datasul. cadastramos nossos usuários e grupos de usuários e definimos módulos. igualmente. através do aplicativo Rcodekey. Este aplicativo insere nos programas compilados as informações que seriam . ou ser compilados contra o banco que possui segurança (na compilação o Progress já inclui as senhas de acesso no . botões) ou de acesso a campos (queries. Na segunda situação. para que os programas tenham acesso aos dados. programas que podem ser acessados. atualmente. definimos que a segurança seria feita no sistema. ou mesmo são obrigados a utilizar esta segurança para não terem problemas com auditorias ou. a fim de evitar que seus dados fiquem expostos ou corram o risco de serem alterados sem autorização.CAPÍTULO 16 Dicas de Desenvolvimento Segurança de Banco x Objetos Dinâmicos Objetivo Detalhament o Indicar os motivos pelos quais não deve-se utilizar objetos dinâmicos nos programas Datasul. Os objetos dinâmicos podem ser de tela (campos. muitos de nossos clientes optam por utilizar a segurança de banco. Objetos estáticos são aqueles que já estão resolvidos em tempo de desenvolvimento e o executável do programa já possui a informação de sua existência. A segurança de um produto pode ser feita de duas maneiras: no banco ou no sistema. Porém. Uma vez que o objeto só é criado em tempo de execução.Construção de Programas utilizando os Estilos e suas Técnicas 391 inseridas no . por exemplo. os comandos de disable triggers também causam o mesmo problema com os clientes que utilizam segurança em banco de dados. Sendo assim. o Progress atualmente não tem como incluir os dados de segurança no . desaconselha-se a utilização de objetos dinâmicos de acesso a dados. deve-se evitar utilizar comandos de disable triggers em programas normais do produto. como query ou buffer. Deve-se sempre esgotar a busca por uma alternativa a utilização destes recursos. A figura abaixo representa o erro que ocorre nestas situações: . para evitar problemas nos clientes que utilizam segurança no banco de dados.r. Além dos objetos dinâmicos. Apenas em casos especiais de programas que serão executados uma única vez. A utilização de objetos dinâmicos nos programas Datasul causa um problema em clientes que utilizam segurança em banco de dados. por essa razão. pois neste momento ele desconhece qual objeto a query ou buffer dinâmico representam.r caso fosse feita à compilação contra o banco que possui segurança.