Logo Passei Direto
Buscar

MANUAL-REFERENCIA-TOTVS

Manual de referência sobre customizações do Datasul EMS Framework. Aborda definição e funcionamento de APIs (parâmetros, entrada/saída, mensagens de erro), exemplos práticos (geração de gráficos, includes), pontos de chamada em Smart/EMS/ThinTemplate/DBO, EPCs e documentação.

Material
páginas com resultados encontrados.
páginas com resultados encontrados.

Escolha uma das opções e acesse esse e outros materiais sem bloqueio. 🤩

Cadastre-se ou realize login

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Escolha uma das opções e acesse esse e outros materiais sem bloqueio. 🤩

Cadastre-se ou realize login

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Escolha uma das opções e acesse esse e outros materiais sem bloqueio. 🤩

Cadastre-se ou realize login

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Escolha uma das opções e acesse esse e outros materiais sem bloqueio. 🤩

Cadastre-se ou realize login

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Escolha uma das opções e acesse esse e outros materiais sem bloqueio. 🤩

Cadastre-se ou realize login

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Escolha uma das opções e acesse esse e outros materiais sem bloqueio. 🤩

Cadastre-se ou realize login

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Escolha uma das opções e acesse esse e outros materiais sem bloqueio. 🤩

Cadastre-se ou realize login

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Escolha uma das opções e acesse esse e outros materiais sem bloqueio. 🤩

Cadastre-se ou realize login

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Escolha uma das opções e acesse esse e outros materiais sem bloqueio. 🤩

Cadastre-se ou realize login

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Escolha uma das opções e acesse esse e outros materiais sem bloqueio. 🤩

Cadastre-se ou realize login

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Prévia do material em texto

Manual de Referência 
Customizações 
Novembro/2006 
 
Copyright © 1998 DATASUL S.A. Todos os direitos reservados. 
Nenhuma parte deste documento pode ser copiada, reproduzida, traduzida ou 
transmitida por qualquer meio eletrônico ou mecânico, na sua totalidade ou em 
parte, sem a prévia autorização escrita da DATASUL S.A., que reserva-se o 
direito de efetuar alterações sem aviso prévio. A DATASUL S.A não assume 
nenhuma responsabilidade pelas conseqüências de quaisquer erros ou 
inexatidões que possam aparecer neste documento. 
DATASUL S.A. 
Av. Santos Dumont, 831, Joinville, SC, CEP 89.222-900 
 
 i 
Índice 
Índice .................................................................................................................. i 
CAPÍTULO 1 Introdução ............................................................................ 1 
CAPÍTULO 2 Application Program Interface - API ................................. 3 
External Program Call ..................................................................................... 6 
Pontos de Chamada em Smart ....................................................................... 8 
Pontos de Chamada no EMS 5 .................................................................... 17 
Pontos de Chamada em ThinTemplate ........................................................ 20 
Pontos de Chamada em DBO ...................................................................... 30 
EPCs em Gatilhos de Dicionários de Dados ................................................ 32 
EPCs em pontos Estratégicos de Programas ................................................ 34 
Como aplicar Facelift em programas específicos ........................................ 36 
Localização de Programas Específicos ........................................................ 37 
Considerações Gerais ................................................................................... 38 
 
 1 
CAPÍTULO 1
 
Introdução 
O produto Datasul EMS Framework, possui duas tecnologias criadas para 
facilitar as customizações, visando padroniza-las e principalmente facilita-las, 
sem necessitar de conhecimento da Base de Dados e seus relacionamentos. 
Desta forma garantindo também que o acesso e entrada de dados sejam feitos 
de maneira correta e precisa.. 
 
Definição 
 3 
CAPÍTULO 2
 
Application Program Interface - API 
Basicamente, é um programa que recebe 
parâmetros específicos e executa uma determinada 
tarefa no Datasul EMS Framework . Esta tarefa 
pode ser: uma atualização, um programa que 
retorne infromações, que realize um cálculo, que 
gere um gráfico. 
É uma interface aberta para as funções de negócio 
do produto. 
 
 
Efetuar a contabilização de um lote de lançamentos provindos de um sistema 
remoto; 
 
Gerar movimentos de estoque para um item ou movimentos de Material/MOB 
/GGF para uma ordem de produção; 
 
Extrair saldos em estoque de determinados itens; 
 
 
 
 
 
 
 
 
 
 
Definição 
Exemplos 
Esquema de 
Funcionamento 
API
Entrada
Datasul-EMS
Acesso
Saída
OK / NOK
Extração
de dados
4 
A partir da chamada de uma API e entrada dos devidos parâmetros ou de 
dados para uma atualização, podem ocorrer três situações: 
 
 a API pode fazer um acesso ao produto Datasul EMS Framework, e 
receber uma resposta que podem ser dados lidos da base ou o resultado de 
alguma função, este é repassada para o programa chamador. 
 a API pode fazer uma extração de dados, gerando um gráfico, um relatório 
ou uma consulta. 
 a API pode realizar uma função, por exemplo de eliminação de dados e 
retornar se a execução foi correta “OK” ou incorreta “NOK”. 
Convencional - executa a API passando parâmetros e obtendo resultados. 
com Métodos - instancia a API e dispara os seus métodos (procedures internas 
ou functions). 
 
Toda API criada pela Datasul possui um padrão que está documentado e a 
partir dele que são criadas quaisquer APIs; 
Os componentes podem ser: 
 Objetivo: O que vai ser gerado pela API, quando deve ser utilizada, para 
que função ; 
 Os parâmetros de entrada e saída também possuem sua definição, o que 
devem passar para a API e o que podem retornar; 
 Em caso de ocorrência de erro, quais as mensagens de erro podem ser 
retornadas para o programa chamador; 
 As documentações de APIs estão no diretório docapi, com o nome da api 
mais a extensão .doc; 
--- Exemplo 
 
 
 São passados como parâmetros para a API os atributos e dados 
para montagem do gráfico e devolvido uma temp-table com os 
possíveis erros. 
 A include {UTP/UTAPI001.I} contém as definições das temp-tables 
e essa deve ser inclusa no programa gerador de gráficos. 
 A exibição do gráfico é feita através da execução da API, 
UTP/UTAPI001.P; 
 Exemplo: 
 
 
API para Geração de Gráficos (v.003) 
 
Tipos 
Documentação 
CAPÍTULO 2 Application Program Interface - API 5 
Nome Físico: utp\utapi001.p 
Nome do Include com a definição dos Parâmetros: utp\utapi001.i 
Versão de Integração: 003 
Objetivo: Criação de gráficos. 
 
Parâmetros de Entrada: 
Temp-table tt-atributos: 
Na Temp-Table tt-atributos são definidas as características gerais de 
apresentação do gráfico. 
 
 
 As APIs possuem parâmetros de entrada bem definidos e processos que 
são executados de maneira correta sobre o produto; 
 As APIs são bem documentadas e executam tarefas de acordo com o 
objetivo, funcionando para seus usuário como uma caixa preta, ou seja, 
estes não precisam saber de que forma o processo é executado, apenas que, 
sendo realizadas as entradas corretas, a API executa o processo esperado 
de maneira transparente; 
 As integrações entre módulos do produto Datasul EMS Framework são 
realizadas através das APIs, portanto este é o caminho natural para que 
customizadores integrem outras soluções com o produto; 
 A tecnologia empregada e as regras de negócio de uma API podem evoluir 
fazendo com que o cliente usufrua destes benefícios sem a necessidade de 
reescrever1 seus programas. 
 
Portanto, o que as APIs fornecem é uma maior facilidade, rapidez e 
produtividade no desenvolvimento de customizações. 
 
1 Quando houver alguma alteração da interface da API esta verifica se o programa 
chamador está de acordo com a nova interface, em caso negativo, é emitida uma 
mensagem informando que o programa deve ser revisto. 
Vantagens 
6 
External Program Call 
São chamadas a programas 
desenvolvidos pelo usuário, em pontos 
pré-definidos do produto, possibilitando a 
sua adaptação e integração com outras 
aplicações. 
Constituem-se num 
aperfeiçoamento das “Saídas X” 
existentes no produto MAGNUS I.00, 
pois os pontos de chamada estão ligados a 
eventos da interface com o usuário, 
eventos da base de dados (gravação e 
eliminação de registros) ou em pontos 
estratégicos em programas de atualização 
e cálculo. 
Basicamente, uma maior integração 
é possibilitada, porque através das EPCs 
pode-se interagir com a interface do produto, com a lógica de aplicação e com 
os eventos de dicionário de dados. 
Com exceção do último tipo de chamada (pontos estratégicos) as demais 
chamadas não precisam ser solicitadas para a Datasul, pois já se encontram 
disponíveis no produto. Além de que as chamadas em eventos da base de 
dados reduzem a necessidade de chamadas em programas de atualização. 
 
 possibilitar a customização e integração do produto Datasul-EMS pelos 
usuários, respectivamente, de uma forma padronizada e controlada; 
 possibilitar localizações do Datasul-EMS que não devem ser incorporadas 
ao produto standard pela própria Datasul; 
 possibilitar ao usuário a administração de suas customizações, 
identificando através do Datasul-EMS, quais programas e tabelas do 
produto possuem customização; 
 possibilitar a administração de integrações desenvolvidas por usuários da 
Datasul sobre o produto Datasul-EMS; 
DefiniçãoObjetivos 
External Program Call 7 
 
 Customização 
 Clientes - Necessidades específicas e especialistas 
 User Program Call - UPC 
 Integração 
 Parceiros - Integrações com outros softwares 
 Application Partner Program Call – APPC 
 UPC + APPC = EPC 
 
 
