Customizao UPC
Short Description
Download Customizao UPC...
Description
Abril/1999
Não homologado
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
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........................................2 External Program Call.....................................................................................6
1
CAPÍTULO 1
Introdução Definiçã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..
2
CAPÍTULO 2
Application Program Interface API Definição
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.
Exemplos
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;
Esquema de Funcionamen to
External Program Call
3
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: •
•
•
Tipos
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).
Documentaçã o •
•
•
•
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) 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.
Vantagens
•
•
•
•
1
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 reescrever 1 seus programas;
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.
External Program Call
Portanto, o que as APIs fornecem é uma maior facilidade, rapidez e produtividade no desenvolvimento de customizações;
5
External Program Call Definição
São chamadas a programas desenvolvidos pelo usuário, em pontos pré-definidos do produto, possibilitando a Aplicação sua adaptação e integração com outras Específica aplicações. Constituem-se num aperfeiçoamento das “Saídas X” API existentes no produto MAGNUS I.00, pois os pontos de chamada estão ligados a eventos da interface com o usuário, Datasul eventos da base de dados (gravação e eliminação de registros) ou em pontos EMS estratégicos em programas de atualização e cálculo. framework 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.
UPC
Objetivos
•
•
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;
External Program Call
•
•
Tipos de EPCs
•
7
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; 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
•
EPCs na Interface de Programas
UPC + APPC = EPC
Através do procedimento de Manutenção de Programas do DatasulEMS (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: Parâmetro
p-ind-event p-ind-object p-wgh-object p-wgh-frame p-cod-table p-row-table
I/O Input Input Input Input Input Input
Tipo de Dado
Conteúdo
Character Character
Indicador de Evento Indicador de Objeto Handle do objeto corrente Handle do frame corrente Nome da tabela corrente Rowid do registro corrente da tabela
Handle Widget -handle
Character Rowid
Pode retornar ao programa que o chamou, através do recurso RETURNVALUE, 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 def def def def def def
input param p-ind-event input param p-ind-object input param p-wgh-object input param p-wgh-frame input param p-cod-table input param p-row-table var c-objeto as char no-undo.
as as as as as as
char char handle widget-handle char rowid
no-undo. no-undo. no-undo. no-undo. no-undo. 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.
External Program Call
9
Pontos de Chamada 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 BEFORE-INITIALIZE INITIALIZE BEFORE-DISPLAY DISPLAY ENABLE AFTER-ENABLE DISABLE AFTER-DISABLE BEFORE-ADD ADD UNDO AFTER-UNDO CANCEL AFTER-CANCEL VALIDATE AFTER-VALIDATE BEFORE-ASSIGN ASSIGN END-UPDATE AFTER-END-UPDATE DELETE AFTER-DELETE •
SRC
Smart.i Smart.i Record.i Record.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i Tableio.i
Include include/i-epc018.i include/i-epc001.i include/i-epc023.i include/i-epc006.i include/i-epc004.i include/i-epc021.i include/i-epc005.i include/i-epc022.i include /i-epc028.i include /i-epc011.i include/i-epc012.i include/i-epc029.i include/i-epc013.i include/i-epc030.i include /i-epc002.i include /i-epc019.i include /i-epc020.i include /i-epc003.i include /i-epc010.i include /i-epc027.i include/i-epc015.i include/i-epc032.i
Trata Retorno ?
Não Não Não Não Não Não Não Não Não Não Não Não Não Não Sim Sim Sim Sim Não Não Sim Sim
para SmartBrowsers devem haver chamadas EPC nos seguintes eventos:
Evento
SRC
VALUE-CHANGED AFTER-VALUE-CHANGED BEFORE-INITIALIZE INITIALIZE BEFORE-OPEN-QUERY AFTER-OPEN-QUERY
Brschnge.i Brschnge.i Smart.i Smart.i Record.i Record.i
•
Local–Estrutura UIB Adm-initialize Adm-initialize Adm-display-fields Adm-display-fields Adm-enable-fields Adm-enable-fields Adm-disable-fields Adm-disable-fields Adm-add-record Adm-add-record Adm-reset-record Adm-reset-record Adm-cancel-record Adm-cancel-record Adm-assign-record Adm-assign-statement Adm-assign-statement Adm-assign-statement Adm-end-update Adm-end-update Adm-delete-record Adm-delete-record
Local value-changed value-changed adm-initialize adm-initialize adm-open-query adm-open-query
Include include /i-epc016.i include /i-epc033.i Include/ i-epc034.i Include/ i-epc017.i Include/ i-epc035.i Include/ i-epc036.i
Trata Retorno ?
Não Não Não Não Não Não
para Containers devem haver chamadas EPC nos seguintes eventos:
Evento
SRC
Local
Include
BEFORE-INITIALIZE INITIALIZE BEFORE-ENABLE ENABLE
smart.i smart.i smart.i smart.i
adm-initialize adm-initialize adm-enable adm-enable
Include/i-epc024.i Include/i-epc007.i Include/i-epc025.i Include/i-epc008.i
Trata Retorno ?
Não Não Não Não
BEFORE-DISABLE DISABLE CHANGE-PAGE AFTER-CHANGE-PAGE DESTROY •
smart.i smart.i Containr.i Containr.i smart.i
Não Não Não Não Não
No caso do EMS 5, os pontos de chamada estão nos seguintes eventos: Evento
INITIALIZE DISPLAY ENABLE VALIDATE ASSIGN BEFORE_DELETE AFTER_DELETE
Exemplos
Include /i-epc026.i Include /i-epc009.i Include/ i-epc014.i Include/ i-epc031.i include /i-epc100.i
adm-disable adm-disable adm-change-page adm-change-page adm-destroy
Local Depois do view da frame Depois do display da frame Depois do enable da frame Depois da chamada da pi de validação Depois da pi de assign dos campos Antes de eliminar o registro Depois de eliminar o registro
Trata Retorno ?
Não Não Não Sim Sim Sim Sim
Criar um botão novo em uma window para chamar um subprograma a partir deste; def def def def def def
input input input input input input
param param param param param param
p-ind-event p-ind-object p-wgh-object p-wgh-frame p-cod-table p-row-table
as as as as as as
char char handle widget-handle char rowid
no-undo. no-undo. no-undo. no-undo. no-undo. no-undo.
def var wh-button as widget-handle no-undo. def var c-objeto as char no-undo. assign c-objeto = entry(num-entries(p-wgh-object:privatedata, "~/"), p-wgh-object:private-data, "~/"). if p-ind-event = "INITIALIZE" and p-ind-object = "CONTAINER" then do: create button wh-button assign 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.
External Program Call
11
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 def def def def def
input input input input input input
def new global def new undo. def new undo. def var
param param param param param param
p-ind-event p-ind-object p-wgh-object p-wgh-frame p-cod-table p-row-table
as as as as as as
char char handle widget-handle char rowid
no-undo. no-undo. no-undo. no-undo. no-undo. no-undo.
shared var wh-button as widget-handle no-undo. global shared var wh-fill as widget-handle noglobal shared var tx-label
as widget-handle no-
c-objeto as char no-undo.
assign c-objeto = entry(num-entries(p-wgh-object:privatedata, "~/"), p-wgh-object:private-data, "~/"). if p-ind-event = "BEFORE-INITIALIZE" and p-ind-object = "VIEWER" and c-objeto = "v24ad098.w" then do: create button wh-button assign 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 = 1 visible = yes. create fill-in wh-fill assign frame = p-wgh-frame side-label-handle = tx-label:handle
format width height row col bgcolor fgcolor label visible sensitive
= = = = = = = = = =
"x(20)" 12 0.88 2.7 71 1 15 "Perfil Marketing:" yes no.
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.
Encontrar o handle de um widget; def def def def def def
input input input input input input
def new undo. def new undo. def new undo. def new undo. def var def var
param param param param param param
p-ind-event p-ind-object p-wgh-object p-wgh-frame p-cod-table p-row-table
as as as as as as
char char handle widget-handle char rowid
no-undo. no-undo. no-undo. no-undo. no-undo. no-undo.
global shared var wh-button
as widget-handle no-
global shared var wh-fill
as widget-handle no-
global shared var tx-label
as widget-handle no-
global shared var h_campo
as widget-handle no-
c-objeto as char no-undo. h_frame as widget-handle no-undo.
assign c-objeto = entry(num-entries(p-wgh-object:privatedata, "~/"), p-wgh-object:private-data, "~/"). if p-ind-event = "DISPLAY" and p-ind-object = "VIEWER" and c-objeto = "v24ad098.w" then do:
External Program Call
13
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 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.
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 screenvalue 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 noundo. define new global shared var h-folder as handle noundo. define new global shared var h-viewer as handle noundo. /* 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. /* Main Block ************************************************************* **/ if p-ind-event = "INITIALIZE" and p-ind-object = "CONTAINER" then do: RUN get-link-handle IN adm-broker-hdl (INPUT p-wghobject, INPUT "PAGESOURCE":U, OUTPUT c-folder). assign h-folder = widget-handle(c-folder) no-error. if valid-handle(h-folder) then do:
External Program Call
15
RUN create-folder-page IN h-folder (INPUT 5, INPUT "Pag. 05":U). 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-wghobject, INPUT "CONTAINER-TARGET":U, OUTPUT cobjects). do i-objects = 1 to num-entries(c-objects): assign h-object = widget-handle(entry(i-objects, cobjects)). if index(h-object:private-data, "qry") 0 and verificar se e a query principal */ not l-record then do: assign l-record = yes.
/* Você deve
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. RUN add-link IN adm-broker-hdl (INPUT h-object, INPUT "GroupAssign":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 def def def def def
input input input input input input
param param param param param param
p-ind-event p-ind-object p-wgh-object p-wgh-frame p-cod-table p-row-table
def new global shared var wh-fill undo. def new global shared var tx-label undo. def var c-objeto as char no-undo.
as as as as as as
char char handle widget-handle char rowid
no-undo. no-undo. no-undo. no-undo. no-undo. no-undo.
as widget-handle noas widget-handle no-
assign c-objeto = entry(num-entries(p-wgh-object:privatedata, "~/"), 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 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. end. if p-ind-event = "ENABLE" and p-ind-object = "VIEWER"
External Program Call
17
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 def new def new undo. def new def new
wh-pesquisa as widget-handle. global shared var l-implanta as logical init no. global shared var wh-fill as widget-handle noglobal shared var wh-window as handle no-undo. 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 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 BEFORE-ADD AFTER-ADD BEFORE-CANCEL AFTER-CANCEL BEFORE-COPY AFTER-COPY BEFORE-DELETE AFTER-DELETE BEFORE-ASSIGN AFTER-ASSIGN BEFORE-UNDO AFTER-UNDO BEFORE-CONTROL-TOOL-BAR
Método Padrão ADDRECORD ADDRECORD CANCELRECORD CANCELRECORD COPYRECORD COPYRECORD DELETERECORD DELETERECORD SAVERECORD SAVERECORD UNDORECORD UNDORECORD CONTROLTOOLBAR
AFTER-CONTROL-TOOL-BAR BEFORE-DESTROY-INTERFACE AFTER-DESTROY-INTERFACE BEFORE-DISABLE AFTER-DISABLE BEFORE-DISPLAY AFTER-DISPLAY BEFORE-ENABLE AFTER-ENABLE BEFORE-INITIALIZE AFTER-INITIALIZE BEFORE-SAVE-FIELDS AFTER-SAVE-FIELDS BEFORE-CHANGE-PAGE AFTER-CHANGE-PAGE •
para ThinMaintenanceNoNavigation existem chamadas EPC nos seguintes eventos: Evento BEFORE-ADD AFTER-ADD BEFORE-COPY AFTER-COPY BEFORE-ASSIGN AFTER-ASSIGN BEFORE-DESTROY-INTERFACE AFTER-DESTROY-INTERFACE BEFORE-DISABLE AFTER-DISABLE BEFORE-DISPLAY AFTER-DISPLAY BEFORE-ENABLE AFTER-ENABLE BEFORE-INITIALIZE AFTER-INITIALIZE BEFORE-SAVE-FIELDS AFTER-SAVE-FIELDS BEFORE-CHANGE-PAGE AFTER-CHANGE-PAGE
•
CONTROLTOOLBAR DESTROYINTERFACE DESTROYINTERFACE DISABLEFIELDS DISABLEFIELDS DISPLAYFIELDS DISPLAYFIELDS ENABLEFIELDS ENABLEFIELDS INITIALIZEINTERFACE INITIALIZEINTERFACE SAVEFIELDS SAVEFIELDS CHANGEPAGE CHANGEPAGE
Método Padrão ADDRECORD ADDRECORD COPYRECORD COPYRECORD SAVERECORD SAVERECORD DESTROYINTERFACE DESTROYINTERFACE DISABLEFIELDS DISABLEFIELDS DISPLAYFIELDS DISPLAYFIELDS ENABLEFIELDS ENABLEFIELDS INITIALIZEINTERFACE INITIALIZEINTERFACE SAVEFIELDS SAVEFIELDS CHANGEPAGE CHANGEPAGE
para ThinMasterDetail existem chamadas EPC nos seguintes eventos: Evento BEFORE-DELETE AFTER-DELETE BEFORE-CONTROL-TOOL-BAR AFTER-CONTROL-TOOL-BAR BEFORE-DESTROY-INTERFACE AFTER-DESTROY-INTERFACE BEFORE-DISPLAY AFTER-DISPLAY
Método Padrão DELETERECORD DELETERECORD CONTROLTOOLBAR CONTROLTOOLBAR DESTROYINTERFACE DESTROYINTERFACE DISPLAYFIELDS DISPLAYFIELDS
External Program Call
BEFORE-INITIALIZE AFTER-INITIALIZE BEFORE-VALUE-CHANGED AFTER-VALUE-CHANGED BEFORE-CHANGE-PAGE AFTER-CHANGE-PAGE BEFORE-OPEN-QUERY AFTER-OPEN-QUERY •
Método Padrão DESTROYINTERFACE DESTROYINTERFACE DISPLAYFIELDS DISPLAYFIELDS INITIALIZEINTERFACE INITIALIZEINTERFACE
para ThinReport existem chamadas EPC nos seguintes eventos: Evento BEFORE-DESTROY-INTERFACE AFTER-DESTROY-INTERFACE BEFORE-DISABLE AFTER-DISABLE BEFORE-ENABLE AFTER-ENABLE BEFORE-INITIALIZE AFTER-INITIALIZE
•
Método Padrão CONTROLTOOLBAR CONTROLTOOLBAR DESTROYINTERFACE DESTROYINTERFACE DISPLAYFIELDS DISPLAYFIELDS INITIALIZEINTERFACE INITIALIZEINTERFACE CHANGEPAGE CHANGEPAGE
para ThinFormationNoNavigation existem chamadas EPC nos seguintes eventos: Evento BEFORE-DESTROY-INTERFACE AFTER-DESTROY-INTERFACE BEFORE-DISPLAY AFTER-DISPLAY BEFORE-INITIALIZE AFTER-INITIALIZE
•
INITIALIZEINTERFACE INITIALIZEINTERFACE APPLYVALUECHANGED APPLYVALUECHANGED CHANGEPAGE CHANGEPAGE OPENQUERY OPENQUERY
para ThinFormation existem chamadas EPC nos seguintes eventos: Evento BEFORE-CONTROL-TOOL-BAR AFTER-CONTROL-TOOL-BAR BEFORE-DESTROY-INTERFACE AFTER-DESTROY-INTERFACE BEFORE-DISPLAY AFTER-DISPLAY BEFORE-INITIALIZE AFTER-INITIALIZE BEFORE-CHANGE-PAGE AFTER-CHANGE-PAGE
•
19
Método Padrão DESTROYINTERFACE DESTROYINTERFACE DISABLEFIELDS DISABLEFIELDS ENABLEFIELDS ENABLEFIELDS INITIALIZEINTERFACE INITIALIZEINTERFACE
para ThinWindow existem chamadas EPC nos seguintes eventos: Evento BEFORE-DESTROY-INTERFACE
Método Padrão DESTROYINTERFACE
AFTER-DESTROY-INTERFACE BEFORE-DISPLAY AFTER-DISPLAY BEFORE-ENABLE AFTER-ENABLE BEFORE-INITIALIZE AFTER-INITIALIZE BEFORE-CHANGE-PAGE AFTER-CHANGE-PAGE •
DESTROYINTERFACE DISPLAYFIELDS DISPLAYFIELDS ENABLEFIELDS ENABLEFIELDS INITIALIZEINTERFACE INITIALIZEINTERFACE CHANGEPAGE CHANGEPAGE
para ThinZoom existem chamadas EPC nos seguintes eventos: Evento BEFORE-VALUE-CHANGED AFTER-VALUE-CHANGED BEFORE-DESTROY-INTERFACE AFTER-DESTROY-INTERFACE BEFORE-INITIALIZE AFTER-INITIALIZE BEFORE-CHANGE-PAGE AFTER-CHANGE-PAGE
Exemplos
Método Padrão APPLYVALUECHANGED APPLYVALUECHANGED DESTROYINTERFACE DESTROYINTERFACE INITIALIZEINTERFACE INITIALIZEINTERFACE CHANGEPAGE CHANGEPAGE
Criar um widget novo em uma frame; def def def def def def
input input input input input input
param param param param param param
p-ind-event p-ind-object p-wgh-object p-wgh-frame p-cod-table p-row-table
as as as as as as
char char handle widget-handle char rowid
no-undo. no-undo. no-undo. no-undo. no-undo. 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. IF
p-ind-event = "AFTER-INITIALIZE" THEN DO: CREATE BUTTON wh-button ASSIGN 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
External Program Call
21
ASSIGN FRAME FORMAT WIDTH SCREEN-VALUE ROW COL VISIBLE FONT
= = = = = = = =
p-wgh-frame "x(40)" 15 "Comentário:" 2 10 YES 1.
CREATE FILL-IN wh-fill ASSIGN FRAME SIDE-LABEL-HANDLE FORMAT WIDTH HEIGHT ROW COL LABEL VISIBLE SENSITIVE FONT
= = = = = = = = = = =
p-wgh-frame tx-label:HANDLE "x(20)" 40 0.88 1.7 18.5 "Comentário:" YES NO 1.
END. IF
p-ind-event = "BEFORE-ENABLE" THEN DO: ASSIGN wh-button:SENSITIVE = YES wh-fill:SENSITIVE = YES.
END. IF
p-ind-event = "BEFORE-DISABLE" THEN DO: ASSIGN wh-button:SENSITIVE = NO wh-fill:SENSITIVE = NO. END.
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 def def def def def
input input input input input input
param param param param param param
p-ind-event p-ind-object p-wgh-object p-wgh-frame p-cod-table p-row-table
as as as as as as
char char handle widget-handle char rowid
no-undo. no-undo. no-undo. no-undo. no-undo. 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 = “BEFORE-INITIALIZE” THEN DO: DO: assign h-objeto = p-wgh-frame:FIRST-CHILD. assign h-objeto = h-objeto:FIRST-CHILD. do while valid-handle(h-objeto): IF h-objeto:TYPE "field-group" THEN DO: IF h-objeto:NAME = "nome-mic-reg" 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.
END.
Habilitar o folder;
Somente é possível habilitar o folder se o programa utilizar as páginas fPage0 e fPage1. def def def def def def
input input input input input input
param param param param param param
p-ind-event p-ind-object p-wgh-object p-wgh-frame p-cod-table p-row-table
as as as as as as
char char handle widget-handle char rowid
no-undo. no-undo. no-undo. no-undo. no-undo. no-undo.
DEF NEW GLOBAL SHARED VAR h-fpage1 AS HANDLE NO-UNDO. DEF NEW GLOBAL SHARED VAR h-folder AS HANDLE NO-UNDO. DEF VAR h-frame AS HANDLE NO-UNDO. IF
p-ind-event = "BEFORE-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.
External Program Call
23
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:GETSIGNATURE("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 def def def def def
input input input input input input
param param param param param param
p-ind-event p-ind-object p-wgh-object p-wgh-frame p-cod-table p-row-table
as as as as as as
char char handle widget-handle char rowid
no-undo. no-undo. no-undo. no-undo. no-undo. no-undo.
DEF NEW GLOBAL SHARED VAR h-fpage2 AS WIDGET-HANDLE NO-UNDO. DEF VAR h-objeto IF
AS HANDLE
NO-UNDO.
p-ind-event = "AFTER-INITIALIZE" THEN DO: CREATE FRAME h-fPage2 ASSIGN COL ROW WIDTH HEIGHT NAME SIDE-LABELS SENSITIVE OVERLAY BGCOLOR BOX THREE-D
= = = = = = = = = = =
3.57 6.38 84.43 5.88 "fpage2" YES YES YES ? NO YES.
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 INPUT INPUT
?, p-wgh-frame, h-fPage2, "Ref Call").
End.
Chamar o zoom para um campo criado dinamicamente; def def def def def def
input input input input input input
param param param param param param
p-ind-event p-ind-object p-wgh-object p-wgh-frame p-cod-table p-row-table
as as as as as as
char char handle widget-handle char rowid
no-undo. no-undo. no-undo. no-undo. no-undo. 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. /*encontrar o handle da frame onde deseja criar o campo*/ IF
p-ind-event = "AFTER-INITIALIZE" THEN DO: CREATE TEXT tx-label ASSIGN FRAME FORMAT WIDTH SCREEN-VALUE ROW COL VISIBLE FONT
= = = = = = = =
h-fPage2 /*handle da frame*/ "x(40)" 15 "Comentário:" 2 10 YES 1.
CREATE FILL-IN wh-fill ASSIGN FRAME SIDE-LABEL-HANDLE FORMAT NAME WIDTH HEIGHT ROW COL LABEL VISIBLE
= = = = = = = = = =
h-fPage2 tx-label:HANDLE "x(20)" "comentario" 40 0.88 1.7 18.5 "Comentário:" YES
External Program Call
25
SENSITIVE = NO FONT = 1 TRIGGERS: ON "F5":U PERSISTENT RUN epc/epczoom.p. ON "MOUSE-SELECT-DBLCLICK":U PERSISTENT RUN epc/epczoom.p. 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. 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="fPage2" &fieldHandle1=wh-fill}
Buscar registro corrente/atualizar registro de uma DBO; def def def def def def
input input input input input input
DEF DEF DEF DEF
NEW NEW NEW NEW
param param param param param param
GLOBAL GLOBAL GLOBAL GLOBAL
p-ind-event p-ind-object p-wgh-object p-wgh-frame p-cod-table p-row-table
SHARED SHARED SHARED SHARED
VAR VAR VAR VAR
wh-fill tx-label h-fPage1 h-bo
as as as as as as
char char handle widget-handle char rowid
AS AS AS AS
WIDGET-HANDLE WIDGET-HANDLE WIDGET-HANDLE HANDLE
{spbo/bosp001.i tt-Customer} DEF VAR h-objeto AS HANDLE DEF VAR c-comments AS CHAR
no-undo. no-undo. no-undo. no-undo. no-undo. no-undo.
NO-UNDO. NO-UNDO.
NO-UNDO. NO-UNDO. NO-UNDO. NO-UNDO.
/*encontrar o handle da frame onde deseja criar o campo*/ IF
p-ind-event = "AFTER-INITIALIZE" THEN DO: CREATE TEXT tx-label ASSIGN FRAME FORMAT WIDTH SCREEN-VALUE ROW COL VISIBLE FONT
= = = = = = = =
h-fPage1 /*handle da frame*/ "x(40)" 15 "Comentário:" 2 10 YES 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. 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). ASSIGN wh-fill:SCREEN-VALUE = c-comments. END. END.
External Program Call
27
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.
Pontos de Chamada 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 BeforeCreateRecord AfterCreateRecord BeforeDeleteRecord AfterDeleteRecord BeforeUpdateRecord AfterUpdateRecord
Exemplos
Método Padrão CREATERECORD CREATERECORD DELETERECORD DELETERECORD UPDATERECORD UPDATERECORD
Atualizar campo(s) de um registro via 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 IF
AS HANDLE NO-UNDO.
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 IF
AS HANDLE NO-UNDO.
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" tt-epc.cod-parameter = "EPC-ERROR"
External Program Call
29
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
WRITE
final do gatilho
Include include/i-epc101.i
Trata Retorno ?
Sim
Parâmetros Parâmetro
p-table p-old-table
I/O buffer buffer
Tipo de Dado buffer de registro buffer de registro
Conteúdo Buffer do registro após as alterações Buffer do registro antes das alterações
Pode retornar ao gatilho que o chamou, através do recurso RETURNVALUE, 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.
EPCs em Gatilhos de DELETE
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
DELETE
após validações e antes da eliminação em cascata
Include include/i-epc102.i
Trata Retorno ?
Sim
External Program Call
31
Parâmetros
Parâmetro
p-table
I/O Buffer
Tipo de Dado buffer de registro
Conteúdo 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 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’ .
Sugestão:
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
p-ind-event tt-epc
I/O Input
Tipo de Dado
Character
Conteúdo
indicador de evento
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 ‘ttepc.cod-parameter’ são definidos em inglês e sem espaços em branco entre as 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. 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 where tt-epc.cod-event = "Single-Point". delete tt-epc. end. /* Include i-epc200.i2: Criação de registro para TempTable tt-epc */ {include/i-epc200.i2 &CodEvent='"Single-Point"' &CodParameter='"item.it-codigo"' &ValueParameter="item.it-codigo"} /* Include i-epc200.i2: Criação de registro para TempTable tt-epc */ {include/i-epc200.i2 &CodEvent='"Single-Point"' &CodParameter='"item rowid"' &ValueParameter="string(rowid(item))"}
External Program Call
33
/* Include i-epc201.i: Chamada do programa de EPC */ {include/i-epc201.i "Single-Point"} if return-value = "NOK" then /* Exemplo de tratamento de 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.
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 / 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:\\XYZ\APP\AP0101.W Para executar programas Datasul, fazer: RUN APP\AP0101.W
Para cadastrar o programa no menu, fazer: Programa : XYZ/AP0101 Nome externo : XYZ/APP/AP0101.W Para cadastrar uma UPC, fazer: Programa : XYZ/APP/AP0101.P O PROPATH fica: PROPATH = "c:\;c:\;..."
Obs.: O diretório XYZ está debaixo de c:\
Consideraçõe s 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, ( 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;
External Program Call
•
•
•
35
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.
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:
View more...
Comments