Você está na página 1de 424

Manual de Padrões

Programação
EMS 2.0
Março/2011
Copyright © 2009 TOTVS 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 TOTVS S.A., que reserva-se o
direito de efetuar alterações sem aviso prévio. A TOTVS S.A não assume
nenhuma responsabilidade pelas conseqüências de quaisquer erros ou
inexatidões que possam aparecer neste documento.
TOTVS 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......................................................7
Datasul-EMS 2.0...........................................................................................7
Datasul-HR 1.0...........................................................................................12
CAPÍTULO 3 Nomenclatura....................................................................15
Padrões para Localização............................................................................15
Nomenclatura para bancos de dados de Localização...................................16
Nomenclatura padrão para programas DPC de Triggers de Localização.....17
Nomenclatura para Tabelas de Localização................................................18
Nomenclatura para Setup de Localização (XML).......................................19
Sigla de bancos de dados............................................................................20
Banco de Dados do Datasul-HR 1.00......................................................21
Siglas de módulos do produto.....................................................................21
Módulos do Datasul-EMS 2.00...............................................................21
Módulos do Datasul-HR 1.00.................................................................22
Tipos de Atributos.......................................................................................22
Dump-name de tabelas................................................................................23
Gatilhos do dicionário de dados..................................................................24
Programas...................................................................................................24
Includes.......................................................................................................26
Include com view-as de campos para o dicionário de dados...................26
Includes de programas............................................................................26
ii

Includes padrões.....................................................................................26
Widgets.......................................................................................................27
Variáveis.....................................................................................................27
Datasul-EMS 2.00...................................................................................27
Datasul-HR 1.00.....................................................................................27
Outros componentes da linguagem Progress...............................................28
Siglas de países...........................................................................................28
Nomenclatura para Caixas de diálogos em programas de Zoom e
SmartBrowser.............................................................................................29
Adapters......................................................................................................29
CAPÍTULO 4 Layout de Telas.................................................................31
Tipos de Telas (janelas)...............................................................................31
Janela Mestre..........................................................................................31
Janela Detalhe.........................................................................................31
Caixas de Diálogo...................................................................................31
Objetos........................................................................................................32
Combo-boxes..........................................................................................32
Retângulos..............................................................................................32
Botões.....................................................................................................32
Fill-in´s...................................................................................................32
Frames(Telas).........................................................................................32
Radio-Sets...............................................................................................33
Editores...................................................................................................33
Considerações sobre os SmartObjects.........................................................34
SmartBrowser.........................................................................................34
SmartViewer...........................................................................................34
SmartQuery.............................................................................................34
Considerações sobre as Imagens.................................................................34
WebEnabler.............................................................................................34
CAPÍTULO 5 Estilos................................................................................35
Cadastro Simples........................................................................................35
Cadastro Complexo.....................................................................................37
Quando utilizar o Cadastro Complexo....................................................37
Cadastro Simples - Atualiza........................................................................38
Cadastro Complexo - Atualiza....................................................................39
Pai x Filhos - Atualiza Filho.......................................................................40
Quando utilizar Pai x Filhos - Atualiza Filho..........................................40
Manutenção de Filhos.................................................................................41
Índice iii

Pai x Filhos - Atualiza Ambos.....................................................................42


Manutenção de Pais....................................................................................43
Consulta Cadastral Simples........................................................................44
Consulta Cadastral Complexa.....................................................................45
Consulta Relacionamento...........................................................................46
Relatórios, Cálculos, Fechamentos.............................................................47
Parâmetros Únicos......................................................................................51
Parâmetros Múltiplos..................................................................................51
Formação....................................................................................................52
Formação sem Navegação..........................................................................53
Importação..................................................................................................54
Exportação..................................................................................................56
Zoom de Tabelas.........................................................................................59
Vá Para.......................................................................................................60
Digitação Rápida........................................................................................61
Painéis.........................................................................................................61
Funções.......................................................................................................62
Relatórios Relacionados..........................................................................62
Consultas Relacionadas..........................................................................62
CAPÍTULO 6 Includes e Utilitários Padrão...........................................63
UT-FIELD.I................................................................................................63
UT-RTLBL.I...............................................................................................64
UT-RUN.I...................................................................................................64
UT-MSGS.P................................................................................................68
IND01-10.I, IND11-50.I E IND51500.I......................................................70
UT-TABLE.I...............................................................................................71
UT-LITER.I................................................................................................72
UT-LIMIT.P................................................................................................73
UT-GLOB.I.................................................................................................73
I-FREEAC.I................................................................................................74
UT-DIR.P....................................................................................................74
BTB917ZX.P..............................................................................................75
BTB917ZY.P..............................................................................................76
BTB917ZZ.P..............................................................................................77
UT-VRBIN.P..............................................................................................78
UT-FINFO.P...............................................................................................79
UT-CMDLN.P............................................................................................80
UT-OSVER.P..............................................................................................80
I-COUNTDS.I............................................................................................81
UT-WIN.I....................................................................................................81
UT-TRACE.P..............................................................................................84
UT-LOCK.I.................................................................................................85
UT-ZIP.P.....................................................................................................87
UT-GENXML.P..........................................................................................89
UT-VALIDA-FACELIFT.P.........................................................................89
UT-VERIF-RAW.P.....................................................................................90
BTB962ZZ.P..............................................................................................91
CAPÍTULO 7
Tradução........................................................................................................ 92
TRADUÇÃO MONO-IDIOMAS...............................................................92
Tradução de variáveis com view-as nas telas..............................................92
Espaço Extra para tradução em relatórios...................................................97
TRADUÇÃO MULTI-IDIOMAS...............................................................98
Nomenclatura Padrão e Características do modelo.....................................98
Pontos de tradução....................................................................................100
Contextos de tradução...............................................................................100
Itens de Tradução......................................................................................101
Sequência de busca...................................................................................103
UT-TRCAMPOS.P...................................................................................104
UT-TRFRRP.P..........................................................................................104
UT-LSTIT.P..............................................................................................105
UT-LITER.P.............................................................................................106
UT-MSGS.P..............................................................................................107
UT-FIELD.P.............................................................................................108
UT-TABLE.P............................................................................................109
UT-LTMNU.P...........................................................................................109
OBJETOS PROGRESS NÃO-INDEXADOS...........................................111
Tradução de variáveis com view-as nas telas............................................111
Espaço Extra para tradução em relatórios.................................................115
PRÁTICAS PARA IMPLEMENTAÇÃO MULTI-IDIOMAS..................116
Caso Prático Diferenças LIST-ITEMS para LIST-ITEM-PAIRS..............116
Caso conversão de List-items para LIST-ITEM-PAIRS............................119
Tradução automática em frame de relatório..............................................120
Traduzir valor armazenado em uma variável............................................121
Tratando lista enorme de tradução em includes.........................................122
Índice v

CAPÍTULO 8
Construção de Programas utilizando os Estilos e suas Técnicas.........127
Como construir um Cadastro Simples.......................................................127
Como construir um Cadastro Complexo...................................................129
Como construir um Cadastro Pai X Filho - Atualiza Filho........................133
Como construir um Cadastro Inclui/Modifica Filho.................................137
Como construir um Cadastro Pai X Filho - Atualiza Ambos.....................143
Como construir um Cadastro Inclui/Modifica Filho.................................147
Como construir um Cadastro Inclui/Modifica Pai.....................................151
Como construir um CustomBrowser Inclui/Modifica...............................154
Como construir um CustomBrowser Zoom Wizard..................................156
Como construir uma Consulta Simples.....................................................160
Como construir uma Consulta Complexa..................................................162
Como construir uma Consulta Relacionamentos.......................................166
Como construir um programa de Relatórios.............................................169
Preparação do Relatório - Interface.......................................................170
Página de Impressão.............................................................................172
Relatórios no formato RTF...................................................................173
Preparando documento Word (.DOC) para RTF...................................174
Dicas para criação do Programa RP.P de Relatório...............................175
Preparando o Relatório para Execução no Módulo JOB EXECUTION....181
Como construir um programa de Parâmetros Únicos................................188
Como construir um programa de Formação..............................................189
Como construir um programa de Formação sem Navegação....................193
Seqüência..............................................................................................194
Como construir um programa de Importação............................................196
Dicas Gerais..........................................................................................196
Preparação do programa.......................................................................197
Dicas para criação do Programa RP.P de Importação............................199
Como construir um programa de Exportação............................................202
Dicas Gerais..........................................................................................202
Preparação do programa.......................................................................202
Dicas para criação do Programa RP.P de Exportação............................205
Como construir um programa de Pesquisa................................................208
Como construir um programa "Vá Para"...................................................210
Como construir um programa de Digitação Rápida..................................211
Como construir um Browse de Digitação..............................................211
Como construir uma Query.......................................................................212
Como construir viewers............................................................................213
Como definir viewer Padrão.................................................................213
Como definir viewer sem campos de tabela:.........................................216
Como definir viewers só com campos chave:.......................................221
CAPÍTULO 9 Validações.......................................................................227
Validações de Tela.....................................................................................227
Validações na Navegação de Registro...................................................227
Validações Antes da Alteração..............................................................227
Validações em Entrada de Dados..........................................................228
Validações em Cadastro Simples..........................................................228
Validações em Cadastro Complexo.......................................................228
Validações para Window Relatório.......................................................229
Validações em Triggers de Dicionário de Dados.......................................229
CAPÍTULO 10 Mensagens......................................................................231
Regras para a criação de novas mensagens...........................................233
Padrões para tradução de mensagens para Inglês e Espanhol................236
CAPÍTULO 11 Programas Reutilizáveis................................................237
Procedures Internas...................................................................................237
CAPÍTULO 12 Ferramentas....................................................................239
Application Compiler................................................................................239
Selecionar arquivos a serem compilados...............................................240
Eliminar e Modificar a lista de arquivos a serem compilados...............241
Opções de Compilação.........................................................................241
Iniciar Compilação................................................................................242
Roundtable................................................................................................243
CAPÍTULO 13 API´s................................................................................247
O que são API´s e como construí-las.........................................................247
Código da API.......................................................................................251
Como documentar API´s...........................................................................252
Como implementar evoluções de API´s....................................................253
UTAPI002.P..............................................................................................263
UTAPI003.P..............................................................................................263
UTAPI004.P..............................................................................................263
UTAPI005.P..............................................................................................264
UTAPI006.P..............................................................................................266
UTAPI007.P..............................................................................................267
UTAPI008.P..............................................................................................267
UTAPI009.P..............................................................................................268
Índice vii

UTAPI010.P..............................................................................................268
UTAPI012.P..............................................................................................268
UTAPI013.P..............................................................................................269
UTAPI018.P..............................................................................................269
UTAPI019.P..............................................................................................269
UTAPI027.P..............................................................................................270
UTAPI028.P..............................................................................................270
UTAPI029.P..............................................................................................270
APAPI009.P..............................................................................................271
Parâmetros de Entrada..........................................................................271
Parâmetros de Saída..............................................................................272
Execução...............................................................................................272
CAPÍTULO 14 Portabilidade de RCODES.............................................274
Regras para Portabilidade de RCODE......................................................274
Caso em Especial......................................................................................275
CAPÍTULO 15 Técnicas..........................................................................277
Como alterar o caracter de senha..............................................................277
Como alterar o diretório corrente..............................................................277
Como alterar ou criar uma variável de ambiente.......................................278
Como dar foco a qualquer objeto..............................................................279
Como deixar uma janela sempre visível....................................................280
Como utilizar OCX...................................................................................280
Como executar um aplicativo do Windows...............................................303
Como implementar Correção Ortográfica em Editores.............................304
Como obter as coordenadas do mouse......................................................306
Como obter o diretório corrente................................................................307
Como obter o diretório de sistema do Windows........................................307
Como obter o diretório do Windows.........................................................308
Como obter o nome do computador..........................................................309
Como obter o valor de uma variável de ambiente.....................................309
Como transformar uma janela em barra de ferramentas............................310
Como desabilitar Radio-Buttons...............................................................311
Como executar programas que são janelas................................................312
Como habilitar ou desabilitar botões em painéis.......................................313
Como habilitar ou desabilitar botões específicos em Browse Inclui/Modifica
..................................................................................................................315
Como implementar campos indicadores com view-as combo-box nas telas
..................................................................................................................316
Como implementar campos indicadores com view-as radio-set nas telas. 317
Como implementar campos indicadores num SmartBrowser....................319
Como implementar labels em retângulos utilizando o dicionário de dados
..................................................................................................................321
Como implementar mensagens para o usuário..........................................322
Mensagem de Erro/Advertência/Informação sem Parâmetros...............322
Mensagem de Erro/Advertência/Informação com Parâmetros..............322
Mensagens com Questionamento ao Usuário........................................323
Como implementar Tooltip em um determinado botão.............................324
Como implementar uma barra de progresso..............................................325
Como implementar acompanhamento (UT-ACOMP)...............................327
Como implementar Zoom e campos de referência para campos chave
estrangeira.................................................................................................329
Como implementar ThinZoom e campos de referência para campos chave
estrangeira em SmartObjects.....................................................................333
Como imprimir campos editores nos relatórios.........................................337
Como totalizar colunas de um browse......................................................338
Como adaptar a procedure pi-retorna-valor no Custom Browser Zoom
Wizard.......................................................................................................339
Situações necessárias............................................................................339
Como implementar Parâmetros de Impressão em Relatórios....................341
Impressão Página de Parâmetros:..........................................................341
Formato de Impressão (80 colunas ou 132 colunas):............................343
Como implementar Botão de Filtro em Zoom...........................................345
Como implementar reposicionamento de registro com base nas variáveis
globais.......................................................................................................345
Definição da Variável Global................................................................345
Reposicionamento Automático do Browser de Zoom...............................347
Como validar campos em viewers diferentes............................................348
Como construir gatilhos de dicionários de dados......................................350
Como implementar localizações...............................................................352
Padronização dos parâmetros do progress.ini............................................355
Como setar os modos de inclusão (Simple/Multiple)................................356
Como utilizar "functions" no UIB.............................................................356
Como verificar o registro de um OCX......................................................358
Como construir um browse com ordenação por coluna............................360
Mini-Flexibilização...................................................................................362
Como registrar campo do tipo Fill-in para o WebEnabler.........................370
Como contar a quantidade de registros numa tabela.................................371
Como chamar um programa que é janela a partir de uma transação..........372
Índice ix

Como descobrir se o EAI está habilitado..................................................372


Como enviar gráficos ou documentos office para o WebEnabler..............373
Como migrar relatórios antigos para RTF.................................................374
Como converter consultas For Each para Send-SQL-Statement...............380
Utilitário para Geração de Comandos SQL...............................................386
Conversão de Query em Frame para SmartQuery.....................................399
Utilizando ZOOM na página de digitação.................................................401
Aplicar facelift em programas fora do padrão...........................................402
Como implementar segurança em programas específicos.........................404
Como Ignorar Códigos no WBD...............................................................404
Como Salvar chaves em Oracle e evitar o erro de UNIQUE-CONSTRAINT
..................................................................................................................405
Como ignorar o FaceLift em um programa...............................................405
Como desenvolver para o Datasul 10 e versões superiores.......................406
Como utilizar bancos históricos no Datasul 11 e versões superiores.........408
Como utilizar Histórico de Alterações do Audit Trail...............................410
CAPÍTULO 16 Dicas de Desenvolvimento............................................413
Segurança de Banco x Objetos Dinâmicos................................................413
Definição

CAPÍTULO 1

Revisão do Dicionário de Dados

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.00, 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)";
 criar os campos necessários para limpar os campos do tipo char-1, dec-1,
int-1, etc...;
 criar tabelas necessárias que hoje estão "camufladas" em arquivos
temporários e/ou em tabelas não utilizadas;
 para todos os campos que são indicadores, sejam de tipo de dado caracter
ou lógico, trocar por campo indicador correspondente com tipo de dado
inteiro. Exemplo:
DE PARA
Emitente.identific Emitente.identific
"C"liente 1
"F"ornecedor 2
"A"mbos 3

 implementar o view-as nos campos possíveis. Exemplo: editor, radio-set, e


toggle-box;
 substituir os campos do tipo "texto livre" por campos do tipo caracter
formato "x(15000)" view-as editor;
2

 revisar os labels e column-labels dos campos para internacionalização,


reservando espaço extra para tradução;
 as palavras que compõem os labels e column-labels, quando não
abreviadas, devem ser acentuadas;
 os labels não podem conter preposições (de, da, em ...) e pontuação (.;-);
 a primeira letra de cada palavra, que compõe o label ou col-label, deve ser
maiúscula, as demais minúsculas;
 evitar column-labels com duas ou mais linhas;
 sugestão: Incorporar no Field-Validation as validações que estão no
formato de include. Exemplo: {inc/conta.fv};
 Dump-Name das tabelas tem a nomenclatura: xx999, onde 'xx' é a sigla do
banco conforme tabela abaixo, e 999 é o número seqüencial da tabela.
SIGLA BANCO
AD Administrativo
BH Bancos Históricos
CL Coletor de Dados
DI Distribuição
ED EDI
IN Industrial
IV Investimentos
MP MultiPlanta
PE Ponto Eletrônico
RH Recursos Humanos
UN 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);
 campo "Condado(Bairro)" deve ter formato x(30);
 campo "Endereço2" deve ter formato de x(40);
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 3

 campo "Número do Documento (do AP/CR)" para MAGNUS deve ter


como nomenclatura x(16);
 campo "Série do Documento" deve ter formato x(05);
 os campos de "Conta + sub-conta" devem ter formato x(8) + x(8);
 os campos de "Códigos de Contribuição Fiscal (CGC, Inscrição Estadual,
etc ...)" devem ter como nomenclatura x(18);
 campo "Código do Item" deve ter formato x(16);
 separar tudo que for especificados no Brasil em folder separados.
Exemplo: Cadastro de Cliente-Código Febraban, Cacex ...;
 na confecção de Relatórios evitar posicionamento de campos;
 os indicadores comuns a várias tabelas, 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, deve ser sempre
assumido a empresa do corrente usuário, que é definida no menu, e está
disponível na variável global i-ep-código-usuário;
 em todas as tabelas, que representem pessoas físicas ou jurídicas,
implementar o campo para endereço eletrônico da entidade: e-mail
formato 'x(40)' label "Internet E-Mail".

Gatilhos do Dicionário de Dados


No Dicionário de Dados, os seguintes itens deverão ser obedecidos:
1. Todas as tabelas deverão possuir os gatilhos de dicionário de dados
CREATE, DELETE e WRITE mesmo que não possuam código algum
para validação.
2. As triggers de WRITE e DELETE deverão conter a chamada as includes
para EPC´s em Gatilhos de Dicionário de Dados.
3. Ao especificar caminhos, deverá ser referenciado apenas o caminho
relativo, ou seja, a partir do diretório de instalação do produto. O caracter
"\" (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 Tipo de Dado
Livre
char-1 Caracter
char-2
data-1 Data
data-2
dec-1 Decimal
dec-2
int-1 Inteiro
int-2
log-1 Lógico
log-2
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);
 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;
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 5

 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 DWB-
DDD;
 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 FIELD-
VALIDATION.
Definição

CAPÍTULO 2

Estrutura de Diretórios

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órios Conteúdo
\ADBRW Objetos Browsers do banco Administrativo
\ADGO Objetos "Vá para" do banco Administrativo
\ADINC Includes de campos indicadores do banco
Administrativo
\ADQRY Objetos Queries do banco Administrativo
\ADVWR Objetos Viewers do banco Administrativo
\ADZOOM\ Zooms do banco Administrativo
\AEP Programas do módulo Aplicações e Empréstimos
\APP Programas do módulo Contas a Pagar
\BCP Programas do módulo Coleta de Dados
\BHP Programas do módulo Bancos Históricos
\BSP Programas do módulo Benefícios Sociais
\BTB Programas do módulo Básico
\CBP Programas do módulo Caixa e Bancos
\CCP Programas do módulo Compras
\CDP Programas do módulo Cadastro
\CEP Programas do módulo Controle de Estoque
\CFP Programas do módulo Configurador Produto
8

\CLBRW Objetos Browsers do banco Coletor de Dados


\CLGO Objetos "Vá para" do banco Coletor de Dados
\CLINC Includes de campos indicadores do banco Coletor de
Dados
\CLQRY Objetos Queries do banco Coletor de Dados
\CLVWR Objetos Viewers do banco Coletor de Dados
\CLZOOM Zooms do banco Coletor de Dados
\CPP Programas do módulo Controle da Produção
\CQP Programas do módulo Controle de Qualidade
\CRP Programas do módulo Contas a Receber
\CSP Programas do módulo Custos
\DATABASE \DMAD Programas de Dump do banco MGADM
\DMCL Programas de Dump do banco MGLCD
\DMDI Programas de Dump do banco MGDIS
\DMIN Programas de Dump do banco MGIND
\DMIV Programas de Dump do banco MGINV
\DMMP Programas de Dump do banco MGMP
\DMPE Programas de Dump do banco MGPE
\DMRH Programas de Dump do banco MGRH
\DMUN Programas de Dump do banco MGUNI
\LDAD Programas de Dump do banco MGADM
\LDCL Programas de Dump do banco MGCLD
\LDDI Programas de Dump do banco MGDIS
\LDIN Programas de Dump do banco MGIND
\LDIV Programas de Dump do banco MGINV
\LDMP Programas de Dump do banco MGMP
\LDPE Programas de Dump do banco MGPE
\LDRH Programas de Dump do banco MGRH
\LDUN Programas de Dump do banco MGUNI
\TGAD \TAP Gatilhos de assign do banco MGADM
\TCP Gatilhos de create do banco MGADM
\TDP Gatilhos de delete do banco MGADM
\TFP Gatilhos de find do banco MGADM
\TWP Gatilhos de write do banco MGADM
\TGCL \TAP Gatilhos de assign do banco MGCLD
\TCP Gatilhos de create do banco MGCLD
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 9

\TDP Gatilhos de delete do banco MGCLD


\TFP Gatilhos de find do banco MGCLD
\TWP Gatilhos de write do banco MGCLD
\TGDI \TAP Gatilhos de assign do banco MGDIS
\TCP Gatilhos de create do banco MGDIS
\TDP Gatilhos de delete do banco MGDIS
\TFP Gatilhos de find do banco MGDIS
\TWP Gatilhos de write do banco MGDIS
\TGIN \TAP Gatilhos de assign do banco MGIND
\TCP Gatilhos de create do banco MGIND
\TDP Gatilhos de delete do banco MGIND
\TFP Gatilhos de find do banco MGIND
\TWP Gatilhos de write do banco MGIND
\TGIV \TAP Gatilhos de assign do banco MGINV
\TCP Gatilhos de create do banco MGINV
\TDP Gatilhos de delete do banco MGINV
\TFP Gatilhos de find do banco MGINV
\TWP Gatilhos de write do banco MGINV
\TGPE \TAP Gatilhos de assign do banco MGPE
\TCP Gatilhos de create do banco MGPE
\TDP Gatilhos de delete do banco MGPE
\TFP Gatilhos de find do banco MGPE
\TWP Gatilhos de write do banco MGPE
\TGRH \TAP Gatilhos de assign do banco MGRH
\TCP Gatilhos de create do banco MGRH
\TDP Gatilhos de delete do banco MGRH
\TFP Gatilhos de find do banco MGRH
\TWP Gatilhos de write do banco MGRH
\TGUN \TAP Gatilhos de assign do banco MGUNI
\TCP Gatilhos de create do banco MGUNI
\TDP Gatilhos de delete do banco MGUNI
\TFP Gatilhos de find do banco MGUNI
\TWP Gatilhos de write do banco MGUNI
\DIBRW Objetos Browsers do banco Distribuição
\DIGO Objetos "Vá para" do banco Distribuição
\DIINC Includes de campos indicadores do banco Distribuição
\DIQRY Objetos Queries do banco Distribuição
\DIVWR Objetos Viewers do banco Distribuição
\DIZOOM Zooms do banco Distribuição
\DOC Módulo Documentação
\DOCAPI Documentação de API´s
\DOCHLP Documentação dos módulos em formato.hlp
\DOCRTF Documentação dos Manuais impressos (*.rtf)
\DPP Programas do módulo de Desenvolvimento Produto
\ENP Programas do módulo de Engenharia
\FCP Programas do módulo de FASB/CMI
\FPP Programas do módulo Folha de Pagamentos
\FRP Programas do módulo Férias Rescisões
\FTP Programas do módulo Faturamento
\GEP Programas do módulo Gerencial
\GRP Programas do módulo Gerador Relatórios
\IMAGE Imagens
\IMGDIS Diretório padrão de imagens do Aplicativo
Distribuição
\IMGFIN Diretório padrão de imagens do Aplicativo Financeiro
\IMGHUR Diretório padrão de imagens do Aplicativo Recursos
Humanos
\IMGMAN Diretório padrão de imagens do Aplicativo
Manufatura
\IMGMAT Diretório padrão de imagens do Aplicativo Materiais
\IMGTEC Diretório padrão de imagens do Aplicativo Tecnologia
\INBRW Objetos Browsers do banco Industrial
\INCLUDE Includes Padrões
\INGO Objetos "Vá para" do banco Industrial
\ININC Includes de campos indicadores do banco Industrial
\INP Programas do módulo Investimentos
\INQRY Objetos Queries do banco Industrial
\INTERFAC Arquivos de interfaces Produto com outros softwares
\INVWR Objetos Viewers do banco Industrial
\INZOOM Zooms do banco Industrial
\IVBRW Objetos Browsers do banco Investimentos
\IVGO Objetos "Vá para" do banco Investimentos
\IVINC Includes de campos indicadores do banco
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 11

Investimentos
\IVQRY Objetos Queries do banco Investimentos
\IVVWR Objetos Viewers do banco Investimentos
\IVZOOM Zooms do banco Investimentos
\LAYOUT Layout´s de Importação
\MASTERS Masters do SmartObjects
\MEN Módulo Menu
\MIP Programas do módulo Manutenção Industrial
\MPBRW Objetos Browsers do banco MultiPlanta
\MPGO Objetos "Vá para" do banco MultiPlanta
\MPINC Includes de campos indicadores do banco MultiPlanta
\MPP Programas do módulo MultiPlanta
\MPQRY Objetos Queries do banco MultiPlanta
\MPVWR Objetos Viewers do banco MultiPlanta
\MPZOOM Zooms do banco MultiPlanta
\OFP Programas do módulo Obrigações Fiscais
\PANEL Painéis dos SmartObjects
\PCP Programas do módulo Planejamento Capacidade
\PDP Programas do módulo de Pedidos
\PEBRW Objetos Browsers do banco Ponto Eletrônico
\PEGO Objeto "Vá para" do banco Ponto Eletrônico
\PEINC Includes de campos indicadores do banco Ponto
Eletrônico
\PEP Programas do módulo Ponto Eletrônico
\PEQRY Objetos Queries do banco Ponto Eletrônico
\PEVWR Objetos Viewers do banco Ponto Eletrônico
\PEZOOM Zooms do banco Ponto Eletrônico
\PIP Programas do módulo Planejamento Manutenção
Industrial
\PLP Programas do módulo Planejamento
\PMP Programas do módulo Plano Mestre
\PTP Programas do módulo Patrimônio
\PVP Programas do módulo Previsão de Vendas
\QOP Programas do módulo Cotação de Vendas
\REP Programas do módulo Recebimentos
\RHBRW Objetos Browsers do banco Recursos Humanos
\RHGO Objetos "Vá para" do banco Recursos Humanos
\RHINC Includes de campos indicadores do banco Recursos
Humanos
\RHQRY Objetos Queries do banco Recursos Humanos
\RHVWR Objetos Viewers do banco Recursos Humanos
\RHZOOM Zooms do banco Recursos Humanos
\SCRIPTS Scripts de Carga da Aplicação
\SEC Módulo Segurança
\SPOOL Diretório default de destino dos Relatórios
\SPP Programas especiais dos módulos (não será expedido)
\SRC Includes Padrões PROGRESS
\SUPPORT Programas UIB customizados
\UNBRW Objetos Browsers do banco Universal
\UNGO Objetos "Vá para" do banco Universal
\UNINC Includes de campos indicadores do banco Universal
\UNQRY Objetos Queries do banco Universal
\UNVWR Objetos Viewers do banco Universal
\UNZOOM Zooms do banco Universal
\UTB Módulo Universal
\UTP Programas Utilitários
\VARINC Includes de variáveis indicadores
\LOCAL Programas que possuem localizações
\XXX Prefixo do País
\DATABASE Gatilhos do Banco de Dados do País

Datasul-HR 1.0
Diretórios Conteúdo
\DATABASE \INPM Includes de campos indicadores do banco MGPMG
\INPY Includes de campos indicadores do banco MGPYC
\INTM Includes de campos indicadores do banco MGTMA
\INUN Includes de campos indicadores do banco MGUNI
\TGPM \TAP Gatilhos de assign do banco MGPMG
\TCP Gatilhos de create do banco MGPMG
\TDP Gatilhos de delete do banco MGPMG
\TFP Gatilhos de find do banco MGPMG
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 13

\TWP Gatilhos de write do banco MGPMG


\TGPY \TAP Gatilhos de assign do banco MGPYC
\TCP Gatilhos de create do banco MGPYC
\TDP Gatilhos de delete do banco MGPYC
\TFP Gatilhos de find do banco MGPYC
\TWP Gatilhos de write do banco MGPYC
\TGTM \TAP Gatilhos de assign do banco MGTMA
\TCP Gatilhos de create do banco MGTMA
\TDP Gatilhos de delete do banco MGTMA
\TFP Gatilhos de find do banco MGTMA
\TWP Gatilhos de write do banco MGTMA
\TGUN \TAP Gatilhos de assign do banco MGUNI
\TCP Gatilhos de create do banco MGUNI
\TDP Gatilhos de delete do banco MGUNI
\TFP Gatilhos de find do banco MGUNI
\TWP Gatilhos de write do banco MGUNI
\DOCAPI Documentação de API´s
\DOCHLP Documentação dos Módulo em formato .hlp
\DOCRTF Documentação de Manuais Impressos (*.rtf)
\IMAGE Imagens
\IMGHUR Diretório padrão de imagens do Aplicativo Recursos
Humanos
\INCLUDE Includes Padrões
\INTERFAC Arquivos de interfaces do Produto com outros softwares
\LAYOUT Layout´s de importação
\MASTERS Masters do SmartObjects
\MEN Módulo Menu
\OBJECT \SOPM \BRW Browsers do Banco MGPMG
DIALOG Filtros, narrativas, etc ... do Banco MGPMG
\QRY Objetos Queries do banco MGPMG
\GO Objetos "Vá para" do banco MGPMG
\VWR Objetos Viewers do banco MGPMG
\ZOOM Zoom do banco MGPMG
\SOPY \BRW Browsers do Banco MGPYC
DIALOG Filtros, narrativas, etc ... do Banco MGPYC
\QRY Objetos Queries do banco MGPYC
\GO Objetos "Vá para" do banco MGPYC
\VWR Objetos Viewers do banco MGPYC
\ZOOM Zoom do banco MGPYC
\SOTM \BRW Browsers do Banco MGTMA
DIALOG Filtros, narrativas, etc ... do Banco MGTMA
\QRY Objetos Queries do banco MGTMA
\GO Objetos "Vá para" do banco MGTMA
\VWR Objetos Viewers do banco MGTMA
\ZOOM Zoom do banco MGTMA
* \SOUN \BRW Browsers do Banco MGUNI
DIALOG Filtros, narrativas, etc ... do Banco MGUNI
\QRY Objetos Queries do banco MGUNI
\GO Objetos "Vá para" do banco MGUNI
\VWR Objetos Viewers do banco MGUNI
\ZOOM Zoom do banco MGUNI
\PANEL Painéis dos SmartObjects
\PGHUR \ATP Programas do módulo Administração de Treinamento
\BSP Programas do módulo Benefícios
\CAP Programas do módulo Cargos e Salários
\DSP Programas do módulo Desenvolvimento de Pessoal
\FPP Programas do módulo Folha de Pagamento
\FRP Programas do módulo Férias e Rescisões
\PEP Programas do módulo Ponto Eletrônico
*\PRGTEC \BTB Módulo Básico
\DOC Módulo Documentação
\MEN Módulo Menu
\SEC Módulo Segurança
\SCRIPTS Scripts de Carga da Aplicação
\SPOOL Diretório default de destino dos Relatórios
\SRC Includes Padrões PROGRESS
\SUPPORT Programas UIB customizados
\UTB Módulo Universal
\UTP Programas Utilitários
\VARINC Includes de variáveis indicadores
* Diretórios em implementação
Definição

15

CAPÍTULO 3

Nomenclatura

O objetivo deste capítulo é descrever as regras de nomenclatura para os


objetos dentro do Datasul-EMS 2.00 e Datasul-HR 1.00.

Padrões para Localização


Cada produto EMS2 e EMS5 terão sua própria Localização. Para cada país
terá dois bancos de dados próprios um para Cadastros e um para Movimentos
(se necessário).

Os bancos de dados de localização devem “nascer” multi-empresa, ou seja, as


tabelas que precisarem devem conter também o código da empresa a exemplo
do MGADM. Inclusive as tabelas de extensão dos bancos de dados somente
multi-estabelecimentos como: MGDIS, MGMAT, e outros.
Definição

16

Nomenclatura para bancos de dados de Localização


O objetivo deste capítulo é descrever as regras de nomenclatura para os
bancos de dados de localização do Datasul-EMS 2.00 e Datasul-EMS 5.00.

Veja abaixo exemplos de nomenclatura de bancos de localização:

 Para o banco dos Cadastros do EMS2:


'lcxxx' onde ‘xxx’ é a sigla do país, conforme norma 3166-1. Exemplo:
lcmex.

 Para o banco dos Movimentos do EMS2:


'mov2xxx' onde ‘xxx’ é a sigla do país, conforme norma 3166-1. Exemplo:
mov2mex.

 Para o banco dos Cadastros do EMS5:


'emsxxx' onde ‘xxx’ é a sigla do país, conforme norma 3166-1. Exemplo:
emsmex.

 Para o banco dos Movimentos do EMS5:


'mov5xxx' onde ‘xxx’ é a sigla do país, conforme norma 3166-1. Exemplo:
mov5mex.

 Para os Dump-names dos bancos de Localização do EMS2:


'xx2999' onde ‘xx’ é a sigla de duas letras do país, conforme norma 3166-
1, ‘2’ representa o produto “EMS2” e ‘999’ é uma numeração seqüencial
gerada pelo DWB.

 Para os Dump-names dos bancos de Localização do EMS5:


'xx5999' onde ‘xx’ é a sigla de duas letras do país, conforme norma 3166-
1, ‘5’ representa o produto “EMS5” e ‘999’ é uma numeração seqüencial
gerada pelo DWB.
Definição

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 17

Nomenclatura padrão para programas DPC de Triggers de


Localização
O objetivo deste capítulo é descrever as regras de nomenclatura para as os
programas DPC de triggers de localização.

Funcionamento dos programas DPC de triggers de localização:

 Para tratar as regras de Localização de determinado país é criada


uma tabela de extensão para a tabela do produto padrão no banco
de dados do país (ex. lcmex). No ambiente de localização são
criados programas DPC que são cadastrados e invocados nos
programas triggers da tabela padrão com a finalidade de manter a
sincronização entre a tabela padrão e a tabela de extensão.

Nomes dos programas DPC de triggers de localização:

 Os códigos destes programas DPC de Triggers ficarão amarrados


ao dump-name da tabela do produto padrão, ao invés de utilizar o
dump-name da tabela de extensão. Deverão também usar como
prefixo a sigla do País (ISO 3166-1).

 O padrão de nomenclatura será:


“pppttddddd.p”, onde:

ppp = sigla do pais, conforme norma ISSO 3166-1.


tt = “TD” para trigger de delete, “TW” para trigger de
write, “TC” para trigger de create.
ddddd = dump-name da tabela do produto padrão, cujo trigger
vai chamar o programa DPC de localização.

 Exemplo: Para a tabela “Emitente” do produto padrão tem o


dump-name “ad098”. A tabela “mexext-emitente” do banco
“lcmex” tem o dump-name “mx2001”, então para o programa
DPC de trigger de delete da localização “Emitente” para o país
México deverá ter a seguinte nomenclatura:
“mextdad098.p”, onde:

ppp = mex “sigla do pais”


Definição

tt = td “trigger de delete”.
ddddd = ad098 “dump-name da tabela do produto padrão”.

 Estes programas DPC devem ficar armazenados no mesmo


diretório físico dos triggers de localização daquele país. Exemplo:
local/mex/database/mextdad098.p

Nomenclatura para Tabelas de Localização


O objetivo deste capítulo é descrever as regras de nomenclatura para as
tabelas dos bancos de localização do Datasul-EMS 2.00 e Datasul-EMS 5.00.

Veja abaixo exemplos de nomenclatura das tabelas de localização:

Nomes das tabelas de localização:

 Para as tabelas de localização teremos a seguinte regra, devem iniciar


com a sigla do país, formato ‘xxx-yyy...’, onde ‘xxx’ é a abreviatura da
sigla do país e ‘yyy...’ será uma ou mais abreviaturas cadastradas.
 Exemplo: chi-movto-estoq.

Nomes das tabelas de extensão para localização:

 Para as tabelas de extensão, o padrão é começar com o prefixo


(abreviatura) ‘xxxext’ onde ‘xxx’ é a abreviatura da sigla do país e
‘ext’ indica que é uma tabela de extensão.
 Exemplo: mexext-movto-extrat-bco.

Observação O DWB do EMS5 usa o underline como separador entre cada uma das
abreviaturas e o DWB do EMS2 usa o hífen.
Definição

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 19

Decidiu-se que inicialmente estes padrões serão inspecionados no momento da Homologação


de dicionário. No futuro pode-se alterar a ferramenta DWB para validar em tempo real.

Nomenclatura para Setup de Localização (XML)


O objetivo deste capítulo é descrever as regras de nomenclatura para os
arquivos de Setup de Localização do Datasul-EMS 2.00 e Datasul-EMS 5.00.

Padrão para o produto EMS2:

A nomenclatura padrão para o XML schema será “setup_localiz.xsd”.


O arquivo do XML Schema deve ficar gravado na raiz do diretório
“local”.
Cada país que possui localização contém um subdiretório com três letras
abaixo do diretório local, exemplo:
 local/arg
 local/chi
 local/pry
 local/mex
 local/col

Observação salvo exceções homologadas a sigla do diretório do país respeita a


codificação de países definida na norma ISO 3166-1.

O arquivo XML do setup de cada país ficará abaixo do respectivo diretório


do país.
A nomenclatura do arquivo xml deve respeitar a seguinte padronização:
 Lpp2setup.xml (L = ´Localização´, pp = ´sigla país com 2 letras,
conforme norma ISO3166-1´, 2 = ´Produto EMS2´)
 Exemplos:
- local/arg/lar2setup.xml
- local/mex/lmx2setup.xml
- local/col/lco2setup.xml

Padrão para o produto EMS5:


Descrição

O produto EMS5 não trabalha com o diretório “local”. O equivalente será


o próprio diretório “prgfin”.
A nomenclatura padrão para o XML Schema será “setup_localiz.xsd”.
O arquivo do XML Schema deve ficar gravado na raiz do diretório
“prgfin/lschema” (module lschema do RoundTable).
Cada país que possui localização contém um subdiretório com três letras,
com a mesma sigla do módulo da localização, abaixo do diretório prgfin,
exemplo:
 prgfin/nam
 prgfin/lco
 prgfin/lmx

Observação salvo exceções homologadas, a sigla do módulo da localização do país,


começará com “L” seguida da sigla de 2 letras do país definida na norma ISO 3166-1.

O arquivo xml do setup de cada país ficara abaixo do respectivo diretório


do módulo de localização do país:
A nomenclatura do arquivo xml deve respeitar a seguinte padronização:
 Lpp5setup.xml (L = ´Localização´, pp = ´Sigla país com duas
letras´, 5 = ´Produto EMS5´)
 Exemplos:
- prgfin/lco/lco5setup.xml
- prgfin/lmx/lmx5setup.xml

Sigla de bancos de dados


Para cada banco de dados do Datasul-EMS 2.00 e Datasul-HR 1.00, foi
determinada uma sigla de dois caracteres. Esta sigla serve para compor o
dump-name das tabelas, nome do diretório de gatilhos, nome de objetos como
zoom e browsers.
Banco Sigla Nome lógico
Administrativo AD MGADM
Coletor de Dados CL MGCLD
Distribuição DI MGDIS
Industrial IN MGIND
Investimentos IV MGINV
MultiPlanta MP MGMP
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 21

Ponto Eletrônico PE MGPE


Recursos Humanos RH MGRH
Universal UN MGUNI

Banco de Dados do Datasul-HR 1.00


No Datasul-HR 1.00 deve-se utilizar nomes e abreviaturas no idioma inglês.
Banco Sigla Nome lógico
Personal Management (Administração de PM DTHRPMG
Pessoal)
Payroll (Folha de Pagamento PY DTHRPYC
Time and Attendence (Controle de Freqüência) TA DTHRTMA
Universal (Universal) UN 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.
Módulos do Datasul-EMS 2.00
Módulo Sigla
Aplicações e Empréstimos AE
Benefícios Sociais BS
Caixas e Bancos CB
Coleta de Dados BC
Coletor de Dados CL
Compras CC
Configurador Produto CF
Contabilidade CT
Contas a Pagar AP
Contas a Receber CR
Controle Contratos CN
Controle de Estoque CE
Controle de Produção CP
Controle de Qualidade CQ
Cotação de Vendas QO
Custos CS
Desenvolvimento Produto DP
EDI ED
Engenharia EN
FASB/CMI FC
Faturamento FT
Férias Rescisões FR
Folha de Pagamento FP
Gerencial GE
Investimentos IN
Manutenção Industrial MI
MultiPlanta MP
Obrigações Fiscais OF
Patrimônio PT
Pedidos PD
Planejamento PL
Planejamento Capacidade PC
Planejamento Manutenção PI
Industrial
Plano Mestre PM
Ponto Eletrônico PE
Recebimento RE
Recebimento Internacional RI

Módulos do Datasul-HR 1.00

Módulo Sigla
Administração de Treinamento AT
Benefícios BS
Cargos e Salários CA
Desenvolvimento de Pessoal DS
Férias e Rescisões FR
Folha de Pagamento FP
Ponto Eletrônico PE
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 23

Tipos de Atributos
Tipos de Atributos são classificadores para os tipos de informações que são
gravadas. Segue abaixo, uma lista de todos os tipos de atributos, descrições e
tipos de dados.
Tipo Descrição Tipo de Dado Formato Default
cb1 Código de Barra Tipo 1 Integer >>>>>>>9
cb2 Código de Barra Tipo 2 Integer >>>>>>>>>>>9
cb3 Código de Barra Tipo 3 Character X(20)
cdd Código - Decimal Decimal >>>,>>>,>>9
cdn Código - Numérico Integer >>>,>>9
cod Código Character X(8)
dat Data Date 99/99/9999
des Descrição Character X(40)
dsl Descrição - Longa Character X(15000)
hra Hora Character 99:99:99
idi Indicador - Inteiro Integer 9
Img Imagem Character X(08)
log Lógico Logical Sim/Não
mmp Memory pointer MenPtr X(8)
nom Nome Character X(30)
num Número Integer >>>>,>>9
qtd Quantidade Decimal ->>>>,>>9.9999
qti Quantidade - Inteira Integer >>>,>>9
raw Raw Character X(15000)
rec Recid Recid >>>>>>9
row Rowid Rowid X(20)
som Som Character X(40)
val Valor Decimal ->>,>>>,>>>,>>9.99
vid Vídeo Character X(40)
vli Valor-inteiro Integer >>>,>>9
wgh Widget-Handle Widget-Handle >>>>>>9
Dump-name de tabelas
O Dump-name de uma tabela, tem o formato "xx999", onde "xx" é a sigla do
banco de dados do produto, no qual, a tabela é armazenada, e 999 é um
número seqüencial único dentro do banco de dados, Assim, a tabela "item" que
está no banco de dados industrial tem o dump-name "in172". É importante
utilizar letras minúsculas para a sigla da base de dados.
Não existe processo automático para determinar o número seqüencial para a
tabela no banco de dados. Basta acrescentar uma unidade ao último número já
utilizado.

Gatilhos do dicionário de dados


Gatilho Nomenclatura Exemplos para a tabela "item"
Create da tabela tcxx999.p1 database/tgint/tcp/tcin172.p
Delete da tabela tdxx999.p database/tgin/tdp/tdin172.p
Find da tabela tfxx999.p database/tgin/tfin172.p
Write da tabela twxx999.p database/tgin/twin172.p
Assign de campo TA999999.p² 2
database/tgin/tap/ta002242.p

Programas
A nomenclatura de um programa é determinada em função do seu tipo/estilo, e
a sua extensão é .w, se possuir interface e .p, quando não. Entretanto dois
programas, mesmo se tiverem extensões diferentes, não podem ter o mesmo
nome de arquivo, porque na geração do executável .r, ambos tem o mesmo
nome do arquivo com extensão .r.
Todos os arquivos - sejam programas com extensão .p, includes com
extensão .i*, imagens, nomes de diretórios, etc., deverão obedecer a regra
imposta pelo DOS para o seu nome, isto é, o tamanho máximo do arquivo
deve ter 8 caracteres e o tamanho máximo para a extensão deve ter 3
caracteres no máximo.
Também, todos os nomes de arquivo dos programas devem estar em letras
minúsculas.
1
"xx999" é o dump-name da tabela.
2
O gatilhos de assign do campo obedece a nomenclatura diferenciada pois podemos ter mais de um gatilho
assign por tabela, assim a parte 999999, no padrão, é um número seqüencial de campos em todo o Datasul-
EMS 2.0.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 25

Para os programas que são objetos (SmartObjects) e estão ligados a uma tabela
adota-se a nomenclatura abaixo:
Tipo do Objeto Diretório destino Nomenclatura Exemplos para a tabela "item"
Browser xxbrw 3
b99xx999.w 4
bo01in172.w
Dialog xxdialog d99xx999.w d01in172.w
Go (Vá para) xxgo g99xx999.w g01in172.w
Query xxqry q99xx999.w q01in172.w
Viewer xxvwr v99xx999.w v01in172.w
Zoom (Pesquisa) xxzoom z99xx999.p z01in172.w
 para os programas que estão ligados a um módulo do Datasul-EMS 2.00,
sendo então, containers ou programas .p, sem interface ou ainda API´s,
adota-se a nomenclatura abaixo, sendo que o diretório destino do
programa é sempre o diretório do módulo:
Tipo Nomenclatura Exemplos
API xxapi999.p cep/ceapi001.p
Container xx9999zz.w5 cep/ce0401.w
Subprograma de relatório xx9999rp.p 6
cep/ce0401rp.p
Subprograma qualquer sem interface xx9999zz.p cep/ce0401a.p
 para programas do produto Datasul-HR 1.00 deve ser observado um
controle na criação da numeração do nome do programa, conforme tabela
a seguir:
Numeração Tipo de Programas
0000 à 0099 Manutenções Cadastrais
0100 à 0199 Manutenções Gerais
0200 à 0299 Consultas Cadastrais
0300 à 0399 Consultas Complexas/Relacionamento
0400 à 0499 Listagens Cadastrais
0500 à 0699 Relatórios
0700 à 0799 Tarefas
0800 à 0899 Especiais/Gráficos
0900 à 0999 Utilitários
3
"xx" é a sigla do banco de dados da tabela principal do objeto.
4
"99" é um número seqüencial de objetos de um determinado tipo para uma tabela e "xx999" e dump-name
desta tabela.
5
"xx" indica a sigla do módulo e "zz" caracteres de diferenciação entre programas e subprogramas.
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.
Os programas CADASTRAIS tem sempre uma numeração concordante,
conforme exemplo:
Cadastro: AT0017
Consulta: AT0217
Relatório: AT0417.

Includes
Da mesma maneira que os programas, os includes, também, devem ter seus
nomes de arquivo em letras minúsculas, e também, obedecem a algumas regras
de nomenclatura, conforme o objetivo do include. As extensões dos includes
devem ser sempre .i, i1, .i2, ... e .i9.
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. Estes includes são fundamentais para a tradução do
produto.
Diretório destino Nomenclatura Exemplos
varinc var99999.i 7
varinc/var00002.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,
o nome deste include é igual ao do programa, apenas com a extensão .i ou .i1 a
.i9. Exemplo: cdp/cd0206.i para cdp/cd0206.w ou advwr/v01ad102.i para
advwr/v01ad102.w.
Quando um include é utilizado por vários programas de um mesmo módulo, o
nome deste include é a sigla do módulo mais um número seqüencial,
geralmente acima de 9000. Exemplo: cep/ce9000.i.
Quando um include é utilizado por vários programas de vários módulos, o
nome deste include é 'cd' mais um número seqüencial. Exemplo:cdp/cd9500.i.

7
"999999" é um número seqüencial de includes dentro do diretório "varinc".
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 27

Includes padrões
Os includes padrões dos Estilos devem ser depositados no diretório include, e
o seu nome de arquivo iniciar por "i-" mais um nome significativo, que
indique o estilo ou a função. Exemplo: include/i-rpini.i.

Widgets
O padrão de nomenclatura adotado é um prefixo que identifique o widget mais
um nome significativo. A tabela de prefixo é apresentada a seguir:
Widget Prefixo Exemplo
Botão bt- bt-ok
Browse br- br-zoom
Combo-box cb- cb-tipo-conta
Fill-in fi- fi-texto
Radio-set rs- rs-modo-execucao
Retângulo rt- rt-moldura
Selection-list ls ls-estados
Slider sl sl-percentual
Toggle-box tb tb-ativo
Observação O padrão para nome de retângulo não é importante, pois dificilmente são
realizados tratamentos nos programas para este tipo de widget.

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, conforme tabela a
seguir:
Tipo de dado Prefixo Exemplo
Caracter c- c-conta
Inteiro i- i-contador
Data da- da-atualizacao
Decimal de- de-total-geral
Handle h- h-acomp
Lógico l- l-ativo
Raw raw- raw-param
Rowid rw- rw-
Widget-handle wh- wh-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 Qualificador Exemplo
Conforme tabela no item 4.3 Nome que qualifica a variável V_cod_fornec

Outros componentes da linguagem Progress


Componente Prefixo Exemplo
Buffer de Tabela b- b-item
Frame f- f-cad
Parâmetro p- p-rw-emitente
Stream s- s-import
Temporarytable tt- tt-param

Siglas de países
Será utiliza a norma ISO 3166-1 para definição das siglas dos países. A norma
ISO 3166-1 pode ser consultada em http://pt.wikipedia.org/wiki/ISO_3166-1
Será utilizada sempre a sigla de três letras:
Num Alfa-3 Alfa-2 Pais
32 ARG AR Argentina
44 BHS BS Bahamas
68 BOL BO Bolívia
76 BRA BR Brasil
124 CAN CA Canadá
152 CHL CL Chile
170 COL CO Colômbia
188 CRI CR Costa Rica
192 CUB CU Cuba
222 SLV SV El Salvador
218 ECU EC Equador
Estados Unidos da
840 USA US América
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 29

308 GRD GD Grenada


320 GTM GT Guatemala
328 GUY GY Guiana
388 JAM JM Jamaica
484 MEX MX México
558 NIC NI Nicarágua
591 PAN PA Panamá
600 PRY PY Paraguai
604 PER PE Peru
630 PRI PR Porto Rico
858 URY UY Uruguai
862 VEN VE Venezuela

Nomenclatura para Caixas de diálogos em programas de Zoom e


SmartBrowser
Principalmente, nos programas de Zoom (z99xx999), temos todas as posições
(oito) tomadas pelo próprio nome do arquivo. Nestes programas, quando
necessitamos janelas para filtros, narrativas, etc. Não lemos como criar um
subprograma para o programa de Zoom. Nestes casos, estes subprogramas
devem ter a seguinte nomenclatura:
XX9NNN.W, onde:
XX - Sigla do Módulo
9 - Fixo
NNN - Número seqüencial dentro do Módulo.
Estes subprogramas podem ser reutilizados.

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].
Nome: a[sigla do parceiro - 2 dígitos][sigla módulo - 2 dígitos][inteiro
seqüencial - 3 números].p
Exemplo: adapters/neogrid/ccp/anecc102.p - adapter Neogrid do módulo de
compras
31

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.00, sendo que se caracterizam
pela existência de um menu de barra, uma régua de botões no topo da janela
que disponibilizam as funções existentes naquele programa, e possuem
moldura (resizeable).
Exemplo: Tela de um programa de cadastro.
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. Estas janelas
não possuem menu de barra e a régua de botões fica na parte de baixo da tela,
a idéia é simular a visualização de um dialog-box.
Como diferenciação, não possuem moldura (resize = no).
Exemplo: Tela de um programa de zoom.
Caixas de Diálogo
Caixas de diálogo são utilizadas em funções onde é imprescindível que a
interface seja modal, normalmente em funções de grande risco aos sistemas.
Nestas caixas existe uma régua de botões disposta na parte de baixo da caixa.
Exemplo: Programa de Cálculo do Preço Médio.
32

Observação Não é aconselhável salvar uma Dialog com uma Window aberta. Quando isto é
feito, é possível que o menu da Window seja copiado para a Dialog eliminando-o. Caso isto
aconteça é necessário recriar a Dialog e o menu da Window.

Objetos
Combo-boxes
Ver capítulo Como implementar campos indicadores com view-as combo-box
nas telas.
Retângulos
São utilizados para agrupar a chave de acesso das telas, agrupar campos de um
mesmo assunto, emoldurar itens de radio-set e emoldurar editores que
necessitem de label.
Botões
 os botões com label devem ter:
 altura: 1,00 unidade de caracter;
 largura: 10, 15 ou 20 unidades de caracter;
 quando representarem ações e possuírem labels estes termos devem ser
verbos no infinitivo. Exemplo: Cancelar, Incluir, Modificar, Eliminar ...;
 botão 'OK' sempre confirma a ação e sai da tela corrente;
 botão 'Cancelar' não confirma a ação e sai da tela corrente;
 botão 'Ajuda' sempre é disposto no canto inferior direito nas janelas
detalhe e caixas de diálogo;
 os botões de 'Sair' e 'Ajuda' devem estar sempre no canto superior direito
nas janelas pai.
Fill-in´s
 os campos e variáveis view-as fill-in devem ter altura de 0,88 unidade de
caracter, excepcionalmente, os campos e variáveis view-as combo-box tem
a altura de 1,00 unidade de caracter.
Frames(Telas)
 título das telas é feito a partir do UT-9000.i, não necessitando intervenção
do programador;
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 33

 as telas podem ter no máximo 90 colunas, sendo que este tamanho é


sempre fixo, por 17 linhas, já este tamanho pode ser variável para menos,
mas sempre em número inteiro, estas dimensões acompanham o limite
para VGA. Estas dimensões devem ser informadas na "Property Sheet" da
janela no UIB, nos campos "Width" e "Height";
 definida a altura e largura de uma janela, as mesmas dimensões devem ser
utilizadas para as propriedades MAX-WIDTH-CHARS e MIN-WIDTH-
CHARS (altura máxima e mínima) e MAX-HEIGHT-CHARS e MIN-
HEIGHT-CHARS (largura máxima e mínima) (isto deve ficar num include
padrão). Com isso as janelas podem possuir a moldura dada pela
propriedade RESIZEABLE. O include WIN-SIZE.I faz estas atribuições.
Radio-Sets
 não podem possuir label, devido à limitações do UIB, por isso devem ser
emoldurados por um retângulo com uma literal para identificá-lo, que é o
próprio label. Ver capítulo: Como implementar labels em retângulos
utilizando o dicionário de dados; Exemplo:

 podem ser horizontais ou verticais, prevalecendo o modo vertical quando o


número de itens for maior que 4, sendo que maiores que 7 itens devem ser
combo-boxes.
Editores
 não podem possuir label, devido ao UIB, então quando a tabela possui
apenas um editor, que represente comentário ou narrativa, não deve ser
colocado qualquer literal ou texto para identificá-lo. Caso contrário,
emoldurá-lo com um retângulo e dispor uma literal para identificá-lo;
 em View-as Editor, deve-se no UIB, atribuir ou utilizar as seguintes
propriedades (Property Sheet): RETURN-INSERTED, e o fonte deve ser
escolhido o "2", padrão do Progress, que é um fonte fixo.
Recomendações

Considerações sobre os SmartObjects


SmartBrowser
SmartBrowser é um objeto Procedure que recupera e visualiza dados,
utilizando um browse. O nome padrão do Browse não deve ser modificado.
Durante a montagem, o tamanho do SmartBrowser deve ser mantido padrão
não importando o n.º de campos.
SmartViewer
SmartViewer é uma procedure object, o qual, visualiza os campos da base de
dados. Um SmartViewer tipicamente preenche registros da base de dados
desde um SmartQuery ou SmartBrowser.
O SmartViewer deve ter um distanciamento de uma linha após e uma linha
antes de outros objetos na sua localização.
SmartQuery
SmartQuery é uma procedure object que contém uma base de dados query. Um
SmartQuery preenche tipicamente registros para outro SmartObjects, tal como
um SmartViewer ou SmartBrowser. Um SmartQuery pode também responder
a pedido de navegação de um SmartPanel.
Na tela de características da "Query Builder", em "Options", o campo
"Returned" deve ser alterado de "All Fields" para "Fields Used".
Observação: O identificador :T no início de alguns comentários, é usado para a
tradução dos fontes dos templates para outros idiomas. Este identificador não
afeta em nada a funcionalidade do programa.

Considerações sobre as Imagens


WebEnabler
WebEnabler é um produto que disponibiliza o DATASUL EMS 2, EMS 5 e
HR através de um Web Browser, como o Internet Explorer. Assim sendo todos
as telas que utilizam imagens, normalmente no formato Bitmap (.bmp),
também devem possuir a mesma imagem, como mesmo nome no formato GIF
(.gif), pois o WebEnabler sendo um produto voltado para a Web só irá suportar
os padrões da mesma quanto as imagens.
Características

35

CAPÍTULO 5

Estilos

Cadastro Simples

 todas as funções, com exceção do zoom e do 'vá para', são realizadas na


própria tela base do programa;
 os campos devem estar alinhados pelo colon e formando colunas;
 a tabulação deve ser de cima para baixo nos campos, passando por todos
os campos de uma coluna para depois passar para a outra coluna;
 o menu de barra da janela contém todas as opções disponíveis através dos
botões dispostos na tela;
36

 novas funções, 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, 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');
 não é permitida a alteração da chave da tabela através da função 'Alterar';
 a função 'Eliminar' deve pedir confirmação;
 menu de barra tem a seguinte configuração:
Arquivo Ajuda
Primeiro Ctrl-Home Conteúdo
Anterior Ctrl-Left Sobre
Próximo Ctrl-Right
Último Ctrl-End
Vá Para Ctrl-T
Pesquisa Ctrl-F5
Incluir Ctrl-Ins
Copiar Ctrl-C
Alterar Ctrl-A
Eliminar Ctrl-Del
Desfazer Ctrl-U
Cancelar Ctrl-F4
Salvar Ctrl-S
Imprimir Ctrl-P
Sair Ctrl-X
Características

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 37

Cadastro Complexo

 menu de barra tem a mesma configuração demonstrada na tela de Cadastro


Simples. Possui porém, folders que permitem a utilização de mais de uma
viewer.
Quando utilizar o Cadastro Complexo
 deve ser usado sempre que o número de campos de uma tabela não
couberem em uma única viewer.
Características

Cadastro Simples - Atualiza

 o menu de barra da janela contém apenas as opções para Atualizar, sem as


funções de 'Incluir', 'Copiar', 'Eliminar', como disposto no Cadastro
Simples.
Características

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 39

Cadastro Complexo - Atualiza

 tem as mesmas características do Cadastro Simples - Atualiza, porém


possui mais de uma viewer e está disposto em folders.
Características

Pai x Filhos - Atualiza Filho

 os campos devem estar alinhados pelo colon e formando colunas;


 a tabulação deve ser de cima para baixo nos campos, passando por todos
os campos de uma coluna para depois passar para a outra coluna;
 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, 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, 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 'Folder' tem como objetivo, selecionar browsers de tabelas filho;
 Incluir, Modificar e Eliminar serve apenas para manutenção da(s) tabela(s)
filho, as opções 'Incluir' e 'Modificar', chamam janelas semelhantes ao
Cadastro Simples ou Complexo (sem a régua);
Quando utilizar Pai x Filhos - Atualiza Filho
É feita a navegação na tabela pai e a manutenção é executada somente no
campo selecionado da tabela filho, para modificação pode se selecionar
'Modificar' para abrir uma janela.
Características

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 41

Manutenção de Filhos

 é uma janela sem painéis, podendo possuir ou não folders de acordo com
a necessidade, é chamada a partir de um programa Pai x Filho, a janela é a
mesma tanto para inclusão quanto para alteração;
 a janela possui quatro botões: 'Ok', 'Salvar', 'Cancelar' e 'Ajuda';
 o botão de 'Ok' tem função igual tanto para chamada do programa, para
inclusão, quanto para modificação;
 o botão de 'Salvar', quando o programa é chamado para inclusão, possui
função de salvar o registro corrente e criar um registro novo;
 o botão 'Cancelar', anula qualquer mudança feita no registro corrente do
programa, ou seja, cancela apenas a última inclusão ou a última alteração;
 o botão 'Ajuda' é responsável por chamar o help do programa.
Caraterísticas

Pai x Filhos - Atualiza Ambos

 tem as mesmas características da tela Pai x Filho - Atualiza Filho, além de


que a atualização não só é feita no Folder como no registro pai;
 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, 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, 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');
 Incluir, Modificar e Eliminar serve para manutenção da(s) tabela(s) filho;
 as opções 'Incluir' e o 'Modificar', chamam janelas semelhantes ao
Cadastro Simples ou Complexo (sem a régua);
 Incluir, Modificar, Eliminar e Copiar serve apenas para manutenção da
tabela pai, as opções 'Incluir', 'Modificar' e 'Copiar, chamam janelas
semelhantes ao Cadastro Simples ou Complexo (sem a régua).
Caraterísticas

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 43

Manutenção de Pais

 é uma janela sem painéis, podendo possuir ou não folders, de acordo com
a necessidade, é chamada a partir de um programa Pai x Filho, a janela é a
mesma tanto para inclusão quanto para alteração ou cópia;
 a janela possui quatro botões: 'Ok', 'Salvar', 'Cancelar' e 'Ajuda';
 o botão de 'Ok' tem função igual tanto para chamada do programa, para
inclusão, quanto para modificação;
 o botão 'Salvar', quando o programa é chamado para inclusão, possui
função de salvar o registro corrente e criar um registro novo;
 o botão 'Ajuda' é responsável por chamar o help do programa.
Características

Consulta Cadastral Simples

 as funções com exceção do zoom e do 'Vá para', são realizadas na própria


tela base do programa, apenas para consulta;
 o menu de barra da janela contém as opções disponíveis através dos botões
dispostos na tela.
Características

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 45

Consulta Cadastral Complexa

 além das mesmas características da tela de Consulta Cadastral Simples,


tem um 'Folder', com o objetivo de selecionar as demais viewers da tabela;
 as funções, com exceção do zoom e do 'Vá para', são realizadas na própria
tela base do programa, apenas para Consulta;
 o menu de barra da janela contém as opções disponíveis através dos botões
dispostos na tela, além do botão de 'Relacionamento'.
Características

Consulta Relacionamento

 o objetivo é apresentar os relacionamentos de uma determinada tabela,


denominada tabela pai;
 as funções de navegação, 'Vá para' e 'Pesquisa' se aplicam sobre a tabela
pai;
 em cada página do folder é apresentado um relacionamento (tabela filho)
da tabela, onde um browser apresenta os registros relacionados da tabela
filho com o corrente registro da tabela pai;
 cada browser de apresentação dos relacionamentos deve possuir um botão
'Detalhar', cuja função é chamar a consulta cadastral da tabela filho,
posicionando-se no registro corrente no browser, o evento default-action
sobre estes browsers, representado por um duplo clique ou por um
pressionar na barra de espaços, é um atalho para botão 'Detalhar';
 acima do folder, isolados por um retângulo, ficam dispostos os principais
campos da tabela pai (normalmente, a chave primária e alguma descrição);
 menu de barra da janela contém todas as opções disponíveis na barra de
botões disposta no topo da tela.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 47

Relatórios, Cálculos, Fechamentos


Características

 é uma janela do tipo detalhe, isto é, sem menu de barra emoldura,


simulando uma caixa de diálogo;
 o botão 'Executar' tem como função executar toda a parametrização
realizada nos Folders;
 o 'Fechar' do frame sai da tela;
 o botão 'Ajuda' é responsável por chamar o help do programa;
 Seleção: tudo que é faixa;
 Classificação: Radio-se com as opções;
 Parâmetros: com exceção da faixa, as outras informações que o usuário
digita;
 Digitação: browse updatable.
A seguir, estão demonstrados os folders de Seleção, Classificação, Parâmetros
e Digitação:
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 49
Características

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 51

Parâmetros Únicos

 é uma janela do tipo detalhe, isto é, sem menu de barra e moldura,


simulando uma caixa de diálogo;
 o default-button do frame é o botão de 'Ok', que confirma a escolha do
usuário;
 o cancel-button do frame é o botão de 'Cancelar' que sai da tela;
 o botão 'Imprimir' é responsável por chamar o browse dos relatórios
relacionados;
 o botão 'Ajuda' é responsável por chamar o help do programa.

Parâmetros Múltiplos
Seguir as mesmas regras dos Cadastros Simples ou Complexo, dependendo do
número de campos.
Exemplo: Parâmetros por estabelecimento.
Características

Formação

 este estilo de formação possui o palette de navegação, portanto o programa


é independente, não sendo necessário um programa principal para sua
chamada;
 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;
 novas funções, 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, 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';

 o botão 'Incluir' , adiciona no Browse de formação os dados de


outras 2 tabelas;

 o botão 'Deletar' , remove dados do Browse de formação;


 o botão 'Modifica' chama o programa de atualização dos atributos, que é
uma janela semelhante ao Cadastro Simples ou Complexo (sem a régua).
Características

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 53

Formação sem Navegação

 este estilo de formação não possui o palette de navegação, portanto o


programa é dependente, sendo que ele deve ser chamado por um programa
que possua um Browser Formação;
 os campos devem estar alinhados pelo colon e formando colunas;
 menu de barra da janela contém todas as opções disponíveis através dos
botões dispostos na tela;
 novas funções, 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, 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 'Incluir' , adiciona no Browse de formação os dados de


outras 2 tabelas;

 botão de 'Deletar' , remove dados do Browse de formação;


 botão 'Modifica' chama o programa de atualização dos atributos.
Características

Importação

 é uma janela do tipo detalhe, isto é, sem menu de barra e moldura,


simulando uma caixa de diálogo;
 o botão 'Executar' tem como função disparar a importação que foi
parametrizada nos folders;
 possui quatro folders: Layout, Seleção, Parâmetros e Log;
 no folder de "Layout" é mostrado o layout do arquivo a ser importado;
 o botão 'Editar Layout' permite que seja editado o arquivo de layout
através de um editor de texto;
 no folder de "Seleção" é determinada a faixa dos registros que são
importados;
 no folder de "Parâmetros" é determinado o nome do arquivo de entrada
contendo registros a serem importados no formato do Layout;
 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, contém ainda a determinação do modo de execução do
mesmo.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 55

A seguir estão demonstrados os folders de Layout, Seleção e Parâmetros:


Exportação
Características

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 57

 é uma janela do tipo detalhe, isto é, sem menu de barra e moldura,


simulando uma caixa de diálogo;
 o botão 'Executar' tem como função disparar a exportação que foi
parametrizada nos folders;
 possui quatro folders: Layout, Seleção, Parâmetros e Log;
 no folder de Layout é mostrado o layout do arquivo a ser exportado;
 o botão 'Editar Layout' permite que seja editado o arquivo de layout
através de um editor de texto;
 no folder de "Seleção" é determinada a faixa dos registros que serão
exportados;
 no folder de "Parâmetros" é determinado o nome do arquivo de saída que é
exportado no formato do Layout;
 a página de "Log" contém a determinação de modo de execução do
mesmo.
A seguir são mostrados os folders de Layout, Seleção e Parâmetros:
Características

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 59

Zoom de Tabelas

 é uma janela do tipo detalhe, isto é, sem menu de barra e moldura,


simulando uma caixa de diálogo;
 default-button do frame é o botão de 'OK', que confirma a escolha do
usuário;
 cancel-button do frame é o botão de 'Cancelar' que sai da tela, retornando
ao programa chamador porém sem retornar um registro escolhido;
 o botão 'Implantar' é responsável por chamar o programa de cadastro da
tabela, que pode estar desativado dependendo do programa chamador;
 ao lado do botão 'Implantar' que é padrão, devem ser colocados os botões
específicos de cada programa de zoom, por exemplo: Narrativa, Filtro,
Texto Livre, etc..., normalmente estes botões chamam caixas de diálogo;

 o botão é responsável pela aplicação do valor inicial e final definido


pelo usuário sobre a query apresentada no browse;
 cada folder representa uma opção de classificação disponível no zoom;
Características

 os iniciais e finais devem ser apresentados no formato, independentemente


do número de campos para a faixa:

Label do campo: [valor inicial] ............... [valor final].


 não devem ser utilizadas literais em tela para denominar inicial e final.
Observação Verificar se cada folder tem um browser diferente ou não, se isto for necessário
inverter a ordem dos campos, conforme a classificação.
O Zoom não tem os botões de INÍCIO e de FIM (como no MAGNUS antigo), logo se utiliza o
teclado: "HOME" e "END", para substituir as características destas funções.

 para utilizar o 'Pesquisa', usar o para acessar.

Vá Para

 o objetivo é permitir um reposicionamento rápido do registro corrente no


cadastro, quando o usuário tem o conhecimento da chave do registro,
evitando que o usuário tenha que navegar sobre os registros ou acionar o
zoom;
 é aberta uma pequena caixa de diálogo com os botões de 'Ok' e 'Cancelar' e
'Ajuda', sendo que o botão de 'Ok' é o default-button, o que possibilita ao
usuário digitar a chave e apenas teclar "Enter" para confirmar a tela;
 não tem possibilidade zoom;
 para utilizar esta tabela, usar o para acessá-la.
Observação Não é aconselhável salvar uma Dialog com uma Window aberta. Quando isto é
feito, é possível que o menu da Window seja copiado para a Dialog eliminando-o. Caso isto
aconteça é necessário recriar a Dialog e o menu da Window.
Características

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 61

Digitação Rápida

 é uma janela do tipo detalhe, isto é, sem menu de barra e moldura,


simulando uma caixa de diálogo;
 default-button do frame é o botão 'Ok', que efetiva a transação;
 cancel-button do frame é o botão 'Cancelar' que sai da tela sem considerar
as informações;
 as páginas iniciais são reservadas para as informações genéricas;
 a última página é reservada para o browser.

Painéis

Estes são os painéis padrão mais utilizados para navegação.


Características

Funções
Relatórios Relacionados

 chama um Browser que lista todos os relatórios relacionados ao programa


que está sendo executado;
 o botão 'Executar', chama o relatório selecionado no browser.

Para utilizar a função de "Relatórios Relacionados", usar o para acessar.


Consultas Relacionadas

 chama um Browser que lista todas as consultas relacionadas ao programa


que está sendo executado;
 o botão 'Executar', chama a consulta selecionada no browser.

Para utilizar a função de "Consultas Relacionadas", usar o para acessar.


Utilização
Objetivo

63

CAPÍTULO 6

Includes e Utilitários Padrão

UT-FIELD.I
Retornar propriedades dos campos do dicionário de dados, como label,
column-label, etc..
{utp/ut-field.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úmero Propriedade
1 Label
2 Column-Label
3 Help
4 Format
5 Initial
6 Description
7 Data Type

O retorno é obtido através do return-value. Exemplo:


def var c-tipo as character no-undo.
{utp/ut-field.i mgadm conta tipo 1}
Formato
Utilização
Objetivo

64

assign c-tipo:label in browse br-table = return-value.

UT-RTLBL.I
Permitir a utilização de literais para colar labels em retângulos na tela
minimizando os problemas de internacionalização.
 campos view-as radio-set ou editor, onde seja necessário emoldurá-lo com
retângulo com um label para identificá-lo;
 literais utilizados em telas para substituir labels;
{utp/ut-rtlbl.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.i mgadm conta natureza text-1}

UT-RUN.I
Seu objetivo é executar programas que não possuam interface (.p), através do
recurso de RPC (Remote Procedure Call). Deve executar apenas programas
(.p), chamados a partir de programas (.w). Não deve chamar um programa (.p),
a partir de um outro programa (.p), como por exemplo um programa de
impressão de relatórios xxp/xx9999rp.p, porque o programa chamador (.p), já
está rodando no servidor (Application Server) e não é necessário iniciar um
novo servidor.
Sempre que for chamado algum programa sem interface a partir de um .W e
que este programa seja candidato para ser executado via RPC.
Nota Para utilizar os includes é necessário relacionar ao programa os includes {utp/ut-glob.i}
e {btb/btb008za.io} no main-block, para definição de variáveis e funções.

Para a chamada de rotinas via RPC, tem-se:


Modelo Simplificado
Include
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 65

{utp/ut-run.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, utilize aspas duplas ("") com aspas
simples (''). Exemplo: ' " " '.
Não sendo informados os parâmetros opcionais estes receberão "yes" e ' " " ' respectivamente.

Funções
 solicita a conexão e cria a instância do servidor, conforme servidor do
aplicativo ou parâmetro;
 mostra mensagem se ocorrer um erro (por exemplo, de conexão), quando
solicitada ({3} = yes);
 dispara a execução do programa no servidor;
 encerra a conexão e elimina a instância.
Aplicações
Quando o programa API será disparado uma única vez para realizar todo o
processo.
Exemplo: {utp/ut-run.i cep/ceapi001.p "input-output table tt-
mvto, input-output table tt-erro, input yes ' " " '}

Modelo Aberto
Includes
{btb/btb008za.i1 {1} {2} {3}}

Onde:
{1} = nome externo do programa
{2} = mostra mensagem de acompanhamento
{3} = servidor de RPC determinado
{btb/btb008za.i2 {1} {2} {3}}

Onde:
Considerações
Exemplo
Gerais

{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.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, porém distribuídas em três includes:
 solicita a conexão e cria a instância do servidor;
 dispara a execução do programa;
 encerra a conexão e elimina a instância.
Aplicações
Quando o programa API é disparado n vezes dentro de um laço (repeat, for
each...).
def var h-handle as handle no-undo.
{btb/ btb008za.i1 cep/ceapi001.p yes "rpc-test"}
for each cta_ctbl no-lock:
/* Prepara tt_movto */
{btb/btb008za.i2 cep/ceapi001.p "input tt_movto, output
tt_erro" "h-handle"}
end.
{btb/btb008za.i3 cep/ceapi001.p "h-handle"}

Nota Existe a API BTAPI008 que possui funções que podem ser utilizadas no desenvolvimento.
Caso não seja informado nenhum servidor RPC, será utilizado o servidor RPC
definido no aplicativo do programa;
Se o processo estiver sendo executado via RPW e o servidor RPC não foi
informado o programa será executado On-line.
Parâmetros X
Compo
rtament
o

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 67

Quando informado valor parar servidor RPC, caso ocorra algum erro não será
possível a execução On-line.
Ocorrendo erros na tentativa de execução do programa (faltou passar
parâmetros, por exemplo), estes serão retornados juntamente com a mensagem
16435 (*).
Quando for informada a variável do tipo "handle" para a include
btb/btb008za.i2, deve-se tomar dois cuidados: Primeiro, esta variável deve
estar previamente definida no programa. E segundo, ao final da execução,
deve-se eliminar o programa persistent passando o nome da variável para a
include btb008za.i3.
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). Logo, as informações como usuário corrente, grupos
de segurança em que o usuário se encontra, empresa do usuário... estarão
disponíveis na sessão remota.
Dados:
Nome Programa: btb/btb923za.p
Sintaxe: run btb/btb923za.p
(<versão_integração>, <handle_application_server>)
Programa Servidor RPC Mensagem Comportamento
Inexistente - Yes Exibe mensagem 3045(*) via
PI_STATUS_ERROR.
Inexistente - No Retorna mensagem 3045(*)
Existe e Executa - Yes Exibe mensagem 16431(*) via
RPC =no PI_STATUS_ERROR.
Existe e Executa Informado No Retorna mensagem 16431(*)
RPC =no
Existe e Executa Não Informado No Executa ON-LINE
RPC =no
Existe e Executa Informado e Yes Exibe mensagem 16433(*) via
RPC =yes Inexistente PI_STATUS_ERROR.
Existe e Executa Informado e No Retorna mensagem 16433(*)
RPC =yes Inexistente
Existe e Executa Não Informado e Yes Exibe mensagem 16432(*) via
RPC =yes Inexistente PIA_STATUS_ERROR.
Existe e Executa Não Informado e No Executa ON_LINE
RPC =yes Inexistente
Existe e Executa Informado, No Retorna mensagem 16434(*)
RPC =yes Existe e Não
disponível
Existe e Executa Não Informado, Yes Exibe as mensagens 16434(*) via
RPC =yes Existe e Não PI_STATUS_ERROR
disponível
Existe e Executa Não Informado, No Executa ON-LINE
RPC =yes Existe e Não
disponível
Existe e Executa Informado, Yes Executa via RPC (**)
RPC =yes Existe e
Disponível
Existe e Executa Informado, No Executa via RPC (***)
RPC =yes Existe e
Disponível
Existe e Executa Não Informado, Yes Executa via RPC (**)
RPC =yes Existe e
Disponível
Existe e Executa Não Informado, No Executa VIA RPC
RPC =yes Existe e
Disponível
Observação Ocorrendo erro na conexão
do Servidor RPC, será executado ON-LINE

(*) Mensagens:
3045 - Programa não cadastrado no menu !
6160 - Não foi possível executar o programa via RPC !
16431 - Programa não pode ser executado via RPC
16432 - Não foi possível encontrar servidor RPC para programa '&1' !
16433 - Servidor RPC não cadastrado
16434 - Servidor RPC não disponível
164 35 - Não foi possível executar programa !
(**) Ocorrendo erros na conexão do servidor RPC, estes serão exibidos em
tela juntamente com a mensagem 6160.
(***) Ocorrendo erros na conexão do servidor RPC, estes serão retornados
juntamente com a mensagem 6160.
Formato
Utilização
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 69

UT-MSGS.P
Apresentar para o usuário uma mensagem previamente cadastrada, no Sistema
de Mensagens, ou ainda, retornar para o programa propriedades desta
mensagem.
Notas :
 ao ser exibida uma mensagem, seu número vai ser exibido na barra de título da caixa de
diálogo, juntamente com o tipo de mensagem. Ex.: Pergunta: (10);
 antes da exibição de qualquer mensagem, será verificado se ela possui uma substituta, se
houver, a mensagem substituta será exibida ao invés da original. Da mesma forma, antes da
exibição da mensagem substituta, será verificado se esta também, possui uma mensagem
substituta e assim por diante;
 quando da exibição de mensagens substitutas, os números da mensagem original e da
mensagem substituta serão exibidos na barra de títulos da caixa de diálogo. Exemplo:
Advertência: (134) - (354), onde 134 seria a mensagem exibida e 354 a mensagem original.

 apresentação de mensagens de erro, informação, advertência ou


questionamentos ao usuário;
 impressão de mensagens em log´s.
 apresentação da pilha de execução dos programas até o ponto de chamada
da ut-msgs, através do botão “trace”.
run utp/ut-msgs.p (input <ação>
input <número da mensagem>
input <parâmetros>).

Onde:
<ação>: ação desejada, conforme a tabela a seguir:
Ação Resultado
show Apresenta a mensagem, com texto de ajuda no padrão do produto
msg Retorna o texto da mensagem
help Retorna o texto de ajuda
type Retorna o tipo da mensagem (Erro, Advertência, Informação ou Questão)
codtype Retorna o código do tipo da mensagem
<número da mensagem>: número da mensagem desejada.
<parâmetros>: são os campos, tabelas e outras palavras que se deseja colocar
na mensagem no momento de sua utilização. Cada um dos parâmetros deve ser
separado por "~~" como por exemplo:
Formato
Utilização
Objetivo
Observações
Exemplo

input "campo~~" + variável + "~~tabela".


run utp/ut-msgs.p (input "show",
input 1235,
input repres.cod-repres + "~~" +
regiao.cod-regiao + "~~" +
string(regiao.val-minimo).

A manutenção do cadastro das mensagens, assim como a inclusão de novas


mensagens só pode ser realizada pela Datasul. Para clientes e parceiros é
autorizada somente a utilização das mensagens já cadastradas. Para acessar o
Sistema de Mensagens, você deve primeiro entrar em contato com a equipe de
ADF e solicitar a criação de um usuário no Sistema de Mensagens. Em
seguida você pode acessar o Sistema pelo endereço:
X:\Atalhos\SistTec\Mensagem.
Quando a opção codtype é usada o retorno pode ser:
0. Mensagem não Cadastrada.
1. Mensagem de Erro.
2. Mensagem de Advertência
3. Pergunta
4. Informação

IND01-10.I, IND11-50.I E IND51500.I


Viabilizar a utilização de combo-boxe´s e radio-set´s com representação para
campos inteiros do tipo indicador.
Nos includes de dicionário de dados criados para cada campo indicador.
{include/ind01-10.i {1} {2}}

Onde:
{1}: indica a função a ser realizada, conforme tabela abaixo:
Função Objetivo
01 define view-as combo-box
02 define view-as radio-set
03 lista com os itens separados por vírgula
04 n Retorna o item n da lista
05 Retorna o número de itens da lista
Formato
Utilização
Objetivo
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 71

06 item retorna a posição do item (número)


07 retorna valores para a propriedade radio-buttons
{2}: utilizado quando a função necessita de um segundo parâmetro, isto é, nas
opções 04 e 06.
/******************************
* Include: i01un001.i
* Campo: tipo-cod-situacao
*******************************/
{include/i-lgcode.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 {01} {02}}
/* Fim */

UT-TABLE.I
Retornar propriedades das tabelas do dicionário de dados.
 nos SmartBrowsers ou Browsers para por label em campos calculados;
 para utilização de literais ou textos nas telas com função de label, como no
retângulo que envolve o radio-set.
{utp/ut-table.i <banco> <tabela> <propriedade>}

Onde:
Formato
Utilização
Objetivo

<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úmero Propriedade
1 File-Label
2 Dump_Name
3 Desc
O retorno é obtido através do return-value. Exemplo:
def var c-tipo as character no-undo.
{utp/ut-table.i mgadm conta 1}
assign c-tipo:label in browse br-table = return-value.

UT-LITER.I
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.
 em todos os lugares onde literais passíveis de tradução forem apresentadas
na interface do programa.
{utp/ut-liter.i <literal> <modulo contexto> <alinhamento>}

Onde:
<literal>: Literal a ser utilizada na tela com os espaços substituídos por "_"
(undescore). OBS.: Se a literal passada terminar com “:U” a literal não será
traduzida e a mesma será retornada sem os dois últimos caracteres.
<módulo contexto>: parâmetro opcional que define o contexto de tradução da
literal, este contexto é um módulo do Datasul-EMS, se omitido a literal deve
ter o contexto universal de tradução, que é representado pelo valor *
(asterisco)
<alinhamento>: parâmetro opcional que define onde é incrementado o espaço
extra para tradução, conforme tabela abaixo, se omitido deve reservar o espaço
à esquerda da literal:
Tipo Alinhamento
L A esquerda
C Centralizado
R A direita
Exemplo de
Formato
Utilização
Objetivo
variáve
is
definid
as

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 73

O retorno é obtido através do return-value. Exemplo:


def var l-lista-narra as character no-undo.
{utp/ut-liter.i Lista_Narrativa MCE R}
assign l-lista-narra:label in frame {&frame-name} =
return-value.

UT-LIMIT.P
Determinar o valor inicial e final de campos caracter, cujo formato é variável,
como por exemplo a conta-contábil.
Na seleção de relatórios, cálculos, atualizações e zooms que tenham faixas de
seleção sobre campos caracter com formato variável.
run utp/ut-limit.p (input <opção>,
<formato>).

Onde:
<opção>: indica o limite desejado, MIN = Mínimo e MAX = Máximo
<formato>: formato do campo caracter
O retorno é obtido através do return-value.
def var c-conta-ini as char no-undo.
find first param-global no-lock no-error.
run utp/ut-limit.p (input "MIN",
input param-global. formato-conta-contabil).
Assign c-conta-ini = return-value.

UT-GLOB.I
Define as variáveis globais.
Já está definido dentro dos SmartObjects.
i-ep-codigo-usuario: contém a empresa corrente do usuário.
l-implanta: variável lógica usada no Zoom, para habilitar o botão implanta.
c-seg-usuario: contém o nome do usuário corrente logado no menu.
Exemplo
Formato
Utilização
Objetivo

I-FREEAC.I
Converter strings acentuadas e caracteres especiais para strings não acentuadas
e caracteres simples.
 nos Templates de Relatório, Importação, Exportação e em pontos
específicos que necessitem que a saída de dados (impressora/arquivo/tela)
seja feita sem acentuação;
{include/i-freeac.i}
assign <variável> = fn-free-accent("<string>").
display fn-free-accent("<string>").

Onde:
<variável>: variável que irá armazenar o valor do retorno da função fn-free-
accent
<string>: string acentuada a ser convertida.
{include/i-freeac.i}
define var c-texto as char no-undo.
assign c-texto = fn-free-accent ("ÁÀÃÂÄ-ÉÈÊË-ÍÌÎÏ-ÓÒÔÕÖ-ÚÙÛÜ-ÝŸ-
Ç-Ñ").
message fn-free-accent("áàãâä-éèêë-~íìîï-óòõôö-úùûü-y´¨y-ç-ñ")
chr(10) c-texto view-as alert-box.

UT-DIR.P
Este utilitário deve ser usado sempre que o usuário tiver que informar um
diretório.
run utp/ut-dir.p (input <título>,
output <pasta>,
output <cancelado>).

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:
Instalação
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 75

run utp/ut-dir.p (input "Escolha um diretório",


output <pasta>,
output <cancelado>).

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 (input "Escolha um diretório,
output pasta,
output cancelado).

BTB917ZX.P
Permitir a execução de sons do tipo MID e WAV.
Como este programa utiliza os recursos de OCX, é preciso que este OCX
esteja registrado e instalado na máquina que deve ser utilizado. Para fazer esta
instalação proceda da seguinte forma:
 executar o SETUP.EXE, que se encontra no diretório \INTERFAC\SOM\;
 clicar no botão de 'OK', quando for solicitado;
Objetivo
Formato

 clicar no botão ;
 clicar em 'Ok' para terminar.
run btb/btb917zx.p (input <som>).

Onde:
<som>: caminho completo do arquivo de som a ser executado
Exemplo:
run btb/btb917zx.p (input "c:\windows\media\start.wav").

BTB917ZY.P
Permitir a visualização dos seguintes tipos de imagens:
 Bitmaps (*.bmp; *.dib);
 Gif Images (*.gif);
 JPEG Images (*.jpg);
 Metafiles (*.wmf, *.emf);
 Icons (*.ico, *.cur).
Nota As imagens em formato Bitmap (.bmp) devem possuir um correspondente de mesmo
nome no formato GIF (.gif) devido a uma restrição do WebEnabler
Instalação Como este programa utiliza os recursos de OCX, é preciso que este OCX
esteja registrado e instalado na máquina que deve ser utilizado. Para fazer esta
instalação proceda da seguinte forma:
 executar o SETUP.EXE, que se encontra no diretório
\INTERFAC\IMAGEM\;
 clicar no botão de 'Ok', quando for solicitado;

 clicar no botão: ;
 clicar em 'Ok', para terminar.
run btb/btb917zy.p (input <imagem>).

Onde:
Formato
Instalação
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 77

<imagem>: caminho completo da imagem a ser visualizada


Exemplo:
run btb/btb917zy.p (input "c:\windows\egito.bmp").

BTB917ZZ.P
Permitir a visualização de vídeos do tipo AVI.
Como este programa utiliza os recursos de OCX, é preciso que este OCX
esteja registrado e instalado na máquina que deve ser utilizado. Para fazer esta
instalação proceda da seguinte forma:
 executar o SETUP.EXE, que se encontra no diretório
\INTERFAC\VIDEO\DISK1;
 clicar no botão de 'Ok', quando for solicitado;

 clicar no botão: ;
 clicar em 'Ok', para terminar.
run btb/btb917zz.p (input <video>)
Observações
Formato
Objetivo

Onde:
<vídeo>: caminho completo do vídeo a ser apresentado
Exemplo:
run btb/btb917zz.p (input "c:\windows\help\explorer.avi").

UT-VRBIN.P
Este utilitário pode ser usado sempre que for necessário saber a versão de um
programa compilado (.R).
run utp/ut-vrbin.p (input <arquivo>,
input <acomp>,
output <versao>).

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:
run utp/ut-vrbin.p (input "c:\tmp\cd0101.r",
input no,
output c-versao).

 programa só conseguirá buscar a versão dos programas que foram


construídos conforme os padrões de desenvolvimento da Datasul S.A. e
que utilizem as Técnicas e Templates do Datasul-EMS 2.0;
Observações
Exemplo
Formato
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 79

 a tela de acompanhamento deixa o programa sensivelmente mais lento,


pois faz interações com tela, mas em compensação, deixa o usuário
informado do que está ocorrendo naquele momento;
 se o retorno da versão for "?", o programa não conseguiu obter a versão.
Os principais motivos disto são:
 programa a ser pesquisado não for encontrado;
 programa não está dentro das técnicas e templates do Datasul-EMS
2.0;
 programa não possui a versão internamente.

UT-FINFO.P
Este utilitário pode ser usado sempre que for necessário saber a data, a hora ou
o tamanho de um arquivo no Windows.
run utp/ut-finfo.p (input <arquivo>,
output <data>,
output <hora>,
output <tamanho>).

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
run utp/ut-finfo.p (input "c:\autoexec.bat",
output d-data,
output c-hora,
output i-tam).

Caso o programa não se encontra, o utilitário irá retornar "?", na data e


"00:00:00", na hora.
Exemplo
Formato
Objetivo

UT-CMDLN.P
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.
Esta função pode ser muito útil quando se deseja obter os valores dos
parâmetros da sessão (ini, inp, basekey, etc ...).
run utp/ut-cmdln.p (output <linha-comando>).

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 (output c-linha-comando).

UT-OSVER.P
Esta técnica pode ser usada sempre que for necessário saber informações mais
detalhadas sobre o Sistema Operacional (somente para Windows).
run utp/ut-osver.p (ouput <plataforma>,
output <versao>,
output <release>,
output <build>,
output <extrainfo>).

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, se houver, a versão do
Windows
<release>: variável do tipo inteira que irá receber, se houver, a "release" do
Windows
<build>: variável do tipo inteira que irá receber, se houver, o "build" do
Windows
<extrainfo>: variável do tipo caracter que irá receber informações extras sobre
o Windows (Versão do Service Pack, etc ...)
run utp/ut-osver.p (output c-plataforma,
output i-versao,
output i-release,
Observações
Exemplo
Formato
Utilização
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 81

output i-build,
output c-extrainfo).

I-COUNTDS.I
Descobrir a quantidade de registros numa tabela de acordo a condição passada.
 Quando é necessário determinar a quantidade de registros numa tabela,
evitando que o OWNER seja incluído antes do nome da tabela no
programa compilado, quando o banco de dados é acessado através do
DataServer (veja o item “Como contar a quantidade de registros numa
tabela” no cap. 15).
{include/i-countds.i &BANCO=mgadm
&TABELA=<tabela>
&COND=<condição>
&DEST=<variável> }

Onde:
<variável>: variável que irá armazenar o resultado da consulta.
<condição>: cláusa where que deve ser usada na consulta. Opcional.
<tabela>: tabela que deve ter o número de registros contados.
<banco>: banco de dados onde a tabela se encontra.
DEF VAR iCount AS INT NO-UNDO.
{include/i-countds.i &BANCO=mgadm
&TABELA="cheque-pend"
&COND="WHERE cod-banco > 20"
&DEST=iCount}
message iCount view-as alert-box.

 Utilize apenas se o banco de dados não for PROGRESS, isto é, for


acessado através do DataServer.
 <condição> e <tabela> devem estar entre aspas.
Procedures
Objetivo

UT-WIN.I
A UT-WIN.I define procedures para acesso a funções externas de API’s do
Windows.
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
 ShowWindow
 SystemParametersInfo{&A}
 GetUserName{&A}
Exemplo 321

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 83

Ver nome do usuário logado.


DEFINE VARIABLE chrUserID AS CHARACTER NO-UNDO.
DEFINE VARIABLE intSize AS INTEGER NO-UNDO.

ASSIGN
chrUserID = FILL(' ',256)
intSize = 255.

RUN GetUserName{&A} (INPUT-OUTPUT chrUserID,


INPUT-OUTPUT intSize).

MESSAGE TRIM(chrUserID)
VIEW-AS ALERT-BOX.

Bloquear arraste de janela.


PROCEDURE SupressWindowMove:
/*----------------------------------------------------------------------
Purpose: Disable the MOVE option of the window object.
Parameters: windowHandle – window que não poderá mais ser arrastada
----------------------------------------------------------------------*/

DEFINE INPUT PARAMETER windowHandle AS WIDGET-HANDLE NO-UNDO.

&SCOPED-DEFINE SC_MOVE 61456


&SCOPED-DEFINE MF_BYCOMMAND 0
&SCOPED-DEFINE MF_DELETE 512

DEFINE VARIABLE iHWND AS INTEGER INITIAL 0 NO-UNDO.


DEFINE VARIABLE iMenu AS INTEGER INITIAL 0 NO-UNDO.
DEFINE VARIABLE iResult AS INTEGER INITIAL 0 NO-UNDO.

RUN GetParent (INPUT windowHandle:HWND, OUTPUT iHWND).

RUN GetSystemMenu (INPUT iHWND, INPUT 0, OUTPUT iMenu).

RUN RemoveMenu (INPUT iMenu, INPUT {&SC_MOVE},


INPUT {&MF_BYCOMMAND} + {&MF_DELETE}, OUTPUT iResult).

RUN DrawMenuBar (INPUT iHWND, OUTPUT iResult).


END PROCEDURE.

Remover botões do sistema (maximizar, minimizar, fechar).


Exemplo 4
Objetivo

PROCEDURE RemoveSystemMenuItem:
/*----------------------------------------------------------------------
Purpose: Remove a SystemMenuItem
Parameters: windowHandle – window que terá os itens removidos
itemId - 5 close
3 maximize
2 minimize
----------------------------------------------------------------------*/

DEFINE INPUT PARAMETER windowHandle AS WIDGET-HANDLE NO-UNDO.


DEFINE INPUT PARAMETER itemId AS INTEGER NO-UNDO.

&SCOPED-DEFINE MF_BYPOSITION 1024


&SCOPED-DEFINE MF_REMOVE 4096

DEFINE VARIABLE viWinHWND AS INTEGER INITIAL 0 NO-UNDO.


DEFINE VARIABLE viSysMenu AS INTEGER INITIAL 0 NO-UNDO.
DEFINE VARIABLE viRetCode AS INTEGER INITIAL 0 NO-UNDO.

IF viWinHWND = 0 THEN
RUN GetParent (windowHandle:HWND, OUTPUT viWinHWND).

RUN GetSystemMenu (INPUT viWinHWND, INPUT 0, OUTPUT viSysMenu).

RUN RemoveMenu (INPUT viSysMenu, INPUT itemId,


INPUT {&MF_BYPOSITION} + {&MF_REMOVE},
OUTPUT viRetCode).

RUN DrawMenuBar (INPUT viWinHWND, OUTPUT viRetCode).


END PROCEDURE.

Definir variável de ambiente.


DEFINE VARIABLE intResult AS INTEGER NO-UNDO.

RUN SetEnvironmentVariableA (INPUT "DUMMYVAR",


INPUT "SOME-VALUE",
OUTPUT intResult).

IF intResult = 1 THEN
MESSAGE "Environment Variable Has Been Changed" VIEW-AS ALERT-BOX.
ELSE
MESSAGE "Function Failed. Not Sure Why" VIEW-AS ALERT-BOX.

UT-TRACE.P
Exibir em tela toda a lista de programas e procedures internas executadas até o
ponto de execução deste aplicativo. É semelhante ao stack trace do Progress,
Exemplo
Formato
Utilização

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 85

disponível nas mensagens de erro, com a vantagem que o desenvolvedor pode


escolher o ponto do programa para exibição da pilha de execução.

Pode ser utilizado em qualquer template da datasul, independente do programa


ser Smart ou Thin Template. É necessário incluir no programa a include utp/ut-
trace.i e rodar o utilitário de forma persistente. 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.

RUN utp/ut-trace.p PERSISTENT SET h-trace.


RUN pi-monta-trace IN h-trace (OUTPUT TABLE tt-trace).
RUN utp/trace.w (INPUT TABLE tt-trace).
Exemplo
Formato
Utilização
Objetivo

UT-LOCK.I
Retornar se um registro já está locado na base, substituindo a função LOCKED
do PROGRESS que não funciona corretamente em ambiente ORACLE.
Normalmente utiliza-se um FIND EXCLUSIVE-LOCK com a cláusula NO-
WAIT para buscar um registro que pode estar locado. Dessa forma, o
programa não fica parado no EXCLUSIVE-LOCK esperando o registro ser
liberado. Neste caso utilizávamos a função LOCKED pra confirmar se a
indisponibilidade de dados deve-se ao fato do registro desejado já estar locado
em outra sessão, mas conforme dito anteriormente, esta função não funciona
no ambiente ORACLE. Este utilitário verifica o estado de lock do registro
diretamente no banco ORACLE para garantir esta funcionalidade.

Pode ser utilizado em qualquer template da datasul, independente do programa


ser Smart ou Thin Template. Ou mesmo um fonte qualquer.

{utp/ut-lock.i <banco> <tabela> <tipo_busca> <where_clause>}


<tratamento de retorno com a variável lRetorno>

Onde:
<banco>: nome lógico do banco de dados que contém a tabela.
<tabela>: nome da tabela na qual está se realizando a busca.
<tipo_busca >: a clausula de busca do registro, podendo ser: First Last, Next,
Prev ou Current.
<where_clause>: Opcional. Clausula where de condição de busca do registro.
Para o correto funcionamento do utilitário, deve ser exatamente o mesmo
where clause do FIND realizado com EXCLUSIVE-LOCK e NO-WAIT.
Deve-se definir um pré-processador para armazenar a cláusula do Where pois
em alguns casos a complexidade da consulta não permite que a mesma seja
transferida através da chamada da include.

&GLOBAL-DEFINE WHERE-LOCKED "where it-codigo = "".alan""" ~


+ CHR(10) + "AND cd-planejado = ""0010"""

FIND FIRST ITEM WHERE it-codigo = ".alan"


AND cd-planejado = "0010" EXCLUSIVE-LOCK NO-ERROR NO-WAIT.
Formato
Utilização
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 87

{utp\ut-lock.i mgind ITEM FIRST {&WHERE-LOCKED}}.


CASE lRetorno:
WHEN ? THEN
MESSAGE "Registro não existe"
VIEW-AS ALERT-BOX INFO BUTTONS OK.
WHEN YES THEN
MESSAGE "Registro locado"
VIEW-AS ALERT-BOX INFO BUTTONS OK.
WHEN NO THEN
MESSAGE "Registro livre"
VIEW-AS ALERT-BOX INFO BUTTONS OK.
END CASE.

UT-ZIP.P
Este utilitário faz o tratamento de arquivos zipados, compactando os arquivos
listados em um arquivo denominado zipFileName.
Uma outra aplicação além da compactação dos arquivos listados é a proteção
dos arquivos com uma senha.

Pode ser utilizado em qualquer template da Datasul, independente do


programa ser Smart ou Thin Template. Ou mesmo um fonte qualquer.

run utp\ut-zip.p persistent set h-zip.


run zipFiles in h-zip (input <zipFileName>,
input <tt-listFiles>,
input <logical>,
output <tabela erro>).
Onde:
<zipFileName>: receber o endereço completo do arquivo .ZIP a ser gerado
(Ex.: “c:\tmp\teste.zip”)
<tt-listFiles>: temp-table onde são definidas as informações referentes a cada
um dos arquivos que deve ser inserido no arquivo .ZIP gerado
<logical>: variável que irá Verificar se o arquivo zipFileName pode ser
sobrescrito e se não puder verifica se o arquivo já existe para retornar a
mensagem de erro
<tabela erro>: Temp-table que armazena os erros que ocorreram durante o
processo de compactação, definida na include utp\ut-zip.i

{utp/ut-zip.i}
Exemplo

DEFINE VARIABLE h-zip AS HANDLE NO-UNDO.


RUN utp/ut-zip.p PERSISTENT SET h-zip.
CREATE tt-listFiles.
ASSIGN tt-listFiles.cFile = "c:\temp\teste01.txt".
CREATE tt-listFiles.
ASSIGN tt-listFiles.cFile = "c:\temp\teste02.txt".
RUN zipFiles IN h-zip (INPUT "c:\temp\teste01.zip",
INPUT TABLE tt-listFiles,
INPUT TRUE,
OUTPUT TABLE tt-erros).
FOR EACH tt-erros:
DISP tt-erros.
END.
RUN zipFilesEncrypt IN h-zip (INPUT "c:\temp\teste02.zip",
INPUT TABLE tt-listFiles,
INPUT "senha",
INPUT FALSE,
OUTPUT TABLE tt-erros).
FOR EACH tt-erros:
DISP tt-erros.
END.
Delete procedure h-zip.
Exemplo
Utilização
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 89

UT-GENXML.P
Este utilitário facilita a criação e manipulação de arquivos XML.

O programa que deve ser executado para manipulação de XML é o xmlutp/ut-


genxml.p. A documentação do mesmo encontra-se no capítulo 4 ( Utilizando
API XML ) do arquivo xmlmanual/ ManualConstrucaoAdapters.doc.

UT-VALIDA-FACELIFT.P
Este utilitário verifica: versão, patch e fix do progress instalado na máquina,
ele retorna um campo lógico informando se a estação está apta para executar o
produto com facelift.

O utilitário deve ser chamado por outro programa passando um campo lógico
como parâmetro.

DEF VAR l-aplica-facelift AS LOGICAL NO-UNDO.

RUN utp\ut-valida-facelift.p (OUTPUT l-aplica-facelift).

IF l-aplica-facelift THEN
MESSAGE "Ambiente apto para alicar facelift !" VIEW-AS ALERT-BOX.
ELSE
MESSAGE "Ambiente não apto para alicar facelift !" VIEW-AS ALERT-BOX.

Observações Se o ambiente estiver apto para ser aplicado o facelift a variável l-aplica-
facelift terá valor “True”, caso contrário terá valor “False”.
Exemplo
Utilização
Objetivo

UT-VERIF-RAW.P
Este utilitário verifica se o campo passado por parâmetro é do tipo RAW ou
não. Caso seja do tipo RAW, o utilitário irá retornar "OK". Caso não, retornará
"NOK". Se o banco, tabela ou campo passados como parâmetros não existirem
o retorno será “?”.

O utilitário deve ser chamado por outro programa passando o banco, tabela e
campo como parâmetro.

DEFINE VAR cBanco AS CHAR.


DEFINE VAR cTabela AS CHAR.
DEFINE VAR cAtributo AS CHAR.

Assign cBanco = "shemsfnd"


cTabela = "ped_exec_param"
cAtributo = "raw_param_ped_exec".

RUN utp\ut-verif-raw.p (INPUT cBanco,cTabela,cAtributo).

IF RETURN-VALUE = "OK" THEN


MESSAGE "Campo do tipo RAW"
VIEW-AS ALERT-BOX INFO BUTTONS OK.
ELSE
MESSAGE "Campo do tipo VARCHAR"
VIEW-AS ALERT-BOX INFO BUTTONS OK.

Observações Este utilitário é utilizado, principalmente, em ambientes com banco Oracle


para verificar a necessidade de converter um campo VARCHAR para RAW.
Caso o campo seja do tipo VARCHAR, será necessário converter este campo
para o tipo VARCHAR utilizando o btb\btb928za.p.
Utilização
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 91

BTB962ZZ.P
Permitir a desconexão de um banco de dados específico, gerando logs para
rastreamento (programa e usuário que fizeram a solicitação de desconexão) e
eliminando todos os ALIASES pertinentes.
 Para desconectar um determinado banco de dados;
RUN btb/btb962zz.p (input <ldbname>)

Formato Onde:
<ldbname>: nome lógico do banco de dados que deve ser desconectado

Exemplo:
RUN btb/btb962zz.p (input “mguni”)
View-as Radio-Set

CAPÍTULO 7
Tradução

TRADUÇÃO MONO-IDIOMAS
Este modelo é utilizado até as versões EMS 2.04 e HR 2.07. Acima destas
releases deve ser utilizada a técnica multi-idiomas especificada no próximo
item neste documento.

Tradução de variáveis com view-as nas telas


Para o label do retângulo que emoldura o radio-set e dá significado ao mesmo,
deve-se utilizar a técnica Como implementar labels em retângulos.
Quanto à tradução dos 'radio-buttons' da variável view-as radio-set deve-se
utilizar o include XXINC/I99XX999.I.
Estes includes (XXINC e VARINC) precisam ser multidioma. Quando um
desenvolvedor cria um novo include de dicionário de dados, deve criá-lo no
layout a seguir, conforme exemplo:
/*******************************************************
**
** i01ad047.i campo natureza (conta) - Devedora/Credora
**
********************************************************/
{include/i-lgcode.i}
&IF "{&LANGUAGE-CODE}" = "POR" &THEN
&glob val1 Devedora
&glob val2 Credora
&ENDIF
&IF "{&LANGUAGE-CODE}" = "ESP" &THEN
&glob val1
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 93

&glob val2
&ENDIF
&IF "{&LANGUAGE-CODE}" = "ING" &THEN
&glob val1
&glob val2
&ENDIF
{include/ind01-10.i} {1} {2}}
/* fim */

Observação Foi incorporada uma chamada para um include i-lgcode.i, cujo objetivo é
determinar qual o idioma da instalação do Datasul-EMS 2.0.

Mas, é possível utilizar o radio-set como view-as de variáveis independentes


de campos do dicionário de dados, através da utilização de includes padrões,
de acordo com o roteiro abaixo:
1. Colocar um radio-set na tela (por exemplo, SmartViewer) e definir o seu
'radio-buttons' com valores 'brancos'.
2. Seguir a nomenclatura abaixo para a include que é utilizada para tradução:
Para o Datasul-EMS 2.00: Dentro do diretório VARINC, criar uma include
que tem como padrão de nomenclatura um prefixo "var" e uma seqüência
que vai de 000001 até 09999.
Exemplos: var00001.i
var00002.i
.
.
var09999.i
Para o Datasul-HR 1.00: Dentro do diretório VARINC-RH, criar uma
include que deve ter como padrão de nomenclatura um prefixo "var" e
uma seqüência que vai de 10000 até 19999.
Exemplos: var10000.i
var10001.i
.
.
var19999.i
3. Este include tem o seguinte conteúdo:
/****************************************************
**
** var99999.i Variável: cb-xxx Programa:xxp/xx9999.w
Exemplo

**
*****************************************************/
{include/i-lgcode.i}
&IF "{&LANGUAGE-CODE}" = "POR" &THEN
&glob val1 Devedora
&glob val2 Credora
&ENDIF
&IF "{&LANGUAGE-CODE}" = "ESP" &THEN
&glob val1
&glob val2
&ENDIF
&IF "{&LANGUAGE-CODE}" = "ING" &THEN
&glob val1
&glob val2
&ENDIF
{include/ind01-10.i} {1} {2}}
/* fim */

4. No 'local-initialize', ou em momento próprio, em seu programa, deve-se


carregar o 'radio-buttons' deste radio-set, 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.

View-as Combo-box Inicialmente, a sua utilização deve estar limitada à representação de


campos indicadores do dicionário de dados, e através dos includes
XXINC/I99XX999.I, próprios para este fim.
Os includes de dicionário de dados (XXINC e VARINC) precisam ser
multidioma. Quando um desenvolvedor cria um novo include de dicionário de
dados, deve criá-lo no layout a seguir:
/***********************************************************
**
** i01ad047.i campo natureza (conta) - Devedora/Credora
**
************************************************************/
{include/i-lgcode.i}
&IF "{&LANGUAGE-CODE}" = "POR" &THEN
&glob val1 Devedora
&glob val2 Credora
&ENDIF
&IF "{&LANGUAGE-CODE}" = "ESP" &THEN
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 95

&glob val1
&glob val2
&ENDIF
&IF "{&LANGUAGE-CODE}" = "ING" &THEN
&glob val1
&glob val2
&ENDIF
{include/ind01-10.i} {1} {2}}
/* fim */

Observação Como se pode observar, foi incorporada uma chamada para um


include i-lgcode.i, cujo objetivo é determinar qual o idioma da instalação do
Datasul-EMS 2.0.
Mas, é possível utilizar o combo-box, como view-as de variáveis
independentes de campos do dicionário de dados, através da utilização de
includes padrões, de acordo com o roteiro a seguir:
1. Colocar um combo-box na tela (por exemplo, SmartViewer) e não definir o
seu 'list-items' e 'initial'.
2. Seguir a nomenclatura abaixo para a include que é utilizada para tradução:
Para o Datasul-EMS 2.00: Dentro do diretório VARINC, criar uma include
que tem como padrão de nomenclatura um prefixo "var" e uma seqüência
que vai de 00001 até 09999.
Exemplos: var00001.i
var00002.i
.
.
var09999.i
Para o Datasul-HR 1.00: Dentro do diretório VARINC-RH, criar uma
include que deve ter como padrão de nomenclatura um prefixo "var" e
uma seqüência que vai de 10000 até 19999.
Exemplos: var10000.i
var10001.i
.
.
var19999.i
3. Este include tem o seguinte conteúdo:
/****************************************************
**
** var99999.i Variável: cb-xxx Programa:xxp/xx9999.w
**
*****************************************************/
{include/i-lgcode.i}
&IF "{&LANGUAGE-CODE}" = "POR" &THEN
&glob val1 Devedora
&glob val2 Credora
&ENDIF
&IF "{&LANGUAGE-CODE}" = "ESP" &THEN
&glob val1
&glob val2
&ENDIF
&IF "{&LANGUAGE-CODE}" = "ING" &THEN
&glob val1
&glob val2
&ENDIF
{include/ind01-10.i} {1} {2}}
/* fim */

4. No 'local-initialize', ou em momento próprio, em seu programa, deve-se


carregar o 'list-items' deste combo-box, bem como seu valor inicial
(screen-value):
assign cb-xxx:list-items in frame {&frame-name} =
{varinc/var99999.i 03}
cb-xxx:screen-value in frame {&frame-name} =
{varinc\var99999.i 04 1}.

5. Toda codificação que precisar referenciar o valor de um item do combo-


box, deve ser realizada através do include var99999.i, isto é, não podem
existir referências diretas na forma de string ("") aos itens do combo-box
no fonte. Exemplo:
ERRADO:
if cb-tipo:screen-value in frame {&frame-name} = "Passivo"
then...

CERTO:
if cb-tipo:screen-value in frame {&frame-name} =
{varinc\var99999.i 04 2} then ...

Em ambas as utilizações, ainda resta a tradução do label, então no 'Main-


Block', ou 'Local-initialize', ou ainda, qualquer ponto onde o programa
View-as Toggle-Box
Exemplo:
Column-Labels
Help
e View-
as Fill-in

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 97

execute antes da realização do frame, deve-se implementar lógica que


altere o label do combo-box:
{utp/ut-field.i <banco> <tabela> <campo> <propriedade>}
assign <var-combo-box>:label in frame {&frame-name} =
return-value.

No caso dos toggle-boxes e fill-in´s é necessário preparar a tradução dos


labels, e para isto pode-se usar o include utp/ut-field.i quando se tratar de uma
variável like ou ainda o include utp/ut-liter.i para aproveitar o cadastro de
literais.
Utilizando utp/ut-field.i:
{utp/ut-field.i <banco> <tabela> <campo> <propriedade>}
assign <variável>:label in frame {&frame-name} = return-
value.

Utilizando utp/ut-liter.i:
{utp/ut-liter.i <literal> <modulo> <alinhamento>}
assign <variável>:label in frame {&frame-name} = return-
value.

Sempre que estas variáveis possuam 'help', este deve ter a preparação para
tradução através do include utp/liter.i, conforme o exemplo:
{utp/ut-liter.i <literal> <modulo> <alinhamento>}
assign <variavel>:help in frame {&frame-name} = return-
value.

Espaço Extra para tradução em relatórios


 o tamanho de uma coluna em um layout (down frame) está limitada ao
tamanho do formato do campo ou do label Brasil do mesmo, o que for
maior. Com base nisto, os espaços extras para tradução foram recalculados
para column-labels dos campos no dicionário de dados;
 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, entretanto não
se deve esquecer da possibilidade de tradução.
{utp/ut-liter Total_Pedidos}
assign de-total-pedidos:label in frame f-relat = trim{return-
value}.
Side-Labels

Cliente Descrição Total Pedidos


--------------------------------------
>>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>9,99
>>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>9,99
>>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>9,99

 deve existir o tratamento do espaço extra para tradução, que deve ser
reservado sempre à esquerda do label.
{utp/ut-liter ____Total_Geral}
assign de-total-geral:label in frame f-total = return-value.
Cliente Descrição Total Pedidos
--------------------------------------
>>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>9,99
>>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>9,99
>>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>9,99
____Total Geral: >>.>>>.>>9,99

TRADUÇÃO MULTI-IDIOMAS
Este modelo é utilizado a partir das versões EMS 2.05 e HR 2.08 ou
superiores.

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, e está definida na ISO639-1. Segue
abaixo uma tabela exemplificando as definições de cada sigla para os dialetos
suportados pela Datasul:
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 99

Dialeto Nome idioma/Dialeto


en-US English - United States
es-AR Spanish - Argentina
pt-BR Portuguese - 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, e que
estas customizações podem ser tratadas pelo cliente/distribuidor na forma
como estes julgarem conveniente para sua aplicação, sendo obrigatório como
padrão validado apenas as duas primeiras letras do código do idioma/dialeto.
Quando se comenta em dialeto padrão, este pode ser considerado o próprio
idioma, ou ainda o dialeto que é expedido pela própria Datasul, que atualmente
são en, es e pt, na forma de três arquivos .d presentes na pasta \univdata abaixo
do diretório do produto. Qualquer outro dialeto criado pelo
usuário/distribuidor é considerado dialeto secundário ou customizado, ou ainda
um dialeto qualquer do usuário, que mantém uma relação com o dialeto padrão
através da própria tabela de dialetos do produto, podendo este ser filho de
qualquer dialeto padrão, ou ainda de algum outro dialeto que já é filho de um
dialeto padrão, e assim sucessivamente de acordo com a necessidade definida.
Ex: pt-nr-fm - Português Nordestino das indústrias farmacêuticas. Podemos
dizer aqui então que o pt-nr-fm é filho de pr-nr, e pr-nr é filho de pt.

Importante Para que o produto saiba que dialeto trabalhar na sessão corrente, existe na tabela
de usuários um campo chamado cod_dialeto que irá armazenar a informação do dialeto do
usuário, sendo possível com isto em uma mesma instalação do produto vários usuários
acessando com um idioma/dialeto diferente.

Quando o usuário realiza o login no EMS/HR, 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. Caso queira-se tratar/consultar
esta variável de alguma forma em algum programa, basta defini-la conforme
segue abaixo:
define new global shared var v_cod_dialet_corren as char no-
undo.
Pontos de tradução

No modelo de tradução Multi-Idiomas, para os programas que possuem telas,


sejam estes SmartObjects ou ThinTemplates, foram criados o que chamamos
de pontos de traduçã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, ou
seja, nestes pontos, um utilitário é chamado e este identifica todos os objetos
dispostos em tela, identifica todos as propriedades destes objetos que são
passíveis de tradução, como labels, tooltip's, help's, etc, e realiza uma chamada
automática ao ut-liter para sua posterior atribuição ao valor retornado. Tudo o
que está em tela e que está antes deste ponto de tradução, não é necessário que
seja realizado nenhum tipo de intervenção manual. Caso tenha-se alguma
atribuição em tela para atributos de objetos passíveis de tradução após estes
pontos, este deverá ser trabalhado para que se inclua uma chamada ao utilitário
ut-liter.p e posterior atribuição ao atributo em questão pelo valor retornado
através do return-value.

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, foi adicionado um conceito de contexto


de tradução. Este contexto pode ser usado de forma idêntica ao utilizado na
versão anterior do ut-liter, através da sigla do módulo, mas não fica
necessariamente limitado a esta contextualização, podendo ser definido
qualquer tipo de semântica que se julgue necessário para o módulo/programa
do produto que se está trabalhando. Caso, durante a análise para a construção
do programa, seja verificado que não existe a necessidade da criação de uma
nova contextualização de Strings, mesmo passando-se o caracter "*" para o
utilitário de tradução ut-liter em tempo de desenvolvimento, este programa irá
disponibilizar um contexto automático para o cliente/usuário em tempo de
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 101

execução, este contexto automático disponibilizado é pela sigla do módulo.


Isto para que o cliente/distribuidor possa realizar suas customizações, caso
julgar necessário, 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.p. Após este cadastro, 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.

Nota Ver sobre seqüência de busca a seguir neste documento

O caracter "*" é considerado para fins de tradução, o contexto genérico das


strings.

Itens de Tradução

Para a técnica de tradução Multi-Idiomas, foi criado um conceito de itens de


tradução, onde cada um destes itens possui uma característica que deve ser
levada em consideração no momento da inclusão de novas strings, bem como
no momento da customização dos termos em telas do produto.
Hoje existem 9 itens de tradução, sendo que estes itens, suas características, e
codificação dentro da tabela de strings externas estão descritos a seguir neste
documento. Estes itens estão todos armazenados dentro de uma tabela
chamada string_ext_produt, sendo sua chave composta pelo dialeto, contexto,
seu ID e a Origem String, 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
aplicativos
Datasul
2 modul_dtsul des_modul_dtsul Tabela que armazena os
módulos
Datasul
3 procedimento des_proced Tabela que armazena os
procedimentos Datasul
4 produt_dtsul des_produt_dtsul Tabela que armazena os
produtos Datasul
5 rot_dtsul des_rot_dtsul Tabela que armazena as
rotinas Datasul
6 sist_dtsul des_sist_dtsul Tabela que armazena os
sistemas Datasul
7 sub_rot_dtsul des_sub_rot_dtsul Tabela que armazena as sub-
rotinas Datasul
8 cad-msgs cd-msg Tabela que armazena as
mensagens dos produtos
Datasul

9 cad-literal cod-literal Tabela que armazena as


Literais dos produtos Datasul*

* Os registros com este último indicador ainda armazenam mais algumas


informações relevantes para o produto, como títulos dos programas em todos
os idiomas, e também todas as strings presentes nos bancos de dados do
produto, como labels, descrições dos campos e tabelas, help's, etc. Sendo que
para as strings em bancos, a chave buscada sempre seguirá a seguinte forma:
Para Tabela: banco.tabela.propriedade
Ex: mguni.cad-literal.desc - Com esta chave você encontra a
tradução no dialeto desejado para a descrição da tabela cad-literal no banco
mguni. Esta chave é utilizada pelo utilitário ut-table.p, que será abordado ainda
neste documento.
Para Campo: banco.tabela.campo.propriedade
Ex: mguni.cad-literal.cod-literal.label - Com esta chave você
encontra a tradução no dialeto desejado para o label do campo cod-literal, na
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 103

tabela cad-literal no banco mguni. Esta chave é utilizada pelo utilitário ut-
field.p, que será abordado ainda neste documento.

Sequência de busca

Após verificarmos alguns conceitos sobre o modelo de tradução Multi-


Idiomas, desde sua nomenclatura, os pontos de tradução dentro dos programas,
o que são contextos dentro deste novo processo, e os itens de tradução que
estão englobados por esta técnica, é necessário que se consiga visualizar como
isto irá funcionar de forma prática dentro dos programas, dentro dos módulos
dos produtos Datasul. Para isto, foi definida uma sequência de busca que visa
disponibilizar uma hierarquia de Dialetos, contextos e strings no intuito de
facilitar a customização e o entendimento por parte dos usuários e
desenvolvedores da funcionalidade. Com isso, 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, ut-msgs, ut-ltmnu), a
sequência de busca utilizada é a que segue:

Seqüência Dialeto Padrão Dialeto Usuário Contexto


1 X  Contexto
informado/módulo
2 X  Contexto Genérico (“*”)
3  X Contexto
informado/módulo
4  X Contexto Genérico (“*”)

Através desta hierarquia de busca, é possível o cliente/distribuidor fazer


qualquer tipo de customização de termos de negócio que julgar necessário,
seja por região geográfica, por segmentação de mercado, por departamento
funcional, ou qualquer outro tipo de separação de termos que julgar
conveniente. Com as funcionalidades deste modelo de tradução abordado,
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 à
Utilização
Objetivo

tradução nos produtos Datasul. A seguir neste documento descrição destes


programas/situações com o objetivo de facilitar/tornar sua implementação o
mais simples possível.

UT-TRCAMPOS.P
Realizar tradução automática de telas. Este programa tem a função de
pesquisar todos os objetos de uma tela Progress baseado em sua Window,
através da hierarquia existente, e realizar a chamada ao utilitário ut-liter.p para
que sejam feitas as devidas traduções da interface. Este utilitário reconhece
todas as frames que são filhas da window, e traduz todas os objetos presentes
nestas frames automaticamente.
É utilizado nos dois pontos de tradução dentro das templates:
 InitializeInterface nas ThinTemplates
 Adm-Initialize nos Smart Objects quando existe container definido.
Caso exista uma window que não seja de uma template padrão Datasul, 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.
Este programa não espera nenhum parâmetro de entrada, e deve ser chamado
diretamente através do fonte.
Ex: run utp/ut-trcampos.p.

UT-TRFRRP.P
Difere do anterior porque realiza tradução automática de uma única frame,
apenas. Busca os itens de tradução apenas na hierarquia da frame que foi
passada como parâmetro, buscando os objetos passíveis de tradução e
realizando então a chamada ao ut-liter.p e posterior atribuição do valor
traduzido retornado à estes objetos, de forma automática.
Pode ser utilizado para traduzir Dialog-frames, frames de relatório, ou
qualquer outra frame que se julgue necessário.
Utilização
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 105

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, não
podendo nestes casos ser utilizado o utilitário anterior (ut-trcampos.p).
Ex: run utp/ut-trfrrp.p (input frame f-parametros:handle).

Obs: Quando o programa for um relatório, existe um filtro no RTB que caso o
programa não possua nenhuma chamada a este utilitá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, ou
seja, antes da include i-rpout.i ou i-rpcab.i respectivamente, dependendo da
estrutura do programa.

UT-LSTIT.P
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, para que
possa ser utilizado no programa chamador. 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.
Deverá ser utilizado sempre quando da necessidade de uma conversão de
valores de um objeto Progress não indexado para valores indexados, ou ainda,
converter valor de LIST-ITEMS para LIST-ITEM-PAIRS.
Sua utilização deve ser da seguinte forma:
Sintaxe: run utp/ut-lstit.p (input-output cLista).

Onde cLista deve ser uma lista separada por "," provinda de uma das seguintes
situações:
 Include de domínio;
 Valor populado de um for each;
 List-items de um campo (Este apenas caso ainda não tenha passado pelos
pontos de tradução, ou já tenha passado e necessita ser repopulado devido
a uma lógica de negócio);
 Sub-programa;
Utilização
Objetivo

 Qualquer fonte que gere uma lista separada por vírgula e que este será
utilizada em algum objeto Progress não-indexado (Combo-Box, Selection-
List).
O programa irá retornar na mesma variável informada os valores já indexados
e traduzidos, conforme exemplo abaixo:
Valor cLista antes: “casado,solteiro”
Valor cLista depois: “married,casado,single,solteiro”

Podendo a atribuição ao objeto Progress indexado ser realizada da seguinte


forma:
assign combo-box:list-item-pairs = cLista. /* para combo-box
*/
assign select-list:list-item-pairs = cLista. /* para
Selection-Lits */

Importante Com a técnica de tradução Multi-Idiomas, tudo o que antes era LIST-ITEMS, é
automaticamente convertido para LIST-ITEM-PAIRS nos pontos de tradução pelos programas já
mencionados, com isso, qualquer referência a LIST-ITEMS destes campos após os pontos de
tradução, deverão ser retrabalhados para tratar a partir de agora, LIST-ITEM-PAIRS, tendo este
utilitário como facilitador para esta implementação. Qualquer dúvida adicional, verificar o item
abaixo que trata sobre LIST-ITEMS.

UT-LITER.P
Utilitário já existente em releases anteriores dos produtos EMS 2 e HR. Este
sofreu alterações para contemplar as novas funcionalidades do modelo de
tradução Multi-Idiomas, como novo conceito de contextualização, hierarquia
de busca e dialetos das Strings.
Para que não fosse gerado nenhum tipo de impacto sobre todo o legado de
programas com o antigo modelo do ut-liter, seu forma de chamada e
parâmetros não foram alterados, mantendo o padrão já conhecido e definido
neste manual.
Sintaxe: {utp/ut-liter.i <Literal> <Contexto> <Alinhamento>}

Sendo que nesta nova ut-liter, o alinhamento não irá gerar nenhum tipo de
diferença no comportamento da string de retorno, mantida apenas para fins de
compatibilidade. Para evitar problemas com este parâmetro, sempre passá-lo
Utilização
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 107

com valor em branco ("") caso utilizando o programa .p, ou simplesmente não
passar, caso utilizando a include, conforme exemplos abaixo:
Ex: run utp/ut-liter.p (input “Teste”,”*”,””).
{utp/ut-liter Teste *}

Onde “Teste” é a literal sendo passada, e "*" é o contexto, sendo este


considerado o contexto genérico, não sendo passado nada para o terceiro
parâmetro, que seria o alinhamento, considerado então como branco.
Importante No modelo de tradução Multi-Idiomas, 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. Outra regra importante é que strings que possuem espaços em branco, estes espaços
devem ser convertidos para "_" antes da chamada a ut-liter.p. Ex: {utp/ut-liter.i Teste_agora *}
OBS.: Se a literal passada terminar com “:U” a literal não será traduzida e a mesma será
retornada sem os dois últimos caracteres.

UT-MSGS.P
Utilitário já existente em releases anteriores dos produtos EMS 2 e HR,
utilizado para apresentar as mensagens dos produtos Datasul. 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.
Para manter compatilidade com o legado existente nos produtos, sua sintaxe
foi mantida inalterada, conforme segue abaixo:
Sintaxe: run utp/ut-msgs.p (input <ação>
input <número da mensagem>
input <parâmetros>).

Onde:
<ação> é a ação que será tomada pelo programa, podendo ser "show" para
mostrar, "msg" para retornar a mensagem, e "help" para retornar o help da
mensagem.
<número da mensagem> é o número da mensagem
<parâmetros> São os parâmetros a serem substituídos na mensagem
Utilização
Objetivo

Maiores detalhes podem ser consultados na referência geral deste utilitário


neste documento.

UT-FIELD.P
Utilitário já existente em releases anteriores dos produtos EMS 2 e HR.
Utilizado para retornar valores das propriedades dos campos do dicionário de
dados, como label, description, etc. 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, e sim diretamente na tabela de strings
externas do produto, baseando-se na chave banco.tabela.campo.propriedade,
conforme mencionado em itens de tradução neste documento.
Foi mantido basicamente para não gerar incompatibilidade com o legado
existente nos produtos, mas pode ser totalmente substituído pelo ut-liter,
devido sua maior facilidade de identificação e customização futura pelo
usuário.
Sua sintaxe não foi alteradada, sendo ainda:
{utp/ut-field.i banco tabela campo propriedade}

onde propriedade pode ser:


Propriedade Descrição Observação
1 Label
2 Column-Label
3 Help
4 Format Continua
buscando do
banco
5 Initial Continua
buscando do
banco
6 Description

Ex: {utp/ut-field.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.
Nota Onde Existe a frase “Continua buscando do banco”, significa que o comportamento do
utilitário não foi alterado, mantendo a mesma funcionalidade da implementação anterior.
Utilização
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 109

UT-TABLE.P
Utilitário já existente em releases anteriores dos produtos EMS 2 e HR.
Utilizado para retornar valores de propridades das tabelas do dicionário de
dados, como desc, label, etc. 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, e sim diretamente na tabela de strings externas do
produto, baseando-se na chave banco.tabela.propriedade, conforme citado em
itens de tradução neste documento.
Foi mantido basicamente para não gerar incompatibilidade com o legado
existente nos produtos, mas pode ser totalmente substituído pelo ut-liter,
devido sua maior facilidade de identificação e customização futura pelo
usuário.
Sua sintaxe não foi alteradada, sendo ainda:
{utp/ut-table.i <banco> <tabela> <propriedade>}

onde propriedade é:
Propriedade Descrição Observação
1 File-Label
2 Dump_name Continua
buscando do
banco
3 Desc

Ex: {utp/ut-table magadm conta 1}

Este exemplo irá retornar o label da tabela conta do banco mgadm no dialeto
do usuário.
Nota Quando comentado "Continua buscando do banco", isto quer dizer que o programa não
está buscando o valor das strings externas, e sim continua buscando do schema do banco atual
que está conectado a sessão, como a versão anterior já realizava.

UT-LTMNU.P
Novo utilitário criado para a tradução de todos os itens de menu (Itens de
tradução de 1 a 7). Este utilitário realiza a busca na tabela de strings externas,
Utilização

dos respectivos itens de menu, e retorna sua tradução para o programa


chamador.
Para este programa é passado como parâmetro 4 valores, sendo estes:
 Origem String substituindo os espaçõs em branco por "_".
 Contexto desejado. Neste caso, normalmente "*" (Contexto Genérico)
 Identificador da String (Os itens de menu estão entre 1 e 7).
 Identificador String de retorno - Para os itens de menu, existe nestas
tabelas além das descrições dos respectivos itens nos dialetos suportados,
também o nome de menu utilizado para que estes itens sejam apresentados
no produto. Este identificador tem o objetivo de indicar qual a string que o
desenvolvedor requer que seja retornado pelo utilitário, tendo para este
parâmetro dois possíveis valores:
Parâmetro Retorno
1 Descrição do Item de Menu
Traduzido
2 Descrição do nome de menu do
item de menu traduzido.

Sintaxe: run utp/ut-ltmnu.p (input r


replace(<des_item_menu>," ","_"),
Input <contexto>,
Input <Identificador>,
Input <IndStringRetorno>).

Ex: utp/ut-ltmnu.p (input replace(des_modul_dtsul,


" ","_"),
"*",
2,
1).

Este exemplo irá retornar a descrição do respectivo módulo Datasul no dialeto


do usuário através do RETURN-VALUE.
View-as Radio-Set

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 111

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, como selection-list's e
combo-box's, e ainda para não gerar muitos impactos sobre o modelo de
tradução mono-idiomas, nos pontos de tradução acima citados através da ut-
trcampos (InitializeInterface e Adm-Initialize), todos os objetos que utilizavam
LIST-ITEMS nos programas passaram a ser automaticamente convertidos para
LIST-ITEM-PAIRS, indexando este objeto sempre pelo seu valor original
normalmente em Português, fazendo com que esta alteração não gere maiores
impactos sobre lógicas de negócio utilizadas nos programas. Caso um destes
objetos Progress não-indexados for referenciado via LIST-ITEMS após estes
pontos de tradução, será apresentada uma mensagem Progress de erro que
evidencia a necessidade de troca de LIST-ITEMS para LIST-ITEM-PAIRS
(Erro 7454). Neste caso, deverá ser utilizado o utilitário ut-lstit.p explicado
acima neste documento para realizar o devido tratamento e sua troca de list-
items para list-item-pairs.

Tradução de variáveis com view-as nas telas


Para o label do retângulo que emoldura o radio-set e dá significado ao mesmo,
pode-se utilizar a técnica Como implementar labels em retângulos. Mas no
caso da funcionalidade multi-idiomas, isto não é obrigatório devido aos
tradutores automáticos de telas já realizarem esta tradução de forma
automática.
Para popular o valor de ‘radio-buttons’ da variável view-as radio-set pode-se
utilizar o include XXINC/I99XX999.I mas não necessariamente, podendo
estes serem realizados diretamente com os valores em Português, devido ao
modelo de tradução Multi-Idiomas contemplar sua tradução de forma
automática em tela.
Estes includes (XXINC e VARINC) precisam ser idioma Português. Quando
um desenvolvedor cria um novo include de dicionário de dados, deve criá-lo
no layout a seguir, conforme exemplo:
/*******************************************************
**
** i01ad047.i campo natureza (conta) - Devedora/Credora
**
********************************************************/
&glob val1 Devedora
&glob val2 Credora
{include/ind01-10.i} {1} {2}}
/* fim */

Observação Na versão anterior a multi-idiomas, era necessário a include i-lgcode para


determinar o idioma. Neste novo modelo tal referência não é mais necessária, pois nesta tem-se
uma única instalação com suporte a multi-idiomas.

Mas, é possível utilizar o radio-set como view-as de variáveis independentes


de campos do dicionário de dados, através da utilização de includes padrões,
de acordo com o roteiro abaixo:
1. Colocar um radio-set na tela (por exemplo, SmartViewer) e definir o seu
'radio-buttons' com valores 'brancos'.
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.05: Dentro do diretório VARINC, criar uma include
que tem como padrão de nomenclatura um prefixo "var" e uma seqüência
que vai de 000001 até 09999.
Exemplos: var00001.i
var00002.i
.
.
var09999.i
Para o Datasul-HR 2.08: Dentro do diretório VARINC-RH, criar uma
include que deve ter como padrão de nomenclatura um prefixo "var" e
uma seqüência que vai de 10000 até 19999.
Exemplos: var10000.i
var10001.i
.
.
var19999.i
3. Este include tem o seguinte conteúdo:
/****************************************************
**
** var99999.i Variável: cb-xxx Programa:xxp/xx9999.w
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 113

**
*****************************************************/
&glob val1 Devedora
&glob val2 Credora
{include/ind01-10.i} {1} {2}}
/* fim */

4. No 'local-initialize' antes do dispatch da ADM deve-se carregar o 'radio-


buttons' deste radio-set, 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} =

View-as Combo-box
"1":U.

Inicialmente, a sua utilização deve estar limitada à representação de campos


indicadores do dicionário de dados, e através dos includes
XXINC/I99XX999.I, próprios para este fim.
Os includes de dicionário de dados (XXINC e VARINC) precisam ser sempre
em Português. Quando um desenvolvedor cria um novo include de dicionário
de dados, deve criá-lo no layout a seguir:
/***********************************************************
**
** i01ad047.i campo natureza (conta) - Devedora/Credora
**
************************************************************/
&glob val1 Devedora
&glob val2 Credora
{include/ind01-10.i} {1} {2}}
/* fim */

Observação Na versão anterior a multi-idiomas, era necessário a include i-lgcode para


determinar o idioma. Neste novo modelo tal referência não é mais necessária, pois nesta tem-se
uma única instalação com suporte a multi-idiomas.

Mas, é possível utilizar o combo-box, como view-as de variáveis


independentes de campos do dicionário de dados, através da utilização de
includes padrões, de acordo com o roteiro a seguir:
1. Colocar um combo-box na tela (por exemplo, SmartViewer) e não definir o
seu 'list-items' e 'initial'.
2. Seguir a nomenclatura abaixo para a include que é utilizada para tradução:
Para o Datasul-EMS 2.05: Dentro do diretório VARINC, criar uma include
que tem como padrão de nomenclatura um prefixo "var" e uma seqüência
que vai de 00001 até 09999.
Exemplos: var00001.i
var00002.i
.
.
var09999.i
Para o Datasul-HR 2.08: Dentro do diretório VARINC-RH, criar uma
include que deve ter como padrão de nomenclatura um prefixo "var" e
uma seqüência que vai de 10000 até 19999.
Exemplos: var10000.i
var10001.i
.
.
var19999.i
3. Este include tem o seguinte conteúdo:
/****************************************************
**
** var99999.i Variável: cb-xxx Programa:xxp/xx9999.w
**
*****************************************************/
&glob val1 Devedora
&glob val2 Credora
{include/ind01-10.i} {1} {2}}
/* fim */

4. No 'local-initialize' antes do dispatch do método ADM, ou em momento


posterior utilizando-se o utilitário ut-lstit.p, em seu programa, deve-se
carregar o 'list-items' deste combo-box, bem como seu valor inicial
(screen-value):
assign cb-xxx:list-items in frame {&frame-name} =
{varinc/var99999.i 03}
cb-xxx:screen-value in frame {&frame-name} =
{varinc\var99999.i 04 1}.
Exemplo:
Column-Labels

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 115

Importante Apenas antes do método DISPATCH do procedure Adm-Initialize é possível


implementação com LIST-ITEMS. Após este ponto, é necessário a utilização do utilitário ut-
lstit.p para sua devida conversão para LIST-ITEM-PAIRS.

5. Toda codificação que precisar referenciar o valor de um item do combo-


box, deve ser realizada através do include var99999.i, isto é, não podem
haver referências diretas na forma de string ("") aos itens do combo-box
no fonte. Exemplo:
ERRADO:
if cb-tipo:screen-value in frame {&frame-name} = "Passivo"
then...

CERTO:
if cb-tipo:screen-value in frame {&frame-name} =
{varinc\var99999.i 04 2} then ...

O seu label será automaticamente tratado pelo tradutor automático de


telas presente nas templates, e o valor será a referência em Português
presente na include, não gerando problemas com lógica de negócio.

Espaço Extra para tradução em relatórios


 tamanho de uma coluna num layout (down frame) está limitada ao
tamanho do formato do campo ou do label do mesmo, o que for maior.
Com base nisto, os espaços extras para tradução foram recalculados para
column-labels dos campos no dicionário de dados;
 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, entretanto não
se deve esquecer da possibilidade de tradução.
{utp/ut-liter Total_Pedidos}
assign de-total-pedidos:label in frame f-relat = trim{return-
value}.
Cliente Descrição Total Pedidos
--------------------------------------
>>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>9,99
>>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>9,99
>>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>9,99
Side-Labels

 deve existir o tratamento do espaço extra para tradução, que deve ser
reservado sempre à esquerda do label.
{utp/ut-liter.i Total_Geral}
assign de-total-geral:label in frame f-total = return-value.
Cliente Descrição Total Pedidos
--------------------------------------
>>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>9,99
>>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>9,99
>>>>>9 XXXXXXXXXXXXXXXX >.>>>.>>9,99
____Total Geral: >>.>>>.>>9,99

PRÁTICAS PARA IMPLEMENTAÇÃO MULTI-IDIOMAS

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.
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.

Caso Prático Diferenças LIST-ITEMS para LIST-ITEM-PAIRS


Este primeiro caso prático está relacionado com a utilização de LIST-ITEM-
PAIRS e suas diferenças em relação à utilização com LIST-ITEMS.
A seguir uma lógica que era antes realizada com LIST-ITEMS, e algumas
observações:
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 117

assign cb-tp-oper-terc:list-items in frame fPage1 = "Remessa


Beneficiamento",
"Retorno Beneficiamento",
”Remessa Consignação",
"Faturamento Consignação",
"Devolução Consignação",
"Reajuste Preço",
"Drawback" .
ASSIGN cb-tp-oper-terc:screen-value in frame fPage2 = entry(tt-
natur-oper.tp-oper-terc,cb-tp-oper-terc:list-items in frame
fPage2,",").

Se o campo tt-natur-oper.tp-oper-terc ter o valor 2 trará com SCREEN-VALUE


"Retorno Beneficiamento".

ASSIGN tt-natur-oper.tp-oper-terc = lookup(cb-tp-oper-terc,cb-


tp-oper-terc:list-items in frame fPage2,",").

Se o usuário informar na tela "Remessa Consignação" gravará o valor no


campo tt-natur-oper.tp-oper-terc como 3. Agora, esta mesma lógica depois de
convertida para LIST-ITEM-PAIRS, seja esta conversão feita de forma direta
no programa ou através do utilitário ut-lstit.p, será apresentada como segue:

assign cb-tp-oper-terc:LIST-ITEM-PAIRS in frame fPage1


= "Remessa Beneficiamento","Remessa Beneficiamento",
"Retorno Beneficiamento","Retorno Beneficiamento",
"Remessa Consignação","Remessa Consignação",
"Faturamento Consignação","Faturamento Consignação",
"Devolução Consignação","Devolução Consignação",

"Reajuste Preço","Reajuste Preço",


"Drawback","Drawback" .
ASSIGN cb-tp-oper-terc:screen-value in frame fPage2 =
entry(tt-natur-oper.tp-oper-terc,cb-tp-oper-terc:list-items in
frame fPage2,",").

Se o campo tt-natur-oper.tp-oper-terc ter o valor 2 trará com SCREEN-VALUE


"Remessa Beneficiamento".

ASSIGN tt-natur-oper.tp-oper-terc = lookup(cb-tp-oper-


terc,cb-tp-oper-terc:LIST-ITEM-PAIRS in frame fPage2,",").

Se o usuário informar na tela "Remessa Consignação" gravará o valor no


campo tt-natur-oper.tp-oper-terc como 6. Apenas tomar o cuidado de sempre
gravar o valor par, que é o valor indexador do campo. Caso seja retornado o
valor impar, será necessário acresce-lo em 1 unidade, devido este estar
repetido, principalmente em sessões que estão executando em Português.
A questão principal neste trecho é a necessidade de analisar onde a tt-natur-
oper.tp-oper-terc é populada, 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, que alteraria de 3 para 6
no primeiro caso.
 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, no caso 3. Neste caso, é necessário realizar
alguns tratamentos para contemplar qualquer idioma sendo executado pelo
produto, conforme abaixo:

define variable tp-oper-terc as int init 2. /* Valor arbitrado


para fins de demonstração */
define variable cb-tp-oper-terc as char format "x(30)" view-as
combo-box list-items "".
define frame fPage1
cb-tp-oper-terc.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 119

assign cb-tp-oper-terc:LIST-ITEM-PAIRS in frame fPage1 =


"Remessa Beneficiamento,Remessa Beneficiamento,Retorno
Beneficiamento,Retorno Beneficiamento,Remessa
Consignação,Remessa Consignação,Faturamento
Consignação,Faturamento Consignação,Devolução
Consignação,Devolução Consignação,Reajuste Preço,Reajuste
Preço,Drawback,Drawback".
/* Considerando que esta temp-table tt-natur-oper.tp-oper-terc
sempre estará armazenando os valores como não indexados, ou
seja, ainda utilizando list-items para a sua gravação, caso
contrário, 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,cb-tp-oper-terc:list-item-pairs in frame
fPage1,",").
update cb-tp-oper-terc with frame fPage1.
If lookup(cb-tp-oper-terc:screen-value,cb-tp-oper-terc:LIST-
ITEM-PAIRS in frame fPage1,",") mod 2 <> 0 Then
ASSIGN tp-oper-terc = (lookup(cb-tp-oper-terc:screen-
value,cb-tp-oper-terc:LIST-ITEM-PAIRS in frame fPage1,",") +
1) / 2.
else ASSIGN tp-oper-terc = lookup(cb-tp-oper-terc:screen-
value,cb-tp-oper-terc:LIST-ITEM-PAIRS in frame fPage1,",") / 2.

Para estes casos é necessário definir qual a melhor forma de implementação


realizando uma análise do caso. Deixamos como sugestão, analisando-se o fato
que as manutenções estarão sendo realizadas em WorkSpaces de releases que
já estão no mercado, utilizar a lógica com gravação do valor da temp-table
ainda tomando como base o valor não-indexado, evitando assim erros com
lógicas de negócio deste mesmo programa sendo utilizado em releases
anteriores.
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-ITEM-PAIRS


Quando da necessidade de atribuir valores a algum objeto Progress não-
indexado em tela após os pontos de tradução, seguir o modelo de construção
abaixo:
Antes:
assign cb-combo:list-items = {varinc/var00002.i 04 02}

Depois:
&if "{&FNC_MULTI_IDIOMA}" = "Yes" &then
assign cLista = {varinc/var00002.i 04 02}.
run utp/ut-lstit.p (input-output cLista).
assign cb-combo:list-item-pairs = cLista.
&else
assign cb-combo:list-items = {varinc/var00002.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, mantendo inclusive a
lógica anterior no sentido de não gerar impacto sobre releases já liberadas
comercialmente.

Tradução automática em frame de relatório

Para este caso, 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. Para
isto, deverá realizar sua chamada ou imediatamente após a definição da frame
ou antes da realização do display da frame. Segue abaixo um exemplo de sua
aplicação:

form
skip(2)
c-lit-selecao no-label colon 55
skip(1)
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 121

tt-param.tp-etiq-ini format "zzzzzzzzz9" colon 60 "|<


>|"
tt-param.tp-etiq-fim format "zzzzzzzzz9" no-label
skip(1)
c-lit-impressao no-label colon 55
skip(1)
c-destino colon 60 "-"
tt-param.arquivo no-label format "x(30)"
with side-label stream-io width 132 frame f-fim.

&IF "{&FNC_MULTI_IDIOMA}" = "Yes" &THEN


Run utp/ut-trfrrp.p (input Frame f-fim:Handle).
&ENDIF

Traduzir valor armazenado em uma variável

Para tradução de valores em variáveis, ao invés de utilizar a include ut-liter.i, é


necessário utilizar o programa .p associado a esta include. Segue exemplo
abaixo:
define variable c-destino as char init "Destino Impressão" no-
undo.
run utp/ut-liter.p (input replace(c-destino," ","_"),"*","").
assign c-destino = return-value.
disp c-destino.

Importante Sempre passar valores fixos e de variáveis substituindo-se o " " (Branco) por "_"
(underline).
Implementação
Objetivo

Tratando lista enorme de tradução em includes


Evitar a ocorrência do erro ** More than 32000 characters in a single
statement--use -inp parm. (135) na compilação de programas que incorporam
includes de tradução para uma lista muito longa de valores. O erro 135 do
Progress é devido ao limite de 32.000 caracteres para uma única atribuição de
valores. As includes da pasta VARINC geralmente são utilizadas dessa forma:

ASSIGN c-lista-retencao = ENTRY(1,TRIM({varinc/var00137.i 03})).

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. Para evitar isso foi
desenvolvida esta técnica que modifica a forma de chamada das includes
varinc, além de mudar a estrutura das includes responsáveis pelo retorno.
Todas as includes da nomenclatura varinc/var99999.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, que pode ser um list-items de
COMBO-BOX, valores para RADIO-BUTTON, um único elemento da lista,
entre outros. 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
programa que incorpora a include. Sendo assim é necessário alterar a include
de retorno para gravar na variável desejada os valores um por vez. Para tal, é
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.
As alterações desta técnica exigem um grande trabalho para adequar a include
de retorno na proposta das temp-table, porque é necessário popular a tabela
com os valores, sendo necessário incluí-los um a um. Em compensação, o
trabalho de manipulação dos valores para retorno diminui, 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.
As includes de retorno trabalham com 7 tipos de retorno atualmente:
1. View-as combo-box
2. View-as radio-set
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 123

3. Lista com os itens separados por virgula


4. Retorna o item n da lista
5. Retorna o numero de itens da lista
6. Retorna a posição do item (número)
7. Valores para a propriedade Radio-Buttons de uma Radio-Set

Para cada um desses tipos de retorno, é necessário ler a temp-table que contém
os valores da lista. Esta temp-table deve ser definida dessa forma:

DEFINE TEMP-TABLE tt-list-items NO-UNDO


FIELD posicao AS INT.
FIELD val-item AS CHAR

Em seguida, a temp-table deve ser populada com os valores dos pré-


processadores:

CREATE tt-list-items.
ASSIGN tt-list-items.val-item = "{&val1}"
tt-list-items.posicao = 1.

CREATE tt-list-items.
ASSIGN tt-list-items.val-item = "{&val2}"
tt-list-items.posicao = 2.
.
.
.
.
.
CREATE tt-list-items.
ASSIGN tt-list-items.val-item = "{&val250}"
tt-list-items.posicao = 250.

Abaixo segue lista de tarefas para implementação da técnica, 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.

DEF VAR l-log AS LOG INITIAL FALSE NO-UNDO.

FOR EACH tt-list-items BY posicao:

IF l-log = NO THEN DO:


ASSIGN c-lista = tt-list-items.val-item.
ASSIGN l-log = TRUE.
END.
ELSE
ASSIGN c-lista = c-lista + "," + tt-list-
items.val-item.

END.

Neste tipo de retorno o programa precisa estar preparado para ler a


variável c-lista.

 Tratamento para o retorno do item n da lista:

FIND LAST tt-list-items WHERE posicao = {2}.


ASSIGN c-lista = tt-list-items.val-item.

O parametro {2} utilizado contém o indice do item desejado e é


passado como parâmetro para a include de retorno.

 Tratamento para retornar o número total de itens na lista:

FIND LAST tt-list-items.


ASSIGN c-lista = STRING(tt-list-items.posicao).

Como a temp-table que armazena os itens possui um campo chamado


“posicao”, sendo os valores gravados em ordem seqüencial, basta ler o
campo posição do ultimo registro da temp-table para saber o número
total de itens.

 Tratamento para retornar a posição de um item na lista:

DEF VAR c-chave AS CHAR NO-UNDO.

ASSIGN c-chave = "{2}".


APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 125

FIND FIRST tt-list-items WHERE val-item = c-chave NO-


LOCK NO-ERROR.

IF AVAIL tt-list-items THEN


ASSIGN c-lista = STRING(tt-list-items.posicao).
ELSE
ASSIGN c-lista = ?.

Neste tratamento também utilizamos o parâmetro {2} para localizar o


item na temp-table, sendo que dessa vez o parâmetro irá conter o
próprio item. Uma vez localizado esse item podemos pegar a posição
dele na lista com o campo tt-list-items.posicao.

 Tratamento para retonar valores para a propriedade Radio-Buttons de


uma Radio-Set:

DEF VAR l-log AS LOG INITIAL FALSE NO-UNDO.

FOR EACH tt-list-items BY posicao:

IF l-log = NO THEN DO:


ASSIGN c-lista = tt-list-items.val-item + ","
+ STRING(tt-list-items.posicao).
ASSIGN l-log = TRUE.
END.
ELSE
ASSIGN c-lista = c-lista + "," + tt-list-
items.val-item + "," + STRING(tt-list-items.posicao).

END.

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.

 Alterar o ponto de chamada da include VARINC nos programas que a


utilizam:

Devido as mudanças propostas pela técnica, não é possível fazer mais


este tipo de atribuição:

ASSIGN c-lista-retencao = ENTRY(1,TRIM({varinc/var00137.i


03})).
É necessário colocar a include em uma linha isolada, de preferência
logo após a definição de variáveis do programa.
Implementação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 127

CAPÍTULO 8
Construção de Programas utilizando os
Estilos e suas Técnicas

Como construir um Cadastro Simples


Estilo Usado Nome Físico
Cadastro Simples Masters/w-cadsim.w
Cadastro Simples -Alteração Masters/w-cadsi2.w
Cadastro Simples - Inclusão Masters/w-cadsi3.w
 em Arquivo | Novo, selecionar um dos estilos relacionados acima, de
acordo com o tipo de Cadastro Simples que se deseja construir;

 verificar se já existe uma SmartQuery para a tabela que se deseja construir


um Cadastro Simples. Caso não exista, 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 um programa de vá para e um programa de pesquisa
para a tabela que se deseja construir um Cadastro Simples. 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;

 criar um SmartLink do tipo STATE, tendo como Source: p-navega e como


Target: SmartQuery;
 criar um SmartLink do tipo STATE, tendo Source: p-exihel e como Target:
SmartQuery;
 verificar se já existe uma SmartViewer com os atributos da tabela que
devem ser editados. Caso não exista, criar uma nova SmartViewer
utilizando o estilo CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar a SmartViewer na página 0 da SmartWindow e aceitar as


sugestões de SmartLink do Wizard;
 redimensionar a SmartWindow de acordo com os objetivos que foram
colocados nela. Ter o cuidado para que a SmartViewer fique centralizada
na SmartWindow;
 salvar a SmartWindow com o nome definido para o Cadastro Simples;
Implementação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 129

Lista de Links:
Source Link Type target
h_p-cadsim STATE h_p-exihel
h_p-cadsim TABLEIO h_viewer
h_p-navega NAVIGATION h_query
h_p-navega STATE h_query
h_query RECORD h_viewer
h_p-exihel STATE h_query

Como construir um Cadastro Complexo


Estilo Usado Nome Físico
Cadastro Complexo Masters/w-cadcom.w
Cadastro Complexo - Masters/w-cadcon2.w
Atualiza
 selecionar um dos estilos relacionados na tabela acima, de acordo com o
tipo de Cadastro Complexo que se deseja construir;

 verificar se já existe uma SmartQuery para a tabela que se deseja construir


um Cadastro Complexo. Caso não exista, criar uma nova utilizando o
estilo CustomQuery Wizard;
 instanciar a SmartQuery na página 0 da SmartWindow e aceitar as
sugestões de SmartLink do Wizard;
 verificar se já existe um programa de Vá para e um programa de pesquisa
para a tabela que se deseja construir um Cadastro Complexo. 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;
 criar um SmartLink do tipo STATE, tendo como Source: p-navega e como
Target: SmartQuery;
 criar um SmartLink do tipo STATE, tendo como Source: p-exihel e como
Target: SmartQuery;
 verificar se já existe uma SmartViewer com os atributos da tabela que
devem estar expostos na parte principal da SmartWindow, ou seja, acima
do folder. Caso não exista, criar uma nova SmartViewer utilizando o estilo
CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar a SmartViewer na página 0 da SmartWindow, acima do folder, e


aceitar as sugestões de SmartLink do Wizard;
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 131

 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. Caso não exista, criar uma nova,
utilizando o estilo CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar a SmartViewer em determinada página do folder e aceitar as


sugestões de SmartLink do Wizard;
 criar um SmartLink de GROUP-ASSIGN, tendo como Source:
SmartViewer da página 0 e como Target: SmartViewer recém
instanciada no folder;
 redimensionar a SmartWindow de acordo com os objetos que foram
colocados nela. Ter o cuidado para que a SmartViewer fique centralizada
na SmartWindow;

 acessar as propriedades do folder e renomear os labels das páginas;


 salvar a SmartWindow com o nome definido para o Cadastro Complexo.
Lista de Links:
Source Link Type Target
h_folder PAGE THIS-PROCEDURE
h_p-cadsim STATE h_p-exihel
h_p-cadsim TABLEIO h_viewer-l
h_p-navega NAVIGATION h_query
h_query RECORD h_viewer-1
h_query RECORD h_viewer-2
h_query RECORD h_viewer-3
h_query RECORD h_viewer-4
Implementação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 133

h_viewer-1 GROUP-ASSIGN h_viewer-2


h_viewer-1 GROUP-ASSIGN h_viewer-3
h_viewer-1 GROUP-ASSIGN h_viewer-4
h_p-exihel STATE h_query
h_p-navega STATE h_query

Como construir um Cadastro Pai X Filho - Atualiza Filho


Estilo Utilizado Nome Físico
Window Cadastro Pai x Filho - Masters/w-adf.w
Filho
 selecionar o estilo relacionado na tabela acima;

 verificar se já existe uma SmartQuery para a tabela pai. Caso não exista,
criar uma nova utilizando o estilo CustomQuery Wizard;
 instanciar a SmartQuery na página 0 da SmartWindow e aceitar as
sugestões de SmartLink do Wizard;
 verificar se já existe um programa de "Vá para" e um programa de
pesquisa para a tabela pai. 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 pai e no
atributo "Programa VáPara" o nome do programa de Vá Para da tabela pai;
 criar um SmartLink do tipo STATE, tendo como Source: p-navega e como
Target: SmartQuery;
 criar um SmartLink do tipo STATE, tendo como Source: p-exihel e como
Target: SmartQuery;
 verificar se já existe uma SmartViewer com os atributos da tabela pai que
devem estar expostos na página 0 da SmartWindow, ou seja, acima do
folder. Caso não exista, criar uma nova SmartViewer utilizando o estilo
CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar a SmartViewer na página 0 da SmartWindow e aceitar as


sugestões de SmartLink do Wizard;
APÍTULO 8 Construção de
rogramas 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. Caso não
exista, criar um novo utilizando o estilo CustomBrowser
Inclui/Modifica;
 colocar o SmartBrowser na página correspondente do folder, aceitando
os links indicados pelo Wizard;
 acessar os atributos de instância do SmartBrowser e informar o
nome do programa de atualização da tabela filha. Se este programa
não existir, deve ser criado utilizando-se o template Cadastro
Inclui/Modifica Filho;
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 137

 criar um SmartLink de Record, tendo como Source: SmartQuery e


como Target: SmartBrowser recém instanciado no folder;
 caso seja necessário incluir botões de Seleção e/ou Parâmetros
para a tabela do SmartBrowser, deve-se incluir os botões abaixo
do browse.
 ter o cuidado para que a SmartViewer fique centralizada na
SmartWindow;
 salvar a SmartWindow com o nome definido para o Cadastro Pai x
Filho.
Lista de Links
Source Link Type Target
h_folder PAGE THIS-PROCEDURE
h_p-exihel STATE THIS-PROCEDURE
h_p-navega NAVIGATION h_query
h_p-navega STATE h_query
h_query RECORD h_viewer
h_query RECORD h_browser1
h_query RECORD h_browser2
Implementação

h_p-exihel STATE h_query

Como construir um Cadastro Inclui/Modifica Filho


Estilo Utilizado Nome Físico
Window Inclui/Modifica Filho Masters/w-incmo3.w
 selecionar o estilo relacionado na tabela acima;

 se os campos a serem inclusos/modificados couberem em uma única


viewer, o cadastro deve ser do tipo Simples, devendo-se eliminar o folder
da SmartWindow;

 se os campos a serem inclusos/modificados não couberem em uma única


viewer, estes devem ser divididos em mais viewers que devem ser
colocadas nas páginas do folder, formando um cadastro do tipo Complexo;
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 139

 verificar se já existe uma SmartQuery para a tabela que se deseja construir


o Cadastro Inclui/Modifica Filho. Caso não exista, criar uma nova
utilizando o estilo CustomQuery Wizard;
 instanciar a SmartQuery na página 0 (zero) da Window;
 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, criar uma nova SmartViewer
utilizando o estilo CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar a SmartViewer na SmartWindow ou na página


correspondente do folder no caso de um cadastro complexo, e aceitar
as sugestões de SmartLinks do Wizard;
 criar um SmartLink de TABLEIO, tendo como Source: THIS-
PROCEDURE e como Target: SmartViewer recém instanciada;
 se o cadastro for do tipo complexo:
 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);
 incluir a seguinte linha após o Dispatch padrão na Local-Initialize:
{include/i-inifld.i}

 deve-se atribuir a página 1 como sendo a página inicial do


programa. Para isso é necessário:
 acessar o Procedure Properties na janela do UIB;
 entrar em Propertie Pages;

 em Startup on Page atribuir o valor 1.

 na Local-Initialize da window, devem ser substituídas as ocorrências de


"<viewer_principal>", pelo nome da viewer que contém o(s) campo(s)
chave(s) da tabela.
Exemplo:
run pi-atualiza-parent in h_v06pd001 (input v-row-parent).

 nas triggers de Choose dos botões de 'Ok' e 'Salvar', substituir as


ocorrências de "<handle da viewer principal>" pelo handle da viewer que
contém o campo chave da tabela;
Exemplo:
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 141

{include/okfil.i h_v06pd001}

 na procedure pi-reposiciona da window, substituir a ocorrência "<query-


name>" pelo nome da query utilizada no cadastro.
Exemplo:
RUN pi-reposiciona-query IN h_q06pd001 (input v-row-
table).

 na SmartViewer que possuir a chave da tabela, deve ser criada uma local-
create-record e após o run dispatch deve ser inserida a seguinte lógica:
find <tabela pai> where rowid (<tabela pai>) = v-row-
parent no-lock no-error.
if available <tabela pai> then do:
assign <tabela filho>.<chave pai> = <tabela pai>.<chave
pai>.
end.

Onde:
<tabela pai>: deve ser substituído pelo nome da tabela pai da tabela que se
está utilizando no cadastro. 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.
/* Code placed here will execute PRIOR to standard behavior. */
/* Dispatch standard ADM method. */
RUN dispatch IN THIS-PROCEDURE (INPUT 'create-record':U ).
/* Code placed here will execute AFTER standard behavior. */
find order where rowid (order) = v-row-parent no-lock no-error.
if available order then
assign order-line.order-num = order.order-num.

 Se desejar preencher os campos chave da tabela pai na viewer para


inclusão:
 Na SmartViewer que possuir a chave da tabela, deve ser criada uma
local-display-fields e uma local-add-record, e após o run dispatch deve
ser inserida a seguinte lógica nas duas procedures:
Exemplo

def buffer <nome buffer> for <tabela pai>.


find <nome buffer> where rowid(<nome buffer>) = v-row-
parent no-lock no-error.
if avail <nome buffer> then
assign <tabela filho>.<chave pai>:screen-value in
frame {&frame-name} = string(<nome buffer>.<chave pai>).
else
assign <tabela filho>.<chave pai>:screen-value in
frame {&frame-name} = “”.

Onde:
<nome buffer>: deve ser substituído pelo nome que se deseja dar ao buffer da
tabela pai.
<tabela pai>: deve ser substituído pelo nome da tabela pai da tabela que se
está utilizando no cadastro. 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 está 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.
/* Code placed here will execute PRIOR to standard behavior. */
/* Dispatch standard ADM method. */
RUN dispatch IN THIS-PROCEDURE (INPUT 'add-record':U ).
/* Code placed here will execute AFTER standard behavior. */
def buffer b-customer for customer.
find b-customer where rowid(b-customer) = v-row-parent no-lock
no-error.
if avail b-customer then
assign order.cust-num:screen-value in frame {&frame-name} =
string(b-customer.cust-num).
else
assign order.cust-num:screen-value in frame {&frame-name} =
"".

 Se desejar preencher seqüencialmente o campo chave da tabela filho para


inclusão:
 Na SmartViewer que possuir a chave da tabela, 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>.


find last <nome buffer> where <nome buffer>.<chave pai> =
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 143

<tabela pai>.<chave pai> no-lock no-error.


if avail <nome buffer> then
assign <tabela filho>.<chave filho>:screen-value in
frame {&frame-name} = string(<nome buffer>.<chave filho>
+ 1).
else
assign <tabela filho>.<chave filho>:screen-value in
frame {&frame-name} = “1”.

Onde:
<nome buffer>: deve ser substituído pelo nome que se deseja dar ao buffer da
tabela filho.
<tabela pai>: deve ser substituído pelo nome da tabela pai da tabela que se
está utilizando no cadastro. 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 está 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.
/* Code placed here will execute PRIOR to standard behavior. */
/* Dispatch standard ADM method. */
RUN dispatch IN THIS-PROCEDURE (INPUT 'add-record':U ).
/* Code placed here will execute AFTER standard behavior. */

def buffer b-order for order.


find last b-order where b-order.cust-num = customer.cust-num no-
lock no-error.
if avail b-order then
assign order.order-num:screen-value in frame {&frame-name} =
string(b-order.order-num + 1).
else
assign order.order-num:screen-value in frame {&frame-name} =
“1”.

Lista de Links (Uma Viewer):


Source Link Type Target
THIS- TABLEIO h_viewer
PROCEDURE
h_query RECORD h_viewer
Lista de Links (Mais de uma Viewer):
Source Link Type Target
Implementação

h_query RECORD h_viewer1


THIS- TABLEIO h_viewer1
PROCEDURE
h_viewer1 GROUP-ASSIGN h_viewer2
h_viewer1 GROUP-ASSIGN h_viewer3
h_query RECORD h_viewer2
h_query RECORD h_browser3

Como construir um Cadastro Pai X Filho - Atualiza Ambos


Estilo Utilizado Nome Físico
Window Cadastro Pai x Filho - Masters/w-paiamb.w
Ambos
 selecionar o estilo relacionado na tabela acima;

 verificar se já existe uma SmartQuery para a tabela pai. Caso não exista,
criar uma nova utilizando o estilo CustomQuery Wizard;
 instanciar a SmartQuery na página 0 da SmartWindow e aceitar as
sugestões de SmartLink do Wizard;
 verificar se já existe um programa de Cadastro Inclui/Modifica Pai para
manutenção da tabela Pai, caso não exista, deve ser criado, para isso
utilizar o template Cadastro Inclui/Modifica Pai;
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 145

 verificar se já exista um programa "Vá para" e um programa de pesquisa


para a tabela pai. Caso não existam, eles devem ser criados;
 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;
 criar um SmartLink do tipo STATE, tendo como Source o Painel p-navega
e como Target a SmartQuery;
 criar um SmartLink do tipo STATE, tendo como Source o Painel p-cadpai
e como Target a SmartQuery;
 criar um SmartLink do tipo STATE, tendo como Source o Painel p-exihel e
como Target a SmartQuery;
 verificar se já existe uma SmartViewer com os atributos da tabela pai que
estão expostos na página 0 da SmartWindow, ou seja, acima do folder.
Caso não exista, criar uma nova SmartViewer, utilizando o estilo
CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar a SmartViewer na página 0 da SmartWindow e aceitar as


sugestões da SmartLink do Wizard;
 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, criar um novo utilizando o estilo CustomBrowser
Inclui/Modifica;
 colocar o SmartBrowser na página correspondente do folder, aceitando
os links indicados pelo Wizard;

 acessar os atributos de instância do SmartBrowser e informar o nome


do programa de atualização da tabela filha. Se este programa não
existir, deve ser criado utilizando-se o template Cadastro
Inclui/Modifica Filho;
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 147

 ter o cuidado para que a SmartViewer fique centralizada na


SmartWindow;
 caso seja necessário incluir botões de Seleção e/ou Parâmetros para a
tabela do SmartBrowser, deve-se incluir os botões abaixo do browse;
 salvar a SmartWindow com o nome definido para o Cadastro Pai x
Filho.
Lista de Links:
Source Link Type Target
h_folder PAGE THIS-PROCEDURE
p-cadpai TABLEIO h_viewer
p-cadpai STATE h_query
h_p_exihel STATE h_query
h_p-navega NAVIGATION h_query
h_p-navega STATE h_query
h_query RECORD h_viewer
h_query RECORD h_browse1
h_query RECORD h_browse2
Implementação

Como construir um Cadastro Inclui/Modifica Filho


Estilo Utilizado Nome Físico
Window Inclui/Modifica Filho Master/w-incmo3.w
 selecionar o estilo relacionado na tabela acima;

 se os campos a serem inclusos/modificados couberem em uma única


viewer, o cadastro deve ser do tipo Simples, devendo-se eliminar o
folder da SmartWindow.

 se os campos a serem inclusos/modificados não couberem em uma


única viewer, estes devem ser divididos em mais viewers que devem
ser colocadas nas páginas do folder, formando um cadastro do tipo
Complexo;
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 149

 verificar se já existem uma SmartQuery para a tabela que se deseja


construir o Cadastro Inclui/Modifica Filho. Caso não exista, criar uma
nova utilizando o estilo CustomQuery Wizard;
 instanciar a SmartQuery na página 0 (zero) da Window;
 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, criar uma nova SmartViewer
utilizando o estilo CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar a SmartViewer na SmartWindow ou na página


correspondente do folder no caso de um cadastro complexo, e aceitar
as sugestões de SmartLinks do Wizard;
 criar um SmartLink de TABLEIO, tendo como Source: THIS-
PROCEDURE e como Target: SmartViewer recém instanciada;
 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);
 incluir a seguinte linha após o Dispatch padrão no Local-Initialize:
{include/i-inifld.i}

 deve-se atribuir a página 1 como sendo a página inicial do programa. Para


isso é necessário:
 acessar o Procedure Properties na janela do UIB;
 entrar em Propertie Pages;

 em Startup on Page atribuir o valor 1;

 na Local-Initialize da window, devem ser substituídas as ocorrências de


"<viewer_principal>", pelo nome da viewer que contém o(s) campo(s)
chave(s) da tabela.
Exemplo:
run pi-atualiza-parent in h_v06pd001 (input v-row-parent).

 nas triggers de Choose dos botões de 'Ok' e 'Salvar', substituir as


ocorrências de "<handle da viewer principal>" pelo handle da viewer que
contém o campo chave da tabela;
Exemplo:
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 151

{include/okfil.i h_v06pd001}

 na procedure pi-reposiciona da window, substituir a ocorrência "<query-


name>" pelo nome da query utilizada no cadastro;
Exemplo:
RUN pi-reposiciona-query IN h-q06pd001 (input v-row-
table).

 na SmartViewer que possuir a chave da tabela, deve ser criada uma local-
create-record e após o run dispatch deve ser inserida a seguinte lógica:
find <tabela pai> where rowid (<tabela pai>) = v-row-parent
no-lock no-error.
if available <tabela pai> then do:
assign <tabela filho>.<chave pai> = <tabela pai>.<chave
pai>.
end.

Onde:
<tabela pai>: deve ser substituído pelo nome da tabela pai da tabela que se
esta utilizando no cadastro. 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
/* Code placed here will execute PRIOR to standard behavior. */
/* Dispatch standard ADM method.
RUN dispatch IN THIS-PROCEDURE ( INPUT 'create-record':U ).
/* Code placed here will execute AFTER standard behavior. */
find order where rowid (order) = v-row-parent no-error.
if available order then
assign order-line.order-num = order.order-num.

Lista de Links (Uma Viewer):


Source Link Type Target
THIS- TABLEIO h_viewer
PROCEDURE
h_query RECORD h_viewer
Implementação

Lista de Links (Mais de uma Viewer):


Source Link Type Target
h_query RECORD h_viewer1
THIS- TABLEIO h_viewer1
PROCEDURE
h_viewer1 GROUP-ASSIGN h_viewer2
h_viewer1 GROUP-ASSIGN h_viewer3
h_query RECORD h_viewer2
h_query RECORD h_viewer3

Como construir um Cadastro Inclui/Modifica Pai


Estilo Utilizado Nome Físico
Window IncluiModifica Pai Master/w-incmdp.w
 selecionar o estilo relacionado na tabela acima;

 se os campos a serem inclusos/modificados couberem em uma única


viewer, o cadastro deve ser do tipo Simples, devendo-se eliminar o folder
da SmartWindow;
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 153

 se os campos a serem inclusos/modificados não couberem em uma única


viewer, estes devem ser divididos em mais viewers que devem ser
colocadas nas páginas do folder, formando um cadastro do tipo Complexo;

 verificar se já existe uma SmartQuery para a tabela que se deseja construir


o Cadastro Inclui/Modifica Filho. Caso não exista, criar uma nova
utilizando o estilo CustomQuery Wizard;
 instanciar a SmartQuery na página 0 (zero) da Window;
 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, criar uma nova SmartViewer
utilizando o estilo CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar a SmartViewer na SmartWindow ou na página


correspondente do folder no caso de um cadastro complexo, e aceitar
as sugestões de SmartLinks do Wizard;
 criar um SmartLink de TABLEIO, tendo como Source: THIS-
PROCEDURE e como Target: SmartViewer recém instanciada;
 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);
 incluir a seguinte linha após o Dispatch padrão na Local-Initialize:
{include/i-inifld.i}

 deve-se atribuir a página 1 como sendo a página inicial do programa. Para


isso é necessário;
 acessar a Procedure Properties na janela do UIB;
 entrar em Propertie Pages;

 em Startup on Page atribuir o valor 1;

 nas triggers de Choose dos botões de 'Ok' e 'Salvar', substituir as


ocorrências de "<handle da viewer principal>" pelo handle da viewer que
contém o campo chave da tabela;
Exemplo:
Implementação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 155

{include/okpai.i h_v07pd002}

 na procedure pi-reposiciona da window, substituir a ocorrência "<query-


name>" pelo nome da query utilizada no cadastro;
Exemplo:
RUN pi-reposiciona-query IN h_q07pd001 (input v-row-
table).

Lista de Links (Uma Viewer):


Source Link Type Target
THIS- TABLEIO h_viewer
PROCEDURE
h_query RECORD h_viewer
Lista de Links (Mais de uma Viewer):
Source Link Type Target
h_query RECORD h_viewer1
THIS- TABLEIO h_viewer1
PROCEDURE
h_viewer1 GROUP-ASSIGN h_viewer2
h_viewer1 GROUP-ASSIGN h_viewer3
h_query RECORD h_viewer2
h_query RECORD h_viewer3

Como construir um CustomBrowser Inclui/Modifica


Estilo Utilizado Nome Físico
Window Inclui/Modifica Master/w-incmdp.w
Pai
 selecionar o estilo relacionado na tabela acima;

 seguir os passos do Wizard, observando que:


 deve-se indicar uma tabela externa, essa tabela deve ser a mesma
tabela utilizada na query do Cadastro PaiXFilho em que o browser
deve ser utilizado;

 a query deve conter a tabela dos registros filhos que irão ser exibidos no
Cadastro PaiXFilho. Exemplo de query do browser:
Implementação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 157

 toggle-box "Indexed-Reposition" deve ser marcado;


 em "Options", a coluna "Returned" do browse, deve conter o valor
"Fields Used" e o toggle-box "Sort-ByPhrase" deve ser marcado;

 após a criação do browse com a ajuda do Wizard, salvar o browse de


acordo com as normas de nomenclatura.

Como construir um CustomBrowser Zoom Wizard


Estilo Utilizado Nome Físico
Custom Browser Zoom Wizard Masters/wbrwzoo.w
 selecionar o estilo relacionado na tabela acima;
 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, deve-se obedecer aos seguintes
itens:
 na página where, deve-se entrar com a seguinte condição:
<Tabela>.<Campo> >= fi-ini-<campo> and
<Tabela>.<Campo> <= fi-fin-<campo>

Onde:
<Tabela>.<Campo>: é o campo da tabela ao qual deseja-se estabelecer limites,
e, fi-ini-campo e fi-fin-campo são os fill-ins que o usuário irá entrar com a
faixa de valores

Obs.: A condição pode obedecer a valores de mais campos bastando adicioná-


la. Exemplo:
<Tabela>.<Campo1> >= fi-ini-<campo1> and
<Tabela>.<Campo1> >= fi-ini-<campo1> and
<Tabela>.<Campo2> >= fi-ini-<campo2> and
<Tabela>.<Campo2> >= fi-ini-<campo2> ...

 depois de concluída a definição do browse, o nome, tipo, 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,
para isso deve-se:
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 159

 acessar os atributos do fill-in c-inicial, 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;
 na dialog Dictionary Defaults, desmarcar os toogle-boxes Label e
Database Variable;
 o nome do fill-in deve ser alterado para o mesmo nome relacionado na
condição da query do browse, no formato fi-ini-<campo>. Exemplo:
fi-ini-cust-num;
 repetir os mesmos passos para o fill-in c-final, observando que seu
nome deve ser alterado para o formato fi-fin-<campo>. Exemplo: fi-
fin-cust-num;
 alterar o valor inicial do fill-in de início de faixa, para o menor valor
aceito por ele. Exemplo: para um fill-in do tipo inteiro de formato
"999.999,99", seu valor inicial deve ser 0 (zero), para um fill-in do
tipo caracter de formato "x(6)", seu valor inicial deve ser "" (branco).
 alterar o valor inicial do fill-in de fim de faixa para o maior valor
aceito por ele. Exemplo: para um fill-in do tipo inteiro de formato
"999.999,99", seu valor inicial deve ser 999.999,99, para um fill-in do
tipo caracter de formato "x(6)", seu valor inicial deve ser "ZZZZZZ"
(seis letras "z" maiúsculas).
 mais campos podem ser adicionados a condição de faixa de valores,
bastando que sejam adicionados os fill-in´s e que sejam seguidos os
passos citados anteriormente, ou inserir diretamente os campos na
frame e em seguida desvinculá-los da base através de suas
propriedades e alterando seus nomes.
Obs.: se forem adicionados mais campos para a faixa de valores, as
imagens Image-1 e Image-2 devem ser copiadas e reposicionadas entre
os dois novos campos, conforme a faixa original.
 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.
Implementação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 161

Exemplo:
assign input frame {&frame-name} c-inicial c-final.

Para:
assign input frame {&frame-name} fi-ini-cust-num fi-fin-cust-
num.

 se necessário, ou se houverem mais de um campo para seleção de valores,


os fill-in´s de inicio de faixa (fi-ini-<campo>) poderão possuir labels.
Como esses fill-in´s não são vinculados ao banco de dados, a atribuição do
label deverá ser feita por meio do utilitário ut-field ou ut-liter, criando a
procedure local-initialize antes do dispatch. Para isso os fill-in´s não
devem se no-labels. Exemplo:
{utp/ut-field.i Sports Customer Cust-Num 1}
assign fi-ini-Cust-Num:Label in frame {&frame-name} =
return-value.

 alterar a procedure pi-retorna-valor, onde:


- <tabela>: nome da tabela do browser
- <campo1>: primeiro campo do browser
- <campo2>: segundo campo do browser
- <campo...>: campo ... do browser
- <campoN>: campo N do browser
 salvar o browse seguindo as normas de nomenclatura.

Como construir uma Consulta Simples


Estilo Utilizado Nome Físico
Window Consulta Simples Masters/w-consim.w
 em Arquivo | Novo, selecionar o estilo relacionado acima;
 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;
 instanciar a SmartQuery na página 0 da Window Consulta Simples e
aceitar as sugestões de SmartLinks do Wizard;
 verificar se já existe um programa de vá para e um programa de pesquisa
para a tabela que se deseja construir a Consulta Simples. 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;

 criar um SmartLink do tipo STATE, tendo como Source: p-navega e como


Target: SmartQuery;
 criar um SmartLink do tipo STATE, tendo como Source: p-exihel e como
Target: SmartQuery;
 verificar se já existe uma SmartViewer com os atributos da tabela que
devem ser editados. Caso não exista, criar uma nova SmartViewer
utilizando o estilo CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, conforme técnica Como registrar
campo do tipo Fill-in para o WebEnabler.
Implementação

APÍTULO 8 Construção de
rogramas 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar a SmartViewer na página 0 da SmartWindow e aceitar as


sugestões de SmartLink do Wizard;
 redimensionar a altura da SmartWindow de acordo com os objetos que
foram colocados nela. Ter o cuidado para que a SmartViewer fique
centralizada na SmartWindow;
 salvar a SmartWindow com o nome definido para o Cadastro Simples;
Lista de Links
Source Link Type Target
h_p-navega NAVIGATION h_query
h_p-navega STATE h_query
h_query RECORD h_viewer
h_p-exihel STATE h_query

Como construir uma Consulta Complexa


Estilo Utilizado Nome Físico
Window Consulta Complexa Masters/w-concom.w
 selecionar o estilo relacionado na tabela acima;

 verificar se já existe uma SmartQuery para a tabela que se deseja construir


um Cadastro Complexo. Caso não exista, criar uma nova utilizando o
estilo CustomQuery Wizard;
 instanciar a SmartQuery na página 0 da SmartWindow e aceitar as
sugestões de SmartLink do Wizard;
 verificar se já existe um programa de Vá para e um programa de pesquisa
para a tabela que se deseja construir um Cadastro Complexo. 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;

 criar um SmartLink do tipo STATE, tendo como Source: p-navega e como


Target: SmartQuery;
 criar um SmartLink do tipo STATE, tendo como Source: p-exihel e como
Target: SmartQuery;
 verificar se já existe uma SmartViewer com os atributos da tabela que
devem estar expostos na parte principal da SmartWindow, ou seja, acima
do folder. Caso não exista, criar uma nova SmartViewer utilizando o estilo
Custom Viewer com Auto-Field;
 instanciar a SmartViewer na página 0 da SmartWindow, acima do folder, e
aceitar as sugestões de SmartLink do Wizard;
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 165

 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, criar uma nova,
utilizando o estilo CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar a SmartViewer em determinada página do folder e aceitar as


sugestões de SmartLink do Wizard;
 criar um SmartLink de GROUP-ASSIGN, tendo como Source:
SmartViewer da página 0 e como Target: SmartViewer recém
instanciada no folder;
 redimensionar a altura da SmartWindow de acordo com os objetos que
foram colocados nela. Ter o cuidado para que a SmartViewer fique
centralizada na SmartWindow;
 acessar as propriedades do folder e renomear os labels das páginas;
 salvar a SmartWindow com o nome definido para o Cadastro Complexo.

Source
' Link Type Target
h_folder PAGE THIS-PROCEDURE
h_p-navega NAVIGATION h_query
h_query RECORD h_viewer1
h_query RECORD h_viewer2
h_query RECORD h_viewer3
h_query RECORD h_viewer4
h_viewer-1 GROUP-ASSIGN h_viewer-2
h_viewer-1 GROUP-ASSIGN h_viewer-3
h_viewer-1 GROUP-ASSIGN h_viewer-4
h_p-exihel STATE h_query
h_p-navega STATE h_query
Implementação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 167

Como construir uma Consulta Relacionamentos


Estilo
' Utilizado Nome Físico
Window Consulta Relacionamento Masters/w-conrel.w
 selecionar o estilo relacionado na tabela acima;

 verificar se já existe uma SmartQuery para a tabela que se deseja construir


uma Consulta Relacionamento. Caso não exista, criar uma nova utilizando
o estilo CustomQuery Wizard;
 instanciar a SmartQuery na página 0 da SmartWindow e aceitar as
sugestões de SmartLink do Wizard;
 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 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 pai e no
atributo "Programa Vá para" o nome do programa de vá para da tabela pai;

 criar um SmartLink do tipo STATE, tendo como Source: p-navega e como


Target: SmartQuery;
 criar um SmartLink do tipo STATE, tendo como Source: p-exihel e como
Target: SmartQuery;
 verificar se já existe uma SmartViewer com os atributos da tabela pai que
devem estar expostos na página 0 da SmartWindow, ou seja, acima do
folder. Caso não exista, criar uma nova SmartViewer utilizando o estilo
CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar a SmartViewer na página 0 da SmartWindow e aceitar as


sugestões de SmartLink do Wizard;

 repetir os seguintes passos para os SmartBrowsers que devem estar


colocadas nas páginas do folder:
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 169

 verificar se já existe um SmartBrowser para a tabela filho da consulta


relacionamento. Caso não exista, criar um novo utilizando o estilo
CustomBrowser Consulta;
 botão "Detalhar" deve ser responsável por chamar um determinado
programa de consulta que deve detalhar o registro selecionado no
SmartBrowser. O critério de escolha para esse programa deve ser o
seguinte:
 1º Consulta cadastral do filho;
 2º Consulta relacionamento do filho;
 3º Consulta cadastral de uma tabela associativa ao filho;
 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.

 criar um SmartLink de Record, tendo como Source: SmartQuery e


como Target: SmartBrowser recém instanciado no folder;
 redimensionar a SmartWindow de acordo com os objetos que foram
colocados nela. Ter o cuidado para que a SmartViewer fique centralizada
na SmartWindow;
 salvar a SmartWindow com o nome definido para a Consulta
Relacionamento.
Lista de Links:
Source
' Link Type Target
h_folder PAGE THIS-PROCEDURE
h_p-exihel STATE THIS-PROCEDURE
h_p-navega NAVIGATION h_query
h_p-navega STATE h_query
h_query RECORD h_viewer
h_query RECORD h_browse1
h_query RECORD h_browse2
h_p-exihel STATE h_query

Como construir um programa de Relatórios


Para a construção de relatórios que não são gerados pelo Data Viewer, deve-se
utilizar o estilo Window Relatórios/Cálculos/Fechamentos (w-relat.w), que se
apresenta um pouco diferente dos demais estilos existentes, pois não se utiliza
de SmartObjects.
Outra diferença é que o relatório é constituído por dois programas, o primeiro
com o nome do formato xxp/xx9999.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, o segundo programa, com nome de formato xxp/xx9999rp.p, executa
a geração do relatório propriamente dito, conforme os parâmetros passados
pelo primeiro programa.
Dicas Gerais
 tabela de para de folder/páginas e com objetos relacionados:
Página-Folder
' Frame Imagem Preprocessador
Seleção f-pg-sel im-pg-sel PGSEL
Classificação f-pg-cla im-pg-cla PGCLA
Parâmetros f-pg-par im-pg-par PGPAR
Digitação f-pg-dig im-pg-dig PGDIG
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 171

Impressão f-pg-imp im-pg-imp PGIMP


 para selecionar uma página para trabalhar, na janela do UIB, clicar no
botão 'List Objects' que apresenta um browse com os objetos do programa,
selecionar a frame desejada e então acionar o botão 'TO TOP';

Botão List Objects;

Botão to Top;
 neste estilo, todo trabalho de tradução de labels, helps, screen-values é
feito automaticamente por um include padrão do estilo. Exceções: list-
items do widget combo-box.
Preparação do Relatório - Interface
1. Verificar quais as páginas que devem ser necessárias ao programa, se as
cinco páginas forem necessárias desconsiderar as tarefas 2, 3, 4 e 5.
2. Eliminar as frames das páginas desnecessárias com base na tabela acima.
3. Eliminar n imagens com as "orelhas" mais a direita, onde n é o número de
páginas desnecessárias, renomeando as remanescentes conforme a tabela
acima.
4. Em 'Definitions' limpar o conteúdo dos preprocessadores das páginas
desnecessárias, assim se está informando ao estilo que estas páginas não
existem no relatório. Exemplo, onde a página de digitação não é
necessária:
&GLOBAL-DEFINE PGSEL f-pg-sel
&GLOBAL-DEFINE PGCLA f-pg-cla
&GLOBAL-DEFINE PGPAR f-pg-par
&GLOBAL-DEFINE PGDIG
&GLOBAL-DEFINE PGIMP f-pg-imp

5. Se a página de seleção não existir, no 'Main-block' do programa, corrigir a


chamada do include i-rpmbl.i, adicionando o nome da imagem associada a
página que se deseja apresentar como inicial, exemplo:
{include/i-rpmbl.i im-pg-par}

Observação Não deve ser alterado o tamanho da frame de relatório, pois há possibilidade de
gerar erros na interface quando os programas são executados com Facelift.
Página de Seleção
1. Colocar os fill-in´s de inicial e final, para cada campo que precisa de faixa.
A sugestão é criar como 'Database Fields' e após convertê-los para
variáveis para obter automaticamente os labels, formatos e tamanhos do
dicionário de dados.
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

2. Corrigir os 'initial values' das variáveis de inicial e final.


3. Retirar possíveis queries que o UIB automaticamente queira associar a
frame.
Página de Classificação
1. Redefinir o 'list-items' do radio-set rs-classif , com as opções de
classificação de seu relatório;
2. Se necessário adicionar mais opções de classificação.
Pagina de Parâmetros
1. Colocar as variáveis necessárias na representação desejada (radio-set,
toggle-box, fill-in), definindo label, formato, initial e help para as mesmas.
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

2. Caso seja necessário implementar retângulos com label, estes labels devem
ser fill-in´s view-as text, e o seu valor deve ser informado no seu initial e
private-data. As propriedades 'Display' e 'Enable' devem ser retiradas.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 173

Página de Digitação
1. Em 'Definitions', corrigir a definição da temp-table de digitação tt-digita
inserindo os campos necessários;
2. Em 'Section Editor', 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;
'Row-entry': determina valores iniciais para os campos da temp-table na
inclusão de novas linhas, exceto quando se trata da primeira linha do
browse;
'Row-leave': salva as alterações feitas pelo usuário.
3. Ainda em 'Section Editor', mas para os botões bt-inserir e bt-alterar,
adaptar os seus gatilhos de 'Choose', na linha que aplica um evento 'Entry',
sobre o primeiro campo habilitado no browse;
4. Todas as validações do browse br-digita devem ser feitas na procedure pi-
executar no local indicado pelo comentário;
5. Opcionalmente, os gatilhos de 'leave' (para atributos de referência), 'f5' e
'mouse-select-dblclick' (para acionamento do zoom), para as colunas do
browse podem ser necessários. Neste caso, tais gatilhos devem ser
codificados "à mão", no início do 'Main Block' do programa. Exemplo:
ON F5, MOUSE-SELECT-DBLCLICK OF tt-digita.<campo> in
browse br-digita do:
{include/zoomvar.i ...}
END.

Observação Para mais detalhes sobre esta técnica, ver capítulo Como implementar Zoom e
campos de referência para campos de chave estrangeira.

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. Porém, se necessário, seguir a
técnica Como implementar Parâmetros de Impressão em Relatórios.
Gravação e validação dos parâmetros
Exemplo

1. Em 'Definitions' implementar os campos de parâmetros e seleção na


definição da temp-table tt-param.
2. Na procedure 'pi-executar', colocar as validações necessárias às opções do
usuário para execução do relatório no local indicado pelo comentário,
lembrando que elas devem apresentar uma mensagem de erro cadastrada,
posicionar na página com problemas, colocando o focus no campo com
problemas.
if input frame f-pg-par i-nr-nivel > 19 then do:
run utp/ut-msgs.p (input "show",
input 73,
input " ").
apply 'mouse-select-click' to im-pg-par in frame f-relat.
apply 'entry' to i-nr-nivel in frame f-pg-par.
return error.
end.

3. Na procedure 'pi-executar', no local indicado pelo comentário, colocar a


lógica de gravação dos parâmetros e seleção na temp-table tt-param.
4. Ainda na procedure 'pi-executar', substituir na chamada do include
{include/i-rprun.i} a literal 'XXP/XX9999RP.P' pelo programa que deve
imprimir o relatório.

Relatórios no formato RTF


O template está preparado para gerar a saída do relatório no formato RTF
(Rich Text Format). Para isto não é necessário realizar nenhuma alteração no
programa de interface.
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”.
Ex: &GLOBAL-DEFINE RTF NO
 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, l-habilitaRtf, text-modelo-rtf, c-modelo-rtf, bt-modelo-rtf
e rect-rtf.
 Reposicionar os componentes de execução de acordo com o
especificado a seguir: text-modo para column 1,14 e row 4,17, rect-9
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 175

para column 2,00 e row 4,46, e rs-execucao para column 2,86 e row
4,83.
Também é possível passar durante a inicialização do programa um arquivo de
modelo padrão para o relatório, neste caso o usuário não será obrigado a
informar um modelo manualmente. Para isto basta incluir no Main Block do
programa, antes da chamada a procedure “enable_UI”, a linha abaixo:
ASSIGN c-modelo-default = SEARCH("<pasta>\<modelo.rtf>").
onde:
<pasta> = sub-pasta aonde se encontra o arquivo de modelo no propath
<modelo.rtf> = arquivo que contém o modelo no formato rtf

Preparando documento Word (.DOC) para RTF


A técnica se baseia em um modelo do documento Word que pode (não é
obrigatório) conter algumas TAGS que auxiliarão na formatação do fonte,
porém o layout é o mesmo apresentado na geração padrão (texto).

A criação do modelo é livre, podendo ser criado ou alterado pelos clientes.


Não é mantido nenhum controle sobre os modelos criados ou utilizados pelos
clientes.

Principais Tags:

&NaoElimineEstaMarcacao: Utilizado para indicar o ponto onde o texto


principal do relatório será impresso. É utilizado também para indicar as
propriedades do fonte a ser utilizado, assim como os efeitos, cores, etc;

&TituloRelatorio: Receberá o título do relatório;

&DataHoraExecucao: Apresentará a informação: "Data: " +


string(today,"99/99/9999") + " - " + "Hora: " + string(time,"HH:MM:SS":U;

&RodapeRelatorio: Apresentará a informação: "DATASUL - ":U + p_sistema


+ " - ":U + p_prg_obj + " - V:":U + p_prg_vrs;

Apesar da tag receber o nome &NaoElimineEstaMarcacao, ela na prática não é


obrigatória. No caso de não ser definida o texto será impresso logo após o
início do documento de modelo, utilizando fonte padrão.
Exemplo

Dicas para criação do Programa RP.P de Relatório


O programa de execução do relatório (rp.p) é um programa procedural sem
qualquer tipo de interface com o usuário, 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. Da mesma forma, nenhum
programa chamado a partir de um rp.p não deve possuir qualquer tipo de
interface. Todas as validações ou informações com necessidade de intervenção
do usuário devem ser tratadas pelo programa .w que o chama.
1. Copiar a definição das temp-tables tt-param e tt-digita (esta última se
houver digitação) do programa de interface (.W) para o programa que deve
gerar o relatório (rp.p);
2. Se a implementação for uma conversão de um programa originário do
MAGNUS:
2.1. retirar a chamada para o include {cdp/cd9000.i} e substituir as
seguintes chamadas:
Include
' Velho Include Novo
Cdp\cd9500.i Include\i-rpvar.i
Cdp\cd9500.fl Include\i-rpcab.i
Cdp\cd9520.i Include\i-rpout.i
Cdp\cd9540.i Include\i-rpclo.i

2.2. caso haja opção de digitação, substituir, com base no programa


original, o work-file de digitação pela temp-table tt-digita.
2.3. substituir, as variáveis de parâmetro, seleção e classificação pelos
respectivos campos da temp-table tt-param.
3. Utilizar um stream padrão definido como STR-RP, para impressão do
relatório, deve-se passar o parâmetro &stream com o nome da stream para
os includes i-rpcab.i, i-rpcb80, i-rpc255.i, i-rpout.i e i-rpclo.i.
{include/i-rpcab.i &stream = "str-rp"}
{include/i-rpcb80.i &stream = "str-rp"}
{include/i-rpc255.i &stream = "str-rp"}
{include/i-rpout.i &stream = "stream str-rp"}
{include/i-rpclo.i &stream = "stream str-rp"}.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 177

4. Nas seleções, ao invés de utilizar a palavra "à", para dar idéia de faixa,
substituí-la pelos caracteres "|< >|" semelhantes as imagens utilizadas na
tela de seleção, e que não necessitam ser traduzidos.
5. 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.i}, {utp/ut-
field.i} ou ainda {utp/ut-table.i}.
6. Em todos os forms/frames de impressão deve-se colocar a cláusula stream-
io.
7. Para utilizar a funcionalidade de impressão para arquivo RTF:
7.1. definir o préprocessador conforme abaixo:
&GLOBAL-DEFINE RTF YES
7.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.
Este número deve ser ajustado para cada relatório conforme o tamanho
do modelo RTF que vai ser utilizado. Caso este tamanho não esteja
correto ocorrerá problema na quebra da página.
7.3. a definição da temp-table tt-param deve ser idêntica a definição da
mesma no programa de interface.
7.4. condicionar o VIEW das frames de cabeçalho/rodapé no início do
programa, para que quando o destino for para RTF as mesmas não
sejam apresentadas. Segue exemplo abaixo:
IF tt-param.l-habilitaRTF <> YES THEN DO:
VIEW STREAM str-rp FRAME f-cabec.
VIEW STREAM str-rp FRAME f-rodape.
END.

O nome das frames vai depender de qual include de cabeçalho esta


sendo utilizado, abaixo segue as includes disponivies e suas
respectivas frames:
{include/i-rpcab.i}  f-cabec e f-rodape
{include/i-rpcb80.i}  f-cabec-80 e f-rodape-80
{include/i-rpc255.i}  f-cabec-255 e f-rodape-255
Exemplo de um
progra
ma
RP.P
de
Relatór
io

Observação Para geração de relatórios em formato PDF é necessário que o view das frames
de cabeçalho e rodapé esteja definido corretamente. Sem esta definição não será possível gerar
relatórios em formato PDF.

/* include de controle de versão */


{include/i-prgvrs.i SP0014RP 1.00.00.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 AS INTEGER
FIELD arquivo AS CHARACTER FORMAT "x(35)"
FIELD usuario AS CHARACTER FORMAT "x(12)"
FIELD data-exec AS DATE
FIELD hora-exec AS INTEGER
FIELD classifica AS INTEGER
FIELD desc-classifica AS CHARACTER FORMAT "x(40)"
FIELD modelo-rtf AS CHARACTER FORMAT "x(35)" /*
arquivo modelo para RTF */
FIELD l-habilitaRtf AS LOG
FIELD ini-cust-num LIKE customer.cust-num /* campo
página seleção */
FIELD fim-cust-num LIKE customer.cust-num /* campo
página seleção */
FIELD sales-rep LIKE salesrep.sales-rep /* campo
página parâmetros */
.

DEFINE TEMP-TABLE tt-raw-digita NO-UNDO


APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 179

FIELD raw-digita AS RAW.

/* recebimento de parâmetros */
DEFINE INPUT PARAMETER raw-param AS RAW NO-UNDO.
DEFINE INPUT PARAMETER TABLE FOR tt-raw-digita.

CREATE tt-param.
RAW-TRANSFER raw-param TO tt-param.

/* include padrão para variáveis de relatório */


{include/i-rpvar.i}

/* definição de variáveis */
DEFINE VARIABLE h-acomp AS HANDLE NO-UNDO.

/* definição de frames do relatório */


FORM /* usar ordenado por order-num */
Order.Order-num
Order.Cust-Num
Order.Order-Date
Order.Promise-Date
Order.Sales-Rep
Order.Ship-Date
Order.Carrier
WITH FRAME f-order DOWN STREAM-IO.
FORM /* usar ordenado por cust-num */
Order.Cust-Num
Order.Order-num
Order.Order-Date
Order.Promise-Date
Order.Sales-Rep
Order.Ship-Date
Order.Carrier
WITH FRAME f-customer DOWN stream-io.

/* include padrão para output de relatórios */


{include/i-rpout.i &STREAM="stream str-rp"}

/* include com a definição da frame de cabeçalho e rodapé */


{include/i-rpcab.i &STREAM="str-rp"}

/* bloco principal do programa */


ASSIGN c-programa = "SP0014RP"
c-versao = "1.00"
c-revisao = ".00.000"
c-empresa = "Empresa Teste"
c-sistema = "Sports"
c-titulo-relat = "Listagem Order".

/* 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.
VIEW STREAM str-rp FRAME f-rodape.
END.

/* executando de forma persistente o utilitário de


acompanhamento */
RUN utp/ut-acomp.p PERSISTENT SET h-acomp.
{utp/ut-liter.i Imprimindo *}
RUN pi-inicializar IN h-acomp (INPUT RETURN-VALUE).
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 181

/* corpo do relatório */
IF tt-param.classifica = 1 THEN DO:
FOR EACH order WHERE
order.sales-rep = tt-param.sales-rep AND
order.cust-num >= tt-param.ini-cust-num AND
order.cust-num <= tt-param.fim-cust-num
NO-LOCK
ON STOP UNDO, LEAVE:
RUN pi-acompanhar IN h-acomp (INPUT STRING(order.order-
num)).
DISPLAY STREAM str-rp
Order.Cust-Num
Order.Order-num
Order.Order-Date
Order.Promise-Date
Order.Sales-Rep
Order.Ship-Date
Order.Carrier WITH FRAME f-order.
DOWN STREAM str-rp WITH FRAME f-order.
END.
END.
ELSE DO:
FOR EACH order WHERE
order.sales-rep = tt-param.sales-rep AND
order.cust-num >= tt-param.ini-cust-num AND
order.cust-num <= tt-param.fim-cust-num
NO-LOCK
BY order.cust-num
ON STOP UNDO, LEAVE:
RUN pi-acompanhar IN h-acomp (INPUT STRING(order.order-
num)).
DISPLAY STREAM str-rp
Cadastro de
Parâme
tros e
Digitaç
ões
(JE010
1)

Order.Cust-Num
Order.Order-num
Order.Order-Date
Order.Promise-Date
Order.Sales-Rep
Order.Ship-Date
Order.Carrier WITH FRAME f-customer.
DOWN STREAM str-rp WITH FRAME f-customer.
END.
END.
RUN pi-finalizar IN h-acomp.
/*fechamento do output do relatório*/
{include/i-rpclo.i &STREAM="stream str-rp"}
RETURN "OK":U.

Preparando o Relatório para Execução no Módulo JOB


EXECUTION
Este módulo, que se encontra no menu de Tecnologia, 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, a cada execução, alguns parâmetros
devem ser alterados (geralmente datas). A esta lista de programas é dado o
nome de JOB (tarefa).

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. Essa
preparação consiste em se cadastrar os parâmetros e as digitações necessários
para que sejam executados estes programas.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 183

Parâmetros

São as informações que constam nas pastas Seleção, Classificação, Parâmetros


e Impressão dos programas de relatórios, ou quaisquer informações únicas em
programas de outro tipo que serão armazenadas na tabela TT-PARAM para
execução do mesmo.
Exemplos de parâmetros: Períodos para execução, destino (arquivo,
impressora), nome de arquivo, classificação, intervalos diversos, data e hora
para execução e etc.
Cadastrando os
Parâme
tros

Clicando no botão Incluir ou Modificar, 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.
O preenchimento de todos os campos é obrigatório.
Digitações

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 185

Seqüência: posição do que representa o parâmetro na temp-table tt-param


Campo: código do atributo na temp-table tt-param
Tipo: tipo de dado do atributo na temp-table tt-param
Extent: Indica, quando assinalado, que o atributo tem extent
Tamanho: tamanho do extent (só pode ser informado se tiver sido marcado
extent)
Formato: formato do atributo da temp-table tt-param (deve respeitar os
padrões Progress)
Label: label do atributo na temp-table tt-param
Ajuda: texto de ajuda a ser apresentado ao usuário, na parte inferior da
janela, 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, respectivamente, “Arquivo” e “Impressora”, no
campo Ajuda deveria ser escrito: “1 – Arquivo, 2 – Impressora”
Val Default 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, o valor default será uma
lista de valores separados por vírgulas

São informações que podem ter n valores diferentes para a execução do


programa, como segue abaixo, no relatório Resumo de Ordens de Serviço.
Cada ocorrência (linha) dessa digitação é chamada registro e sua quantidade é
ilimitada. Somente programas que possuam a pasta digitações em sua
execução normal deverão possuir digitações cadastradas.
Após cadastrados os campos de digitações, clique no botão registros e informe
os valores default para cada campo em N registros.
Considerações
Exportação JOB
sobre o
Executi
cadastr
on
amento
(JE010
de
4)
campos

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 187

Deve sempre ser observada o label e o valor default utilizada na tela do


programa original, pois muitas vezes o nome do campo não expressa em
detalhes o significado correto do mesmo.

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, através do devido cadastramento de seus
parâmetros e digitações.
Para fazer a exportação, basta informar o nome do diretório onde serão
gerados os arquivos .JED (digitações) e .JEP (parâmetros) dos programas, o
intervalo dos programas a serem gerados e clicar em Executar.
Os nomes dos arquivos serão os mesmos dos programas. Ex.: Para o programa
ap0707rp.p será gerado o ap0707rp.jed (digitações e ap0707.jep (parâmetros).
Caso deseje consultar o lay-out do arquivo gerado, selecione a pasta Lay-out.
Nela encontram-se os lay-outs dos dois arquivos gerados: parâmetros e
digitações.
Após a geração destes arquivos, 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.
Observação O módulo JOB EXECUTION somente estará disponível para uso interno
(Datasul S.A.) ou para clientes que tiverem adquirido o produto. Para maiores informações
referentes ao produto, deverá ser consultado o manual do produto, localizado no diretório
DOCPDF/DTSUL.
Implementação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 189

Como construir um programa de Parâmetros Únicos


Estilo
' Utilizado Nome Físico
Window Parâmetros Únicos Masters/w-paruni.w
 selecionar o estilo relacionado na tabela acima;
 verificar se já existe uma SmartQuery para a tabela que se deseja construir
o programa de Parâmetros Únicos. Caso não exista, criar uma nova
utilizando o estilo CustomQuery Wizard;
 instanciar a SmartQuery na página 1 da SmartWindow;
 verificar se já existe uma SmartViewer com os atributos que devem ser
editados. Caso não exista, criar uma nova utilizando o estilo
CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar esta e outras SmartViewers a partir da página 1 no folder e


aceitar a sugestão de SmartLink do Wizard;
 se existirem mais de uma SmartViewer, devem ser criados SmartLinks de
GROUP-ASSIGN, tendo como Source a SmartViewer da página 1 e como
a Target a SmartViewer corrente;
 inserir a seguinte lógica após o run-dispatch da local-initialize da
SmartWindow:
find first <tabela> no-lock no-error.
if not avail <tabela> then do:
run notify in this-procedure ('add-record':U).
end.
else
run new-state('update-begin':U).
run dispatch in this procedure ('enable-fields').
Implementação

 criar um SmartLink de TABLEIO, tendo como Source THIS-


PROCEDURE e como Target a SmartViewer da página1;
 redimensionar o Folder e a SmartWindow de acordo com os objetos nela
instanciados;
 salvar a SmartWindow com o nome definido para o programa de
Parâmetros Únicos.

Como construir um programa de Formação


Estilo
' Utilizado Nome Físico
Window Formação Masters/w-forma.w
 selecionar o estilo relacionado na tabela acima;
 verificar se já existe uma SmartQuery para a tabela que se deseja construir
o programa de Formação. Caso não exista, criar uma nova utilizando o
estilo CustomQuery Wizard;
 instanciar a SmartQuery na página 0 da SmartWindow e aceitar as
sugestões de SmartLink do Wizard;
 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. 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;
 criar um SmartLink do tipo STATE, tendo como Source: p-navega e como
Target: SmartQuery;
 criar um SmartLink do tipo STATE, tendo como Source: p-exihel e como
Target: SmartQuery;
 verificar se já existe uma SmartViewer com os atributos da tabela que
devem ser pesquisados. Caso não exista, criar uma nova SmartViewer
utilizando o estilo CustomViewer com Auto-Field;
Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 191

opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.

 instanciar a SmartViewer na página 0 da SmartWindow;


 verificar se já existe um SmartBrowser que contenha os dados que servem
de fonte para o SmartBrowser de Formação. Caso não exista, criar um
novo utilizando o estilo CustomBrowser Wizard; na construção desse
SmartBrowser, deve ser observado o seguinte:
 como exceção à regra, ele deve ser redimensionado, de modo que
caiba no lado esquerdo dos botões bt-add e bt-del da window
formação;
 deve ser criada uma trigger de MOUSE-SELECT-DOUBLE-CLICK e
inserido o seguinte código:
RUN NEW-STATE(INPUT 'incluir-browse':U).

 instanciar o SmartBrowser que serve de fonte para o SmartBrowser de


Formação no lado esquerdo da página 0 da SmartWindow;
 criar um SmartLink do tipo STATE, tendo como Source: o SmartBrowser
fonte e como Target: THIS-PROCEDURE;
 verificar se já existe um SmartBrowser com a tabela de formação. Caso
não exista, criar um novo utilizando o estilo CustomBrowser Formação;
 na construção desse SmartBrowser, devem ser observados os seguintes
aspectos:
 deve ser definida como tabela externa, a tabela utilizada na
SmartQuery do programa de Formação;
 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
<campo-1>: campo da <tabela-1> que deve constituir parte da chave
da tabela de formação
Exemplo

<campo-2>: campo da <tabela-2> que deve constituir parte da chave


da tabela de formação
 se for necessário, ajustar a lógica da Procedure PI-ADD-BROWSE de
modo que atenda as necessidades do programa.
def input parameter rw-row-1 as rowid no-undo.
def input parameter rw-row-2 as rowid no-undo.
def var i-next-line-num as integer no-undo.
find order where rowid(order) = rw-row-1 no-lock.
find item where rowid(item) = rw-row-2 no-lock.
find last order-line
where order-line.order-num = order.order-num no-lock no-error.
if avail order-line then
assign i-next-line-num = order-line.order-num + 1.
else
assign i-next-1 line num = 1.
create order-line.
assign order-line.order-num = order.order-num
order-line.item-num = item.item-num
order-line.line-num = i-next-line-num.

 inserir o seguinte código na trigger de MOUSE-SELECT-CLICK:


RUN PI-POSICAO-BROWSE IN THIS-PROCEDURE (OUTPUT v-
row).
FIND <tabela-formação> WHERE ROWID (<tabela-formação>)
= V-ROW no-error.
IF AVAIL (<tabela-formação>) THEN DO:
DELETE (<tabela-formação>).
RUN DISPATCH IN THIS-PROCEDURE (INPUT 'open-
query':U).
END.

 instanciar o SmartBrowser de formação no lado direito da página 0 da


SmartWindow;
 criar um SmartLink do tipo STATE, tendo como Source: SmartBrowser
formação e como Target: THIS-PROCEDURE;
 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
atributos do registro de formação. Para criar este programa de
modificaçã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:
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 193

<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(<)", 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. Ter o cuidado para que a SmartViewer fique
centralizada na SmartWindow;
 salvar a SmartWindow com o nome definido para a Consulta
Relacionamento.

Lista de Links:
Source
' Link Type Target
h_browse-formação STATE THIS-PROCEDURE
h_p-exihel STATE h_query
Implementação

h_p-navega NAVIGATION h_query


h_p-navega STATE h_query
h_query RECORD h_viewer
h_query RECORD h_browse-formação
THIS PROCEDURE STATE h_browse-fonte

Como construir um programa de Formação sem Navegação


Estilo
' Utilizado Nome Físico
Window Formação sem Masters/w-form2.w
Navegação
 estilo de formação sem navegação é dependente, ou seja, deve sempre ser
chamado a partir de um CustomBrowser Formação Filho. O botão
"Formação" deve chamar o estilo de Formação sem Navegação;
 o template utilizado para construção deste tipo de programa não utiliza
SmartObjects;
 identifique que tabelas servem como:
Pai;
Origem;
Destino;
 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, 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);
 jamais eliminar um "include" padrão mesmo que ele não possua nenhum
conteúdo/lógica;
Objetos do programa:
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 195

Seqüência
1. Criar browse origem:
 definir query;
 definir campos para display.
2. Colocar campos da tabela pai.
3. Criar browse destino:
 criar uma temp-table (na seção definitions):
 colocar nesta temp-table os atributos da tabela destino.
 definir query (relacionando esta com a tabela pai) para a temp-table,
portanto esta deve ser uma freeform query;
 definir campos para display.
4. Preencher pré-processor da seção de definições com o nome da tabela pai;
5. Acrescentar dentro da procedure local-initialize lógica para carregar a
temp-table com os registros que já existem na tabela de destino.
Implementação

6. Criar funções e procedures internas:


 criar função para mostrar o registro da tabela pai (pi-show-master-
record);
 criar inclusão no browse destino:
 Procedure pi-ins - lê os registros selecionados verifica se o registro
pode ser incluído, através da função is-create-allowed, e caso a
inclusão seja permitida executa a procedure pi-add-to-target;
 Função is-create-allowed - valida se o registro não existe ainda no
browse destino, ou realiza outras regras de negócio que verificam
se a inclusão é valida retorna um status que indica o resultado dos
testes;
 Procedure pi-add-to-target - realiza o create e o assign no browse
destino (temp-table);
 criar eliminação do browse destino:
 Procedure pi-del - 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 pi-
delete-from-target (elimina da temp-table).
 criar uma procedure interna (pi-commit) que transfira os registros da
temp-table para a tabela de destino, esta procedure é chamada pelo
evento choose do botão 'Ok':
Como construir um Browse Formação Filho
Estilo
' Utilizado Nome Físico
CustomBrowser Formação Filho Masters/wbrwfrm.w
 utilizar o wizard, atentando para o seguinte:
 deve ser informada a tabela externa;
 na cláusula Options, deve-se fazer as seguintes alterações:
 modificar na coluna Returned de All Fields para Fields Used;
 desmarcar as opções Key-Phrase e SortBy-Phrase.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 197

 o index-reposition deve ser sempre setado. Para tanto, na cláusula


Table, deve-se marcar a opção Indexed-Reposition.
 salvar o CustomBrowse com o nome definido para Browse de Formação
Filho.

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.w), que é uma variação do estilo de
relatórios, portanto sem SmartViewer e SmartFolders.
Dicas Gerais
 tabela de para de folder/páginas e com objetos relacionados:
'Página-Folder Frame Imagem Preprocessador
Layout f-pg-lay im-pg-lay PGLAY
Seleção f-pg-sel im-pg-sel PGSEL
Parâmetros f-pg-par im-pg-par PGPAR
Log f-pg-log im-pg-log PGLOG
 para selecionar uma página para trabalhar utilizar o botão 'List-Objects',
que apresenta um browse com os objetos do programa, então sobre o
frame relacionado à página, acionar o botão 'TO TOP';

Botão List Objects;

Botão To Top;
 também, neste estilo, todo trabalho de tradução de labels, helps, screen-
values deve ser feito automaticamente por um include padrão do estilo.
Exceções: list-items do widget combo-box;
 durante a importação, existem duas streams abertas, uma para importação
dos dados e outra para impressão do log;
 o log de importação pode ser completo, na opção. 'Todos' ou imprimir
somente os registros que apresentaram erro, através da opção 'Rejeitados'.
Preparação do programa
1. Verificar quantas páginas são necessárias, as páginas de layout, parâmetros
e log são obrigatórias, somente a página de seleção é opcional, caso haja
seleção desconsiderar as tarefas 2, 3 e 4.
2. Eliminar a frame f-pg-sel.
3. Eliminar a imagens im-pg-log e renomear as imagens:
im-pg-par > im-pg-log
im-pg-sel > im-pg-par
4. Em 'Definitions' limpar o conteúdo dos preprocessadores PGSEL
&GLOBAL-DEFINE PGLAY f-pg-lay
&GLOBAL-DEFINE PGSEL
&GLOBAL-DEFINE PGPAR f-pg-par
&GLOBAL-DEFINE PGLOG f-pg-log

5. Se a página de seleção não existir, no 'Main-block' do programa, corrigir a


chamada do include i-immbl.i, passando como parâmetro posicional a
imagem da página, onde o programa deve apresentar inicialmente,
exemplo:
{include/i-immbl.i im-pg-par}

Página de Layout
1. No 'Main Block', existe a chamada para um include denominado
{include/i-imvrf.i}, que possue dois parâmetros, 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). Exemplo:
{ include/i-imvrf.i &programa=CP0406 &versãolayout=001 }

Criar um arquivo que contenha o layout de importação, nos padrões do


Produto Datasul-EMS.
2. Este arquivo tem o seguinte nome e path: LAYOUT/LOXX9999.001.
Página de Seleção
1. Colocar os fill-in´s de inicial e final, para cada campo que precisar de
faixa. A sugestão é criá-los como 'Database Fields' e após convertê-los
para variáveis para obter automaticamente os labels, formatos e tamanhos
do dicionário de dados.
2. Corrigir os 'initial values' das variáveis de inicial e final.
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 199

3. Retirar possíveis queries que o UIB automaticamente queira associar a


frame.
Pagina de Parâmetros
1. Colocar as variáveis necessárias na representação desejada (radio-set,
toggle-box, fill-in), definindo label, formato, initial e help para as mesmas.
2. Caso seja necessário implementar retângulos com label, estes labels devem
ser fill-in´s view-as text, e o seu valor deve ser informado no seu initial e
private-data. As propriedades 'Display' e 'Enable' devem ser retiradas
3. No on choose do bt-arquivo-entrada, pode ser adicionado um terceiro
parâmetro na include i-imarq.i , onde é possível passar como parâmetro os
filtros que serão utilizados na sistem dialog, se não for passado nada neste
parâmetro a include assumira como padrão o tipo de arquivo *.lst e todos
os tipos de arquivos.

DO:
{include/i-imarq.i c-arquivo-entrada f-pg-par "'*.XLS' '*.xls' , 'todos' '*.*'" }
END.

Página de Log
Não existem tarefas.
Gravação e validação dos parâmetros
1. Em 'Definitions', implementar os campos de parâmetros e seleção na
definição da temp-table tt-param.
2. Na procedure 'pi-executar', colocar as das páginas de parâmetros e seleção,
lembrando que elas devem apresentar uma mensagem de erro cadastrada,
posicionar na página com problemas, colocando o focus no campo com
problemas.
if input frame f-pg-par i-nr-nivel > 19 then do:
run utp/ut-msgs.p (input "show",
input 73,
input " ").
apply 'mouse-select-click' to im-pg-par in frame f-relat.
apply 'entry' to i-nr-nivel in frame f-pg-par.
return error.
end.
Exemplo

3. Na procedure 'pi-executar', colocar a lógica de gravação dos parâmetros e


seleção na temp-table tt-param.
4. Ainda na procedure 'pi-executar', substituir na chamada do include
{include/i-imrun.i} a literal 'XXP/XX9999RP.P' pelo programa que deve
importará os registros.
Dicas para criação do Programa RP.P de Importação
O programa de execução do relatório (rp.p) é um programa procedural sem
qualquer tipo de interface com o usuário, exceto pela caixa de
acompanhamento de execução (ut-acomp/ut-perc) quando necessário. Da
mesma forma, nenhum programa chamado a partir de um rp.p não deve
possuir qualquer tipo de interface. Todas as validações ou informações com
necessidade de intervenção do usuário devem ser tratadas pelo programa .w
que o chama.
1. Definir uma stream para a importação, deixando a stream padrão definido
como STR-RP para a impressão do log.
2. Se a implementação for uma conversão de um programa originário do
MAGNUS, retirar a chamada para o include {cdp/cd9000.i} e substituir as
seguintes chamadas, referentes a impressão do log de importação:
Include
' Velho Include Novo
Cdp\cd9500.i Include\i-rpvar.i
Cdp\cd9500.fl Include\i-rpcab.i
Cdp\cd9520.i Include\i-rpout.i
Cdp\cd9540.i Include\i-rpclo.i
2.1. Substituir as variáveis de parâmetros e seleção pelos respectivos
campos da temp-table tt-param.
3. Utilizar um stream padrão definido como STR-RP, para impressão do log,
deve-se passar o parâmetro &stream com o nome da stream para os
includes i-rpcab.i, i-rpcb80, i-rpc255.i, i-rpout.i e i-rpclo.i.
{include/i-rpcab.i &stream = "str-rp"}
{include/i-rpcb80.i &stream = "str-rp"}
{include/i-rpc255.i &stream = "str-rp"}
{include/i-rpout.i &stream = "stream str-rp"}
{include/i-rpclo.i &stream = "stream str-rp"}.

4. Na chamada do include i-rpout.i, passar o parâmetros {&tofile}. Exemplo:


{include/i-rpout.i &tofile=tt-param.arq-destino}
Exemplo de um
progra
ma
RP.P
de
Importa
ção

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 201

5. 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}, {utp/ut-field.i}
ou ainda {utp/ut-table.i}.
6. Em todos os forms/frames de impressão deve-se colocar a cláusula stream-
io.
7. Nas seleções, ao invés de utilizar a palavra "à", para dar idéia de faixa,
substituí-la pelos caracteres "|< >|" semelhantes as imagens utilizadas na
tela de seleção, e que não necessitam ser traduzidos.
/* include de controle de versão */
{include/i-prgvrs.i XX9999RP 1.00.00.000}
/* definição das temp-tables para recebimento de parâmetros */
define temp-table tt-param
field destino as integer
field arq-destino as char
field arq-entrada as char
field todos as integer
field usuario as char
field data-exec as date
field hora-exec as integer
field cust-ini as integer
field cust-fim as integer

def temp-table tt-raw-digita


field raw-digita as raw.
/* recebimento de parâmetros */
def input parameter raw-param as raw no-undo.
def input parameter tabel for tt-raw-digita.
create tt-param.
raw-transfer.raw-param to tt-param.
/* include padrão para variáveis para o log */
{include/i-rpvar.i}
/* definição de variáveis e streams */
def stream s-imp.
def var h-acomp as handle no-undo.
def var c-linha as char no-undo.
def var i-cust as int no-undo.
/* definição de frames do log */
/* include padrão para output de log */
{include/i-rpout.i &STREAM="stream str-rp" &TOFILE=tt-param.arq-
destino}
/* include com a definição da frame de cabeçalho e rodapé */
{include/i-rpcab.i &STREAM="str-rp"}
/* bloco principal do programa */
assign c-programa = "XX0006RP"
c-versao = "1.00"
c-revisao = ".00.000"
c-empresa = "Empresa Teste"
c-sistema = 'Sports'
c-titulo-relat = "Listagem de Erros da Importação de
Clientes".
view stream str-rp frame f-cabec.
view stream str-rp frame f-rodape.
run utp/ut-acomp.p persistent set h-acomp.
{utp/ut-liter.i Importando *}

run pi-inicializar in h-acomp (input RETURN-VALUE).


/* define o arquivo de entrada informando na página de
parâmetros */
input stream s-imp from value(tt-param.arq-entrada).
/* bloco principal do programa */
repeat on stop undo, leave:
import stream s-imp unformatted c-linha.
run pi-acompanhar in h-acomp (input c-linha).
assign i-cust = integer(substring(c-linha,1,5)).
find customer where customer.cust-num = i-cust no-lock.
if not avail customer then do:
create customer.
assign customer.cust-num = i-cust
customer.name = substring(c-linha,5).
end.
end.
input stream s-imp close.
/* fechamento do output do log */
{include/i-rpclo.i &STREAM="stream str-rp"}
run pi-finalizar in h-acomp.
return "Ok":U.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 203

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.w), que é uma variação do estilo de
relatórios, portanto sem SmartViewers e SmartFolders.
Dicas Gerais
 tabela de para de folder/páginas e com objetos relacionados:
Página-Folder
' Frame Imagem Preprocessador
Layout f-pg-lay im-pg-lay PGLAY
Seleção f-pg-sel im-pg-sel PGSEL
Parâmetros f-pg-par im-pg-par PGPAR
Log f-pg-log im-pg-log PGLOG
 para selecionar uma página para trabalhar utilizar o botão 'List-Objects',
que apresenta um browse com os objetos do programa, então sobre o
frame relacionado à página, acionar o botão 'TO TOP';

Botão List Objects;

Botão To Top;
 também, neste estilo, todo trabalho de tradução de labels, helps, screen-
values deve ser feito automaticamente por um include padrão do estilo.
Exceções: list-items do widget combo-box;
 durante a exportação, existem duas streams abertas, uma para exportação
dos dados e outra para impressão do log;
Preparação do programa
1. Verificar quantas páginas são necessárias, as páginas de layout, parâmetros
e log são obrigatórias, somente a página de seleção é opcional, caso haja
seleção desconsiderar as tarefas 2, 3 e 4.
2. Eliminar a frame f-pg-sel.
3. Eliminar a imagens im-pg-log e renomear as imagens:
im-pg-par > im-pg-log
im-pg-sel > im-pg-par
4. Em 'Definitions' limpar o conteúdo dos preprocessadores PGSEL
&GLOBAL-DEFINE PGLAY f-pg-lay
&GLOBAL-DEFINE PGSEL
&GLOBAL-DEFINE PGPAR f-pg-par
&GLOBAL-DEFINE PGLOG f-pg-log

5. Se a página de seleção não existir, no 'Main-block' do programa, corrigir a


chamada do include i-immbl.i, passando como parâmetro posicional a
imagem da página, onde o programa deve apresentar inicialmente,
exemplo:
{include/i-immbl.i im-pg-par}

Página de Layout
1. No 'Main Block', existe a chamada para um include denominado
{include/i-imvrf.i}, que possue dois parâmetros, 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). Exemplo:
{ include/i-imvrf.i &programa=CP0406 &versãolayout=001 }

2. Criar um arquivo que contenha o layout de importação, nos padrões do


Produto Datasul-EMS.
3. Este arquivo tem o seguinte nome e path: LAYOUT/LOXX9999.001.

Página de Seleção
1. Colocar os fill-in´s de inicial e final, para cada campo que precisar de
faixa. A sugestão é criá-los como 'Database Fields' e após convertê-los
para variáveis para obter automaticamente os labels, formatos e tamanhos
do dicionário de dados.
2. Corrigir os 'initial values' das variáveis de inicial e final.
3. Retirar possíveis queries que o UIB automaticamente queira associar a
frame.
Página de Parâmetros
1. Colocar as variáveis necessárias na representação desejada (radio-set,
toggle-box, fill-in), definindo label, formato, initial e help para as mesmas.
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 205

2. Caso seja necessário implementar retângulos com label, estes labels devem
ser fill-in´s view-as text, e o seu valor deve ser informado no seu initial e
private-data. As propriedades 'Display' e 'Enable' devem ser retiradas.
3. Mudar o private-data e o initial do label "Arquivo de Entrada" do
retângulo para "Arquivo de Saída".
4. No on choose do bt-arquivo-entrada, pode ser adicionado um terceiro
parâmetro na include i-imarq.i , onde é possível passar como parâmetro os
filtros que serão utilizados na sistem dialog, se não for passado nada neste
parâmetro a include assumira como padrão o tipo de arquivo *.lst e todos
os tipos de arquivos.

DO:
{include/i-imarq.i c-arquivo-entrada f-pg-par "'*.XLS' '*.xls' , 'todos' '*.*'" }
END.

Página de Log
1. Remover o retângulo, o label e o radio-set com as opções "Todos" e
"Rejeitados".
2. Mover todos os outros objetos desta frame para cima. Não esquecer do
botão "Configurar Impressora".
Gravação e validação dos parâmetros
1. Em 'Definitions', implementar os campos de parâmetros e seleção na
definição da temp-table tt-param.
2. Eliminar o campo todos da temp-table tt-param.
3. Na procedure 'pi-executar', colocar as validações das páginas de
parâmetros e seleção, lembrando que elas devem apresentar uma
mensagem de erro cadastrada, posicionar na página com problemas,
colocando o focus no campo com problemas.
if input frame f-pg-par i-nr-nivel > 19 then do:
run utp/ut-msgs.p (input "show",
input 73,
input " ").
apply 'mouse-select-click' to im-pg-par in frame f-relat.
apply 'entry' to i-nr-nivel in frame f-pg-par.
return error.
end.

4. Na procedure 'pi-executar', substituir o código de validação do arquivo de


entrada:
assign file-info: file-name = input frame f-pg-par c-arquivo-
entrada.
if file-info:pathname = ? then do:
run utp/ut-msgs.p (input "show",
input 326,
input c-arquivo-entrada).
apply 'mouse-select-click' to im-pg-par in frame f-import.
apply 'entry' to c-arquivo-entrada in frame f-pg-par.
return error.
end.

por:
run utp/ut-vlarq.p (input frame f-pg-par c-arquivo-entrada).
if return-value = "nok" then do:
run utp/ut-msgs.p (input "show",
input 73,
input "").
apply 'mouse-select-click' to im-pg-log in frame f-import.
apply 'entry' to c-arquivo-destino in frame f-pg-log.
return error.
end.

5. Na procedure 'pi-executar', colocar a lógica de gravação dos parâmetros e


seleção na temp-table tt-param.
6. Ainda na procedure 'pi-executar', substituir na chamada do include
{include/i-imrun.i} a literal 'XXP/XX9999RP.P' pelo programa que
exportará os registros.
Dicas para criação do Programa RP.P de Exportação
O programa de execução da exportação (rp.p) é um programa procedural sem
qualquer tipo de interface com o usuário, exceto pela caixa de
acompanhamento de execução (ut-acomp/ut-perc) quando necessário. Da
mesma forma, nenhum programa chamado a partir de um rp.p não deve
possuir qualquer tipo de interface. Todas as validações ou informações com
Exemplo de um
progra
ma
RP.P
de
Exporta
ção

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 207

necessidade de intervenção do usuário devem ser tratadas pelo programa .w


que o chama.
1. Definir uma stream para a importação, deixando a stream padrão definido
como STR-RP para a impressão do log.
2. Se a implementação for uma conversão de um programa originário do
MAGNUS, retirar a chamada para o include {cdp/cd9000.i} e substituir as
seguintes chamadas, referentes a impressão do log de exportação:
Include
' Velho Include Novo
Cdp\cd9500.i Include\i-rpvar.i
Cdp\cd9500.fl Include\i-rpcab.i
Cdp\cd9520.i Include\i-rpout.i
Cdp\cd9540.i Include\i-rpclo.i
2.1 Substituir as variáveis de parâmetros e seleção pelos respectivos
campos da temp-table tt-param.
3. Utilizar um stream padrão definido como STR-RP, para impressão do log,
deve-se passar o parâmetro &stream com o nome da stream para os
includes i-rpcab.i, i-rpcb80, i-rpc255.i, i-rpout.i e i-rpclo.i.
{include/i-rpcab.i &stream = "str-rp"}
{include/i-rpcb80.i &stream = "str-rp"}
{include/i-rpc255.i &stream = "str-rp"}
{include/i-rpout.i &stream = "stream str-rp"}
{include/i-rpclo.i &stream = "stream str-rp"}.

4. Na chamada do include i-rpout.i, passar o parâmetro {&tofile}. Exemplo:


{include/i-rpout.i &stream = "stream str-rp" &tofile=tt-
param.arq-destino}

5. 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}, {utp/ut-field.i}
ou ainda {utp/ut-table.i}.
6. Em todos os forms/frames de impressão deve-se colocar a cláusula stream-
io.
7. Nas seleções, ao invés de utilizar a palavra "à", para dar idéia de faixa,
substituí-la pelos caracteres "|< >|" semelhantes as imagens utilizadas na
tela de seleção, e que não necessitam ser traduzidos.
/* include de controle de versão */
{include/i-prgvrs.i XX9999RP 1.00.00.000}
/* definição das temp-tables para recebimento de parâmetros */
define temp-table tt-param
field destino as integer
field arq-destino as char
field arq-entrada as char
field usuario as char
field data-exec as date
field hora-exec as integer

def temp-table tt-raw-digita


field raw-digita as raw.
/* recebimento de parâmetros */
def input parameter raw-param as raw no-undo.
def input parameter tabel for tt-raw-digita.
create tt-param.
raw-transfer.raw-param to tt-param.
/* include padrão para variáveis para o log */
{include/i-rpvar.i}
/* definição de variáveis e streams */
def stream s-exp.
def var h-acomp as handle no-undo.

/* definição de frames do log */


/* include padrão para output de log */
{include/i-rpout.i &STREAM="stream str-rp" &TOFILE=tt-param.arq-
destino}
/* include com a definição da frame de cabeçalho e rodapé */
{include/i-rpcab.i &STREAM="str-rp"}
/* bloco principal do programa */
assign c-programa = "XX0006RP"
c-versao = "1.00"
c-revisao = ".00.000"
c-empresa = "Empresa Teste"
c-sistema = 'Sports'
c-titulo-relat = "Listagem de Erros da Exportação de
Clientes".
view stream str-rp frame f-cabec.
view stream str-rp frame f-rodape.
Implementação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 209

run utp/ut-acomp.p persistent set h-acomp.


{utp/ut-liter.i Exportando *}

run pi-inicializar in h-acomp (input RETURN-VALUE).


/* 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.arq-entrada).
/* bloco principal do programa */
for each customer on stop undo, leave:
run pi-acompanhar in h-acomp (input string(customer.cust-
num)).
put stream s-exp unformatted string(customer.cust,
"99999")
string(customer.name,"x(40)")
skip.
end.
output stream s-exp close.
/*fechamento do output do log */
{include/i-rpclo.i &STREAM="stream str-rp"}
run pi-finalizar in h-acomp.
return "Ok":U.

Como construir um programa de Pesquisa


Estilo
' utilizado Nome Físico
Window Pesquisa Masters/w-pesqui.w
 selecionar o estilo relacionado na tabela acima;
 é necessário utilizar um SmartBrowser para cada classificação do
programa de Pesquisa, onde a ordem das colunas no browser deve ser a
ordem de classificação, para todos os SmartBrowsers que devem estar
colocados no programa de Pesquisa, 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. Caso não exista, criar um novo utilizando o estilo
CustomBrowserZoom Wizard;
 instanciar o SmartBrowser no SmartFolder;

 criar um SmartLink do tipo STATE, tendo como Source o


SmartBrowser recém instanciado e como Target, THIS-
PROCEDURE;
 recomenda-se que cada SmartBrowser das diferentes páginas do
SmartFolder tenha o mesmo tamanho;
 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
' Link Type Target
h_browse STATE THIS-PROCEDURE
h_folder PATE THIS-PROCEDURE

Como construir um programa "Vá Para"


Estilo Utilizado Nome Físico
Implementação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 211

'
Dialog VaPara Masters/d-vapara.w
 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:

 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:
Implementação

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 Nome Físico
Window Digitação Rápida Masters/w-digit.w
 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;
Como construir um Browse de Digitação
Estilo
' Utilizado Nome Físico
CustomBrowserDigita Masters/b-digit.w
 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";
Implementação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 213

 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-busca-
valor, 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;
 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 Nome Físico
Custom Query Wizard Masters/wquery.w
 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;
Implementação

Como construir viewers


Estilo
' Utilizado Nome Físico
Custom Viewer com AutoField Masters/vieweraf.w
 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.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 215

 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 'ADM-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 '{&ADM-
CREATE-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 rt-key +
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;
Exemplo

 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 '{&ADM-
MODIFY-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;
/* 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} = return-
value
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";
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 217

 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.
/* 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}

por estas a seguir:


if not frame {&frame-name}:validate() then
return 'ADM-ERROR':U.

 definir no Method-Library a include i-auxtab.i, deve ser a primeira da


lista;
 definir ao menos uma tabela externa;
 inserir os objetos (fill-in´s, combo-boxes, radio-sets, retângulos, etc) na
viewer, esses objetos não podem ser campos de tabelas;
 desabilitar todos os objetos da tela que não devam ser mostrados
habilitados;
 Atenção: o controle de habilitação/desabilitação de campos deve ser feito
pelo usuário. Para isso, deve-se colocar os campos nos preprocessadores
de acordo com a tabela abaixo:

Tipo de Objetos Preprocessador Finalidade
Chaves (variáveis que Adm-create-fields Habilitados somente na
representam chaves) criação de um novo registro.
Outras variáveis Adm-modify-fields Habilitados nas operações de
Adm-assign-fields ADD, COPY e MODIFY.
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 219

 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 (preparação para tradução), atribuição de itens para
combo-boxes e radio-sets, etc.;
/* Code placed here will execute PRIOR to standard behavior. */
{utp/ut-liter.i Quantidade * R}
assign fill-in_Qty:label in frame {&frame-name} = return- Comenta
value. r
{utp/ut-liter.i Preço * R} chamada
padrão
assign fill-in_Price:Label in frame {&frame-name} = return-
value.
{utp/ut-liter.i País * L}
assign cb-country:label in frame {&frame-name} = return-value
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. */

 customizar a procedure LOCAL-DISPLAY-FIELDS, sendo que é nessa


procedure que os valores dos objetos serão exibidos:
 comentar o dispatch padrão;
 inserir os comandos para que os valores dos objetos sejam exibidos.
/* Code placed here will execute PRIOR to standard behavior. */
Comenta
/* Dispatch standard ADM method. */ r
/* RUN dispatch IN THIS-PROCEDURE (INPUT 'initialize':U).chamada
*/
padrão
/* Code placed here will execute AFTER standard behavior. */
DISPLAY Order-Line Qty @ fill-in_Qty
Order-Line.Price @ fill-in_Price
Order-Line.Order-num @ fill-in_order-num
Order-Line.Line-num @ fill-in_line-num
Order-Line.Item-num @ fill-in_item-num
Order-Line.Discount @ fill-in_Discount
WITH FRAME {&FRAME-NAME}

 customizar a procedure LOCAL-ENABLE-FIELDS, sendo que é nessa


procedure que os objetos são habilitados:
 comentar o dispatch padrão;
Exemplo

 comentar a linha em que consta a seguinte sentença: if adm-new-


record then.
/* Code placed here will execute PRIOR to standard behavior. */
/* Dispatch standard ADM method. */ Comenta
r
/* RUN dispatch IN THIS-PROCEDURE (INPUT 'initialize':U). */
chamada
/* Code placed here will execute AFTER standard behavior. */
padrão
/* if adm-new-record = yes then */
&if defined(ADM-MODIFY-FIELDS) &then
enable {&ADM-MODIFY-FIELDS} with frame {&frame-name}.
&endif

Caso seja uma viewer principal, incluir:


RUN notify ('enable-fields, GROUP-ASSIGN-TARGET':U).

 customizar a procedure LOCAL-DISABLE-FIELDS, sendo que é nessa


procedure que os objetos são desabilitados:
 comentar o dispatch padrão;
 inserir as seguintes linhas:
&if defined(ADM-CREATE-FIELDS) &then
disable {&ADM-CREATE-FIELDS} with frame {&frame-name}.
&endif
/* Code placed here will execute PRIOR to standard behavior. */
/* Dispatch standard ADM method. */ Comenta
r */
/* RUN dispatch IN THIS-PROCEDURE (INPUT 'disable-fields':U).
chamada
/* Code placed here will execute AFTER standard behavior. */padrão
&if defined(ADM-CREATE-FIELDS) &then
disable {&ADM-CREATE-FIELDS} with frame {&frame-name}.
&endif
&if defined {ADM-MODIFY-FIELDS} &THEN
disable {&ADM-MODIFY-FIELDS} with frame {&frame-name}.
&endif

Caso seja uma viewer principal colocar:


RUN notify ('disable-fields, GROUP-ASSIGN-TARGET':U).

 customizar a procedure LOCAL-ASSIGN-STANTEMENT, sendo que é


nessa procedure que os objetos terão seus valores salvos:
 comentar o dispatch padrão;
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 221

 inserir a lógica de gravação dos valores das variáveis.


/* Code placed here will execute PRIOR to standard behavior. */
/* Dispatch standard ADM method. */
Comenta
/* RUN dispatch IN THIS-PROCEDURE (INPUT 'assign-statement':U).
*/ r
chamada
/* Code placed here will execute AFTER standard behavior. */
padrão
DO WITH FRAME {&FRAME-NAME} ON ERROR UNDO, RETURN "ADM-ERROR":
ASSIGN {&ADM-CREATE-FIELDS}{&ADM-MODIFY-FIELDS}.
ASSIGN order-line.Discount = FILL-IN_Discount
order-line.Item-num = FILL-IN_Item-num
order-line.Line-num = FILL-IN_Line-num
order-line.Order-num = FILL-IN_Order-num when adm-
new-record = yes
order-line.Price = FILL-IN_Price
order-line.Qty = FILL-IN_Qty
NO-ERROR.
IF ERROR-STATUS:ERROR THEN
RUN dispatch IN THIS-PROCEDURE ('show-erros':U).
END.

 alterar a altura de todos os atributos para 0.88;


 para os atributos que representam a chave de acesso a tabelas, caso forem
postos na tela:
 colocar o primeiro atributo na linha 1.17
 caso existam mais de um atributo que represente uma chave:
 colocá-los com 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 rt-key +
1.25
 se não forem colocados atributos que representem chaves:
 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;
 se não forem colocados atributos não chave, retirar o retângulo rt-mold;
 quanto à largura da SmartViewer:
 se a SmartViewer for usada dentro de um folder de Cadastro
Inclui/Modifica, alterar a largura de rt-key e rt-mold para 76,72;
 se a SmartViewer for usada dentro do Cadastro Inclui/Modifica 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, 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 Option' 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 viewers só com campos chave:
Viewer só com campos chave é aquela que não possui campos não chave
dispostos na tela. Essa viewer poderá conter variáveis dispostas para entrada
de dados pelo usuário;
 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;
 definir no Method-Library a include i-auxtab.i, deve ser a primeira da
lista;
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 223

 desabilitar todos os campos da tela;


Atenção: o controle de habilitação/desabilitação de campos deve ser feito pelo
usuário. Mais instruções a seguir:
 colocar os campos nos preprocessadores de acordo com a tabela abaixo:
Preprocessador Finalidade
Adm-create-fields Habilitados somente na criação de um novo registro
Adm-assign-fields Exemplo: operações de ADD e COPY
Adm-modify-fields Devem ser marcados os objetos que serão habilitados para alteração de
uma ocorrência na tabela. Observe que índices de tabelas não podem ser
alterados.
 customizar a procedure LOCAL-INITIALIZE para que as inicializações
dos objetos sejam feitas. Essas inicializações podem ser, atribuição de
labels (preparação para tradução), atribuição de itens para combo-boxes e
radio-sets, etc.;
/* Code placed here will execute PRIOR to standard behavior. */
{utp/ut-liter.i Quantidade * R}
assign fill-in_Qty:label in frame {&frame-name} = return-
value.
Exemplo

{utp/ut-liter.i Preço * R}
assign Order-line.Price:label in frame {&frame-name} =
return-value.
{utp/ut-liter.i País * L}
assign cb-country:label in frame {*frame-name} = return-value
{pdinc/i01pd001.i 03}.
/* Dispatch standard ADM method. */
RUN dispatch IN THIS-PROCEDURE ( INPUT 'initialize':U ).
/* Code placed here will execute AFTER standard behavior. */

 caso existam na viewer objetos não vinculados ao banco de dados


(variáveis), customizar a procedure LOCAL-DISPLAY-FIELDS para que
seus valores sejam exibidos.
/* Code placed here will execute PRIOR to standard behavior. */
/* Dispatch standard ADM method. */
RUN dispatch IN THIS-PROCEDURE (INPUT 'display-fields':U).
/* Code placed here will execute AFTER standard behavior. */
if avail Order-Line then
DISLPAY order-line.Qty = fill-in_Qty
order-line.Price = fill-in_Price
WITH FRAME {&FRAME-NAME}.

 customizar a procedure LOCAL-ENABLE-FIELDS:


 comentar o dispatch padrão;
 comentado a linha em que apareça a sentença: if adm-new-record =
yes then;
/* Code placed here will execute PRIOR to standard behavior. */
/* Dispatch standard ADM method. */
/* RUN dispatch IN THIS-PROCEDURE (INPUT 'enable-fields':U). */
/* 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}.
&endif

Caso seja uma viewer principal, incluir:


RUN notify ('enable-fields, GROUP-ASSIGN-TARGET':U).
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 225

 caso existam na viewer objetos não vinculados ao banco de dados


(variáveis), customizar a procedure LOCAL-ASSIGN-RECORD para que
seus valores sejam salvos. Exemplo:
(...)
/* Dispatch standard ADM method.
RUN dispatch IN THIS-PROCEDURE (INPUT 'assign-record':U ).
/* Todos os assign´s não feitos pelo assign-record devem ser
feitos aqui */
assign order-line.qty = fi-3.

 criar e customizar a procedure LOCAL-ASSIGN-STATEMENT;


 inserir o seguinte código após o dispatch padrão:
do with frame {&frame-name} on error undo, return "ADM-
ERROR":
&if defined(ADM-CREATE-FIELDS) &then
if ADM-NEW-RECORD then assign {&ADM-CREATE-FIELDS}.
&endif
&if defined(ADM-MODIFY-FIELDS) &then
assign {&ADM-MODIFY-FIELDS}.
&endif
end.

 alterar a altura de todos os atributos para 0.88;


 para os atributos que formam a chave de acesso da tabela:
 colocar o primeiro atributo na linha 1.17;
 caso exista mais de um atributo chave:
 colocá-los com 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 altura do rt-key
+ 1.25;
 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;
 se não forem colocados atributos não chave, retirar o retângulo rt-mold.
Obs.: apesar da viewer só com campos chave não conter outros campos,
poderá conter variáveis;
 colocar na SmartViewer outros objetos, como por exemplo combo-box,
que não estão associados ao 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 '{&ADM-
MODIFY-FIELDS}';
 quanto à largura da SmartViewer:
 se a SmartViewer for usada dentro de um folder de Cadastro
Inclui/Modifica, alterar a largura de rt-key e rt-mold para 76, 72;
 se a SmartViewer for usada dentro do Cadastro Inclui/Modifica sem
folder, alterar a largura de rt-key e rt-mold para 79,29;
 se for usada dentro do outro folder que não seja em um Cadastro
Inclui/Modifica, 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;
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 227

Observação Para os campos do tipo fill-in’s, 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". Caso o fill-in se encaixe em uma das
opções acima, deve ser efetuado o registro para o WebEnabler, 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, ou que possuírem um botão de zoom na sua direita.
Portanto não é necessário efetuar o registro para esses fill-ins.
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, 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.
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. 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.
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.
Deve-se ter cuidado com esse tipo de validação, pois cada vez que o usuário
navegar na tabela, 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.2).
existem casos em que é necessário validar um registro para permitir ou não a
sua alteração, porém em alguns desses casos a validação pode ser complexa e
demorada, consequentemente prejudicial a performance do programa.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 229

Para evitar que a validação acabe afetando a performance do programa, deve-


se fazer a validação apenas quando houver a tentativa de alteração, 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,
INPUT "TableIO-Source",
OUTPUT c-p-cadsim).
if valid-handle(widget-handle(c-p-cadsim)) then do:
RUN pi-cancelar IN widget-handle(c-p-
cadsim).
<mensagem>.
return "ADM-ERROR":U.
end.
end.
end.

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.
Observação Essa técnica deve ser evitada, pois o usuário verá o botão de alteração habilitado
e ao tentar alterar o registro a mensagem irá interrompê-lo, contradizendo a função do botão.

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, de modo que na ocorrência de alguma
inconformidade em qualquer dos valores requisitados pelo programa, este
deverá apresentar uma mensagem de erro através do utilitário ut-msgs.p e
posicionar o foco no campo em que ocorreu o problema para que o usuário
possa corrigi-lo.
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.
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.
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.
Validações para Window Relatório
Pelo fato da Window Relatório ser um Template não composto por
SmartObjects, a validação de seus valores tem as seguintes características:

Validações das páginas de Parâmetros, Seleção e Classificação


Os valores dessas páginas são validados dentro da procedure pi-executar, após o comentário:
/* Coloque aqui as validações das outras páginas, lembrando que elas devem apresentar uma
mensagem de erro cadastrada, 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, no evento Row-Leave do browse.

Validação da Página de Impressão


A página de impressão não precisa sofrer qualquer tipo de validação, o Template se encarrega de
confirmar os valores para essa página. Porém, isso não acontece para os campos que não
pertencem originalmente ao Template, que foram adicionados posteriormente.

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.
Porém as validações de dicionário de dados podem acarretar o mau
funcionamento nos Templates, por isso não são indicadas, já que esse tipo de
validação não pode retornar informações do problema ocorrido para que seja
tratado conforme necessário.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 231

Para que isso não ocorra, as validações de dicionário devem ser replicadas nos
programas, nos locais indicados conforme o Template utilizado, fazendo com
que seja possível o tratamento dos problemas que possam ocorrer no
andamento das validações.
Observações
Importante

233

CAPÍTULO 10

Mensagens

Este capítulo apresenta mensagens padrões para algumas situações comuns no


Datasul-EMS 2.00. As mensagens já cadastradas e utilizadas que se encaixem
nas situações abaixo devem ser alteradas, mas não é necessário realizar esta
alteração agora, somente quando o programa for aberto para outras
manutenções. Para auxiliar o cadastro e manutenção de mensagens, existe o
Sistema de Mensagens. Para acessar o Sistema de Mensagens, você deve
primeiro entrar em contato com a equipe de ADF e solicitar a criação de um
usuário no Sistema de Mensagens. Em seguida você pode acessar o Sistema
pelo endereço: X:\Atalhos\SistTec\Mensagem.
1. Os novos programas devem utilizar estas mensagens;
2. Quando o parâmetro solicitar o label da tabela, deve-se utilizar o return-
value do include utp/ut-table.i.
A manutenção do cadastro das mensagens, assim como a inclusão de novas
mensagens só pode ser realizada pela Datasul. Para clientes e parceiros é
autorizada somente a utilização das mensagens já cadastradas.

Mensagem: &1 já existente !


Número: 1
Help: Já existe ocorrência em &1 com a chave informada.
Parâmetros: &1 = label da tabela
Mensagens substituídas: &1 já cadastrado.
&1 já cadastrada.
Registro &1 já cadastrado.
Agência já cadastrada.
234

&1 já informado !
Observações:  utiliza-se palavra 'existente', pois ela não possui
gênero;
 as palavras derivadas do termo 'cadastro' como
cadastrado, cadastrada e cadastramento devem ser
evitadas;
 a palavra 'registro', também, deve ser evitada, pois
trata-se de um termo computacional estranho ao
usuário, devendo ser substituída por 'ocorrência';
 não é necessário apresentar o conteúdo da chave da
tabela, pois este está na tela.

Mensagem: &1 já existente !


Número: 56
Verificar se existe uma ocorrência para a(o) &1 informado
Help:
em seu cadastro.
Parâmetros: &1 = label da tabela
Mensagens substituídas: &1 não cadastrado.
&1 não cadastrada.
Registro &1 não cadastrado.
Agência não cadastrada.
&1 incorreto(a) !
&1 inválido.
&1 inválida.
Observações:  utiliza-se palavra 'existente', pois ela não possui
gênero;
 as palavras derivadas do termo 'cadastro' como
cadastrado, cadastrada e cadastramento devem ser
evitadas;
A palavra 'inválido', também, deve ser evitada, pois se pode
obter sentido não desejado. Exemplo: Funcionário inválido !

Mensagem: &1 possui relacionamentos ativos com &2 !


Número: 5
A corrente ocorrência de &1 possui relacionamento ativos
Help:
com a tabela &2, portanto não pode ser eliminada.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 235

Parâmetros: &1 = label da tabela pai no relacionamento


&2 = label da tabela filho no relacionamento
Mensagens substituídas: &1 possui relacionamentos ativos.
&1 possui &2 cadastrado(s).
&1 possui &2 cadastrada(s).
Banco possui Agência cadastrada.
Observações: As palavras derivadas do termo 'cadastro' como
cadastrado, cadastrada e cadastramento devem ser
evitadas;

Mensagem: Não encontrado(a) &1 para chave informada !


Número: 2
Não foi encontrada ocorrência em &1 com a chave
Help:
informada.
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.

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.00. 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, facilitar o trabalho de
tradução, pois seguindo estas normas o número de mensagens criadas diminui.
 não utilizar ponto de exclamação ou ponto final, a não ser que haja
sentença posterior.
Exemplo: O código da referência deve ser preenchido. Informe um código
diferente de branco;
 As reticências podem ser utilizadas somente nos casos de uso do gerúndio.
Exemplo: Calculando ... ; Imprimindo ... ; Executando ...
 Outros exemplos de mensagens cadastradas que não podem ocorrer:
Exemplo: Eliminando cálculo antigo ...
 Quando o programador tiver a necessidade de ressaltar a mensagem,
utilizar a função "alert-box warning".
 Exemplo de mensagem incorreta:
Eliminação inválida !
 não utilizar ponto ao abreviar palavra.
Exemplo de mensagem incorreta: Cond. Pagto.
 revisar possíveis erros gramaticais, de concordância e de grafia. 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 !
... de Fim de Perídodo
Confirma elimanação ?
Ano fiscal já esté encerrado.
Eliminção inválida !
 utilizar acentuação sempre. Exemplo:
Períodos para o ano ja cadastrados.
Moeda do credito nao tem cotacao para hoje.
 não utilizar letras maiúsculas no meio da frase sem que seja nome próprio.
Exemplos:
Linha Possui Ordens Valorizadas !
Ordem de Produção Não Possui &1.
 evitar repetir a mesma palavra várias vezes. Exemplos:
Operação &1 não está cadastra para o Roteiro &2. Informe outra
operação para este Roteiro ou cadastre a Operação &1 para o Roteiro
&2.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 237

 antes de criar uma nova mensagem verificar se não há outra similar que
possa ser utilizada. Exemplo:
Eliminação Inválida !
Eliminação inválida!
Para auxiliar esta operação, o Sistema de Mensagens possui o botão Pesquisa,
onde você pode buscar por Código ou pelo Texto da Mensagem. Além disso,
ainda possui a opção de Filtro onde você informa palavras que deseja procurar
dentro do sistema.
 não abreviar palavras sem necessidade (somente por questões de espaço).
Exemplo:
Cond. Pagto.
Estabelec
Dt Ent Prev
Cod Dest Merc
Encer calc não efetuado.
 não utilizar palavras ou jargões técnicos. Exemplos:
Título já existe no browse
Script do Automanager não encontrado.
 utilizar o help da mensagem somente se necessário, se houver algo a
acrescentar. Não utilizá-lo, somente para repetir a mesma mensagem.
Exemplo:
Agência não cadastrada. Help Agência não cadastrada!
Item para debito direto - Help Item para debito direto.
 procurar ser formal. Não utilizar gírias. Exemplo:
Linha Possui Ordens Valorizadas ! Não pode alterar !
 Não utilizar o tratamento VOCÊ.
 utilizar somente o idioma português (com exceção de palavras técnicas
específicas). Exemplo:
Parámetros
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. Exemplo:
** Pendencias de Credito do Cliente
 não criar mensagens sem sentido. Exemplos:
a
nd
fghfhdfh - fhdfjhdfghdf
Vários
Representante
teteretert
fadfads
 a mensagem deve ser o mais clara e sucinta possível. Qualquer
necessidade de detalhamento, utilizar o help;
 não criar mensagem somente com letras maiúsculas.
Padrões para tradução de mensagens para Inglês e Espanhol
 utilizar os mesmos padrões para criação de mensagens novas;
 no caso de dúvidas, consultar Glossário ou demais membros da equipe de
tradução.
Nomenclatura

239

CAPÍTULO 11

Programas Reutilizáveis

Procedures Internas
Procedures Internas reutilizáveis são definidas em includes que devem ser
incorporados aos programas. Se forem incorporadas a programas .w, não
devem fazer acesso muito grande a dados pois se isto acontecer devem ser
transformadas em API(s). 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, e disponibilizadas para
clientes e parceiros da DATASUL.
Exemplo :
Cálculo do valor presente de uma cotação de preços;
Conversão de valores entre moedas;
Rotinas de Extenso.
A nomenclatura dos includes que contém este tipo de procedure interna deve
ser a seguinte:
XXINC999.i, onde:
XX - Sigla do Módulo
INC - Fixo
999 - Seqüencial.
241

CAPÍTULO 12

Ferramentas

Application Compiler
O Application Compiler é uma ferramenta Progress utilizada para compilar
arquivos.
Para iniciar o Application Compiler, deve-se estar com qualquer uma das
ferramentas Progress abertas (Data Dictionary, Procedure Editor, UIB ... ),
pressionar o menu Tools e em seguida o item Application Compiler. Sendo
então, exibida a janela a seguir, na qual se deve informar os arquivos que se
deseja compilar e as opções de compilação.
242

Selecionar arquivos a serem compilados


Para selecionar os arquivos que devem ser compilados seguir os passos abaixo:
1. Pressionar o botão "Add" na janela anterior.
2. Então, deve ser exibida uma caixa de diálogo, na qual, deve ser informado
o diretório e/ou nome dos arquivos e/ou tipo dos arquivos a serem
compilados. Pode-se, informar mais de um tipo de arquivos, separando-os
por espaço. Pode-se, também, utilizar o botão 'Files', para exibir uma caixa
de diálogo padrão do Windows, na qual pode-se localizar mais facilmente
os arquivos desejados.
3. Pressionar o botão 'Ok' e então o diretório e os arquivos devem ser
exibidos na janela do Application Compiler.

Caso os arquivos desejados estejam em diretórios diferentes pode-se adicionar


mais diretórios e/ou arquivos a lista.
E ainda, caso queira incluir a lista de arquivos a serem compilados num
diretório do PROPATH do Progress, deve-se seguir os passos abaixo:
1. Pressionar o botão 'Propath', deve ser exibida uma caixa de diálogo com
todos os caminhos existentes no PROPATH do Progress.
2. Pressionar o botão esquerdo do mouse sobre os diretórios desejados,
selecionando-os.
3. Pressionar o botão 'Ok'.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 243

Eliminar e Modificar a lista de arquivos a serem compilados


Para modificar algum dos diretórios da lista de arquivos a serem compilados,
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.
2. Depois pressionar o botão 'Modify' e será exibida uma caixa de diálogo, na
qual, pode-se modificar o diretório e/ou arquivos e/ou tipos de arquivos a
serem compilados.
3. Após feitas as devidas modificações pressionar o botão 'Ok', retornando
assim a janela anterior.
Para eliminar alguns dos diretórios da lista de arquivos a serem compilados,
seguir os passos abaixo:
1. Pressionar o botão esquerdo do mouse sobre o diretório e/ou arquivos da
lista a ser eliminado, ficando assim selecionado.
2. Depois pressionar o botão 'Delete'.
Opções de Compilação
O Application Compiler disponibiliza algumas opções de compilação,
descritas abaixo:
 salvar os novos arquivos .R gerados - para isso marcar a caixa de
combinação Save New .r Files;
 compilar arquivos existentes nos subdiretórios dos diretórios da lista de
compilação, para isso marcar a caixa de combinação Look in
Subdirectories;
 eliminar os antigos .R existentes - para isso marcar a caixa de combinação
Remove Old .r Files;
 compilar somente os arquivos que não possuam .R - para isso marcar a
caixa de combinação Only Compile If No .r File;
 exibir status da compilação dos arquivos - para isso marcar o item de
menu Show Status que se encontra no menu Options;
 salvar as alterações realizadas nas opções de compilação - para isso marcar
o item de menu Save Settings on Exit que se encontra no menu Options.
Além das opções descritas anteriormente, o Application Compiler possui
outras opções de compilação. Estas opções podem ser acessadas através do
menu Options, item Compiler.
Será então exibida uma caixa de diálogo denominada Compiler Options, na
qual, pode-se informar algumas opções adicionais, tais como:
 tipos de arquivos padrão a serem compilados - digitar os tipos de arquivos
na caixa de texto Default File Spec.;
 arquivo de LOG, este arquivo deve armazenar os resultados (arquivos
compilados com sucesso, erros encontrados, ...) da compilação dos
arquivos - digitar o diretório e o nome do arquivo de LOG na caixa de
texto Message Log File;
 diretório, no qual devem ser gravados os novos arquivos .R - digitar o
nome do diretório onde estes arquivos devem ser gravados, na caixa de
texto Save Into; caso os novos arquivos .R devam ser gravados no mesmo
diretório dos arquivos de origem, não informar nenhum diretório nesta
caixa de texto.
Iniciar Compilação
Para iniciar a compilação dos arquivos deve-se pressionar o botão 'Start
Compile'.
Caso o item de menu Show Status esteja marcado, será exibida uma caixa de
diálogo com informações sobre o status da compilação (arquivos compilados
com sucesso, erros encontrados, ... ); caso este item de menu não esteja
marcado, será exibida a mesma caixa de diálogo mas, somente ao final da
compilação dos arquivos.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 245

Roundtable
O Roundtable é uma ferramenta que facilita o controle de versão de
programas, objetos e includes.
Para a utilização do Roundtable, deve-se seguir os passos descritos abaixo:
1. Selecionar a Workspace;

2. Criar uma task para poder desenvolver os programas, veja os passos a


seguir:
 ir no menu Task - Task Maintenance;
 ir em File - New Task;
 digitar na opção Summary a descrição da Task;
 digitar na opção Manager, a quem está designado (opcional);
 clicar no botão 'Ok';
 clicar no botão 'Done'.
3. Após criada a task, selecionar a task que foi criada na opção Task.
Observação: Poderá ter mais de uma Task criada para um mesmo usuário.
4. Como editar um objeto:
 estar com a task selecionada;
 selecionar o objeto que se quer editar;
Observação: Não há necessidade de se fazer os dois próximos itens, caso o objeto já esteja na
sua task.

 ir em File - Check Object Out:


APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 247

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.

Para verificar se o objeto já está em uso Ir em Folder - Spec (que está na tela
principal do Roundtable) - na última label Event, que deve estar escrito 'Work
in process'.

 selecionar a opção Patch Level;


 ir em File - Edit Selected Object:
Observação Com isso deve abrir o programa no Procedure Editor. Caso se queira abrir no
Interface Builder -

Abrir o Interface Builder e Ir no menu File - Open.


Se for selecionada a opção View Selected Object, deve ser aberto o programa
somente para leitura.
5. 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. Para isso,
deve-se ir no menu Task - Task Maintanence, File - Complete Task e
deve-se perguntar se deseja completar a task e deve-se responder que
sim. Com isso, o Roundtable deve liberar todos os objetos presos a
task, desde que estes estejam sem erros.
6. Como liberar um único objeto:
 ir no menu compile - Compile Object With Xref;
 ir na opção File - Check Object In do menu;
 clicar em Ok.
7. Como saber se todos os objetos estão associados a task:
 selecionar a task desejada;
 ir no menu View, opção Object in Task View.
Características
Objetivo

249

CAPÍTULO 13

API´s

O que são API´s e como construí-las


API (Application Program Interface), é um programa que recebe parâmetros
específicos para a realização de alguma tarefa. Esta tarefa, pode ser desde uma
atualização, quanto um programa que retorne informações. Visando facilitar a
customização e a integração dos módulos.
Uma API, não pode ser chamada diretamente, ou seja, é sempre executada a
partir de um outro programa, que passa os devidos parâmetros.
As API´s são usadas pelos:
 próprios programas do módulo, evitando duplicidade de código e
as mantendo atualizadas;
 outros módulos, alcançando assim a independência dos
aplicativos;
 equipes de desenvolvimento específico para customização dos
módulos;
 parceiros de desenvolvimento da DATASUL;
 próprio cliente, quando desejar fazer alguma customização.
Com isto, o cliente e mesmo os outros módulos, não precisam conhecer em
detalhes o modelo de dados de um módulo para criar registros.
Funcionamento

250

Este conceito, também, segue a idéia de orientação a objeto, ou seja, a


reutilização de código. para acessar determinado objeto, somente um elemento
preestabelecido pode efetuar tal operação.
A API deve ser construída de forma que, receba parâmetros e execute alguma
ação. A API, não deve ter tratamento com tela, deve ser sempre via troca de
parâmetros. Isto facilita no momento da utilização do RPC.
A entrada dos parâmetros na API, deve ser da seguinte forma:
 INPUT-OUTPUT PARAMETER TEMP-TABLE: este é a única
forma de comunicação de dados com a API, podendo-se utilizar
uma ou mais tabelas temporárias para fazê-la.
Logo, dados como empresa, usuário, devem ser enviados para a API, através
da temp-table, de forma alguma pode ser utilizado os valores das variáveis
globais definidas no ut-glob.i, ou qualquer outro tipo de variável global.
O retorno da API, deve ocorrer das seguintes formas:
 RETURN-VALUE: retornando OK ou NOK, para determinar o
sucesso completo (OK) ou parcial (NOK) ou nulo (NOK) da
execução;
 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. Pode ser
utilizada também, uma temp-table somente de retorno, devolvendo
informações ao programa chamador. Além disto, pode ser utilizada
uma temp-table, parar retornar todos os erros ocorridos com
determinado registro.
Cabe ao projetista/programador, definir a forma que mais se adapta ao
programa a ser criado. As API´s devem ter a nomenclatura:
XXAPI999.P, onde:
XXX - indica o nome do módulo
999 - um número seqüencial de API´s dentro do módulo.
A definição das temp-tables, deve ficar num include de nome semelhante ao
programa API, apenas com a extensão .I. Assim, se o programa API, tem o
nome externo MPAPI001.P, o include que contém as definições das temp-
tables de integração tem o nome externo MPAPI001.I.
Documentação
Versão
Retornode
de Erros
Integra
ção

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 251

A API deve ter um controle interno para a versão corrente de integração. Esta
versão é fixa no programa API, sendo controlada pelo programador (deve ser
obrigatoriamente um número seqüencial). Esta versão deve ser incrementada,
sempre que ocorrer alguma alteração no layout das temp-table´s, ou na forma
de passar e receber os parâmetros.
Utilizar um campo com nome cod-versao-integracao.
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. Cabe ao responsável do
programa chamador, adequar seu programa às exigências impostas pela API.
No caso, da versão de integração estiver incompatível, deve ser utilizada a
mensagem de erro número 3941.
Importante lembrar que, esta versão de integração da API é diferente da
versão do programa da API, uma vez que, pode alterar o programa e gerar uma
nova versão, sem que seja necessário alterar a versão de integração da API.
Sempre que a API encontrar algum problema, com os dados recebidos por ela,
a mesma deve retornar no próprio registro da temp-table de entrada com
problemas, ou através de uma temp-table de erros de dois campos com as
seguintes informações:
Campo Descrição
cod-erro Número da mensagem de erro
desc-erro Descrição da mensagem de erro
A mensagem deve estar obrigatoriamente cadastrada no cadastro de
mensagens, e a descrição é o texto da mensagem.
** Item parcialmente definido **
A documentação da API, deve ser feita pelo módulo responsável, devendo
estar sempre atualizada. Esta documentação está contida no manual técnico do
módulo.
Deve ser utilizado módulo de documentação do Datasul-EMS, para gerar o
help da documentação da API. Existe um manual para cada módulo contendo
todas as suas API´s.
A documentação da API, deve conter as seguintes informações:
 nome físico do programa;
Exemplo

 versão de integração;
 objetivo;
 parâmetros de entrada e saída (o que significam os campos na(s)
tabelas temporária(s));
 nome do include que contém a definição das temp-tables de
integração;
 execução (validações e ações);
 considerações gerais.
No manual técnico do módulo deve conter uma relação com todas as API´S do
módulo; nome físico da API, objetivo e nome do arquivo help. Se o usuário
precisar utilizar a API, este deve buscar via BBS o help corrente da API.
Nome Físico: mmp/mpapi001.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.
Parâmetros de Entrada: Para executar a API é necessário utilizar o include
{mpp/mpapi001.i} que contém a definição dos parâmetros de entrada do
programa.
/**************************************************************
** Include: MPAPI001.i
** Definição das temp-tables utilizadas para verificar
** replicação das mensagens para uma planta remota - 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".

Campo Descrição
cod-versao-integracao Número da versão de integração
cod-transacao
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 253

log-replica-msg
cod-erro
desc-erro
cd-maquina-local

Código da API
/*************************************************************
** Programa : MPAPI001.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.i}
def input-output parameter table for tt-replic-msg.
def var i-versao-integ as integer format "999" no-undo.
assign i-versao-integ = 001.
find first tt-replic-msg no-lock no error.
if avail tt-replic-msg then do:
if tt-replic-msg.cod-versao-integracao <> i-versao-integ
then do:
run utp/ut-msgs.p (input "msg",
input 3941,
input "")
assign tt-replic-msg.cod-erro = 3941
tt-replic-msg.desc-erro = return-value.
return "NOK"
end.
else do:
find first maq-dest-trans where maq-dest-trans. cd-
trans = tt-replic-msg.cod-transacao no-lock no-error.
if avail maqui-dest-trans then
assign tt-replic-msg.log-replica-msg = yes.
find first maquina where maquina.tp-conexao = 1 no-lock no-
error.
if avail maquina then
assign tt-replic-msg.cd-maquina-local =
maquina.cd-maquina.
else do:
run utp/ut-msgs.p (input "msg",
input 3942,
input "").
Assign tt-replic-msg.cod-erro = 3942
tt-replic-msg.desc-erro = return-value
tt-replic-msg.cd-maquina-local = 0.
Return "NOK".
end.
end.
end.
else
return "NOK".
/* fim */

Como documentar API´s


Foi criado um documento modelo do Microsoft Word (.dot), que está no
diretório \\enseada\desems2\ferramentas\ddk2000\ModeloDocAPI-DBO, com
o nome "API.dot", para facilitar a documentação técnica das API´s
(Application Program Interface), do DATASUL-EMS 2.00.
O arquivo Word, com a documentação de cada API, deve ter o mesmo nome
da API com extensão (.doc) e ser armazenado no diretório \DOCAPI\, por
exemplo:
Nome do programa API: cep/ceapi003.p
Nome do documento API: docapi/ceapi003.doc
Existem duas API´s documentadas, que podem servir de exemplo:
 btb912zb.doc (API de Criação de Pedidos de Execução para o RPW);
 btb917zb.doc (API de Eliminação de Pedidos de Execução para o RPW).
Algumas recomendações no uso:
 este documento deve ser escrito de forma mais clara possível, pois deve
estar disponível para clientes e parceiros comerciais;
 fonte padrão do documento é Arial 10;
 fonte dentro das tabelas Arial 8;
 a versão do documento deve estar no formato V.99 (exemplo V.01);
 o nome do nosso produto é Datasul-EMS (é importante observar as letras
maiúsculas e minúsculas para não confundir com o produto internacional);
 usar negrito e itálico de forma moderada, procurando destacar nomes ou
aspectos importantes para o entendimento;
Evolução de lógica
Exemplo
de API,
sem
mudan
ça de
parâme
tros

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 255

 o documento, obviamente, pode sofrer alterações no layout, mas, que estas


não sejam muito significativas e não fiquem fora do padrão;

Como implementar evoluções de API´s


Implementar novas funcionalidades nos programas, fazendo com que as
customizações feitas pelos clientes/parceiros continuem funcionando.

Para este tipo de evolução, basta alterar o código principal da API.


/* API antiga */
define input param param-1 as char no-undo.
define input param param-2 as int no-undo.
find first param-global exclusive-lock no-error.
if avail param-global then
assign param-global.taxa = 0.3.

/* API nova */
define input param param-1 as char no-undo.
define input param param-2 as int no-undo.
find first param-global exclusive-lock no-error.
if avail param-global then
assign param-global.taxa = 0.3. + param-global.indic.

Observação O resultado obtido através da nova API deve ser, sempre que
possível, idêntico ao resultado da antiga.
Evolução de lógica
Exemplo
de
API ,
com
mudan
ças de
parâme
tros

Para este tipo de evolução, deve ser criada uma nova API com o mesmo nome
da API antiga, acrescida de um diferenciador. EX.: UTAPI012.P 
UTAPI012A.P.
Esta nova API deve possuir uma procedure interna EXECUTE, que receberá
os novos parâmetros e uma lógica.
A API antiga deve chamar a nova API de forma persistente e roda a procedure
interna EXECUTE, passando todos os antigos parâmetros e um valor padrão
para cada um dos novos parâmetros.
/* API antiga - UTAPI012.P */
define input-output parameter table for tt-configuracao2.
define input-output parameter table for tt-dados.
define input-output parameter table for tt-erros.
for each tt-erros:
delete tt-erros.
end.

/* API antiga e alterada - UTAPI012.P */


define input-output parameter table for tt-configuracao2.
define input-output parameter table for tt-dados.
define input-output parameter table for tt-erros.
define var h-api as handle no-undo.
Evolução de lógica
Exemplo
de API,
com
alteraç
ão de
campos
na
temp-
APÍTULO 8 tables Construção de
rogramas utilizando os Estilos de
e suas Técnicas 257
parâme
tros

run utp/utapi012a.p persistent set h-api.


run execute in h-api (input table tt-configuracao2,
input table tt-dados,
input table tt-erros).
delete procedure h-api.

/* API nova - UTAPI012A.P */


procedure execute:
define input-output param table for tt-configuracao2.
define input-output param table for tt-dados.
define input-output param table for tt-erros.
< código customizado>

end procedure.

Observação Os parâmetros novos que são passados como padrão para a nova API, devem
garantir que o resultado seja o mesmo da antiga API.

Para este tipo de evolução, deve ser criada uma nova API com o mesmo nome
da API antiga, acrescida de um diferenciador. Ex.: UTAPI012.P 
UTAPI012A.P.
Esta nova API deve possuir uma procedure interna EXECUTE, que receberá
os novos parâmetros e uma lógica.
A API antiga deve, primeiramente, copiar todos os campos da antiga temp-
table para a nova, chamar a nova API de forma persistente e rodar a procedure
interna EXECUTE.
/* API antiga - UTAPI012.P */
define temp-table tt-clientes
field cliente as char.
define input param table for tt-clientes.
find first param-global exclusive-lock no-error.
if avail param-global then do:
find first tt-clientes no-lock no-error.
if avail tt-clientes then
assign param-global.ult-cliente = tt-clientes.cliente.

/* API antiga e alterada - UTAPI012.P */


define temp-table tt-clientes
field cliente as char.
define temp-table tt-new-clientes
field cliente as char
field taxa as int.
define input param table for tt-clientes.
define var h-api as handle no-undo.
for each tt-clientes no lock:
create tt-new-clientes.
buffer-copy tt-clientes to tt-new-clientes
assign tt-new-clientes.taxa = 1.
end.
run utp/utapi012a.p persistent set h-api.
run execute in h-api (input table tt-clientes).
delete procedure h-api.

/* API antiga - UTAPI012.P */


define temp-table tt-new-clientes
field cliente as char
field taxa as int.
procedure execute:
define input param table for tt-new-clientes.
find first param-global exclusive-lock no-error.
if avail param-global then do:
find first tt-new-clientes no-lock no-error.
if avail tt-new-clientes then
assign param-global.ult-cliente = tt-new-clientes.cliente
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 259

param-global.taxa = tt-new-clientes.taxa.
end procedure.

Observação Caso a temp-table seja input-output, no retorno da API evoluída, devem ser
repassados os registros da nova temp-table para a antiga.
define input param table for tt-clientes.
define var h-api as handle no-undo.
for each tt-clientes no-lock:
create tt-new-clientes.
buffer-copy tt-clientes to tt-new-clientes
assign tt-new-clientes.taxa= = 1.
end.
run utp/utapi012a.p persistent set h-api.
run execute in h-api (input table tt-clientes).
delete procedure h-api.

/* API nova - UTAPI012A.P */


define temp-table tt-new-clientes
field cliente as char
field taxa as int.
procedure execute:
define input param table for tt-new-clientes.
find first param-global exclusive-lock no-error.
if avail param-global then do:
find first tt-new-clientes no-lock no-error.
if avail tt-new-clientes then
assign param-global.ult-cliente = tt-new-clientes.cliente
param-global.taxa = tt-new-clientes.taxa.
end procedure.

Observação Caso a temp-table antiga seja input-output, no retorno da API evoluída, devem
ser repassados os registros da nova temp-table para a antiga.
Evolução de lógica
Exemplo
de API,
com
mudan
ça de
parâme
tros,
que já
foi
evoluíd
a

Para este tipo de evolução, deve ser criada uma nova procedure interna com o
mesmo nome da procedure interna antiga, acrescida de um diferenciador. Ex.:
EXECUTE  EXECUTE2.
Esta nova procedure interna deve receber os novos parâmetros e possuir toda a
lógica.
A procedure interna antiga deve chamar a nova procedure, passando todos os
antigos parâmetros e um valor padrão para cada um dos novos parâmetros.
/* API antiga - UTAPI012A.P */
procedure execute:
define input-output param table for tt-configuracao2.
define input-output param table for tt-dados.
define input-output param table for tt-erros.
< código customizado>

end procedure.

/* API antiga alterada - UTAPI012A.P */


procedure execute:
define input-output param table for tt-configuracao2.
define input-output param table for tt-dados.
define input-output param table for tt-erros.
run execute2 (input table tt-configuracao2,
input table tt-dados,
input table tt-error,
Evolução de lógica
Exemplo
de API
com
mudan
ça de
parâme
tros,
onde
APÍTULO 8 não é Construção de
rogramas utilizando os Estilos possíve
e suas Técnicas 261
l
determi
nar um
valor input 0).
padrão end procedure.
para o procedure execute2:
novo
define input-output param table for tt-configuracao2.
parâme define input-output param table for tt-dados.
tro ou o define input-output param table for tt-erros.
novo
define input param param-4 as int no-undo.
parâme
tro é find first param-global exclusive-lock no-error.
if avail param-global then
obrigat assign param-global.taxa =
ório if param-4 0 then 0.3 else 0.3 + param-4.
end procedure.

Observação Os parâmetros novos que são passados como padrão para a nova procedure
interna, devem garantir que o resultado seja o mesmo da antiga procedure interna.

Para este tipo de evolução, deve ser criada uma nova procedure interna ou API
com o mesmo nome da procedure interna antiga, acrescida de um
diferenciador, conforme exemplificando nos itens anteriores.
Como não é possível determinar valores padrão, 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.
/* API antiga - UTAPI012A.P */
procedure execute:
define input param param-1 as char no-undo.
define input param param-2 as int no-undo.
define input param param-3 as log no-undo.
run execute 2 (input param-1,
input param-2,
input param-3,
input 0).
end procedure.
procedure execute2:
define input param param-1 as char no-undo.
define input param param-2 as int no-undo.
define input param param-3 as log no-undo.
define input param param-4 as int no-undo.
if param-4 = 0 then
find first param-global exclusive-lock no-error.
if avail param-global then
assign param-global.taxa = 0.3.
end.
else do:
find first param-global exclusive-lock no-error.
if avail param-global then
assign param-global.taxa = 0.3 + param-4.
end.
end procedure.

/* API nova - UTAPI012A.P */


procedure execute:
define input param param-1 as char no-undo.
define input param param-2 as int no-undo.
define input param param-3 as log no-undo.
define var h-execute as handle no-undo.
run execute2 (input param-1,
input param-2,
input param-3,
input 0).
return return-value.
end procedure.
procedure execute2:
define input param param-1 as char no-undo.
define input param param-2 as int no-undo.
define input param param-3 as log no-undo.
Evolução de lógica
Exemplo
de API
com
mudan
ça de
versão
de
integra
APÍTULO 8 ção Construção de
rogramas utilizando os Estilos e suas Técnicas 263

define input param param-4 as int no-undo.


return "999".
end procedure.
procedure execute3:
define input param param-1 as char no-undo.
define input param param-2 as int no-undo.
define input param param-3 as log no-undo.
define input param param-4 as int no-undo.
define input param param-5 as int no-undo.
find first param-global exclusive-lock no-error.
if avail param-global then
assign param-global.taxa = 0.3 + param-4 * param-5
end procedure.

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. A mensagem de que a API possui
uma nova versão com parâmetro obrigatório, deve ser somente apresentada no programa
chamador, e nunca na própria API, já que as API´s não devem possuir eventos de interface. Esta
mensagem deve apresentar um erro dizendo que esta API está desatualizada e o motivo de sua
extinção.

Para este tipo de evolução, deve ser criada uma nova procedure interna ou API
com o mesmo nome da procedure interna antiga, acrescida de um
diferenciador, conforme exemplificando nos itens anteriores.
A antiga API deve retornar um erro para o programa chamador.
A nova API deve conter uma procedure interna que retorne a versão de
integração para o programa chamador.
/* API antiga - UTAPI012.P */
define input param param-1 as char no-undo.
define input param param-2 as int no-undo.
define input param param-3 as log no-undo.
find first param-global exclusive-lock no-error.
if avail param-global then
assign param-global.taxa = 0.3 * param-2.

/* API antiga alterada - UTAPI012.P */


define input param param-1 as char no-undo.
define input param param-2 as int no-undo.
define input param param-3 as log no-undo.
return "999".

/* API nova- UTAPI012A.P */


procedure execute:
define input param param-1 as char no-undo.
define input param param-2 as int no-undo.
define input param param-3 as log no-undo.
define input param param-4 as int no-undo.
define input param param-5 as int no-undo.
find first param-global exclusive-lock no-error.
if avail param-global then
assign param-global.taxa = 0.3 + param-4 * param-5.
end procedure.
procedure get-integration-version:
define output param i-version as int no-undo.
assign i-version = 4.
end procedure.

Observação Esta técnica pode ser utilizada quando as outras técnicas citadas implicarem
muito na performance da API. Antes de rodar a nova API, o programa chamador deve rodar o
método Get-Integration-Version da nova API e verificar se a versão está correta. Lembrar que,
qualquer mensagem para o usuário deve ser emitida pelo programa chamador e nunca pela API.
Parâmetros
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 265

UTAPI002.P
A API utp/utapi002.p faz a integração entre Progress e Microsoft Word 97,
permitindo a criação de arquivos, baseados em formulários, para o Microsoft
Word.
Maiores informações podem ser obtidas na documentação da API de
Integração entre PROGRESS e Microsoft Word 97 (docapi/utapi002.doc).
Importante Para novos programas que venham a utilizar esta API, é
recomendado que seja utilizado o programa utp/utapi012 ao invés deste.

UTAPI003.P
A API utp/utapi003.p faz a Integração entre PROGRESS e Microsoft Excel 97,
permitindo a construção de planilhas e, também, gráficos.
Maiores informações podem ser obtidas na documentação da API de
Integração entre PROGRESS e Microsoft Excel 97 (docapi/utapi003.doc).
Importante Para novos programas que venham a utilizar esta API, é
recomendado que seja utilizado o programa utp/utapi013 ao invés deste.

UTAPI004.P
Permitir o envio de E-Mail ou FAX através do EMS 2.0 usando o MS-
Exchagne (OLE Automation).
 o primeiro parâmetro deve ser endereço E-Mail do destinatário (Exemplo:
"fulano@internet.com.br") ou o número do FAX (Exemplo:
"[FAX:9999999]");
 o segundo parâmetro deve ser o E-Mail ou o número do FAX para uma
"Cópia Carbono" (Cc);
 o terceiro parâmetro é o Assunto (Subject);
 o quarto parâmetro é a mensagem;
 o quinto parâmetro é o arquivo anexo (attachment);
Parâmetros
Objetivo
Configuração
Retorno
Exemplo

 o sexto parâmetro é o Grau de Importância, onde 0  Baixo, 1  Médio,


2  Alto;
 o sétimo parâmetro é a Confirmação de Envio, ou seja, receber um E-Mail
quando o E-Mail foi enviado;
 o oitavo parâmetro é a Confirmação de Leitura, ou seja, receber um E-
Mail quando o destinatário tiver lido a mensagem;
 o nono e último parâmetro é o Acompanhamento, ou seja, verificar o
andamento do envio de E-Mail (UT-ACOMP);
run utp/utapi004.p (input "fulano@internet.com.br",
input "",
input "Manual",
input "Mensagem do manual ... ",
input "c:\autoexec.bat, c:\config.sys",
input 0,
input no,
input no,
input yes).

NPG  Não existe registro na tabela de Parâmetros Globais do Sistema.


NEX  O Servidor de E-Mail não é MS-Exchange conforme os Parâmetros
Globais do Sistema.
NDE  Destinatário inválido.
NCC  Destinatário da Cópia Carbono inválido.
ATT  O Arquivo Anexo não foi encontrado.
OK  E-Mail enviado com sucesso.
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.

UTAPI005.P
Permitir o envio de E-Mail através do EMS 2.0 usando um servidor UNIX ou
qualquer outro servidor com suporte ao protocolo SMTP.
Devem ser passados oito parâmetros para este programa:
Configuração
Retorno
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 267

 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 (param-
global serv-mail);
 o segundo parâmetro deve ser a porta do servidor de E-Mail, que também
pode ser adquirida na tabela de Parâmetros Globais do Sistema (param-
global.porta-mail);
 o terceiro parâmetro deve ser o remetente (Exemplo: "fulano");
 o quarto parâmetro deve ser o endereço E-Mail do destinatário (Exemplo:
"fulano@internet.com.br");
 o quinto parâmetro deve ser o E-Mail para uma "Cópia Carbono" (Cc);
 o sexto parâmetro é o Assunto (Subject);
 o sétimo parâmetro é a mensagem;
 o oitavo parâmetro, caso esteja enviando E-Mail via UNIX, deve ser o
diretório para a criação do SCRIPT de envio de E-Mail, senão, pode ser
deixado em branco.
run utp/utapi004.p (input "172.16.1.89",
input 25,
input c-from,
input c-to,
input c-cc,
input c-assunto,
input c-mesg,
input "").

Se o retorno (return-value) desse programa for igual a Ok, o mail foi enviado
com sucesso, senão algum erro ocorreu no envio ou os parâmetros passados
não estão corretos.
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.
Interface
Instalação

Observação O programa permite enviar um E-Mail para várias pessoas. Para isto deve-se
passar cada nome separado por "," (vírgula) ou por ";" (ponto e vírgula). O mesmo acontece para
a Cópia Carbono.
Exemplo: fulano@internet.com.br, beltrano@internet.com.br". O assunto e a mensagem podem
ser passadas em branco.
Exemplo: ("") O remetente nunca pode conter espaços em branco.

Para que o programa de envio de E-Mail funcione, deve ser executado o


arquivo INSTALA.BAT, que se encontra no diretório \INTERFAC\MAIL.
Este programa não possui interface. Apenas envia o E-Mail.

UTAPI006.P
A API utp/utapi006.p permite a busca de dados de uma planilha Excel para o
Progress.
No programa responsável por buscar os dados deve ser feita a inclusão do
include: utp/utapi006.i, onde estão as definições das temp-table´s que devem
ser passadas como parâmetros à API utp/utapi003.p.
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 269

A chamada da API deve seguir o padrão abaixo:


run utp/utapi006.p (input-output table tt-dados,
output table tt-erros).

Maiores informações podem ser obtidas na documentação da API para Busca


de Dados do Excel para o Progress (docapi/utapi006.doc).

UTAPI007.P
A API utp/utapi007.p permite o uso de funções do Excel, para retornar os
resultados para um programa Progress.
No programa responsável por usar esta API deve ser feita a inclusão do
include: utp/utapi007.i, onde estão as definições das temp-table´s que devem
ser passadas como parâmetros à API utp/utapi007.p.
A chamada da API deve seguir o padrão abaixo:
run utp/utapi007.p (input-output table tt-dados,
output table tt-erros).

Maiores informações podem ser obtidas na documentação da API para Uso de


Funções do Excel no Progress (docapi/utapi007.doc).

UTAPI008.P
Nome Físico: utp/utapi008.p
Nome do Include com os Parâmetros: utp/utapi008.i
Versão de Integração: 001
Atualização de arquivos para o Microsoft Excel 97 e retorno de informações
para o Progress.
Maiores informações podem ser obtidas na documentação da API de
Integração entre Progress e Microsoft Excel 97 (docapi/utapi008.doc).
Importante Para novos programas que venham a utilizar esta API, é
recomendado que seja utilizado o programa utp/utapi018 ao invés deste.
Objetivo

UTAPI009.P
Nome Físico: utp/utapi009.p
Nome do Include com os Parâmetros: utp/utapi009.i
Versão de Integração: 001
Envio de mensagens através do servidor de correio eletrônico e envio de FAX
através de servidor de FAX.
Maiores informações podem ser obtidas na documentação da API de Envio de
FAX/E-mail (docapi/utapi009.doc).
Importante Para novos programas que venham a utilizar esta API, é
recomendado que seja utilizado o programa utp/utapi019 ao invés deste.

UTAPI010.P
Nome Físico: utp/utapi010.p
Nome do Include com os Parâmetros: utp/utapi010.i
Versão de Integração: 001
Permitir que impressoras cadastradas no EMS sejam utilizadas em programas
compilados contra os bancos do MAGNUS.
Maiores informações podem ser obtidas na documentação da API para
Compartilhar Impressoras do EMS com Programas Magnus
(docapi/utapi010.doc).

UTAPI012.P
Nome Físico: utp/utapi012.p
Nome do Include com os Parâmetros: utp/utapi012.i
Versão de Integração: 001
Criação de arquivos, baseados em formulários, para o Microsoft Word. Sendo
que os parâmetros recebidos são utilizados para preencher os campos de
formulário existentes no documento.
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 271

Maiores informações podem ser obtidas na documentação da API de


Integração entre Progress e Microsoft Word (docapi/utapi012.doc).

UTAPI013.P
Nome Físico: utp/utapi013.p
Nome do Include com os Parâmetros: utp/utapi013.i
Versão de Integração: 001
Faz a Integração entre Progress e Microsoft Excel, permitindo a construção de
planilhas e, também, gráficos.
Maiores informações podem ser obtidas na documentação da API de
Integração entre Progress e Microsoft Excel (docapi/utapi013.doc).

UTAPI018.P
Nome Físico: utp/utapi018.p
Nome do Include com os Parâmetros: utp/utapi018.i
Versão de Integração: 001
Atualização de arquivos para o Microsoft Excel e retorno de informações para
o Progress..
Maiores informações podem ser obtidas na documentação da API de
Integração entre Progress e Microsoft Excel (docapi/utapi018.doc).

UTAPI019.P
Nome Físico: utp/utapi019.p
Nome do Include com os Parâmetros: utp/utapi019.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.
Maiores informações podem ser obtidas na documentação da API de Envio de
FAX/E-mail (docapi/utapi019.doc).

UTAPI027.P
Nome Físico: utp/utapi027.p
Nome do Include com os Parâmetros: utp/utapi027.i
Versão de Integração: 001
Criação de documentos, baseados em formulários para o Microsoft Word,
sendo que a decisão de gravar ou não o documento caberá ao usuário final.
Maiores informações podem ser obtidas na documentação da API de
Integração entre Progress e Microsoft Word (docapi/utapi027.doc).

UTAPI028.P
Nome Físico: utp/utapi028.p
Nome do Include com os Parâmetros: utp/utapi028.i
Versão de Integração: 001
Envio de compromisso do tipo reunião via Microsoft Outlook.
Maiores informações podem ser obtidas na documentação da API de Envio de
compromisso via Outlook (docapi/utapi028.doc).

UTAPI029.P
Nome Físico: utp/utapi029.p
Nome do Include com os Parâmetros: utp/utapi029.i
Versão de Integração: 001
Considerações
Objetivo
Gerais

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 273

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.
Maiores informações podem ser obtidas na documentação da API de
Integração com Excel Web (docapi/utapi029.doc).

APAPI009.P
Nome Físico: app/apapi009.p
Nome do Include com os Parâmetros: app/apapi009.i
Versão de Integração: 001
Consistir os parâmetros passados e caso estejam Ok atualizar os pagamentos.
 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;
 todas as temp-tables são passadas como parâmetro através dos comandos
INPUT TABLE ou OUTPUT TABLE.
Exemplo:
run utp/utapi008.p (input table tt-referencia,
output table tt-erro-pef).

 a API funciona da seguinte forma: Recebe como parâmetro a temp-table,


faz as críticas e caso não tenha ocorrido nenhum problema atualiza os
pagamentos.
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 Tipo Formato Valor Inicial Obrigatório
i-ep-codigo Integer Sim
c-referencia Character Sim
Cod-versao-integ Integer Sim
c-usuario Character Sim
l-vid-rel Logical Sim
l-acompanha Logical Sim

Atributo Descrição
i-ep-codigo Empresa do pagamento
c-referencia Referência a ser atualizada
cod-versao-integ Versão de integração
c-usuario Usuário corrente
l-vid-rel Mostra mensagens na tela ou gera temp-table de erros
l-acompanha Mostra acompanhamento na tela?

Parâmetros de Saída
Temp-table tt-erro-pef: serão gerados registros nesta temp-table quando tt-
referencial.l-vid-rel=yes com o código do erro, descrição e informações dos
registros com inconsistências.
TEMP-TABLE TT-ERRO-PEF
Atributo Tipo Formato Valor Inicial Obrigatório
i-cod-erro Integer 9999999 Sim
c-desc-erro Character "x(70)" Sim
c-arquivo-erro Character "x(100)" Não

Atributo Descrição
i-cod-erro Código da mensagem de erro
c-desc-erro Descrição da mensagem de erro
c-arquivo-erro Informações com inconsistências

Execução
O programa app/apapi009.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). Caso
a versão esteja incompatível, 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 Mensagem Ajuda
3941 Versão de integração incorreta ! Aversão de integração informada
através dos parâmetros internos é
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 275

incompatível com a versão atual da


API. Favor contatar suporte técnico.
Além da versão de integração são efetuadas, também as seguintes
consistências.
Número do Erro Mensagem Ajuda
774 Empresa &1 não cadastrada Empresa &1 não cadastrada.
8759 Parâmetro do Contas a Pagar não Parâmetro do Contas a Pagar não
cadastrado cadastrado para esta empresa
6280 Referência inexistente ! Não foram encontrado movimentos
PEF/PEC pendentes cadastrados
com a referência informada.
Caso ocorra um dos erros acima, a seleção não será feita.
Cabe ao programa de origem, verificar os registros que estão com erro.
Objetivo

CAPÍTULO 14

Portabilidade de RCODES

O objetivo da análise de portabilidade de RCODES é validar o funcionamento


dos programas compilados em ambiente Windows e executados em ambientes
Unix. Isto se faz necessário porque programas que respeitam as regras para
portabilidade de RCODE, podem ser executados via RPW/RPC e geralmente
em ambiente Unix. Caso contrário, isto não é possível.
Ao executar programas no Unix, compilados em ambiente Windows e que não
tenha respeitado as regras de portabilidade, é apresentado o erro 4438 como
descrito a seguir:
Program <program-name> was compiled under another incompatible display
environment. Cannot run without recompile. (4438)
You have frames in your program. You compiled it under one windowing
system (for example, MS-Windows) and tried to run it under another (for
example, tty). R-code with user interface components in it is only portable
within a windowing system. Your procedure file is portable across windowing
system, but you need to produce separate r-code files for each windowing
system.

Regras para Portabilidade de RCODE


Para que seja possível a portabilidade de RCODES, três regras básicas devem
ser obedecidas, caso contrário, existe a necessidade de recompilação do
programa. As três regras são:
 códigos que não possuem comandos de User-Interface (especificamente,
códigos que não criam frames, tanto explícitas como implícitas), não
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 277

pertencem a nenhuma arquitetura para mostrar informações. Como


exemplo, estão os programas em batch (RPW);
 mesmo tipo de banco de dados;
 mesma classe de plataforma de servidor, deve ter o mesmo tamanho de
palavra e alinhamento de bytes.
Um exemplo para o problema da não compatibilidade de RCODE e sua
correção, é o uso de frames ou comandos que criam frames. Para que o erro
4438 ocorra, é necessário compilar um programa que possui frame em
ambiente Windows e tentar executar o mesmo (RCODE) em ambiente UNIX.
Por exemplo:
output to value(c-arquivo)
find emitente where emitente.cod-emitente = 10 no-lock.
display emitente.cod-emitente.

O comando DISPLAY cria uma FRAME impossibilitando o uso do programa


compilado em ambiente Windows, em um ambiente Unix ou vice-versa.
Para solucionar este problema de incompatibilidade, é 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.cod-emitente = 10 no-lock.
display emitente.cod-emitente with stream-io.

Outra solução para este problema, é usar o comando PUT, pois o mesmo não
usa FRAME.
output to value(c-arquivo)
find emitente where emitente.cod-emitente = 10 no-lock.
put emitente.cod-emitente.

Caso em Especial
A partir da regra de não utilizar comandos que criam FRAMES explícitas ou
implícitas, alguns problemas foram detectados com a descoberta de comandos
que criam, por algum motivo, FRAMES implícitas.
Até o momento foi constatado o problema nos comandos CREATE SERVER e
EXPORT. Para solucionar o problema, é necessário identificar se existe outra
maneira para realizar a tarefa desejada, caso contrário, será necessário manter
RCODES para cada ambiente existente.
Para os casos identificados, o comando EXPORT pode ser substituído por PUT
ou DIPLAY (utilizando a opção STREAM-IO). Para o comando CREATE
SERVER, será necessário manter um RCODE por ambiente existente, isto é,
um RCODE para ambiente Windows e outro para ambiente Unix.
Implementação
Objetivo

279

CAPÍTULO 15

Técnicas

Como alterar o caracter de senha


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}

 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


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.
Objetivo
Implementação

280

 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 ut-


utils.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


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 OS-
COMAND 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}

 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 SetEnv que está dentro do programa ut-utils.p,


passando os seguintes parâmetros:
Implementação
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 281

 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


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}

 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.
Implementação
Objetivo

Como deixar uma janela sempre visível


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}

 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


Permitir a construção de programas que utilizam OCX.
OCXs Utilizados
Instalação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 283

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.
Abaixo segue a lista dos OCXs que estaremos utilizando nesta técnica com a
sua respectiva descrição.

TreeView  O controle TreeView control é utilizado para exibir dados de


natureza hierárquica.

ImageList  Permite a criação de listas de ícones.

PSTimer  Este controle permite que sejam programadas execuções de uma


rotina dentro de determinados intervalos de tempo.

Imagem  A imagem é um componente OCX que permite a visualização de


imagens em um programa progress.

MediaPlayer  Componente que permite a execução de filmes em aplicações


progress.

ListView  Este componente funciona de maneira muito semelhante ao


TreeView.

CellView  Esse componente possibilita a visualização de células.

DTPicker  Componente para visualização de calendário.

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.

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.
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.
(Este OCX não esta mais homologado.)

ProgressBar  Trata-se de um componente OCX que exibe a barra de


progresso de um determinado procedimento que esteja sendo executado.
TabStrip  O TabStrip é um componente que permite que sejam criadas
diversas tabulações de trabalho.

Sound  Componente que possibilita e execução de arquivos de sons como


wav e mid em aplicações progress.

Tree Chart  Componente OCX destinado à definição do lay-out de


posicionamento das células no organograma.
(Este OCX não esta mais homologado.)

Print Chart  Componente OCX destinado ao tratamento dos parâmetros de


impressão para outros componentes OCX.
(Este OCX não esta mais homologado.)

Org Chart  Componente OCX destinado à criação de organogramas.


(Este OCX não esta mais homologado.)
TreeView

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 285

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
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 i-
escolha. 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.
ImageList

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 287

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.
PSTimer

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.

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”.
Imagem

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 289

Esse componente já acompanha o Progress e por isso não precisa ser instalado,
o arquivo que possui esse componente é PSTIMER.ocx. O nome do
componente a ser utilizado é Progress Timer Control.
Propriedades
 Enabled  É uma propriedade do tipo Lógico (true/false), sempre que
for setado para true o evento Ticker será disparado após o intervalo de
tempo determinado.
Sintaxe: <com-handle>:Controls:Item(1):ENABLED.
chCtrlFrame:Controls:Item(1):ENABLED = TRUE.
 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. Caso o valor setado seja 0 não
será disparado o evento.
Sintaxe: <com-handle>:Controls:Item(1):Interval.
chCtrlFrame:Controls:Item(1):Interval = 50.
Evento
 Tick  É o evento que é disparado após cada intervalo de tempo
determinado.

A imagem é um componente OCX que permite a visualização de imagens em


um programa progress.
O diretório onde se encontra o pacote para instalação desse componente é
em \interfac\imagem\ e o arquivo que possui esse componente é
DATIMAGE.ocx. O nome do componente a ser utilizado é
DatasulImage.Imagem.
Propriedades:
 Imagem - Informa-se o caminho da imagem desejada, esta propriedade
é tanto de leitura quanto de escrita.
Sintaxe: <com-handle>:Controls:Item(1):imagem.
chCtrlFrame:Controls:Item(1):imagem = "c:/tmp/amostra.jpg".
 Largura - Largura da área onde a imagem poderá ser exibida, o valor
dessa propriedade pode ser utilizado para leitura e para escrita.
Sintaxe: <com-handle>:Controls:Item(1):Largura.
chCtrlFrame:Controls:Item(1):Largura = 500.
MediaPlayer

 Altura - Altura da área onde a imagem poderá ser exibida, este valor
pode ser lido e alterado.
Sintaxe: <com-handle>:Controls:Item(1):Altura.
chCtrlFrame:Controls:Item(1):Altura = 500.
 LarguraFigura - Largura da imagem, propriedade de escrita e de
leitura.
Sintaxe: <com-handle>:Controls:Item(1):LarguraFigura.
chCtrlFrame:Controls:Item(1):LarguraFigura = 500.
 AlturaFigura - Altura da imagem, propriedade de escrita e de leitura.
Sintaxe: <com-handle>:Controls:Item(1):AlturaFigura.
chCtrlFrame:Controls:Item(1):AlturaFigura = 500.
 Ajusta - Determina-se se a imagem irá se ajustar para ser totalmente
exibida dentro da área determinada, este valor pode ser acessado tanto
para leitura quanto para escrita.
Sintaxe: <com-handle>:Controls:Item(1):ajusta.
chCtrlFrame:Controls:Item(1):ajusta = yes.

Componente que permite a execução de filmes em aplicações progress. Possui


a propriedade “arquivo” que informa ou recebe o nome do arquivo está sendo
executado ou que irá ser executado, e a propriedade comando que recebe ou
informa o comando que está sendo executado.
O diretório onde se encontra o pacote para instalação desse componente é
em \interfac\video\ e o arquivo que possui esse componente é
DATVIDEO.ocx. O nome do componente a ser utilizado é
DatasulMultimedia.MediaPlayer.
Exemplo:
ASSIGN chCtrlFrame:Controls:Item(1):arquivo = "c:/tmp/count.avi"
chCtrlFrame:Controls:Item(1):comando = "open"
chCtrlFrame:Controls:Item(1):comando = "play".
PAUSE.
ASSIGN chCtrlFrame:Controls:Item(1):comando = "stop".
CellView
ListView

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 291

O diretório onde se encontra o pacote para instalação desse componente é


em \interfac\Estruct\ e o arquivo que possui esse componente é
MSCOMCTL.ocx. O nome do componente a ser utilizado é Microsoft
ListView Control, version 6.0.
Este componente funciona de maneira muito semelhante ao TreeView, sendo
que seus métodos básicos são:
 ListView:ListItems:Clear Este método elimina todas as entradas da
ListView.
Sintaxe: <com-handle>:ListView:ListItems:Clear.
chCtrlFrame: ListView:ListItems:Clear.
 ListView:ListItems:Add  Adiciona um item à ListView.
Sintaxe: <com-handle>: Add (<Index>, <Key>, <Text>, <Icon>,
<SmallIcon>).
Onde:
<Index> - É o índice do item dentro da ListView, caso não seja
necessário esse controle pode-se omitir essa informação.
<Key> - É uma chave única de cada item, a Key não pode repetir nos
itens da ListView.
<Text> - É o texto que irá ser exibido na ListView para representar o
item.
<Icon> - É o índice do ícone na lista de ícones, esse índice é opcional.
<SmallIcon> - É o índice do smallicon na lista de smallicons, esse
índice também é opcional.

chCtrlFrame:ListView:ListItems:Add ( , "indice", "Item1", , 3).


chCtrlFrame:ListView:ListItems:Add ( 1, "indice", "Item1", , ).

Observação Deve-se utilizar sempre o ListView da Microsoft (COMCTL32.OCX).

O diretório onde se encontra o pacote para instalação desse componente é


em \interfac\Cellsvwr\ e o arquivo que possui esse componente é
CELLSVWR.ocx. O nome do componente a ser utilizado é
CellsVwr.CellView.
Esse componente possibilita a visualização de células, seus principais métodos
e propriedades são:
Aloca_Tarefa
DTPicker

 ClearCells  Este método limpa todas as células.


Sintaxe: <com-handle>:ClearCells.
chctrlframe:CellView:ClearCells.
 CellsCount  Propriedade apenas para leitura, que informa a
quantidade de células existentes.
Sintaxe: <com-handle>:CellsCount.
chctrlframe:CellView:CellsCount.
 AddLink  Este método é utilizado para adicionar células, todos os
parâmetros são obrigatórios.
Sintaxe: <com-handle>: AddLink (Integer-Level,Character-
PrevKey,Character-PrevText,Character-PrevToolTipText,Character-
Key,Character-Text, Character-ToolTipText).
chctrlframe:CellView:AddLink
(0,"Key1","Item1","Tip1","Key2","Item2","Tip2").
 Click  Evento disparado quando um item, que foi criado, recebe um
clique do usuário. Existe um parâmetro de entrada que é a Key do item
selecionado.
Sintaxe: <control-frame>.<control>.Click.
PROCEDURE CtrlFrame.CellView.Click:
DEFINE INPUT PARAMETER Key AS CHARACTER.
END PROCEDURE.

Componente para visualização de calendário, seu atributo mais utilizado é o


Value.
Sintaxe: <com-handle>:Value.
Exemplo: chCtrlFrame:Controls:Item(1):value = today.
No exemplo acima, atribuímos a data corrente do sistema operacional para o
componente DTPicker.
O diretório onde se encontra o pacote para instalação desse componente é
em \interfac\calendar\ e o arquivo que possui esse componente é
MSCOMCT2.ocx. O nome do componente a ser utilizado é Microsoft Date
and Time Picker Control 6.0.

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
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 293

gerado exibe a locação dos horários por tarefa cadastrada.


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.ocx.
O nome do componente a ser utilizado é Barras.Aloca_Tarefa.
Seus principais métodos são:
 Data_Inicial_Setar  Este método informa qual a data inicial que será
utilizada pelo componente.
Sintaxe: <com-handle>: Data_Inicial_Setar (dt-ini AS DATE).
chctrlframe:Aloca_Tarefa:Data_Inicial_Setar (DATE(01,01,2004)).
 objetos_mostrar  Método que exibe no componente as tarefas que
foram inseridas no mesmo.
Sintaxe: <com-handle>:objetos_mostrar.
chctrlframe:Aloca_Tarefa:objetos_mostrar.
 Tela_limpar  Quando este método é invocado, todas as tarefas que
estavam sendo exibidas deixam de ser exibidas no componente.
Sintaxe: <com-handle>:Tela_limpar.
chctrlframe:Aloca_Tarefa:Tela_limpar.
 Tarefa_Retorna_Id  Método que retorna um valor caracter que
representa o id da tarefa que está selecionada.
Sintaxe: <com-handle>:Tarefa_Retorna_Id().
chctrlframe:Aloca_Tarefa:Tarefa_Retorna_Id().
 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.
Sintaxe: <com-handle>:Alocacoes_Tarefa_Navegar().
chctrlframe:Aloca_Tarefa:Alocacoes_Tarefa_Navegar().
 Alocar  É utilizando esse método que se adiciona tarefas para o
componente.
Sintaxe: <com-handle>: Alocar ( Character-tarefa_id, Character-
texto_tar, Character-tooltip_tar, Character-hora_ini, Character-
hora_fim, Date-dt_aloc, Character-tooltip_aloc, Integer-cor_aloc ).
Onde:
<tarefa_id>: É o identificador da tarefa, este valor pode se repetir mas
quando isso acontecer todas as tarefas com o mesmo id serão exibidas
em uma mesma linha.
<texto_tar>: Texto que é exibido no canto esquerdo do gráfico e
UColunas

indica qual tarefa está sendo representada naquela linha.


<tooltip_tar>: É o tooltip do texto da tarefa.
<hora_ini>: Horário de início da tarefa.
<hora_fim>: Horário de término da tarefa.
<dt_aloc>: Data em que a tarefa está sendo alocada.
<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:Aloca_Tarefa:Alocar ("1","Tarefa 01","TIP - Tarefa 01",
"08:30","12:00","01/05/2004",
"08:30 - 12:00 / 3 Pessoas",500).

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.
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.ocx. O nome do componente a ser utilizado é
PColunas51.Ucolunas.
Seus principais métodos e atributos são:
 Tela_Limpar  Como o próprio nome do método sugere, sua
funcionalidade é de limpar as barras que já estejam sendo exibidas.
Sintaxe: <com-handle>:Tela_Limpar().
chCtrlFrame:UColunas:Tela_Limpar().
 Linhas_Trocar_Estilo  Utilizando esse método podemos alterar os
estilos das linhas dos gráficos, basta invocar o método e passar um
valor inteiro para definir o estilo da linha.
Os estilos de linha são: 1 – Sem linha; 2 – Pontilhado; 3 – Tracejado; 4
– Linhas.
Sintaxe: <com-handle>:Linhas_Trocar_Estilo (Valor AS Integer).
chCtrlFrame:UColunas:Linhas_Trocar_Estilo (4).
 Valor_Maximo_Setar  Esse método permite que seja definido qual o
valor máximo das colunas do gráfico.
Sintaxe: <com-handle>: Valor_Maximo_Setar (Valor AS
FLOAT,Character-c_format ).
chCtrlFrame:UColunas:Valor_Maximo_Setar (10,">>>>>,>>9.99").
MSComm

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 295

 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>: Colunas_Criar (Id AS SHORT, val1 AS
FLOAT, val2 AS FLOAT, val3 AS FLOAT, val4 AS FLOAT, val5 AS
FLOAT, Character-leg_x1, Character-leg_x2).
Onde:
<Id>: É o identificador de cada grupo.
<val1 – val5>: É o valor correspondente de cada coluna do grupo.
<leg_x1 e leg_x2>: São as legendas que podem ser atribuídas para os
grupos de colunas do componente.
Exemplo: chCtrlFrame:UColunas:Colunas_Criar (1, 10, 9, 8, 7, 6,
"Teste1", "Texto 2").
 Objetos_Mostrar  Método que exibe os grupos de colunas criados
na tela.
Sintaxe: <com-handle>:Objetos_Mostrar().
chCtrlFrame:UColunas:Objetos_Mostrar().
 Coluna_Selecionada  Este método retorna uma string com o
identificador + posição da coluna no grupo. Essa string permite
identificar unicamente cada uma das colunas.
Sintaxe: <com-handle>:Coluna_Selecionada().
chCtrlFrame:UColunas:Coluna_Selecionada().

Nota: Devido a problemas encontrados na utilização deste OCX o mesmo deixa de fazer parte
dos OCX homologados. Estamos mantendo sua documentação apenas para registro por
eventuais programas que já tenham sido construídos utilizando este OCX.

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.
O diretório onde se encontra o pacote para instalação desse componente é
em \interfac\BCportaserial\ e o arquivo que possui esse componente é
MSCOMM32.ocx. O nome do componente a ser utilizado é Microsoft
Communications Control, version 6.0.
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
ProgressBar

dispositivos.
Sintaxe: <com-handle>:CommPort.
ASSIGN chComm:MSComm:CommPort =500.
 Handshaking  Handshaking é o protocolo que é utilizado pelo
hoardware para se comunicar através da porta serial. Essa propriedade
aceita apenas valores inteiros e os possíveis valores para a propriedade
são: 0 – NoHandshaking; 1 – XonXoff; 2 – RtsCts; 3 –
XonXoffAndRtsCts.
Sintaxe: <com-handle>:Handshaking.
ASSIGN chComm:MSComm:Handshaking = 0.
 Settings  Através dessa propriedade definimos as configurações que
serão utilizadas para se comunicar com o outro disposito, essas
configurações são os números de bits por segundo, a paridade,
quantidade de bits e o bit de parada. 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>:Settings.
ASSIGN chComm:MSComm:Settings = “5,2,4,1”.
 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. 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, e para abrir ou fechar a porta basta setar yes ou no
para a porta.
Sintaxe: <com-handle>: PortOpen.
chComm:MSComm:PortOpen = NO.

Como o próprio nome sugere, trata-se de um componente OCX que exibe a


barra de progresso de um determinado procedimento que esteja sendo
executado.
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
ProgressBar Control, version 6.0.
 Min  Nessa propriedade do objeto definimos qual o valor mínimo
que a barra pode assumir.
TabStrip

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 297

Sintaxe: <com-handle>:Min.
ASSIGN chctrlframe:ProgressBar:Min = 0.
 Max  Por meio dessa propriedade definimos qual o maior valor que
a barra de progresso poderá assumir. É importante que se controle o
valor da barra para que não ultrapasse o valor máximo, pois isso causa
erro.
Sintaxe: <com-handle>:Max.
ASSIGN chctrlframe:ProgressBar:Max = 10.
 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..
Sintaxe: <com-handle>:Value.
ASSIGN chctrlframe:ProgressBar:Value =
chctrlframe:ProgressBar:VALUE + 1.

O TabStrip é um componente que permite que sejam criadas diversas


tabulações de trabalho, permitindo assim que em uma mesma frame se consiga
trabalhar com diversas informações de uma forma muito organizada.
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 TabStrip
Control, version 6.0.
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.
Sintaxe: <com-handle>:Clear().
chCtrlFrame:TabStrip:Tabs:CLEAR().
 COUNT  Por meio dessa propriedade conseguimos obter a
quantidade exata de tabs criadas.
Sintaxe: <com-handle>:Count.
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.
Sintaxe: <com-handle>:Index.
chCtrlFrame:TabStrip:SelectedItem:INDEX.
Tree Chart
Sound

 REMOVE  Método utilizado para remover uma determinada tab do


componente.
Sintaxe: <com-handle>:Remove (Index BY-VARIANT-POINTER).
chCtrlFrame:TabStrip:Tabs:Remove(chCtrlFrame:TabStrip:SelectedIte
m:INDEX).
 ADD  Esse método é utilizado para adicionar as tabs no
componente, as tabs devem ser adicionadas uma de cada vez.
Sintaxe: <com-handle>:Add(Index BY-VARIANT-POINTER,
Key BY-VARIANT-POINTER,
Caption BY-VARIANT-POINTER,
Image BY-VARIANT-POINTER ).
Onde:
<Index>: É o índice da tab que está sendo adicionanda.
<Key>: Key é o valor da tab, esse dado não é obrigatório.
<Caption>: Caption é o texto de exibição da tab que está criada.
<Image>: É o índice da imagem da lista de imagem que será exibida
nessa tab, essa informação não é obrigatória.
chCtrlFrame:TabStrip:Tabs:ADD( 1 BY-VARIANT-POINTER , ,
"Teste1" BY-VARIANT-POINTER , ).

Componente que possibilita e execução de arquivos de sons como wav e mid


em aplicações progress. Possui a propriedade “arquivo” que informa ou recebe
o nome do arquivo está sendo executado ou que irá ser executado, e a
propriedade “comando” que recebe ou informa o comando que está sendo
executado.
O diretório onde se encontra o pacote para instalação desse componente é
em \interfac\som\ e o arquivo que possui esse componente é DATSOUND.ocx.
O nome do componente a ser utilizado é DatasulSound.Sound.
Exemplo:
ASSIGN chCtrlFrame:Controls:Item(1):arquivo = "c:/tmp/som1.wav".
ASSIGN chCtrlFrame:Controls:Item(1):comando = "sound".

Nota: Devido a problemas encontrados na utilização deste OCX o mesmo deixa de fazer parte
dos OCX homologados. Estamos mantendo sua documentação apenas para registro por
eventuais programas que já tenham sido construídos utilizando este OCX.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 299

Componente OCX destinado à definição do lay-out de posicionamento das


células no organograma.
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.ocx. O nome do componente a ser utilizado é Tree Chart
Control.
Seus principais métodos e propriedades são:
 LAYERDISTANCE  Atrinbuto que define o tamanho das linhas
verticais do diagrama.
Sintaxe: Get: [ Decimal-Var = ] <com-handle>:LayerDistance.
Set: <com-handle>:LayerDistance [ = Decimal-Var ].
Exemplo: chTree_Layout:LayerDistance = 300.

 VERTEXDISTANCE  Atrinbuto que define o tamanho das linhas


horizontais do diagrama.
Sintaxe: Get: [ Decimal-Var = ] <com-handle>:VertexDistance.
Set: <com-handle>:VertexDistance [ = Decimal-Var ].
Exemplo: chTree_Layout:VertexDistance = 300.

 ORIENTATION  Atributo que define a posição das células pai em


relação às células filhas.
Valores: 0 – Norte;
1 – Leste;
2 – Sul;
3 – Oeste.

Sintaxe: Get: [ <user-defined>-Var = ] <com-handle>:Orientation.


Set: <com-handle>:Orientation [ = <user-defined>-Var ].
Exemplo: chTree_Layout:Orientation = 0.
Print Chart

 LAYOUT  Aplica o lay-out definido no componente de diagrama


definido em Com-Handle-Control.
Sintaxe: NO-RETURN-VALUE <com-handle>: Layout ( Com-Handle-
Control ).
Exemplo: no-return-value chTree_layout:Layout(chOrg).
Onde chOrg é o componente que será aplicado o Layout.

Nota: Devido a problemas encontrados na utilização deste OCX o mesmo deixa de fazer parte
dos OCX homologados. Estamos mantendo sua documentação apenas para registro por
eventuais programas que já tenham sido construídos utilizando este OCX.

Componente OCX destinado ao tratamento dos parâmetros de impressão para


outros componentes OCX.
O diretório onde se encontra o pacote para instalação desse componente é
em \interfac\Print Chart\ e o arquivo que possui esse componente é
PRINTCHART.ocx. O nome do componente a ser utilizado é Print Chart
Activex Control.
Seus principais métodos e propriedades são:
 HWNDFLOW  Esse método é utilizado para armazenar o
componente que possui os dados a serem impressos.
Sintaxe: Get: [Integer-Var =] <com-handle>:hWndFlow.
Set: <com-handle>:hWndFlow [ = Integer-Var ].
Exemplo: chPrn:hWndFlow = chOrg:hwnd .
Onde chOrg é o componente que possui os dados a serem impressos.

 DOCNAME  Esse método armazena o nome do respectivo


documento.
Sintaxe: Get: [Character-Var = ] <com-handle>:DocName.
Set: <com-handle>:DocName [ = Character-Var ].
Exemplo: chPrn:DocName = "Nome do arquivo".
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 301

 FITTOPAGE  Método utilizado para acomodar o conteúdo a ser


impresso em uma única página.
Sintaxe: Get: [ Logical-Var = ] <com-handle>:FitToPage.
Set: <com-handle>:FitToPage [ = Logical-Var ].
Exemplo: chPrn:FitToPage = TRUE.

 PREVIEW  Método utilizado para apresentar a tela de preview de


impressão.
Sintaxe: Get: [ Logical-Var = ] <com-handle>:Preview.
Set: <com-handle>:Preview [ = Logical-Var ].
Exemplo: chPrn:Preview = TRUE.

 PRINTERSETTINGS  Método utilizado para apresentar a tela de


propriedades de impressão.
Sintaxe: Get: [ Logical-Var = ] <com-handle>:PrinterSettings.
Set: <com-handle>:PrinterSettings [ = Logical-Var ].
Exemplo: chPrn:PrinterSettings = true.

 ORIENTATION  Método utilizado para informar a orientação da


folha ( Retrato ou Paisagem ).
Sintaxe: Get: [ <user-defined>-Var = ] <com-handle>:Orientation.
Set: <com-handle>:Orientation [ = <user-defined>-Var ].
Exemplo: chPrn:orientation = 2.

 PRINTDOC  Método utilizado para imprimir o respectivo


documento.
Sintaxe: NO-RETURN-VALUE <com-handle>: PrintDoc.
Exemplo: chPrn:PrintDoc.
Org Chart Nota: Devido a problemas encontrados na utilização deste OCX o mesmo deixa de fazer parte
dos OCX homologados. Estamos mantendo sua documentação apenas para registro por
eventuais programas que já tenham sido construídos utilizando este OCX.

Componente OCX destinado à criação de organogramas. 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.ocx. O nome do
componente a ser utilizado é Org Chart Activex Control.
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.
Set: <com-handle>:FillColor [ = Integer-Var ].
Exemplo: chorg:fillcolor = rgb-value(255,255,255).

 FORECOLOR  Método utilizado para definir a cor dos labels do


diagrama.
Sintaxe: Get: [ Integer-Var = ] <com-handle>:ForeColor.
Set: <com-handle>:ForeColor [ = Integer-Var ].
Exemplo: chorg:forecolor = rgb-value(0,0,0).

 BACKCOLOR  Método utilizado para determinar a cor de fundo do


diagrama.
Sintaxe: Get: [ Integer-Var = ] <com-handle>:BackColor.
Set: <com-handle>:BackColor [ = Integer-Var ].
Exemplo: chorg:backcolor = rgb-value(255,255,255).

 FONT  Método responsável pelo tratamento de fontes.


Sintaxe: Get: [ Com-Handle-Var = ] <com-handle>:Font.
Set: <com-handle>:Font [ = Com-Handle-Var ].
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 303

Exemplo: chOrg:FONT:NAME = "Tahoma".


chOrg:FONT:SIZE = 7.

 SAVEFILE  Salva um diagrama em um arquivo


Sintaxe: NO-RETURN-VALUE <com-handle>: SaveFile (
Character-file ).
Exemplo: no-return-value chOrg:FONT: SaveFile( name file ).

 SAVEIMAGE  Salva um diagrama em um formato meta-arquivo.


Sintaxe: NO-RETURN-VALUE <com-handle>: SaveImage (
Integer-tymed,
Integer-format,
Character-file ).
Exemplo: no-return-value chOrg:FONT: SaveFile( 0, 0, name file).
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: Get: [ Integer-Var = ] <com-handle>:Shape.
Set: <com-handle>:Shape [ = Integer-Var ].
Exemplo: chOrg:shape = 2.

 AUTOSCROLL  Através desse método pode-se determinar se o


diagrama irá apresentar as barras de rolagem quando necessário.
Sintaxe: Get: [ Logical-Var = ] <com-handle>:AutoScroll.
Set: <com-handle>:AutoScroll [ = Logical-Var ].
Exemplo: chOrg:AutoScroll = true.

 SELECTALL  Método utilizado para selecionar todo o diagrama.


Sintaxe: NO-RETURN-VALUE <com-handle>: SelectAll ( ).
Exemplo: chOrg:SelectAll.

 DELETESEL  Método utilizado para apagar os itens selecionados.


Sintaxe: NO-RETURN-VALUE <com-handle>: DeleteSel ( ).
Exemplo: chOrg:DeleteSel.

 ADD  Método utilizado para adicionar novas células no diagrama.


Sintaxe: [ Com-Handle-Var = ] <com-handle>: Add (
Decimal-Left AS FLOAT,
Decimal-Top AS FLOAT,
Decimal-Width AS FLOAT,
Decimal-Height AS FLOAT ).

Para criarmos novas células no diagrama deve-se, primeiramente,


definir três variáveis do tipo com-handle:
def var chNode as com-handle extent 9999 no-undo.
def var chNodos as com-handle no-undo.
def var chLiga as com-handle no-undo.

Utilizando o método “nodes” do componente OCX OrgChart, associá-


lo à variável chNodos:
chNodos = chOrg:nodes.
Onde chOrg é o nome do componente OCX OrgChart.
Implementação
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 305

A variável chNode será utilizada para armazenar as novas células


criadas, sendo que a variável “sequência” será utilizada para
armazenar a seqüência na hierarquia do organograma:
chNode[sequência] = chNodos:add(0,0,1500,600).

A variável chLiga é utilizada para montar os links entre as células.


Utilizando o método “outlinks” criamos a ligação entre a célula pai e a
cáelula filho.
chLiga = chNode[seqüência pai]:outlinks:add(chNode[sequência]).

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).
repeat j = 1 to chNodos:links:count:
chliga = chNodos:links(j).
chliga:LinkStyle = 4.
chLiga:Rigid = true.
end.
end.

Como executar um aplicativo do Windows


Esta técnica deve ser usada sempre que for executado um programa externo.
Essa função substitui a antiga função WINEXEC.
 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 Execute que está dentro do programa ut-utils.p,


passando os seguintes parâmetros:
 caminho do programa para ser executado;
 os parâmetros para o programa a ser executado;
run Execute in h-prog(input "c:\windows\calc,exe",
input "").

 se o retorno for "Ok" a operação foi feita com sucesso;


If return-value = "Ok" then message "A operação foi feita com
sucesso".

 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.
Implementação
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 307

Como implementar Correção Ortográfica em Editores


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.
 criar um botão e colocá-lo ao lado direito superior do Editor;
 alterar os atributos do tamanho do botão para:
Width: 4,00
Height: 1,25
 deixar o botão sem label;
 inserir o Help:"Corretor ortográfico" no botão para implementar o
Tooltip;
 definir a variável 1-control-spell em Definitions. Exemplo:
define variable l-control-spell as logical no-undo init no.

 na procedure local-display-fields da SmartViewer ou na procedure local-


initialize da SmartWindow, dependendo onde se encontra o Editor, deve
ser inserida após o Run Dispatch, a chamada da include i-inispl.i, passando
como parâmetro o nome do botão que foi criado. Exemplo:
{include/i-inispl.i <nome-do-botão>}

 no MAIN-BLOCK, deve ser inserida a chamada da include i-spell.i,


passando como primeiro parâmetro o nome do Editor que sofre a correção
ortográfica, e como segundo parâmetro, o nome do botão que foi criado e
que dispara a correção ortográfica. Exemplo:
{include/i-spell.i <nome-do-editor> <nome-do-botão>}

É importante ressaltar que esta técnica só irá funcionar para quem possui o
Word 97, instalado na sua máquina.
Após a implementação da técnica, ela funciona assim:
 no início, a imagem do botão check deve estar em vermelho, indicando
que o texto do Editor ainda não passou pela correção ortográfica.
Exemplo:
Objetivo

 quando o botão for disparado, a Dialog de correção ortográfica do Word


97 é chamada e todos os seus recursos devem estar disponíveis:

 terminada a execução do corretor ortográfico, a imagem do botão check


está em verde, indicando que o texto do Editor já passou pela correção
ortográfica. Exemplo:

Como obter as coordenadas do mouse


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. Pode ser usado
em browsers para ordenação automática com base em um clique.
Objetivo
Implementação

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 309

 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 GetMousePos que está dentro do programa ut-


utils.p, passando os seguintes parâmetros:
 handle da window onde deve ser verificada a posição do mouse;
 uma variável do tipo inteiro para retornar o valor da coordenada X;
 uma variável do tipo inteiro para retornar o valor da coordenada Y;
run GetMousePos in h-prog(input {&window-name}:handle,
output i-x,
output i-y).

 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.

 este procedimento pode ser usado na trigger de Select-Mouse-Click de um


objeto, fazendo com que este retorne a coordenada do mouse no momento
foi dado o clique no objeto.

Como obter o diretório corrente


Utilizar sempre que for necessário obter o diretório corrente do aplicativo que
está sendo executado.
 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.
Implementação
Objetivo

 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 GetCurrentDir que está dentro do programa ut-


utils.p, passando o seguinte parâmetro:
 uma variável do tipo caracter onde deve ser retornado o diretório
corrente;
run GetCurrentDir in h-prog(output c-dir).

 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 obter o diretório de sistema do Windows


Utilizar esta técnica sempre que for necessário retornar o diretório de sistema
do windows. Pode ser usada quando se deseja copiar algum arquivo para o
diretório SYSTEM.
 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 GetSysDir que deve estar dentro do programa ut-


utils.p, passando o seguinte parâmetro:
 uma variável do tipo caracter para retornar o caminho do diretório de
sistema do windows;
run GetSysDir in h-prog(output c-path).

 eliminar o programa ut-utils.p que foi rodado persistente da memória.


delete procedure h-prog.
Implementação
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 311

Observação Não esquecer de executar o último procedimento descrito, pois na falta deste, o
sistema pode ficar sem recursos e travar.

Como obter o diretório do Windows


Utilizar esta técnica sempre que for necessário retornar o diretório do
windows. Pode ser usada quando se deseja copiar algum arquivo para o
diretório WINDOWS.
 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 GetWinDir que deve estar dentro do programa ut-


utils.p, passando os seguintes parâmetros:
 uma variável do tipo caracter onde deve ser retornado o caminho do
diretório do windows;
run GetWinDir in h-prog(output c-path).

 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 obter o nome do computador


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.
 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;


Implementação
Objetivo

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 GetComputerName que deve estar dentro do


programa ut-utils.p, passando o seguinte parâmetro:
 uma variável do tipo caracter onde deve ser retornado o nome do
computador;
run GetComputerName in h-prog(output c-computador).

 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 obter o valor de uma variável de ambiente


Utilizar esta técnica sempre que for necessário ler alguma variável de
ambiente;
 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 GetEnv que deve estar dentro do programa ut-


utils.p, passando os seguintes parâmetros:
 a variável de ambiente que deseja-se saber o valor;
 uma variável do tipo caracter para retornar o valor da variável de
ambiente informada;
run GetEnv in h-prog(input "PATH", output c-path).
Implementação
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 313

 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 transformar uma janela em barra de ferramentas


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,
funções que não estejam ligadas a nenhum objeto ou programa específico.
 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-style.p persistente e atribuir o seu handle para a


variável que foi criada anteriormente;
run utp/ut-style.p persistent set h-prog.

 rodar o procedimento AddPaletteStyle que deve estar dentro do programa


winstyle.p, passando os seguintes parâmetros:
 atributo hWnd da janela a ser transformada;
run AddPaletteStyle in h-prog(input {&window-name}:hWnd).

 eliminar o programa ut-style.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.

 verificar a possibilidade de deixar a barra de ferramentas sempre visível.


Se a barra for sempre visível, o que é o mais normal, veja Como deixar
uma janela sempre visível;
Como desabilitar Radio-Buttons
A sintaxe normal para desabilitar radio-buttons é:
DISABLE(LABEL_DO_RADIO_BUTTON).

Entretanto essa técnica não corresponde as nossas necessidades, visto que, o


label do radio-button, muda para cada língua. Para isso, iremos adotar uma
técnica que utiliza a seguinte sintaxe:
IF nome-rs:DISABLE(ENTRY(X,(nome-rs:RADIO-BUTTONS IN FRAME
{&FRAME-NAME}))) THEN.

Onde:
Nome-rs: Nome do Radio-set
X: Número que obtém a entrada desejada do radio-set. Este número é obtido
pela seguinte fórmulaX=2 * (entrada desejada)-1.
Observação o Radio-Set Properties mostra que as strings são: "string", 1, "string", 2, ..., então
para obter a posição desejada é necessário utilizar a fórmula descrita anteriormente.
Exemplo:
desabilitar o radio-button empréstimo
Tipo-modalidade.transacao
1 - Aplicação
2 - Empréstimo
X = 2(2) -1
X=3
If tipo-modalidade.transacao:disable(entry(3, tipo-
modalidade:radio-buttons)) in frame {&frame-name} then.
Implementação
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 315

Como executar programas que são janelas


Esta técnica demonstra a forma correta para execução de um programa (.w) a
partir de um outro programa que já é uma janela, evitando a ocorrência do erro
4123 ("None of the widgets used in WAIT-FOR statement are SENSITIVE
WAIT-FOR terminated. (4123))" durante a sua execução.
 deve ser definida uma variável do tipo handle. Exemplo:
def var h-programa as handle no-undo.

 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", exemplo:
run xxp/xx999.w persistent set h-programa.
If valid-handle(h-programa) then
run dispatch in h-programa ('initialize').

 logo após a execução persistente do programa, se necessário, podem-se


executar procedimentos do mesmo, antes ou depois de sua inicialização,
sendo que para cada procedimento a ser executado deve-se verificar a
validade do handle. Exemplo:
run xxp/xx9999.w persistent set h-programa.
If valid-handle(h-programa) then
8
run pi-seta-parametros in h-programa (input "teste").
If valid-handle(h-programa) then
run dispatch in h-programa ('initialize').9
If valid-handle(h-programa) then do:10
run pi-reposiciona-tabela1 in h-programa (input 123).
11
run pi-reposiciona-tabela2 in h-programa (input 456).
End.

8
Procedure pertencente ao programa chamado executada antes de sua inicialização;
9
Inicialização do programa chamado. Deverá sempre ser feita separadamente de outras execuções de
procedimentos devido a possibilidade de a inicialização o handle tornar-se inválido;
10
Validação do handle agrupando mais de uma execução de 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. Isso pode acontecer se, por exemplo, o
procedimento feche o programa chamado.
11
Procedimento, que não tem possiblidade de ocasionar a invalidade do handle, contido em um bloco com
mais procedimentos.
Para verificar se a implementação foi realizada de forma correta, basta fechar
a "janela chamadora" antes de fechar a "janela chamada". Quando for
encerrada a "janela chamada" o erro não deve ocorrer, se a técnica foi
utilizada. O conceito GUI / MS Windows / Progress indica que uma janela
deve rodar como um objeto independente, por isso a execução de programa
chamado deve ser de forma persistente.

Como habilitar ou desabilitar botões em painéis


Foram criados procedures internas, nas masters, para habilitar ou desabilitar
todos os botões dos painéis de Cadastro e Alteração. Para executar a procedure
e habilitar/desabilitar é necessário ter um link do tipo STATE, entre o painel e
a Window (THIS-PROCEDURE). A chamada desta procedure deve ser feita
dentro do local-initialize, depois do run-dispatch, na Window.
A sintaxe desta procedure é:
RUN enable-<função-do-botão> in <handle do painel> (Input
<logical>).

Onde:
<função-do-botão>: Função específica do botão a ser trabalhado
<handle-do-painel>: Handle do painel, onde o link é source
<logical>: Variável em fator lógico, onde "yes" habilita e "no" desabilita.

Funções
Inclui
Elimina
Modifica
Copia
Cancela
Desfaz
Salva
Va-para
Zoom
Relacionamento
Relatório
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 317

Caso você queira desabilitar os botões do painel, conforme alguma validação


existente em uma viewer ou em um browser, você deve proceder da seguinte
maneira:
 Executar a procedure habilitar/desabilitar no state-changed, na Windows.
 Criar um Smart-link, do tipo state, tendo como Source a Viewer ou
Browser e como Target a SmartWindow(this-procedure).
 Na procedure local-row-available ou outro local, da Viewer ou do
Browser, conforme necessidade do usuário, inserir a lógica abaixo:
if ... validação qualquer ...
then run new-state("habilitar":U).
else run new-state("nao-habilitar":U).

 na state-changed da Window, inserir a lógica abaixo:


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>).
end.

Observação Não utilize a opção "else", pois nesta procedure passam vários outros state´s.

Como habilitar ou desabilitar botões específicos em Browse


Inclui/Modifica
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.
Implementação

 inserir o código, em destaque, na procedure STATE-CHANGED do


Browse Inclui/Modifica;
PROCEDURE state-changed:
/* ---------------------------------------------------------
Purpose:
Parameters: <none>
Notes:
----------------------------------------------------- */
DEFINE INPUT PARAMETER p-issuer-hdl AS HANDLE NO-UNDO.
DEFINE INPUT PARAMETER p-state AS CHARACTER NO-UNDO.
CASE p-state:
when "no-record-available":U then
assign bt-name:SENSITIVE in frame {&FRAME-NAME} =
no.
when "no-external-record-available":U then
assign bt-name:SENSITIVE in frame {&FRAME-NAME} =
no.
when "record-available":U then
assign bt-name:SENSITIVE in frame {&FRAME-NAME} =
yes.
/* Object instance CASEs can go here to replace standard
behavior or add new cases. */
{src/adm/template/bstates.i}
END CASE.
run pi-trata-state (p-issuer-hdl, p-state).
END PROCEDURE.

Observações Não elimine o código existente na procedure STATE-CHANGED.


E, ainda, os botões de Modifica/Eliminar são desabilitados automaticamente.

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, nos códigos abaixo:
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 319

XX: sigla do banco de dados


XXINC/I99XX999.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. Colocar um combo-box na tela com formato maior que o tamanho do
maior elemento do list-items deste campo indicador;
Nas propriedades avançadas deste combo-box, marcar os 'Custom lists',
conforme o tipo de SmartViewer:
Viewers de Cadastro Simples Viewers de Folders
ADM-CREATE-FIELDS
ADM-ASSIGN-FIELDS ADM-MODIFY-FIELDS
ADM-MODIFY-FIELDS
2. Retirar a propriedade Enable do combo-box.
3. Na procedure "local-initialize" implementar, antes do run dispatch, 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.I 03}.
/* Dispatch standard ADM method. */
RUN dispatch IN THIS-PROCEDURE (INPUT 'initialize':U).

4. Na procedure "local-display-fields" implementar, após o run dispatch, uma


lógica que apresente o valor caracter correspondente ao valor inteiro do
campo indicador:
/* Dispatch standard ADM method.
RUN dispatch IN THIS-PROCEDURE (INPUT 'display-fields':U).
/* Code placed here will execute AFTER standard behavior. */
if avail <tabela> then
assign <variavel-combo-box>:screen-value in frame {&frame-
name} = {XXINC/I99XX999.I 04 <tabela>.<campo>}.
end.
else
assign <variavel-combo-box>:screen-value in frame {&frame-
name} = {XXINC/I99XX999.I 04 1}.
end.
5. Para gravação do conteúdo do combo-box, na base de dados:
a) Quando for um Cadastro Simples, implementar a seguinte lógica após
o "run dispatch da local-assign-record":
assign <tabela>.<campo> = {XXINC/I99XX999.I 06 <variável-
combo-box>}.

b) Quando for um Cadastro Complexo, implementar a seguinte lógica


após o "run dispatch da local-assign-statement":
assign input frame {&frame-name} <variável-combo-box>
<tabela>.<campo> = {XXINC/I99XX999.I 06 <variável-combo-
box>}.

6. Na procedure local-enable-fields, 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, e este


campo não fizer parte da chave primária, 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. Caso este campo faça
parte da chave, o assign deve ser feito na local-create-record, também após o run dispatch.

Como implementar campos indicadores com view-as radio-set nas


telas
Os campos indicadores podem ser representados nas telas com view-as radio-
set e para isto deve-se seguir os passos, nos códigos abaixo:
XX : sigla do banco de dados
XXINC/I99XX999.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. 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;
Nas propriedades avançadas deste radio-set, marcar os 'Custom lists',
conforme o tipo de SmartViewer:
Viewers de Cadastro Simples Viewers de Folders
ADM-CREATE-FIELDS
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 321

ADM-ASSIGN-FIELDS ADM-MODIFY-FIELDS
ADM-MODIFY-FIELDS
2. Retirar a propriedade Enable do radio-set.
3. 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.

4. Na procedure "local-initialize" implementar, antes do run dispatch, uma


lógica que prepare o "list-items" da variável radio-set:
do i-cont = 1 to num-entries({XXINC/I99XX999.I 03}):
assign c-lista = c-lista + entry(i,{XXINC/I99XX999.I 03}) +
"," + string(i-cont) + ",".
end.
assign c-lista = substring(c-lista,1,lenght(c-lista) - 1).
assign <variavel-radio-set>:radio-buttons in frame {&frame-
name} = c-lista.
/* Dispatch standard ADM method. */
RUN dispatch IN THIS-PROCEDURE (INPUT 'initialize':U).

5. Na procedure "local-display-fields" implementar, após o run dispatch, uma


lógica que apresente o valor caracter correspondente ao valor inteiro do
campo indicador:
/* Dispatch standard ADM method.
RUN dispatch IN THIS-PROCEDURE (INPUT 'display-fields':U).
/* Code placed here will execute AFTER standard behavior. */
if avail <tabela> then
assign <variavel-radio-set>:screen-value in frame {&frame-
name} = {XXINC/I99XX999.I 04 <tabela>.<campo>}.
end.
else
assign <variavel-radio-set>:screen-value in frame {&frame-
name} = {XXINC/I99XX999.I 04 1}.
end.

6. Para gravação do conteúdo do radio-set, na base de dados:


a) Quando for um Cadastro Simples, implementar a seguinte lógica após
o "run dispatch da local-assign-record":
assign <tabela>.<campo> = {XXINC/I99XX999.I 06 <variável-
radio-set>}.

b) Quando for um Cadastro Complexo, implementar a seguinte lógica


após o "run dispatch da local-assign-statement":
assign input frame {&frame-name} <variável-radio-set>
<tabela>.<campo> = {XXINC/I99XX999.I 06 <variável-radio-
set>}.

7. Na procedure local-enable-fields, 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, e este


campo não fizer parte da chave primária, 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. Caso este campo faça
parte da chave, o assign deve ser feito na local-create-record, também após o run dispatch.

Quando for mostrar o campo indicador, em consulta, com view-as radio-set,


deve ser mostrado num fill-in, somente a descrição correspondente ao valor
cadastrado. Na procedure local-display-fields, deve ser dado um assign no fill-
in utilizando a include do dicionário conforme exemplo abaixo:
assign <variavel-fill-in>:screen-value in frame <frame-
name> = {XXINC/I99XX999.I 04 <tabela-campo>}.

Como implementar campos indicadores num SmartBrowser


Quando se precisar colocar um campo do tipo indicador (view-as, 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, porque estes
campos indicadores são inteiros e deve ser apresentado o valor caracter
correspondente. Exemplo:
entry(conta.tipo,"Ativo,Passivo,Receita,Despesa,Vendas,Título")
@ c-tipo

1. Em Definitions do SmartBrowser definir duas novas variáveis para o


campo indicador, uma conter o seu 'label' e ser a coluna do campo
calculado no browse e outra character para conter o seu 'list-items'.
Exemplo:
def var c-tipo as character no-undo. /* coluna no browse */
def var c-lista-tipo as character no-undo. /* list-items */
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 323

2. 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.
/* include que retornará o label do campo */
{utp/ut-field.i mgadm conta tipo 1}
/* acerta o column-label no browse */
assign c-tipo:label in browse br-table = return-value.
/* busca o list-items conforme o include padrão */
assign c-lista-tipo = {adind/i02ad049.i 03}

Onde:
{03}:indica a função a ser realizada, conforme a tabela abaixo:
Função Objetivo
01 define view-as Combo-Box
02 define view-as Radio-Set
03 lista com os itens separados por vírgula
04 n retorna o item n da lista
05 retorna o número de itens da lista
06 item retorna a posição do item (número)
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:
entry(conta.tipo, 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, 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.
O problema é que este 'text' deveria conter o label do dicionário de dados para
o campo. Exemplo:
1. Colocar na tela um fill-in, ao invés de um text, como label do retângulo,
nas suas propriedades defini-lo como 'view-as text', 'no-label', assinalar a
propriedade 'display' e retirar a propriedade 'enable'. Exemplo:
2. No Local-Initialize da SmartViewer fazer a chamada do include ut-rtlbl.i
para definir o screen-value deste fill-in. Exemplo:
{utp/ut-rtlbl.i mgadm conta natureza text-1}

3. Na Local-Display-Fields da SmartViewer também fazer a chamada do


include ut-rtlbl.i para redefinir o screen-value deste fill-in na inclusão,
após a chamada do ADM Method 'display-fields' que aplica um clear no
frame desejado. Exemplo:
RUN dispatch IN THIS-PROCEDURE (input 'display-fields').
{utp/ut-rtlbl.i mgadm conta natureza text-1}

4. Na Local-Add-Record da SmartViewer, depois do


RUN dispatch IN THIS-PROCEDURE (input 'Add_Record:U').

incluir
{utp/ut-rtlbl.i mgadm conta natureza text-1}

Após, quando o SmartViewer estiver rodando, o radio-set fica assim:

Como implementar mensagens para o usuário


A partir da utilização do programa utilitário UTP/UT-MSGS.P para
apresentação de mensagens ou retorno de propriedades, descreve-se abaixo
algumas técnicas para sua utilização.
Observação As mensagens padrões estão descritas no capítulo "Mensagens".

Mensagem de Erro/Advertência/Informação sem Parâmetros


1. Chamar o programa utp/ut-cdmsg.p e criar a mensagem, com texto de
help. Este aplicativo é de uso exclusivo da Datasul. Para quem está
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 325

desenvolvendo específicos e precisa utilizar mensagens que não estão


cadastradas, pode-se utilizar o comando Progress MESSAGE. Se a
mensagem já existir, pode ser utilizado o passo 3 desta técnica. 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 ...

2. Para apresentar a mensagem. Exemplo:


run utp/ut-msgs.p (input "show",
input 1234,
input "").

3. Ou, para utilizar alguma propriedade da mesma. Exemplo:


run utp/ut-msgs.p (input "msg", (ou help)
input 1234,
input "").
display return-value @ c-erro with frame f-log.

Mensagem de Erro/Advertência/Informação com Parâmetros


1. Chamar o programa utp/ut-cdmsg.p e criar a mensagem com texto de help.
Este aplicativo é de uso exclusivo da Datasul. Para quem está
desenvolvendo específicos e precisa utilizar mensagens que não estão
cadastradas, pode-se utilizar o comando Progress MESSAGE. Se a
mensagem já existir, pode ser utilizado o passo 3 desta técnica. 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.

2. Para apresentar a mensagem.


run utp/ut-msgs.p (input "show",
input 1235,
input repres.cod-repres + "~~" + regiao.cod-
regiao + "~~" + string(regiao.val-minimo).

3. Ou, para utilizar alguma propriedade da mesma.


run utp/ut-msgs.p (input "msgs", (ou help)
input 1235,
Implementação
Exemplo

input repres.cod-repres + "~~" + regiao.cod-


regiao + "~~" + string(regiao.val-minimo).
display return-value @ c-erro with frame f-log.

Mensagens com Questionamento ao Usuário


1. Chamar o programa utp/ut-cdmsg.p e criar a mensagem, com texto de
help. Este aplicativo é de uso exclusivo da Datasul. Para quem está
desenvolvendo específicos e precisa utilizar mensagens que não estão
cadastradas, pode-se utilizar o comando Progress MESSAGE. Se a
mensagem já existir, esta técnica pode ser utilizada normalmente.
Exemplo:

Número: 1236
Mensagem: Verificação completa. Confirma atualização ?
Tipo: Questão
Help: A verificação dos dados foi completada, estando os dados
preparados para atualização

2. Para apresentar a mensagem.


run utp/ut-msgs.p (input "show",
input 1236,
input "").
if return-value = "no" then
return.
else
if return-value = "yes" then
message "Aguarde, em Processamento ...".

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. Como pode ser
verificado, os botões padrões (aqueles que formam os painéis) já passaram a
apresentar tooltips durante a execução dos programas. Contudo, todos os
botões criados num determinado programa também devem contar com Tooltip
e, para tanto, esta técnica demonstra como deve ser feita essa implementação.
 para que um botão não padrão apresente seu tooltip é necessário que o
mesmo possua help, pois a include padrão {src/adm/method/smart.i} foi
alterada para copiar o help para o tooltip em todos os botões de todas as
telas;
Implementação
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 327

 para informar o help de um botão, 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, não sendo necessário
qualquer tratamento para tradução, pois os estilo fazem a tradução
automaticamente dos help´s e label´s de botões. Exemplo:

Em tempo: não informar a propriedade tooltip.

Como implementar uma barra de progresso


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.
 definir uma variável do tipo handle;
def var h-prog as handle no-undo.

 rodar o programa ut/ut-perc.p persistente e atribuir o seu handle para a


variável que foi criada anteriormente;
run utp/ut-perc.p persistent set h-prog.
 rodar o procedimento pi-inicializar que deve estar dentro do programa ut-
perc.p, passando os seguintes parâmetros:
 título da janela da barra de processo;
 número total de iterações que a barra deve acompanhar;
for each item no-lock:
assign i-tot = i-tot + 1.
end.
run pi-inicializar in h-prog(input "Importando arquivos",
i-tot).

 rodar o procedimento pi-acompanhar, que está dentro do programa ut-


perc.p para cada iteração:
for each item no-lock on stop undo, leave:
run pi-acompanhar in h-prog.
end.

 rodar o procedimento pi-finalizar, que está dentro do programa ut-perc.p,


logo após a saída da iteração:
run pi-finalizar in h-prog.

 para que seja visualizado o registro que está sendo processado no


momento (na barra de título), deve-se rodar o procedimento pi-registro
logo após a pi-acompanhar, passando como parâmetro, uma string que irá
identificar o registro processado:
for each item no-lock on stop undo, leave:
run pi-acompanhar in h-prog.
run pi-registro in h-prog (input string(item.it-codigo)).
end.

 para verificar se o processo foi cancelado, 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;
 OK  Caso o procedimento tenha sido executado até o fim.
run pi-retorna-status in h-prog (output c-status).

 para desabilitar ou habilitar o botão cancela, deve-se rodar os


procedimentos pi-desabilita-cancela e pi-habilita-cancela logo após a pi-
inicializar:
Implementação
Objetivo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 329

run pi-inicializar in h-prog(input "Importando arquivos",


500).
run pi-desabilita-cancela in h-prog.

Como implementar acompanhamento (UT-ACOMP)


Utilizar esta técnica sempre quando executar um processo longo e que se
deseje manter o usuário informado sobre o andamento do mesmo. Esta técnica
deve ser utilizada sempre que não for conhecido o número total de registros a
serem processados.
 definir uma variável do tipo handle;
def var h-prog as handle no-undo.

 rodar o programa ut/ut-acomp.p persistente e atribuir o seu handle para a


variável que foi criada anteriormente;
run utp/ut-acomp.p persistent set h-prog.

 rodar o procedimento pi-inicializar que deve estar dentro do programa ut-


acomp.p, passando os seguintes parâmetros:
 título da janela da barra de processo;
run pi-inicializar in h-prog(input "Importando arquivos").

 rodar o procedimento pi-acompanhar, que está dentro do programa ut-


acomp.p para cada iteração, passando o seguinte parâmetro:
 o texto a ser visualizado pelo usuário;
for each item no-lock on stop undo, leave:
run pi-acompanhar in h-prog(input string(item.it-codigo)).
end.

 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;
run pi-seta-titulo in h-prog(input "Exportando Arquivos").
 rodar o procedimento pi-finalizar, que está dentro do programa ut-
acomp.p, logo após a saída da iteração:
run pi-finalizar in h-prog.

 para desabilitar ou habilitar o botão cancela, deve-se rodar os


procedimentos pi-desabilita-cancela e pi-habilita-cancela logo após a pi-
inicializar:
run pi-inicializar in h-prog(input "Importando arquivos",
500).
run pi-desabilita-cancela in h-prog.

 para verificar se o processo foi cancelado, 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;
 OK  Caso o procedimento tenha sido executado até o fim.
run pi-retorna-status in h-prog (output c-status).

 para desabilitar ou habilitar o botão cancela, deve-se rodar os


procedimentos pi-desabilita-cancela e pi-habilita-cancela logo após a pi-
inicializar:
run pi-inicializar in h-prog(input "Importando arquivos", 500).
run pi-desabilita-cancela in h-prog.

 para determinar um intervalo de tempo para a exibição do registro corrente


do processamento, deve-se incluir no arquivo .ini utilizado pelo EMS uma
nova chave nomeada “TimeAComp” com o valor do tempo desejado em
segundos no bloco de definições Datasul_EMS2. Exemplo:

[Datasul_EMS2]
Show-Report-Program=notepad.exe
TimeAComp=60

Neste exemplo, o utilitário somente exibirá qual é o registro corrente a cada 60


segundos. Caso não seja informado nenhum valor para “TimeAComp” ou ela
nem mesmo existir no arquivo .ini, o utilitário continuará tendo o
comportamento padrão de exibir cada registro processado.
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 331

Como implementar Zoom e campos de referência para campos


chave estrangeira
Para implementar o zoom em campos chave estrangeira, 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, 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'.
Exemplo: Para o campo de referência state-name temos a variável c-state-
name.
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.
if available customer then do:
find state where state.state = customer.state no-lock no-
error.
assign c-state-name = if avail state then state.state-name
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 ZOOMVAR.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);
 a partir de uma coluna num browse;
Todas estas situações com a possibilidade de passagem de parâmetros para o
programa de zoom;
Sintaxe:
{include/zoomvar.i &prog-zoom=diretório/programa
&campo=variavel/tabela.atributo
&campozoom=nome-atributo
[&frame=nome-frame]
[&browse=nome-browse]
[&parametros="run pi-procedure in wh-
pesquisa".]}

Onde:
<prog-zoom>: é o nome do programa de zoom
<campo>: é o campo/variável na viewer ou frame onde está sendo colocado o
zoom, sendo um campo de tabela, deve ser especificado no formato
tabela.campo
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 333

<campozoom>: é o campo no SmartBrowser do zoom de onde o valor é


buscado, 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;
<parâmetros>: chama uma procedure dentro da Window do programa de
zoom, que recebe os parâmetros. Deve conter um valor do tipo:
&parametros="run pi-procedure in wh-pesquisa(input 'inicio', input 'fim').".
Exemplos:
a) chamada de zoom para atributos em um frame:
ON F5 OF ord-prod.it-codigo in frame {&FRAME-NAME}
OR MOUSE-SELECT-DBLCLICK OF ord-prod.it-codigo in frame
{&FRAME-NAME} DO:
{include/zoomvar.i &prog-zoom=inzoom/z01in172.w
&campo=ord-prod.it-codigo
&campozoom=it-codigo}
END.

b) chamada do zoom para mais de um atributo de um frame:


ON F5 OF det-rateio.ct-codigo in frame {&FRAME-NAME}
OR MOUSE-SELECT-DBLCLICK OF det-rateio.ct-codigo in frame
{&FRAME-NAME} DO:
{include/zoomvar.i &prog-zoom=adzoom/z01ad049.w
&campo=det-rateio.ct-final
&campozoom=ct-codigo
&campo2=det-rateio.sc-final
&campozoom2=sc-codigo}
END.

c) chamada do zoom para variáveis em um frame:


ON F5 OF ord-prod.it-codigo in frame {&FRAME-NAME}
OR MOUSE-SELECT-DBLCLICK OF ord-prod.it-codigo in frame
{&FRAME-NAME} DO:
{include/zoomvar.i &prog-zoom=inzoom/z01in172.w
&campo=c-item-pai
&campozoom=it-codigo}
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.
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 browse
{&BROWSE-NAME} DO:
{include/zoomvar.i &prog-zoom=inzoom/z01in172.w
&campo=tt-digita.it-codigo
&campozoom=it-codigo
&browse=br-digita}
END.

Observação A única diferença está na utilização do parâmetro &browse, 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.i &prog-zoom=inzoom/z01in172.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, que recebe o nome da
frame onde o atributo se encontra.

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).
run pi-seta-inicial in h_b26in172 (input p-tipo-contr).

 criação nos browses do zoom de uma procedure que recebe os


parâmetros recebidos da Window de zoom, 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.
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.it-codigo >= c-item-ini
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 335

and item.it-codigo <= c-item-fim


and item.tipo-contr = p-tipo-contr.

 passagem para o include de zoom dos parâmetros através de


&parametros.
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
&parametros="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}.
Exemplo

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
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-state-
name.
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.
if available customer then do:
find state where state.state = customer.state no-lock no-
error.
assign c-state-name = if avail state then state.state-name
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.
{include/leave.i &tabela=state
&atributo-ref=state-name
&variavel-ref=c-state-name
&where="state.state = input frame {&frame-name}
customer.state"}

Onde:
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 337

<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:
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"
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 339

&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.
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 pi-


print-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/im-
total.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.
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 341

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.
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.val-
credito.
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
Exemplo

disso, implementamos a possibilidade do programador interferir na geração


desta procedure interna.
Para interferir, basta marcar o toggle-box "Manutenção Manual da PI-
RETORNA-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.
/********************************/
/* 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 pi-
retorna-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.
/********************************/
/* PI-RETORNA-VALOR **/
/*******************************/
DEFINE input parameter p-campo as character no-undo.
DEFINE variable p-valor as char initial "" no-undo.
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 343

if avail proced_consult_proced then do:


case p-campo:
when "cond_proced" then
assign p-valor =
string(proced_consult_proced.cod_proced).
when "c-descricao" then
assign p-valor = c-descricao.
end case.
end.
return p-valor.

No caso, o Custom Browser Zoom Wizard criou automaticamente a pi-retorna-


valor para o campo cod_proced que pertence a tabela principal do browse,
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.

Neste caso, na chamada do zoomvar.i, em vez do nome do campo da tabela


que se deseja retornar, coloca-se o nome da variável.

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. Na área de Definições do Programa incluir o campo parâmetro, do tipo
logical, 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.

2. No frame f-pg-imp, inserir um objeto rectangle, com as propriedades


abaixo:
Column: 2,00
Row: 8,63
Width: 46,29
Height: 1,71
3. Na frame f-pg-imp, inserir um objeto fill-in, com as propriedades a seguir:
 Object: text-parametro
 No-Label: selecionado
 Column: 1,29
 Row: 8,25
 Width: 24,72
 Height: 0,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. Na frame f-pg-imp, inserir um objeto toggle-box, com as propriedades
abaixo:
 Object: tb-parametro
 Label: Imprimir Página de Parâmetros
 No-Label: não selecionado
 Column: 3,20
 Row: 9,00
 Width: 32,00
 Height: 0,83
 Initial Value: no
5. Na procedure pi-executar, alterar a lógica de assign da Temp-table tt-
param para gravar o campo parametro
assign tt-param.usuario = c-seg-usuario
tt-param.destino = input frame f-pg-imp rs-
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 345

destino
tt-param.data-exec = today
tt-param.hora-exec = time
tt-param.classifica = input frame f-pg-imp rs-
destino
tt-param.desc-classifica = entry((tt-
param.classifica - 1) * 2 + 1, rs-classif:radio-buttons in
frame f-pg-cla)
tt-param.parametro = if input frame f-pg-imp tb-
parametro = "yes" then yes else no.

6. No programa RP.P, realizar o tratamento do valor do campo parametro,


para imprimir ou não a Página de Parâmetro.
if parametro = yes then do:
page.
display c-parametro
c-impressao
c-destino
tt-param.arquivo
tt-param.usuario
with frame f-parametros.
down with frame f-parametros.
end.

Formato de Impressão (80 colunas ou 132 colunas):


1. Na área de Definições do Programa, incluir o campo formato, do tipo
integer, na definição da Temp-Table tt-param.
define temp-table tt-param
field destino as integer
field arquivo as char
field usuario as char format "x(12)"
field data-exec as date
field hora-exec as integer
field classifica as char format "x(40)"
field desc-classifica as char format "x(40)"
field formato as integer.

2. Na frame f-pg-imp, inserir um objeto rectangle, com as propriedades


abaixo:
 Column: 2,00
 Row: 8,63
 Width: 46,29
 Height: 1,71 ou 2.79 (caso exista o objeto tb-parametro)
3. Na frame f-pg-imp, inserir um objeto fill-in, com as propriedades abaixo:
 Object: text-parametro
 No-Label: selecionado
 Column: 1,29
 Row: 8,25
 Width: 31,00
 Height: 0,92
 Initial Value: Parâmetros de Impressão
 Private Data: Parâmetros de Impressão
4. Na frame f-pg-imp, inserir um objeto radio-set, com as propriedades
abaixo:
 Object: rs-formato
 Buttons:
"80 colunas", 1,
"132 colunas", 2
 Column: 3
 Row: 9,00 ou 10,08 (caso exista o objeto tb-parametro)
 Width: 32,00
 Height: 0,83
 Horizontal: selecionado
 Initial Value: 2
 Help: Formato de Impressão
5. Na procedure pi-executar, alterar a lógica de assign da Temp-table tt-
param para gravar o campo formato
assign tt-param.usuario = c-seg-usuario
tt-param.destino = input frame f-pg-imp rs-destino
tt-param.data-exec = today
tt-param.hora-exec = time
tt-param.classifica = input frame f-pg-cla rs-classif
Exemplo

APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 347

tt-param.desc-classifica = entry((tt-param.classifica
- 1) * 2 + 1, 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.

6. No programa RP.P, além de incluir o include: include/i-rpcab.i deve ser


incluído o include: include/i-rpcb80.i que é idêntico ao anterior, mas
possui a definição de form´s de cabeçalho e rodapé de 80 colunas,
exemplo:
if tt-param.formato = 1
then do: {include/i-rpcb80.i} end.
else do: {include/i-rpcab.i} end.

7. No programa RP.P, definir form´s de 132 colunas e 80 colunas para o


relatório. Para tanto, deve ser alterado o posicionamento dos campos no
form e a propriedade width.
8. No momento de realizar o display dos campos, verificar qual o valor do
campo tt-param.formato e utilizar uma frame ou outro frame.
if tt-param.formato = 1 then do:
view frame f-cabec-80.
view frame f-rodape-80.
end.
else do:
view frame f-cabec.
view frame f-rodape.
end.

Como implementar Botão de Filtro em Zoom


Quando for necessário reabrir as querys do browse, a partir de seleções
efetuadas (Exemplo: Botão do FILTRO), deve-se no choose do botão, após a
chamada da tela de filtro, enviar uma mensagem de notify (open query) para a
Window, conforme comando abaixo:
RUN notify IN this-procedure ('open-query, container-
target':U).

O Zoom Z02IN172.W, pode ser consultado como exemplo.


Como implementar reposicionamento de registro com base nas
variáveis globais
Toda tabela deve possuir no produto uma variável global do tipo rowid, que
deve conter o rowid do último registro acessado na sua tabela.
Assim, se o usuário acessar um programa qualquer e através da navegação
estiver posicionado num registro X de uma tabela t, ao chamar outro programa
que utilize a mesma tabela para navegação, este programa inicia posicionado
no registro X.
Definição da Variável Global
A variável global deve ser definida na área de DEFINITIONS da Window e da
Viewer. Para definir esta variável, deve-se utilizar o include "i-vrtab.i"
conforme é mostrado a seguir:
{include/i-vrtab.i <nome-tabela>}

Na VIEWER, é criada a procedure LOCAL-ROW-AVAILABLE com o


código:
if avail <nome-tabela> then
assign gr-<nome-tabela> = rowid(<nome-tabela>).

Este código é implementado depois do RUN DISPATCH ...


Programa chamado:
Variável global deve ser definida em DEFINITIONS da Window.
É criado a PROCEDURE LOCAL-INITIALIZE e inserir o código a seguir
antes do RUN DISPATCH ...
RUN set-attribute-list IN h_<home-query>
(INPUT "Reposition-Pending=YES":U).

Além disso, deve ser incluso o código a seguir após o RUN DISPATCH ..., em
todas as consultas e nos cadastros em que for usado.
IF gr-<nome-tabela> <> ? THEN
RUN pi-reposiciona-query IN h_<nome-query>
(INPUT gr-<nome-tabela>).
ELSE
RUN dispatch IN h_<nome-query>
(INPUT "get-first":U).
APÍTULO 8 Construção de
rogramas utilizando os Estilos e suas Técnicas 349

Ao utilizar uma mesma viewer em dois programas e um deles é consulta do


outro, a variável global é zerada. Para que seja evitado este problema, faça o
seguinte:
 criar, na Window do programa chamado, na área de DEFINITIONS, uma
variável LOCAL como ROWID:
def var rw-<nome-tabela> as rowid no-undo.

 atualizar a procedure LOCAL-INITIALIZE, da Window do programa


chamado, com o código antes do RUN DISPATCH:
ASSIGN rw-<nome-tabela> = gr-<nome-tabela>.
RUN set-attribute-list IN h_<nome-query>
(INPUT "Reposition-Pending=YES":U).

 após o RUN DISPATCH substituir a variável global pela local, isto é:


IF rw-<nome-tabela> <> ? THEN
RUN pi-reposiciona-query IN h_<nome-query>
(INPUT rw-<nome-tabela>).
ELSE
RUN dispatch IN h_<nome-query>
(INPUT "get-first":U).
ASSIGN gr-<nome-tabela> = rw-<nome-tabela>.

Para prevenir programas posteriores, fazer em todos os programas onde são


utilizadas.
Observação Em caso de posicionamento de Browser, se o programa chamador for do tipo
Consulta-Relacionamento, ou seja, com Browse, colocar o mesmo código do LOCAL-ROW-
AVAILABLE, no Gatilho VALUE-CHANGED do Browse, sendo que o <n