Através do procedimento de Manutenção de Programas do Datasul-
EMS (men/men012aa.w), módulo Menu, o usuário pode determinar o caminho 
e o nome físico do programa a ser chamado nas UPCs de um determinado 
programa do produto. Conforme a tela a seguir: 
 
 
 
 
 
 
Exemplo : 
 Alterar as características das telas: labels, formatos, cores, 
posicionamento, tabulação. 
 Implementar novos campos, novos botões com chamada para sub-
programas. 
 
Parâmetros 
Tanto o programa UPC quanto o programa APPC recebem os seguintes 
parâmetros: 
 
Tipos de EPCs 
EPCs na Interface 
de Programas 
8 
Parâmetro I/O Tipo de Dado Conteúdo 
p-ind-event Input Character Indicador de Evento 
p-ind-object Input Character Indicador de Objeto 
p-wgh-object Input Handle Handle do objeto corrente 
p-wgh-frame Input Widget-handle Handle do frame corrente 
p-cod-table Input Character Nome da tabela corrente 
p-row-table Input Rowid Rowid do registro corrente da tabela 
 
Pode retornar ao programa que o chamou, através do recurso RETURN-
VALUE, o valor ‘NOK’ indicando que o evento que disparou o programa EPC 
não deve ser aplicado, isto viabiliza, por exemplo, validações do usuário a 
serem executadas no evento VALIDATE, que se encontrarem problemas 
podem evitar a confirmação da tela, e consequentemente a atualização de 
registros. 
Dica: Para saber os eventos que estão chamando a EPC e o valor dos 
parâmetros no momento da chamada, pode-se testar fazendo um programa 
EPC como o exemplo a seguir: 
*******************************************************************/ 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input param p-row-table as rowid no-undo. 
def var c-objeto as char no-undo. 
 
assign c-objeto = entry(num-entries(p-wgh-object:private-data, 
"~/"), p-wgh-object:private-data, "~/"). 
 
message "EVENTO" p-ind-event skip 
 "OBJETO" p-ind-object skip 
 "NOME OBJ" c-objeto skip 
 "FRAME" p-wgh-frame skip 
 "TABELA" p-cod-table skip 
 "ROWID" string(p-row-table) view-as alert-box. 
Pontos de Chamada em Smart 
Os pontos de chamada ficam ligados a eventos da interface, estes 
eventos não representam necessariamente eventos Progress, mas sim pontos, 
chamados de ‘ADM-Events’, dentro da estrutura de SmartObjects. 
 
 para SmartViewers existem chamadas EPC nos seguintes eventos: 
 
Evento SRC Local–Estrutura UIB Include Trata Retorno ? 
BEFORE-INITIALIZE Smart.i Adm-initialize include/i-epc018.i Não 
INITIALIZE Smart.i Adm-initialize include/i-epc001.i Não 
BEFORE-DISPLAY Record.i Adm-display-fields include/i-epc023.i Não 
DISPLAY Record.i Adm-display-fields include/i-epc006.i Não 
ENABLE Tableio.i Adm-enable-fields include/i-epc004.i Não 
External Program Call 9 
AFTER-ENABLE Tableio.i Adm-enable-fields include/i-epc021.i Não 
DISABLE Tableio.i Adm-disable-fields include/i-epc005.i Não 
AFTER-DISABLE Tableio.i Adm-disable-fields include/i-epc022.i Não 
BEFORE-ADD Tableio.i Adm-add-record include/i-epc028.i Não 
ADD Tableio.i Adm-add-record include/i-epc011.i Não 
UNDO Tableio.i Adm-reset-record include/i-epc012.i Não 
AFTER-UNDO Tableio.i Adm-reset-record include/i-epc029.i Não 
CANCEL Tableio.i Adm-cancel-record include/i-epc013.i Não 
AFTER-CANCEL Tableio.i Adm-cancel-record include/i-epc030.i Não 
VALIDATE Tableio.i Adm-assign-record include/i-epc002.i Sim 
AFTER-VALIDATE Tableio.i Adm-assign-statement include/i-epc019.i Sim 
BEFORE-ASSIGN Tableio.i Adm-assign-statement include/i-epc020.i Sim 
ASSIGN Tableio.i Adm-assign-statement include/i-epc003.i Sim 
END-UPDATE Tableio.i Adm-end-update include/i-epc010.i Não 
AFTER-END-UPDATE Tableio.i Adm-end-update include/i-epc027.i Não 
DELETE Tableio.i Adm-delete-record include/i-epc015.i Sim 
AFTER-DELETE Tableio.i Adm-delete-record include/i-epc032.i Sim 
 
 para SmartBrowsers devem haver chamadas EPC nos seguintes eventos: 
 
Evento SRC Local Include Trata Retorno ? 
VALUE-CHANGED Brschnge.i value-changed include/i-epc016.i Não 
AFTER-VALUE-CHANGED Brschnge.i value-changed include/i-epc033.i Não 
BEFORE-INITIALIZE Smart.i adm-initialize Include/i-epc034.i Não 
INITIALIZE Smart.i adm-initialize Include/i-epc017.i Não 
BEFORE-OPEN-QUERY Record.i adm-open-query Include/i-epc035.i Não 
AFTER-OPEN-QUERY Record.i adm-open-query Include/i-epc036.i Não 
 
 para Containers devem haver chamadas EPC nos seguintes eventos: 
 
Evento SRC Local Include Trata 
Retorno ? 
BEFORE-INITIALIZE smart.i adm-initialize Include/i-epc024.i Não 
INITIALIZE smart.i adm-initialize Include/i-epc007.i Não 
BEFORE-ENABLE smart.i adm-enable Include/i-epc025.i Não 
ENABLE smart.i adm-enable Include/i-epc008.i Não 
BEFORE-DISABLE smart.i adm-disable Include/i-epc026.i Não 
DISABLE smart.i adm-disable Include/i-epc009.i Não 
CHANGE-PAGE Containr.i adm-change-page Include/i-epc014.i Não 
AFTER-CHANGE-PAGE Containr.i adm-change-page Include/i-epc031.i Não 
DESTROY smart.i adm-destroy include/i-epc100.i Não 
 
Observação: No caso do container ser uma window de relatório o mesmo só 
apresenta chamada para epc nos eventos change-page, before-initialize, 
before-enable, enable e initialize. 
 
Criar um botão novo em uma window para chamar um subprograma a partir deste: 
 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input param p-row-table as rowid no-undo. 
 
def var wh-button as widget-handle no-undo. 
Exemplos 
10 
def var c-objeto as char no-undo. 
 
{include/i_fclpreproc.i} /* Include que define o processador 
do Facelift ativado ou não. */ 
 
assign c-objeto = entry(num-entries(p-wgh-object:private-
data, "~/"), p-wgh-object:private-data, "~/"). 
 
if p-ind-event = "INITIALIZE" 
and p-ind-object = "CONTAINER" then do: 
 create button wh-button 
 assign &IF "{&aplica_facelift}" = "YES" &THEN 
 FLAT-BUTTON = YES 
 &ENDIF 
 frame = p-wgh-frame 
 width = 4 
 height = 1.25 
 row = 1.26 
 label = "teste" 
 col = 65 
 sensitive = yes 
 visible = yes 
 triggers: 
 ON CHOOSE PERSISTENT RUN upc/testeupc1.p. 
 end triggers. 
end. 
 
&IF "{&aplica_facelift}" = "YES" &THEN 
 wh-button:LOAD-IMAGE-UP("image/toolbar/ccmail.bmp"). 
 wh-button:LOAD-IMAGE("image/toolbar/ccmail.bmp"). 
&ELSE 
 wh-button:LOAD-IMAGE-UP("image/ccmail.bmp"). 
 wh-button:LOAD-IMAGE("image/ccmail.bmp"). 
&ENDIF 
 
Obs. O evento utilizado para o botão criado, deve necessariamente 
chamar um subprograma com persistent run e em caso de parâmetros, 
utilizam-se variáveis globais. 
 
Criar um widget novo em uma viewer: 
 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input paramp-row-table as rowid no-undo. 
 
def new 
 global shared var wh-button as widget-handle no-undo. 
def new global shared var wh-fill as widget-handle no-
undo. 
def new global shared var tx-label as widget-handle no-
undo. 
def var c-objeto as char no-undo. 
 
External Program Call 11 
{include/i_fclpreproc.i} /* Include que define o processador 
do Facelift ativado ou não. */ 
 
&IF "{&aplica_facelift}" = "YES" &THEN
 {include/i_fcldef.i} 
&endif 
 
assign c-objeto = entry(num-entries(p-wgh-object:private-
data, "~/"), p-wgh-object:private-data, "~/"). 
 
if p-ind-event = "INITIALIZE" 
and p-ind-object = "VIEWER" 
and c-objeto = "'v24ad098.w'" then do: 
 
 create button wh-button 
 assign 
 &IF "{&aplica_facelift}" = "YES" &THEN 
 FLAT-BUTTON = YES 
 &ENDIF 
 frame = p-wgh-frame 
 width = 18 
 height = 1 
 label = "Assistência Técnica" 
 row = 3.7 
 col = 67 
 visible = yes 
 sensitive = no 
 triggers: 
 ON CHOOSE PERSISTENT RUN upc/demoupc1.p. 
 end triggers. 
 
 create text tx-label 
 assign frame = p-wgh-frame 
 format = "x(17)" 
 width = 6.2 
 screen-value = "Perfil Marketing:" 
 row = 2.8 
 col = 59.5 
 fgcolor = 0 
 visible = yes. 
 
 create fill-in wh-fill 
 assign frame = p-wgh-frame 
 side-label-handle = tx-label:handle 
 format = "x(20)" 
 width = 12 
 height = 0.88 
 row = 2.7 
 col = 71 
 bgcolor = 1 
 fgcolor = 0 
 label = "Perfil Marketing:" 
 visible = yes 
 sensitive = no. 
 &IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldin.i wh-fill} 
 &endif 
 
end. 
12 
 
&IF "{&aplica_facelift}" = "YES" &THEN 
 wh-button:LOAD-IMAGE-UP("image/toolbar/ccmail.bmp"). 
 wh-button:LOAD-IMAGE("image/toolbar/ccmail.bmp"). 
&ELSE 
 wh-button:LOAD-IMAGE-UP("image/ccmail.bmp"). 
 wh-button:LOAD-IMAGE("image/ccmail.bmp"). 
&ENDIF 
 
 
if p-ind-event = "ADD" 
and p-ind-object = "VIEWER" 
and c-objeto = "'v24ad098.w'" then do: 
 
 create text tx-label 
 assign frame = p-wgh-frame 
 format = "x(17)" 
 width = 6.2 
 screen-value = "Perfil Marketing:" 
 row = 2.8 
 col = 59.5 
 fgcolor = 0 
 visible = yes. 
 
 create fill-in wh-fill 
 assign frame = p-wgh-frame 
 side-label-handle = tx-label:handle 
 format = "x(20)" 
 width = 12 
 height = 0.88 
 row = 2.7 
 col = 51 
 bgcolor = 1 
 fgcolor = 0 
 label = "Perfil Marketing:" 
 visible = yes 
 sensitive = YES. 
 &IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldin.i wh-fill} 
 &endif 
 
end. 
 
 
if p-ind-event = "ENABLE" 
and p-ind-object = "VIEWER" 
and c-objeto = "v24ad098.w" then do: 
 assign wh-button:sensitive = yes 
 wh-fill:sensitive = yes. 
end. 
 
if p-ind-event = "DISABLE" 
and p-ind-object = "VIEWER" 
and c-objeto = "v24ad098.w" then do: 
 assign wh-button:sensitive = no 
 wh-fill:sensitive = no. 
end. 
 
External Program Call 13 
Encontrar o handle de um widget: 
 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input param p-row-table as rowid no-undo. 
 
def new global shared var wh-button as widget-handle no-
undo. 
def new global shared var wh-fill as widget-handle no-
undo. 
def new global shared var tx-label as widget-handle no-
undo. 
def new global shared var h_campo as widget-handle no-
undo. 
def var c-objeto as char no-undo. 
def var h_frame as widget-handle no-undo. 
 
assign c-objeto = entry(num-entries(p-wgh-object:private-
data, "~/"), p-wgh-object:private-data, "~/"). 
 
if p-ind-event = "DISPLAY" 
and p-ind-object = "VIEWER" 
and c-objeto = "v24ad098.w" then do: 
 
DO : 
 ASSIGN h_Frame = p-wgh-frame:FIRST-CHILD. /* pegando o 
Field-Group */ 
 ASSIGN h_Frame = h_Frame:FIRST-CHILD. /* pegando o 
1o. Campo */ 
 message h_frame:name view-as alert-box. 
 DO WHILE h_Frame <> ? : 
 if h_frame:type <> "field-group" then do: 
 IF h_Frame:NAME = "nome-mic-reg" THEN 
 DO : 
 assign h_campo = h_Frame. 
 leave. 
 END. 
 ASSIGN h_Frame = h_Frame:NEXT-SIBLING. 
 end. 
 else do: 
 assign h_frame = h_frame:first-child. 
 end. 
 END. 
 END. 
end. 
Dica: Para descobrir o nome de um campo em uma tela, pode-se 
utilizar o comando <Ctrl-Alt-4> sobre o campo desejado. Este 
comando retorna o nome do campo e da tabela a que ele pertence. 
Acessar o valor de um widget: 
Após encontrar o handle do campo desejado, utilizando a lógica do 
item III, fazer o seguinte: 
 
assign c-valor = h-campo:screen-value. 
14 
 
Obs. Lembre-se, em caso da variável ou campo de tabela que vai 
receber o valor do widget não ser do tipo character, o valor do screen-
value deve ser transformado para este tipo, pois o screen-value do 
campo sempre é character. 
 
Alterar o valor de um widget; 
 
Após encontrar o handle do campo desejado, utilizando a lógica do 
item III, fazer o seguinte: 
 
assign h-campo:screen-value = “Novo Valor”. 
 
Lembre-se que mesmo para campos não character, deve-se utilizar “ 
”(aspas), pois o valor do screen-value é sempre character. 
 
Ocultar um widget em uma viewer: 
 
Após encontrar o handle do campo desejado, utilizando a lógica do 
item III, fazer o seguinte: 
 
assign h-campo:visible = no. 
 
Criar uma viewer dinamicamente: 
 
/* Parameter Definitions 
****************************************************/ 
define input parameter p-ind-event as character. 
define input parameter p-ind-object as character. 
define input parameter p-wgh-object as handle. 
define input parameter p-wgh-frame as widget-handle. 
define input parameter p-cod-table as character. 
define input parameter p-row-table as rowid. 
 
/* Global Variable Definitions 
**********************************************/ 
define new global shared var adm-broker-hdl as handle no-
undo. 
define new global shared var h-folder as handle no-
undo. 
define new global shared var h-viewer as handle no-
undo. 
 
/* Variable Definitions 
*****************************************************/ 
define var c-folder as character no-undo. 
define var c-objects as character no-undo. 
define var h-object as handle no-undo. 
define var i-objects as integer no-undo. 
define var l-record as logical no-undo initial no. 
define var l-group-assign as logical no-undo initial no. 
 
External Program Call 15 
{include/i_fclpreproc.i} /* Include que define o processador 
do Facelift ativado ou não. */&IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldef.i} 
&endif 
 
/* Main Block 
*************************************************************
**/ 
if p-ind-event = "INITIALIZE" and p-ind-object = "CONTAINER" 
then do: 
 RUN get-link-handle IN adm-broker-hdl (INPUT p-wgh-
object, 
 INPUT "PAGE-
SOURCE":U, 
 OUTPUT c-folder). 
 assign h-folder = widget-handle(c-folder) no-error. 
 
 if valid-handle(h-folder) then do: 
 RUN create-folder-page IN h-folder (INPUT 5, INPUT 
"Pag. 05":U). 
 &IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldin.i h-folder} 
 &endif 
 RUN create-folder-label IN h-folder (INPUT 5, INPUT 
"Pag. 05":U). 
 
 RUN select-page IN p-wgh-object (INPUT 5). 
 
 RUN init-object IN p-wgh-object (INPUT "nome externo 
da nova viewer ":U, /* Nome do Objeto Viewer */ 
 INPUT p-wgh-frame, 
 INPUT "Layout = ":U, 
 OUTPUT h-viewer). 
 
 RUN set-position IN h-viewer ( 7.10, 5.00). 
 
 RUN get-link-handle IN adm-broker-hdl (INPUT p-wgh-
object, INPUT "CONTAINER-TARGET":U, OUTPUT c-objects). 
 
 do i-objects = 1 to num-entries(c-objects): 
 assign h-object = widget-handle(entry(i-objects, c-
objects)). 
 
if index(h-object:private-data, "qry") <> 0 and /* Você deve 
verificar se e a query principal */ 
 not l-record then do: 
 assign l-record = yes. 
 
 RUN add-link IN adm-broker-hdl (INPUT h-object, 
 INPUT Record":U, 
 INPUT h-viewer). 
 end. 
 
 if index(h-object:private-data, "vwr") <> 0 and /* 
Voce deve verificar se e a viewer principal */ 
 not l-group-assign then do: 
 assign l-group-assign = yes. 
16 
 
 RUN add-link IN adm-broker-hdl (INPUT h-object, 
 INPUT "Group-
Assign":U, 
 INPUT h-viewer). 
 end. 
 end. 
 
 RUN dispatch IN h-viewer ("initialize":U). 
 
 RUN select-page IN p-wgh-object (INPUT 1). 
 end. 
end. 
 
Chamar o zoom para um campo criado dinamicamente: 
 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input param p-row-table as rowid no-undo. 
 
def new global shared var wh-fill as widget-handle no-
undo. 
def new global shared var tx-label as widget-handle no-
undo. 
def var c-objeto as char no-undo. 
 
{include/i_fclpreproc.i} /* Include que define o processador 
do Facelift ativado ou não. */ 
 
&IF "{&aplica_facelift}" = "YES" &THEN
 {include/i_fcldef.i} 
&endif 
 
 
assign c-objeto = entry(num-entries(p-wgh-object:private-
data, "~/"), p-wgh-object:private-data, "~/"). 
 
if p-ind-event = "BEFORE-INITIALIZE" 
and p-ind-object = "VIEWER" 
and c-objeto = "v24ad098.w" then do: 
 create text tx-label 
 assign frame = p-wgh-frame 
 format = "x(17)" 
 width = 6.2 
 screen-value = "Perfil:" 
 row = 2.8 
 col = 59.5 
 fgcolor = 1 
 visible = yes. 
 
 create fill-in wh-fill 
 assign frame = p-wgh-frame 
 format = "x(10)" 
 side-label-handle = tx-label:handle 
 width = 10 
External Program Call 17 
 height = 0.88 
 row = 2.8 
 col = 65 
 bgcolor = 1 
 fgcolor = 15 
 visible = yes 
 sensitive = no 
 triggers: 
 ON F5 PERSISTENT RUN upc-curso/zoomupc.p. 
 end triggers. 
 &IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldin.i wh-fill} 
 &endif 
end. 
 
if p-ind-event = "ENABLE" 
and p-ind-object = "VIEWER" 
and c-objeto = "v24ad098.w" then do: 
 assign wh-fill:sensitive = yes. 
end. 
 
if p-ind-event = "DISABLE" 
and p-ind-object = "VIEWER" 
and c-objeto = "v24ad098.w" then do: 
 assign wh-fill:sensitive = no. 
end. 
 
Para o programa de zoom, que vai chamar um zoom construido no 
padrão do EMS 2.0, deve-se fazer o seguinte: 
 
def var wh-pesquisa as widget-handle. 
def new global shared var l-implanta as logical init no. 
def new global shared var wh-fill as widget-handle no-
undo. 
def new global shared var wh-window as handle no-undo. 
def new global shared var adm-broker-hdl as handle no-undo. 
 
{include/zoomvar.i &prog-zoom=inzoom/z01in172.w 
 &proghandle=wh-window 
 &campohandle=wh-fill 
 &campozoom=it-codigo} 
Pontos de Chamada no EMS 5 
Os pontos de chamada ficam ligados a eventos da interface, estes 
eventos não representam necessariamente eventos Progress, mas sim pontos 
estratégicos, dentro da estrutura dos programas do EMS 5 gerados pelo DWB, 
conforme o estilo. 
 
 No caso do EMS 5, os pontos de chamada estão nos seguintes eventos: 
 
Evento Local Trata Retorno ? 
INITIALIZE Depois do view da frame Não 
DISPLAY Depois do display da frame Não 
18 
ENABLE Depois do enable da frame Não 
VALIDATE Depois da chamada da pi de validação Sim 
ASSIGN Depois da pi de assign dos campos Sim 
BEFORE_DELETE Antes de eliminar o registro Sim 
AFTER_DELETE Depois de eliminar o registro Sim 
 
Criar um widget novo em uma frame: 
 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input param p-row-table as recid no-undo. 
 
DEF NEW GLOBAL SHARED VAR wh-button AS WIDGET-HANDLE NO-UNDO. 
DEF NEW GLOBAL SHARED VAR wh-fill AS WIDGET-HANDLE NO-UNDO. 
DEF NEW GLOBAL SHARED VAR tx-label AS WIDGET-HANDLE NO-UNDO. 
 
{include/i_fclpreproc.i} /* Include que define o processador do 
Facelift ativado ou não. */ 
 
&IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldef.i} 
&endif 
 
IF p-ind-event = "DISPLAY" THEN DO: 
 
 CREATE BUTTON wh-button 
ASSIGN &IF "{&aplica_facelift}" = "YES" &THEN 
 FLAT-BUTTON = YES 
 &ENDIF 
 FRAME = p-wgh-frame 
 WIDTH = 15 
 HEIGHT = 1 
 LABEL = "TESTE" 
 ROW = 4 
 COL = 10 
 FONT = 1 
 VISIBLE = YES 
 SENSITIVE = NO 
 TRIGGERS: 
 ON CHOOSE PERSISTENT RUN epc/trigbotao.p. 
 END TRIGGERS. 
 
 CREATE TEXT tx-label 
 ASSIGN FRAME = p-wgh-frame 
 FORMAT = "x(40)" 
 WIDTH = 15 
 SCREEN-VALUE = "Comentário:" 
 ROW = 2 
 COL = 10 
 VISIBLE = YES 
 FONT = 1. 
 
 CREATE FILL-IN wh-fill 
 ASSIGN FRAME = p-wgh-frame 
 SIDE-LABEL-HANDLE = tx-label:HANDLEExemplos 
External Program Call 19 
 FORMAT = "x(20)" 
 WIDTH = 40 
 HEIGHT = 0.88 
 ROW = 1.7 
 COL = 18.5 
 LABEL = "Comentário:" 
 VISIBLE = YES 
 SENSITIVE = NO 
 FONT = 1. 
 &IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldin.i wh-fill} 
 &endif 
 
END. 
 
&IF "{&aplica_facelift}" = "YES" &THEN 
 wh-button:LOAD-IMAGE-UP("image/toolbar/ccmail.bmp"). 
 wh-button:LOAD-IMAGE("image/toolbar/ccmail.bmp"). 
&ELSE 
 wh-button:LOAD-IMAGE-UP("image/ccmail.bmp"). 
 wh-button:LOAD-IMAGE("image/ccmail.bmp"). 
 &ENDIF 
 
Obs:No evento (trigger) do botão criado deve-se chamar um subprograma com 
persistent run e nesse não utilizar parâmetros, apenas variáveis globais. 
 
Encontrar o handle de um widget: 
 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input param p-row-table as recid no-undo. 
 
DEF NEW GLOBAL SHARED VAR h-campo AS WIDGET-HANDLE NO-UNDO. 
 
DEF VAR h-objeto AS WIDGET-HANDLE NO-UNDO. 
 
If p-ind-event = “DISPLAY” THEN DO: 
 
 DO: 
 assign h-objeto = p-wgh-frame:FIRST-CHILD. 
 do while valid-handle(h-objeto): 
 IF h-objeto:TYPE <> "field-group" THEN DO: 
 IF h-objeto:NAME = "cod_pais" THEN DO: 
 ASSIGN h-campo = h-objeto. 
 Leave. 
 END. 
 assign h-objeto = h-objeto:NEXT-SIBLING. 
 END. 
 ELSE DO: 
 Assign h-objeto = h-objeto:first-child. 
 END. 
 end. 
 END. 
 MESSAGE STRING(h-campo:NAME) VIEW-AS ALERT-BOX. 
20 
END. 
Pontos de Chamada em ThinTemplate 
 
Os pontos de chamada ficam ligados a eventos da interface, estes 
eventos não representam necessariamente eventos Progress, mas sim pontos 
estratégicos, dentro da estrutura do ThinTemplate. A chamada da EPC é feita 
por intermédio da include method/svc/custom/custom.i, e nenhuma das 
chamadas de EPC em interface trata retorno de erro. 
 
 para ThinMaintenance existem chamadas EPC nos seguintes eventos: 
 
Evento Método Padrão 
BEFORE-ADD ADDRECORD 
AFTER-ADD ADDRECORD 
BEFORE-CANCEL CANCELRECORD 
AFTER-CANCEL CANCELRECORD 
BEFORE-COPY COPYRECORD 
AFTER-COPY COPYRECORD 
BEFORE-DELETE DELETERECORD 
AFTER-DELETE DELETERECORD 
BEFORE-ASSIGN SAVERECORD 
AFTER-ASSIGN SAVERECORD 
BEFORE-UNDO UNDORECORD 
AFTER-UNDO UNDORECORD 
BEFORE-CONTROL-TOOL-BAR CONTROLTOOLBAR 
AFTER-CONTROL-TOOL-BAR CONTROLTOOLBAR 
BEFORE-DESTROY-INTERFACE DESTROYINTERFACE 
AFTER-DESTROY-INTERFACE DESTROYINTERFACE 
BEFORE-DISABLE DISABLEFIELDS 
AFTER-DISABLE DISABLEFIELDS 
BEFORE-DISPLAY DISPLAYFIELDS 
AFTER-DISPLAY DISPLAYFIELDS 
BEFORE-ENABLE ENABLEFIELDS 
AFTER-ENABLE ENABLEFIELDS 
BEFORE-INITIALIZE INITIALIZEINTERFACE 
AFTER-INITIALIZE INITIALIZEINTERFACE 
BEFORE-SAVE-FIELDS SAVEFIELDS 
AFTER-SAVE-FIELDS SAVEFIELDS 
BEFORE-CHANGE-PAGE CHANGEPAGE 
AFTER-CHANGE-PAGE CHANGEPAGE 
 
 para ThinMaintenanceNoNavigation existem chamadas EPC nos seguintes 
eventos: 
 
Evento Método Padrão 
BEFORE-ADD ADDRECORD 
AFTER-ADD ADDRECORD 
BEFORE-COPY COPYRECORD 
AFTER-COPY COPYRECORD 
BEFORE-ASSIGN SAVERECORD 
AFTER-ASSIGN SAVERECORD 
BEFORE-DESTROY-INTERFACE DESTROYINTERFACE 
AFTER-DESTROY-INTERFACE DESTROYINTERFACE 
External Program Call 21 
BEFORE-DISABLE DISABLEFIELDS 
AFTER-DISABLE DISABLEFIELDS 
BEFORE-DISPLAY DISPLAYFIELDS 
AFTER-DISPLAY DISPLAYFIELDS 
 BEFORE-ENABLE ENABLEFIELDS 
AFTER-ENABLE ENABLEFIELDS 
BEFORE-INITIALIZE INITIALIZEINTERFACE 
AFTER-INITIALIZE INITIALIZEINTERFACE 
BEFORE-SAVE-FIELDS SAVEFIELDS 
AFTER-SAVE-FIELDS SAVEFIELDS 
BEFORE-CHANGE-PAGE CHANGEPAGE 
AFTER-CHANGE-PAGE CHANGEPAGE 
 
 para ThinMasterDetail existem chamadas EPC nos seguintes eventos: 
 
Evento Método Padrão 
BEFORE-DELETE DELETERECORD 
AFTER-DELETE DELETERECORD 
BEFORE-CONTROL-TOOL-BAR CONTROLTOOLBAR 
AFTER-CONTROL-TOOL-BAR CONTROLTOOLBAR 
BEFORE-DESTROY-INTERFACE DESTROYINTERFACE 
AFTER-DESTROY-INTERFACE DESTROYINTERFACE 
BEFORE-DISPLAY DISPLAYFIELDS 
AFTER-DISPLAY DISPLAYFIELDS 
BEFORE-INITIALIZE INITIALIZEINTERFACE 
AFTER-INITIALIZE INITIALIZEINTERFACE 
BEFORE-VALUE-CHANGED APPLYVALUECHANGED 
AFTER-VALUE-CHANGED APPLYVALUECHANGED 
BEFORE-CHANGE-PAGE CHANGEPAGE 
AFTER-CHANGE-PAGE CHANGEPAGE 
BEFORE-OPEN-QUERY OPENQUERY 
AFTER-OPEN-QUERY OPENQUERY 
 
 para ThinFormation existem chamadas EPC nos seguintes eventos: 
 
Evento Método Padrão 
BEFORE-CONTROL-TOOL-BAR CONTROLTOOLBAR 
AFTER-CONTROL-TOOL-BAR CONTROLTOOLBAR 
BEFORE-DESTROY-INTERFACE DESTROYINTERFACE 
AFTER-DESTROY-INTERFACE DESTROYINTERFACE 
BEFORE-DISPLAY DISPLAYFIELDS 
AFTER-DISPLAY DISPLAYFIELDS 
BEFORE-INITIALIZE INITIALIZEINTERFACE 
AFTER-INITIALIZE INITIALIZEINTERFACE 
BEFORE-CHANGE-PAGE CHANGEPAGE 
AFTER-CHANGE-PAGE CHANGEPAGE 
 
 para ThinFormationNoNavigation existem chamadas EPC nos seguintes 
eventos: 
 
Evento Método Padrão 
BEFORE-DESTROY-INTERFACE DESTROYINTERFACE 
AFTER-DESTROY-INTERFACE DESTROYINTERFACE 
BEFORE-DISPLAY DISPLAYFIELDS 
AFTER-DISPLAY DISPLAYFIELDS 
BEFORE-INITIALIZE INITIALIZEINTERFACE 
AFTER-INITIALIZE INITIALIZEINTERFACE 
 
22 
 para ThinReport existem chamadas EPC nos seguintes eventos: 
 
Evento Método Padrão 
BEFORE-DESTROY-INTERFACE DESTROYINTERFACE 
AFTER-DESTROY-INTERFACE DESTROYINTERFACE 
BEFORE-DISABLE DISABLEFIELDS 
AFTER-DISABLE DISABLEFIELDS 
BEFORE-ENABLE ENABLEFIELDS 
AFTER-ENABLE ENABLEFIELDS 
BEFORE-INITIALIZE INITIALIZEINTERFACE 
AFTER-INITIALIZE INITIALIZEINTERFACE 
 
 para ThinWindow existem chamadas EPC nos seguintes eventos: 
 
Evento Método Padrão 
BEFORE-DESTROY-INTERFACE DESTROYINTERFACE 
AFTER-DESTROY-INTERFACE DESTROYINTERFACE 
BEFORE-DISPLAY DISPLAYFIELDS 
AFTER-DISPLAY DISPLAYFIELDS 
BEFORE-ENABLE ENABLEFIELDS 
AFTER-ENABLE ENABLEFIELDS 
BEFORE-INITIALIZE INITIALIZEINTERFACE 
AFTER-INITIALIZE INITIALIZEINTERFACE 
BEFORE-CHANGE-PAGE CHANGEPAGE 
AFTER-CHANGE-PAGE CHANGEPAGE 
 
 para ThinZoom existem chamadas EPC nos seguintes eventos: 
 
Evento Método Padrão 
BEFORE-VALUE-CHANGED APPLYVALUECHANGED 
AFTER-VALUE-CHANGED APPLYVALUECHANGED 
BEFORE-DESTROY-INTERFACE DESTROYINTERFACE 
AFTER-DESTROY-INTERFACE DESTROYINTERFACE 
BEFORE-INITIALIZE INITIALIZEINTERFACE 
AFTER-INITIALIZE INITIALIZEINTERFACE 
BEFORE-CHANGE-PAGE CHANGEPAGE 
AFTER-CHANGE-PAGE CHANGEPAGE 
 
Criar um widget novo em uma frame: 
 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input param p-row-table as rowid no-undo. 
 
DEF NEW GLOBAL SHARED VAR wh-button AS WIDGET-HANDLE NO-UNDO. 
DEF NEW GLOBAL SHARED VAR wh-fill AS WIDGET-HANDLE NO-UNDO. 
DEF NEW GLOBAL SHARED VAR tx-label AS WIDGET-HANDLE NO-UNDO. 
 
{include/i_fclpreproc.i} /* Include que define o processador do 
Facelift ativado ou não. */ 
 
&IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldef.i} 
&endif 
Exemplos 
External Program Call 23 
 
IF p-ind-event = "AFTER-INITIALIZE" THEN DO: 
 
 CREATE BUTTON wh-button 
 ASSIGN &IF "{&aplica_facelift}" = "YES" &THEN 
 FLAT-BUTTON = YES 
 &ENDIF 
 FRAME = p-wgh-frame 
 WIDTH = 15 
 HEIGHT = 1 
 LABEL = "TESTE" 
 ROW= 4 
 COL = 10 
 FONT = 1 
 VISIBLE = YES 
 SENSITIVE = NO 
 TRIGGERS: 
 ON CHOOSE PERSISTENT RUN epc/trigbotao.p. 
 END TRIGGERS. 
 
 CREATE TEXT tx-label 
 ASSIGN FRAME = p-wgh-frame 
 FORMAT = "x(40)" 
 WIDTH = 15 
 SCREEN-VALUE = "Comentário:" 
 ROW = 2 
 COL = 10 
 VISIBLE = YES 
 FONT = 1. 
 
 CREATE FILL-IN wh-fill 
 ASSIGN FRAME = p-wgh-frame 
 SIDE-LABEL-HANDLE = tx-label:HANDLE 
 FORMAT = "x(20)" 
 WIDTH = 40 
 HEIGHT = 0.88 
 ROW = 1.7 
 COL = 18.5 
 LABEL = "Comentário:" 
 VISIBLE = YES 
 SENSITIVE = NO 
 FONT = 1. 
 &IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldin.i wh-fill} 
 &endif 
 
END. 
 
&IF "{&aplica_facelift}" = "YES" &THEN 
 wh-button:LOAD-IMAGE-UP("image/toolbar/ccmail.bmp"). 
 wh-button:LOAD-IMAGE("image/toolbar/ccmail.bmp"). 
&ELSE 
 wh-button:LOAD-IMAGE-UP("image/ccmail.bmp"). 
 wh-button:LOAD-IMAGE("image/ccmail.bmp"). 
&ENDIF 
 
Obs:No evento (trigger) do botão criado deve-se chamar um subprograma com 
persistent run e nesse não utilizar parâmetros, apenas variáveis globais. 
24 
 
Encontrar o handle de um widget: 
 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input param p-row-table as rowid no-undo. 
 
DEFINE VARIABLE h-objeto AS WIDGET-HANDLE NO-UNDO. 
DEFINE VARIABLE h-objeto2 AS WIDGET-HANDLE NO-UNDO. 
 
If p-ind-event = "AFTER-INITIALIZE" THEN DO: 
 ASSIGN h-objeto = p-wgh-frame:FIRST-CHILD. 
 do while valid-handle(h-objeto): 
 IF h-objeto:TYPE <> "field-group" and 
 h-objeto:TYPE <> "frame" THEN DO: 
 h-objeto = h-objeto:NEXT-SIBLING. 
 END. 
 ELSE DO: 
 IF h-objeto:TYPE = "frame" THEN DO: 
 ASSIGN h-objeto2 = h-objeto:FIRST-CHILD. 
 do while valid-handle(h-objeto2): 
 IF h-objeto2:TYPE <> "field-group" and 
 h-objeto2:TYPE <> "frame" THEN DO: 
 MESSAGE h-objeto2:NAME SKIP 
 h-objeto2:TYPE 
 VIEW-AS ALERT-BOX INFO BUTTONS OK. 
 h-objeto2 = h-objeto2:NEXT-SIBLING. 
 END. 
 ELSE DO: 
 h-objeto2 = h-objeto2:FIRST-CHILD. 
 END. 
 END. 
 h-objeto = h-objeto:NEXT-SIBLING. 
 END. 
 ELSE 
 h-objeto = h-objeto:FIRST-CHILD. 
 END. 
 END. 
END. 
 
Habilitar o folder: 
Somente é possível habilitar o folder se o programa utilizar as páginas fPage0 
e fPage1. 
 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input param p-row-table as rowid no-undo. 
 
DEF NEW GLOBAL SHARED VAR h-fpage1 AS HANDLE NO-UNDO. 
DEF NEW GLOBAL SHARED VAR h-folder AS HANDLE NO-UNDO. 
 
External Program Call 25 
DEF VAR h-frame AS HANDLE NO-UNDO. 
 
IF p-ind-event = "AFTER-INITIALIZE" THEN DO: 
 
 DO: 
 assign h-frame = p-wgh-frame:FIRST-CHILD. 
 assign h-frame = h-frame:FIRST-CHILD. 
 do while valid-handle(h-frame): 
 IF h-frame:TYPE <> "field-group" THEN DO: 
 IF h-frame:NAME = "fPage1" THEN DO: 
 ASSIGN h-fpage1 = h-frame. 
 END. 
 assign h-frame = h-frame:NEXT-SIBLING. 
 END. 
 ELSE DO: 
 LEAVE. 
 END. 
 end. 
 END. 
 
 RUN utp/thinFolder.w PERSISTENT SET h-folder. 
 
 RUN setProgramParent IN h-folder (INPUT p-wgh-object). 
 
 RUN setOCX IN h-folder (INPUT p-wgh-object:GET-
SIGNATURE("control_load":U) <> "":U) NO-ERROR. 
 
RUN initializeFolders IN h-folder (INPUT p-wgh-frame, 
 INPUT STRING(h-fpage1), 
 INPUT "Cadastro", 
 INPUT 1, 
 INPUT ?, 
 INPUT ?, 
 INPUT ?, 
 INPUT ?). 
 RUN setFolder IN h-folder (INPUT 1). 
END. 
 
Inserir uma frame: 
Somente é possível inserir uma frame quando o folder estiver habilitado. 
 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input param p-row-table as rowid no-undo. 
 
DEF NEW GLOBAL SHARED VAR h-fpage2 AS WIDGET-HANDLE NO-UNDO. 
 
DEF VAR h-objeto AS HANDLE NO-UNDO. 
 
{include/i_fclpreproc.i} /* Include que define o processador do 
Facelift ativado ou não. */ 
 
&IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldef.i} 
&endif 
26 
 
IF p-ind-event = "AFTER-INITIALIZE" THEN DO: 
 
 CREATE FRAME h-fPage2 
 ASSIGN COL = 3.57 
 ROW = 6.38 
 WIDTH = 84.43 
 HEIGHT = 5.88 
 NAME = "fpage2" 
 SIDE-LABELS = YES 
 SENSITIVE = YES 
 OVERLAY = YES 
 BGCOLOR = ? 
 BOX = NO 
 THREE-D = YES. 
 &IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldin.i h-fPage2} 
 &endif 
 
 assign h-objeto = p-wgh-object. 
 do while valid-handle(h-objeto): 
 if h-objeto:FILE-NAME = "utp/thinFolder.w" then 
 LEAVE. 
 assign h-objeto = h-objeto:NEXT-SIBLING. 
 end. 
 
 RUN setFolder IN h-objeto (INPUT 1) . 
 
 RUN insertFolder IN h-objeto (INPUT ?, 
 INPUT p-wgh-frame, 
 INPUT h-fPage2, 
 INPUT "Ref Call"). 
 
End. 
 
Chamar o zoom para um campo criado dinamicamente: 
 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input param p-row-table as rowid no-undo. 
 
Def new global shared var tx-label as widget-handle no-undo. 
Def new global shared var wh-fill as widget-handle no-undo. 
DEF NEW GLOBAL SHARED VAR h-fpage1 AS HANDLE NO-UNDO. 
DEF VAR h-frame AS HANDLE NO-UNDO. 
 
{include/i_fclpreproc.i} /* Include que define o processador do 
Facelift ativado ou não. */ 
 
&IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldef.i} 
&endif 
 
 
/*encontrar o handle da frame onde deseja criaro campo*/ 
External Program Call 27 
IF p-ind-event = "AFTER-INITIALIZE" THEN DO: 
 
 DO: 
 assign h-frame = p-wgh-frame:FIRST-CHILD. 
 assign h-frame = h-frame:FIRST-CHILD. 
 do while valid-handle(h-frame): 
 IF h-frame:TYPE <> "field-group" THEN DO: 
 IF h-frame:NAME = "fPage1" THEN DO: 
 ASSIGN h-fpage1 = h-frame. 
 END. 
 assign h-frame = h-frame:NEXT-SIBLING. 
 END. 
 ELSE DO: 
 LEAVE. 
 END. 
 end. 
 END. 
END. 
 
IF p-ind-event = "AFTER-INITIALIZE" THEN DO: 
 CREATE TEXT tx-label 
 ASSIGN FRAME = h-fPage1 /*handle da frame*/ 
 FORMAT = "x(40)" 
 WIDTH = 15 
 SCREEN-VALUE = "Comentário:" 
 ROW = 2 
 COL = 10 
 VISIBLE = YES 
 FONT = 1. 
 
 CREATE FILL-IN wh-fill 
 ASSIGN FRAME = h-fPage1 
 SIDE-LABEL-HANDLE = tx-label:HANDLE 
 FORMAT = "x(20)" 
 NAME = "comentario" 
 WIDTH = 40 
 HEIGHT = 0.88 
 ROW = 1.7 
 COL = 18.5 
 LABEL = "Comentário:" 
 VISIBLE = YES 
 SENSITIVE = NO 
 FONT = 1 
 TRIGGERS: 
 ON "F5":U PERSISTENT RUN epc/epczoom.p. 
 ON "MOUSE-SELECT-DBLCLICK":U PERSISTENT RUN 
epc/epczoom.p. 
 &IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldin.i wh-fill} 
 &endif 
 END TRIGGERS. 
 
 WH-FILL:LOAD-MOUSE-POINTER("image/lupa.cur":U). 
END. 
 
IF p-ind-event = "BEFORE-ENABLE" THEN DO: 
 ASSIGN wh-fill:SENSITIVE = YES. 
 
END. 
28 
 
IF p-ind-event = "BEFORE-DISABLE" THEN DO: 
 ASSIGN wh-fill:SENSITIVE = NO. 
END. 
 
 
Para o programa de zoom, que vai chamar um zoom construído no padrão 
ThinTemplate, deve-se fazer o seguinte: 
 
DEF NEW GLOBAL SHARED VAR wh-fill AS WIDGET-HANDLE NO-UNDO. 
 
DEF VAR hProgramZoom AS HANDLE NO-UNDO. 
 
{method/zoomFields.i &ProgramZoom="spp/sp0008a.w" 
 &FieldZoom1="rep-name" 
 &frame1="fPage1" 
 &fieldHandle1=wh-fill} 
 
Buscar registro corrente/atualizar registro de uma DBO: 
 
def input param p-ind-event as char no-undo. 
def input param p-ind-object as char no-undo. 
def input param p-wgh-object as handle no-undo. 
def input param p-wgh-frame as widget-handle no-undo. 
def input param p-cod-table as char no-undo. 
def input param p-row-table as rowid no-undo. 
 
DEF NEW GLOBAL SHARED VAR wh-fill AS WIDGET-HANDLE NO-UNDO. 
DEF NEW GLOBAL SHARED VAR tx-label AS WIDGET-HANDLE NO-UNDO. 
DEF NEW GLOBAL SHARED VAR h-fPage1 AS WIDGET-HANDLE NO-UNDO. 
DEF NEW GLOBAL SHARED VAR h-bo AS HANDLE NO-UNDO. 
DEF VAR h-frame AS HANDLE NO-UNDO. 
 
{include/i_fclpreproc.i} /* Include que define o processador do 
Facelift ativado ou não. */ 
 
&IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldef.i} 
&endif 
 
{spbo/bosp001.i tt-Customer} 
 
DEF VAR h-objeto AS HANDLE NO-UNDO. 
DEF VAR c-comments AS CHAR NO-UNDO. 
 
/*encontrar o handle da frame onde deseja criar o campo*/ 
IF p-ind-event = "AFTER-INITIALIZE" THEN DO: 
 
 DO: 
 assign h-frame = p-wgh-frame:FIRST-CHILD. 
 assign h-frame = h-frame:FIRST-CHILD. 
 do while valid-handle(h-frame): 
 IF h-frame:TYPE <> "field-group" THEN DO: 
 IF h-frame:NAME = "fPage1" THEN DO: 
 ASSIGN h-fpage1 = h-frame. 
 END. 
 assign h-frame = h-frame:NEXT-SIBLING. 
External Program Call 29 
/* ver observação sobre o NEXT-SIBLING no fim deste exemplo */ 
 END. 
 ELSE DO: 
 LEAVE. 
 END. 
 end. 
 END. 
END. 
 
 
IF p-ind-event = "AFTER-INITIALIZE" THEN DO: 
 
 CREATE TEXT tx-label 
 ASSIGN FRAME = h-fPage1 /*handle da frame*/ 
 FORMAT = "x(40)" 
 WIDTH = 15 
 SCREEN-VALUE = "Coment rio:" 
 ROW = 2 
 COL = 10 
 VISIBLE = YES 
 FONT = 1. 
 
 CREATE FILL-IN wh-fill 
 ASSIGN FRAME = h-fPage1 
 SIDE-LABEL-HANDLE = tx-label:HANDLE 
 FORMAT = "x(20)" 
 NAME = "comentario" 
 WIDTH = 40 
 HEIGHT = 0.88 
 ROW = 1.7 
 COL = 18.5 
 LABEL = "Coment rio:" 
 VISIBLE = YES 
 SENSITIVE = NO 
 FONT = 1 
 TRIGGERS: 
 ON "F5":U PERSISTENT RUN epc/epczoom.p. 
 ON "MOUSE-SELECT-DBLCLICK":U PERSISTENT RUN 
epc/epczoom.p. 
 &IF "{&aplica_facelift}" = "YES" &THEN 
 {include/i_fcldin.i wh-fill} 
 &endif 
 END TRIGGERS. 
 
 WH-FILL:LOAD-MOUSE-POINTER("image/lupa.cur":U). 
 
 assign h-objeto = p-wgh-object. 
 do while valid-handle(h-objeto): 
 if h-objeto:FILE-NAME = "spbo/bosp001.p" then do: 
 ASSIGN h-bo = h-objeto. 
 LEAVE. 
 END. 
 assign h-objeto = h-objeto:NEXT-SIBLING. 
 end. 
 
 IF VALID-HANDLE(wh-fill) AND 
 valid-handle(h-bo) THEN DO: 
 RUN GetCharField IN h-bo (INPUT "comments", 
 OUTPUT c-comments). 
30 
 ASSIGN wh-fill:SCREEN-VALUE = c-comments. 
 END. 
END. 
 
IF p-ind-event = "BEFORE-ENABLE" THEN DO: 
 Assign wh-fill:SENSITIVE = YES. 
END. 
 
IF p-ind-event = "BEFORE-DISABLE" THEN DO: 
 Assign wh-fill:SENSITIVE = NO. 
END. 
 
IF p-ind-event = "BEFORE-DISPLAY" and 
 VALID-HANDLE(wh-fill) AND 
 VALID-HANDLE(h-bo) THEN DO: 
 RUN GetCharField IN h-bo (INPUT "comments", 
 OUTPUT c-comments). 
 ASSIGN wh-fill:SCREEN-VALUE = c-comments. 
END. 
 
IF p-ind-event = "AFTER-ASSIGN" and 
 VALID-HANDLE(wh-fill) AND 
 VALID-HANDLE(h-bo) THEN DO: 
 
 RUN GetRecord IN h-bo (OUTPUT TABLE tt-Customer). 
 
 FIND FIRST tt-Customer EXCLUSIVE-LOCK NO-ERROR. 
 ASSIGN tt-Customer.comments = wh-fill:SCREEN-VALUE . 
 
 RUN SetRecord IN h-bo (INPUT TABLE tt-Customer). 
 
 RUN UpdateRecord IN h-bo. 
END. 
 
Observação: Como visto no início deste exemplo, é utilizado o método 
NEXT-SIBLING para busca dos handles “irmãos” do handle filho que está 
sendo lido no momento. É importante citar que, caso o programa seja do 
template THINMAINTENANCENONAVIGATION, é necessário utilizar o 
método PREV-SIBLING ao invés do next porque neste template o handle da 
DBO é instanciado antes da janela. 
Pontos de Chamada em DBO 
 
A chamada da EPC é feita por intermédio da include method/dboupd.i. 
Todas as chamadas de EPC em DBO tratam retorno de erro. 
Na EPC de DBO é possível executar todos os métodos disponíveis na 
DBO, pois o parâmetro passado é o handle da DBO. 
 
 para as DBOs existem chamadas EPC nos seguintes eventos: 
 
Evento Método Padrão 
External Program Call 31 
BeforeCreateRecord CREATERECORD 
AfterCreateRecord CREATERECORD 
BeforeDeleteRecord DELETERECORD 
AfterDeleteRecord DELETERECORD 
BeforeUpdateRecord UPDATERECORD 
AfterUpdateRecord UPDATERECORD 
 
Atualizar campo(s) de um registrovia EPC de DBO: 
 
{include/i-epc200.i} /*Definição tt-EPC*/ 
{spbo/bosp001.i tt-Customer} /*Definição Temp-table DBO*/ 
 
DEF INPUT PARAM p-ind-event AS CHAR NO-UNDO. 
DEF INPUT-OUTPUT PARAM TABLE FOR tt-epc. 
 
DEF VAR h-BO AS HANDLE NO-UNDO. 
 
IF p-ind-event = "BeforeUpdateRecord" THEN DO: 
 FIND FIRST tt-epc WHERE 
 tt-epc.cod-event = p-ind-event AND 
 tt-epc.cod-parameter = "OBJECT-HANDLE" NO-LOCK NO-ERROR. 
 IF AVAIL tt-epc THEN DO: 
 
 ASSIGN h-bo = WIDGET-HANDLE(tt-epc.val-parameter). 
 
 RUN getRecord IN h-bo (OUTPUT TABLE tt-customer). 
 
 FIND FIRST tt-customer EXCLUSIVE-LOCK NO-ERROR. 
 ASSIGN tt-customer.Address2 = "Rua sem nome". 
 
 RUN setRecord IN h-bo (INPUT TABLE tt-customer). 
 END. 
END. 
 
Validar campo(s) de um registro via EPC de DBO (Geração de erro): 
 
{include/i-epc200.i} /*Definição tt-EPC*/ 
{spbo/bosp001.i tt-Customer} /*Definição Temp-table DBO*/ 
 
DEF INPUT PARAM p-ind-event AS CHAR NO-UNDO. 
DEF INPUT-OUTPUT PARAM TABLE FOR tt-epc. 
 
DEF VAR h-BO AS HANDLE NO-UNDO. 
 
IF p-ind-event = "AfterUpdateRecord" THEN DO: 
 FIND FIRST tt-epc WHERE 
 tt-epc.cod-event = p-ind-event AND 
 tt-epc.cod-parameter = "OBJECT-HANDLE" NO-LOCK NO-ERROR. 
 IF AVAIL tt-epc THEN DO: 
 
 ASSIGN h-bo = WIDGET-HANDLE(tt-epc.val-parameter). 
 
 RUN getRecord IN h-bo (OUTPUT TABLE tt-customer). 
 
 FIND FIRST tt-customer NO-LOCK NO-ERROR. 
 IF tt-customer.comments = "" THEN DO: 
 CREATE tt-epc. 
 ASSIGN tt-epc.cod-event = "ERROR" 
Exemplos 
32 
 tt-epc.cod-parameter = "EPC-ERROR" 
 tt-epc.val-parameter = "O campo comentário deve 
ser preenchido.". 
 END. 
 END. 
END. 
 
EPCs em Gatilhos de Dicionários de Dados 
As External Program Calls estão disponíveis em gatilhos (triggers) de 
dicionário de dados, nos gatilhos de WRITE (gravação) e DELETE 
(eliminação) das tabelas: 
 
 
EPCs em Gatilhos de WRITE 
 
Para as UPCs, através do procedimento de Manutenção de Tabelas do 
Datasul-EMS, módulo Básico (btb/btb006aa.w), o usuário pode determinar o 
caminho e o nome físico do programa de customização a ser executado no 
gatilho de WRITE de uma determinada tabela do produto. (tabela: 
‘tab_dic_dtsul’ atributo: ‘nom_prog_upc_gat_write’). 
 
 
 
Para as APPCs, também na tabela ‘tab_dic_dtsul’, o usuário pode 
determinar o caminho e o nome físico do programa de integração a ser 
executado no gatilho de WRITE através do atributo 
‘nom_prog_appc_gat_write’. 
 
Ponto de Chamada 
 
Evento Local Include Trata Retorno ? 
WRITE final do gatilho include/i-epc101.i Sim 
 
Parâmetros 
 
Parâmetro I/O Tipo de Dado Conteúdo 
p-table buffer buffer de registro Buffer do registro após as alterações 
p-old-table buffer buffer de registro Buffer do registro antes das alterações 
External Program Call 33 
 
 
Pode retornar ao gatilho que o chamou, através do recurso RETURN-
VALUE, o valor ‘NOK’ indicando que o evento não deve ser aplicado, 
retornando o erro ao programa que disparou o gatilho. Assim, é possível 
através de uma EPC, evitar que um registro de uma determinada tabela seja 
atualizado, e interromper um processamento. 
 
 
Através do procedimento de Manutenção de Tabelas do Banco de 
Dados, módulo Básico, o usuário pode determinar o caminho e o nome físico 
do programa a ser chamado na UPC dos gatilhos de DELETE de uma 
determinada tabela do produto. (tabela: tab_dic_dtsul 
atributo:nom_prog_upc_gat_delete), veja o exemplo: 
 
 
 
Para as APPCs o atributo ‘nom_prog_appc_gat_delete’ na tabela de 
‘tab_dic_dtsul’ deve determinar o caminho e o nome físico do programa a ser 
chamado na APPC dos gatilhos de DELETE de uma determinada tabela do 
produto. 
 
Ponto de Chamada 
 
Evento Local Include Trata Retorno ? 
DELETE após validações e 
antes da eliminação em cascata 
include/i-epc102.i Sim 
 
Parâmetros 
 
Parâmetro I/O Tipo de Dado Conteúdo 
p-table Buffer buffer de registro Buffer do registro que será eliminado 
 
Pode retornar ao gatilho de DELETE que o chamou, através do recurso 
RETURN-VALUE, o valor ‘NOK’ indicando que o evento não deve ser 
aplicado, retornando erro ao programa que disparou o gatilho. Assim, é 
possível através de uma EPC, evitar que um registro de uma determinada 
EPCs em Gatilhos 
de DELETE 
34 
tabela seja eliminado, pois possui relacionamentos com outros 
desenvolvimentos específicos, por exemplo. 
EPCs em pontos Estratégicos de Programas 
Há situações para customizações e integrações que não são possíveis de 
ser resolvidas através de EPCs na interface de programas ou em gatilhos de 
dicionário de dados, então são implementados chamadas EPCs em pontos 
estratégicos dentro da lógica destes programas do Datasul EMS Framework. 
Este tipo de EPC somente pode ser implementada em programas que 
não possuam interface com o usuário, quando não há forma de contornar a 
necessidade com a utilização de EPCs de dicionário de dados. 
Da mesma forma que para as EPCs de interface de programas, o usuário 
deve definir o nome e o caminho do programa EPC a ser executado através 
dos atributos ‘nom_prog_upc’ e ‘nom_prog_appc’ respectivamente para UPC 
e APPC. Assim, para viabilizar uma EPC , por exemplo no programa de 
cálculo do preço médio (cep/ce0401rp.p), o usuário deve cadastrar o sub-
programa, onde foi implementada a chamada EPC, na tabela de programas 
‘prog_dtsul’. 
 
Caso houver outra situação de customização, que não seja possível de ser 
resolvida através de EPC´s, se propõe: 
 a construção de um sucinto programa que seja o SETUP da customização 
para cada um de seus clientes (caso for parceiro). Este programa, a 
princípio limparia o conteúdo dos campos: ‘prog_dtsul.nom_prog_upc’ e 
‘tab_dic_dtsul.nom_prog_upc’ e após faria o registro das customizações 
daquele cliente. 
 aplicar o programa SETUP de determinado cliente na base sempre que for 
realizar um teste com o ambiente daquele cliente. 
 
Parâmetros 
 
Parâmetro I/O Tipo de Dado Conteúdo 
p-ind-event Input Character indicador de evento 
tt-epc i-o temp-table temporary table com três atributos: 
  cod-event (character) – indicador de evento, sempre 
o mesmo valor que p-ind-event; 
 cod-parameter (character) – código do parâmetro 
indicando o que significa o valor do parâmetro; 
 val-parameter (character) – valor do parâmetro. 
 
Os valores dos parâmetros ‘p-ind-event’, ‘tt-epc.cod-event’ e ‘tt-
epc.cod-parameter’ são definidos em inglês e sem espaços em branco entre as 
Sugestão: 
External Program Call 35 
palavras, substituindo os espaços em branco pelo caracter traço (-), pois o 
produto é internacional e o idioma inglês é mundialmente aceito. 
Qualquer um dos tipos de EPC pode retornar ao programa chamador, 
através do recurso RETURN-VALUE, o valor ‘NOK’ indicando que o 
processamento seja interrompido/cancelado para aquela interação, ou ainda 
tenha outro efeito definido sobre o programa chamador. 
A temp-table de comunicação ‘tt-epc’ deve obrigatoriamente conter 
apenas um registro, que será o evento desejado. 
 
Exemplo: 
 no fonte de um programa sem interface do produto EMS 2.0, a 
chamada EPC poderia ser implementada da seguinte forma: 
 
 
/* Include i-epc200.i: Definição Temp-Table tt-epc e dos 
programas de EPCs */ 
{include/i-epc200.i XX9999} 
 
for each item no-lock: 
for each tt-epc: 
delete tt-epc. 
end. 
 
/* Include i-epc200.i2: Criação de registro para Temp-
Table tt-epc */ 
{include/i-epc200.i2 &CodEvent='"Single-Point"' 
 &CodParameter='"item.it-codigo"' 
 &ValueParameter="item.it-codigo"} 
 
/* Include i-epc201.i: Chamada do programa de EPC */ 
{include/i-epc201.i "Single-Point"} 
 
if return-value = "NOK" then 
/* Exemplo de tratamentode retorno */ 
undo, leave. 
end. 
 
 Já o programa de customização/integração teria o seguinte 
tratamento como base o seguinte código fonte: 
 
/* Include i-epc200.i: Definição Temp-Table tt-epc */ 
{include/i-epc200.i1} 
 
def input param p-ind-event as char no-undo. 
def input-output param table for tt-epc. 
 
for each tt-epc no-lock 
 where tt-epc.cod-event = p-ind-event: 
 
 /* Exemplo de uso dos parâmetros */ 
 disp tt-epc. 
end. 
36 
 
 
 
Como aplicar Facelift em programas específicos 
Com a liberação da nova interface Datasul, os programas padrões 
passaram a ter um novo visual, mais moderno e amigável. Os programas 
específicos desenvolvidos com templates (DDK) e que seguiram os padrões de 
desenvolvimento da Datasul também absorveram a nova interface, porém os 
programas desenvolvidos na mão ou que não seguiram os padrões, continuam 
com a interface antiga. 
Esta técnica foi criada para auxiliar a alteração destes programas afim 
de também aplicar a nova interface dos produtos Datasul aos específicos de 
cada cliente. 
 
 
Exemplo: 
 no fonte do programa a ser alterado, inserir o código abaixo. 
 O ponto onde o código deve ser inserido varia. Em programas 
criados no UIB deve ser no main-block, antes da include principal 
do main-block. Em programas definidos na mão (todo o código 
fonte é escrito pelo programador), este código deve ser inserido 
antes da frame ficar visível. 
 FRAME {&FRAME-NAME}:HANDLE – aqui deve ser 
informado o handle da frame principal do programa. 
 
RUN btb/btb901zo.p PERSISTENT SET hbtb. 
 
DEFINE VARIABLE h_frame AS WIDGET NO-UNDO. 
DEFINE VARIABLE p-wgh-frame AS WIDGET NO-UNDO. 
 
ASSIGN p-wgh-frame = FRAME {&FRAME-NAME}:HANDLE. 
 
RUN pi_altera_componentes IN hbtb (p-wgh-frame). 
RUN pi_alterar_window IN hbtb (wWin:HANDLE). 
 
ASSIGN h_Frame = p-wgh-frame:FIRST-CHILD. /* pegando o 
Field-Group */ 
ASSIGN h_Frame = h_Frame:FIRST-CHILD. /* pegando o 
1o. Campo */ 
DO WHILE h_Frame <> ? : 
 if h_frame:type <> "field-group" then do: 
 RUN pi_altera_componentes IN hbtb (h_frame). 
 
 ASSIGN h_Frame = h_Frame:NEXT-SIBLING. 
 end. 
 else do: 
 assign h_frame = h_frame:first-child. 
Técnica: 
External Program Call 37 
end. 
 END. 
 
Localização de Programas Específicos 
 
Objetivo 
Especificar a localização para armazenamento de programas 
customizados por terceiros. 
 
Implementação 
Esta localização deve ser feita a partir de um diretório raiz que deve ter 
o nome da empresa que desenvolveu o programa específico. Os diretórios dos 
módulos e os nomes dos programas, podem ter o mesmo nome de programas 
Datasul. 
A diferença fica na chamada destes programas, isto é, para executar um 
programa específico e seus sub-programas e includes, deve-se identificar na 
chamada destes, o nome do diretório específico, identificando assim, estes 
programas como não Datasul. 
Este diretório raiz não deve estar sob o diretório do produto, isto é, não 
deve ser incluído no diretório do produto Datasul instalado e, sim, em um 
diretório de instalação próprio. 
No cadastro destes programas no menu, deve-se ter o nome da empresa 
que criou o específico, mais o nome do programa como a chave de 
identificação. Ainda no cadastro de programas, será necessário colocar o nome 
da empresa que construiu o específico antes do <diretório>/<programa> 
desejado como nome externo. 
Para finalizar, o PROPATH deve conter sempre o diretório do produto 
Datasul em primeiro lugar, isto é, antes do diretório onde estão os específicos. 
Para encontrar os programas do específico, basta adicionar ao PROPATH, o 
diretório anterior ao nome da empresa que desenvolveu o específico, após o 
diretório do produto Datasul. 
 
Exemplo 
Caso a empresa XYZ desenvolva programas para o módulo APP, a 
localização dos programas específicos desenvolvidos devem ficar em: 
C:\EMS20POR\... 
C:\<diretório>\XYZ\APP\AP0101.W 
 
Para executar programas Datasul, fazer: 
 
RUN APP\AP0101.W 
 
Para cadastrar o programa no menu, fazer: 
Programa : XYZ/AP0101 
38 
Nome externo : XYZ/APP/AP0101.W 
 
Para cadastrar uma UPC, fazer: 
Programa : XYZ/APP/AP0101.P 
 
O PROPATH fica: 
 
PROPATH = "c:\<datasul>;c:\<diretório>;..." 
Obs.: O diretório XYZ está debaixo de c:\<diretório> 
 
Considerações Gerais 
 
a partir do momento que uma EPC for cadastrada para um programa ou 
gatilho, sempre que for executado este programa ou gatilho é feita a chamada 
para a EPC. 
Sendo assim, se a EPC estiver cadastrada de forma incorreta ou não existir, vai 
ser gerado um erro Progress, (<programa> was not found (293)). 
 nos programas chamados pelas EPCs, em gatilhos de dicionário de dados, 
não deve ser solicitado qualquer interação do usuário, ou apresentado 
qualquer tipo de tela (frame) ou caixa de mensagem; 
 deve ser feito ainda uma documentação de como construir os programas 
EPC, além do descrito acima, e acompanhar a documentação do produto 
para o usuários. 
 Desaconselhamos que sejam retirados quaisquer objetos(browser, viewer) 
de um programa do Datasul EMS utilizando EPCs. 
 Deve-se tomar cuidado com eventos para objetos do produto Datasul EMS 
Framework, quando se desejar criar um novo evento para um destes 
objetos, deve-se contatar o módulo, pois pode-se estar sobrepondo um 
evento que é importante para o produto. 
 
 
 
 
 
Chamar uma EPC de uma trigger de write: 
 
define input parameter buffer p-table for item no-undo. 
define input parameter buffer p-old-table for item no-undo. 
 
Find cust-table where cust-table.it-codigo = p-table.it-codigo 
then 
 If not available cust-table then do: 
 create cust-table. 
 buffer-copy p-table cust-table. 
 end. 
External Program Call 39 
 
 
Chamar uma EPC de uma trigger de delete: 
 
define input parameter buffer p-table for item no-undo. 
 
find cust-table where cust-table.it-codigo = p-table.it-codigo 
then 
 If not available cust-table then do: 
 create cust-table. 
 buffer-copy p-table cust-table. 
 end. 
 
Como acertar TAB-ORDER em uma EPC 
 
Para acertar o tab-order em uma DPC, pode ser feito da seguinte 
forma: 
 
Por exemplo, imagine a seguinte frame: 
 
A: [ ] 
B: [ ] 
C: [ ] 
 
Um programa de customização deve inserir o fill-in D, que está ao lado 
de A. Portanto, quando for teclado TAB no fill-in A, ele deverá 
posicionar-se no fill-in D. 
 
varD:MOVE-AFTER-TAB-ITEM(varA:HANDLE). 
 
Também, existe o método para mover o fill-in anterior, neste caso: 
 
varD:MOVE-BEFORE-TAB-ITEM(varA:HANDLE).

Mais conteúdos dessa disciplina