Está en la página 1de 35

Manual de Referencia

Personalizaciones
Abril/2003
Copyright © 2009 TOTVS S.A. Todos los derechos reservados.
Ninguna parte de este documento puede ser copiada, reproducida, traducida o
transmitida por cualquier medio electrónico o mecánico, en su totalidad o en
parte, sin la prévia autorización escrita de TOTVS S.A., que se reserva el
derecho de efectuar alteraciones sin aviso prévio. TOTVS S.A no asume
ninguna responsabilidad por las consecuencias de cualesquiera errores o
inexactitudes que puedan aparecer en este documento.
TOTVS S.A.
Av. Santos Dumont, 831, Joinville, SC, CP 89.222-900
i

Índice

Índice................................................................................................................. i

CAPÍTULO 1 Introducción..................................................................1

CAPÍTULO 2 Application Program Interface - API............................3

External Program Call.....................................................................................6


Puntos de Llamada en Smart.........................................................................8
Puntos de Llamada en ThinTemplate..........................................................16
Puntos de Llamada en DBO........................................................................25
EPCs en Gatillos de Diccionarios de Datos................................................27
EPCs en Puntos Estratégicos de Programas................................................29
Ubicación de Programas Específicos..........................................................31
Consideraciones Generales.........................................................................32
Definición

CAPÍTULO 1

Introducción

El producto Datasul EMS Framework posee dos tecnologías creadas para


estandarizar y facilitar las personalizaciones, sin que sea necesario conocer
sobre Base de Datos y sus relaciones.
De esta forma garantizando también que el acceso y entrada de datos sean
hechos de manera correcta y exacta.
Definición de
Esquema
Ejemplos
Funcionamiento

xternal Program Call 3

CAPÍTULO 2

Application Program Interface - API

Basicamente es un programa que recibe parámetros


específicos y ejecuta una determinada tarea en
Aplicação
Datasul EMS Framework. Esta tarea puede ser: Específica
una actualización, un programa que retorne
informaciones, ejecute un cálculo, genere un API
gráfico. Datasul
Es una interfaz abierta a las funciones de negocio EMS
del producto. framework

Efectuar la contabilización de un lote de asientos provenientes de un sistema


remoto;

Generar movimientos de inventario para un ítem o movimientos de


Material/MOB/GGF para una orden de producción;

Extraer saldos en inventario de determinados ítems;

OK / NOK
Saída
Entrada
API

Acesso Extração
de dados
Datasul-EMS
Documentación
Tipos

A partir de la llamada de una API y entrada de los debidos parámetros o de


datos para una actualización, pueden ocurrir tres situaciones:

 la API puede hacer un acceso al producto Datasul EMS Framework, y


recibir una respuesta que pueden ser datos leídos de la base o el resultado
de alguna función, este es repasado al programa llamador.
 la API puede hacer una extracción de datos, generando un gráfico, reporte
o consulta.
 la API puede efectuar una función, por ejemplo de eliminación de datos y
retornar si la ejecución fue correcta “OK” o incorrecta “NOK”.
Convencional - ejecuta la API pasando parámetros y obteniendo resultados.
con Métodos – refiérese a la API y dispara sus métodos (procedures internas o
funciones).

Toda API creada por Datasul tiene un estándar que está documentado y a partir
de él que son creadas cualesquiera APIs;
Los componentes pueden ser:
 Objetivo: Lo que va a ser generado por API, cuando debe ser utilizada,
para que función;
 Los parámetros de entrada y salida también tienen su definición, lo que
deben pasar para la API y lo que pueden retornar;
 En caso de ocurrencia de error, cuales mensajes de error pueden ser
retornados al programa llamador;
 Las documentaciones de APIs están en el directorio docapi, con el nombre
de la api más la extensión .doc;
--- Ejemplo

 Son pasados como parámetros para la API los atributos y datos


para montaje del gráfico y es devuelta una temp-table con los
posibles errores.
 La include {UTP/UTAPI001.I} contienen las definiciones de las
temp-tables y esa debe ser incluida en el programa generador de
gráficos.
 La exhibición del gráfico es hecha a través de la ejecución de API,
UTP/UTAPI001.P;
 Ejemplo:

API para Generación de Gráficos (v.003)


Ventajas

xternal Program Call 5

Nombre Físico: utp\utapi001.p


Nombre de Include con la definición de los Parámetros: utp\utapi001.i
Versión de Integración: 003
Objetivo: Creación de gráficos.

Parámetros de Entrada:
Temp-table tt-atributos:
En Temp-Table tt-atributos son definidas las características generales de
presentación del gráfico.

 Las APIs poseen parámetros de entrada bien definidos y procesos que son
ejecutados de manera correcta sobre el producto;
 Las APIs son bien documentadas y ejecutan tareas de acuerdo al objetivo,
funcionando para sus usuarios como una caja negra, o sea, estos no
necesitan saber de que forma el proceso es ejecutado, sólo que, siendo
realizadas las entradas correctas, la API ejecuta el proceso esperado de
manera transparente;
 Las integraciones entre módulos del producto Datasul EMS Framework
son realizadas a través de las APIs, por eso este es el camino natural para
que personalizadores integren otras soluciones con el producto;
 La tecnología empleada y las reglas de negocio de una API pueden evoluir
haciendo con que el cliente usufrua de estos beneficios sin la necesidad de
reescribir1 sus programas;

Por eso, lo que las APIs proveen es una facilidad más grande, rapidez y
productividad en el desarrollo de personalizaciones;

1
Cuando haya alguna modificación de la interfaz de la API, esta verifica si el
programa llamador está de acuerdo a la nueva interfaz, en caso negativo, es emitido un
mensaje informando que el programa debe ser revisado.
Objetivos
Definición

External Program Call

Son llamadas a programas


desarrollados por el usuario, en puntos
predefinidos del producto, posibilitando Aplicação
su adaptación e integración con otras
aplicaciones. Específica
Constituyense en un
perfeccionamiento de las “Salidas X”
existentes en el producto MAGNUS I.00, UPC API
pues los puntos de llamada están
vinculados a eventos de la interfaz con el
usuario, eventos de la base de datos Datasul
(grabación y eliminación de registros) o
en puntos estratégicos en programas de EMS
actualización y cálculo.
Basicamente, una integración más
framework
grande es posibilitada porque a través de
las EPCs se puede interactuar con la interfaz del producto, con la lógica de
aplicación y con los eventos de diccionario de datos.
Con excepción del último tipo de llamada (puntos estratégicos) las demás
llamadas no necesitan ser solicitadas a Datasul, pues ya están disponibles en el
producto. Además las llamadas en eventos de la base de datos reducen la
necesidad de llamadas en programas de actualización.

 posibilitar la personalización e integración del producto Datasul-EMS por


los usuarios, respectivamente, de una forma estandarizada y controlada;
 posibilitar ubicaciones de Datasul-EMS que no deben ser incorporadas al
producto estándar por la propia Datasul;
 posibilitar al usuario la administración de sus personalizaciones,
identificando a través de Datasul-EMS, cuales programas y tablas del
producto poseen personalización;
 posibilitar la administración de integraciones desarrolladas por usuarios de
Datasul sobre el producto Datasul-EMS;
Tipos de EPCs

xternal Program Call 7

 Personalización
Clientes - Necesidades específicas y especialistas
User Program Call - UPC
 Integración
Socios - Integraciones con otros softwares
Application Partner Program Call – APPC
 UPC + APPC = EPC

EPCs en Interfaz de A través de procedimiento de Mantenimiento de Programas de Datasul-


Programas EMS (men/men012aa.w), módulo Menú, el usuario puede determinar el
camino y el nombre físico del programa a ser llamado en las UPCs de un
determinado programa del producto. De acuerdo a la pantalla a seguir:

Ejemplo :
 Alterar las características de las pantallas: labels, formatos, colores,
posicionamiento, tabulación.
 Implementar nuevos campos, nuevos botones con llamada para
subprogramas.

Parámetros
Tanto el programa UPC cuanto el programa APPC reciben los siguientes
parámetros:
Parámetro I/O Tipo de Dato Contenido
p-ind-event Input Character Indicador de Evento
p-ind-object Input Character Indicador de Objeto
p-wgh-object Input Handle Handle de objeto corriente
p-wgh-frame Input Widget-handle Handle de frame corriente
p-cod-table Input Character Nombre de tabla corriente
p-row-table Input Rowid Rowid de registro corriente de tabla

Puede retornar al programa que lo llamó, a través del recurso RETURN-


VALUE, el valor ‘NOK’ indicando que el evento que disparó el programa
EPC no debe ser aplicado, esto viabiliza, por ejemplo, validaciones del usuario
a ser ejecutadas en el evento VALIDATE, que si encuentran problemas, puede
evitar la confirmación de la pantalla, y consecuentemente la actualización de
registros.
Dica: Para saber los eventos que están llamando la EPC y el valor de los
parámetros en el momento de la llamada, se puede hacer un programa EPC
como el del ejemplo 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.

Puntos de Llamada en Smart


Los puntos de llamada quedan unidos a eventos de la interfaz, estos
eventos no representan necesariamente eventos Progress, pero sí puntos,
llamados de ‘ADM-Events’, dentro de la estructura de SmartObjects.

 para SmartViewers existen llamadas EPC en los siguientes eventos:

Evento SRC Local–Estructura UIB Include Trata Retorno?


BEFORE-INITIALIZE Smart.i Adm-initialize include/i-epc018.i No
INITIALIZE Smart.i Adm-initialize include/i-epc001.i No
BEFORE-DISPLAY Record.i Adm-display-fields include/i-epc023.i No
DISPLAY Record.i Adm-display-fields include/i-epc006.i No
ENABLE Tableio.i Adm-enable-fields include/i-epc004.i No
xternal Program Call 9

AFTER-ENABLE Tableio.i Adm-enable-fields include/i-epc021.i No


DISABLE Tableio.i Adm-disable-fields include/i-epc005.i No
AFTER-DISABLE Tableio.i Adm-disable-fields include/i-epc022.i No
BEFORE-ADD Tableio.i Adm-add-record include/i-epc028.i No
ADD Tableio.i Adm-add-record include/i-epc011.i No
UNDO Tableio.i Adm-reset-record include/i-epc012.i No
AFTER-UNDO Tableio.i Adm-reset-record include/i-epc029.i No
CANCEL Tableio.i Adm-cancel-record include/i-epc013.i No
AFTER-CANCEL Tableio.i Adm-cancel-record include/i-epc030.i No
VALIDATE Tableio.i Adm-assign-record include/i-epc002.i Sí
AFTER-VALIDATE Tableio.i Adm-assign-statement include/i-epc019.i Sí
BEFORE-ASSIGN Tableio.i Adm-assign-statement include/i-epc020.i Sí
ASSIGN Tableio.i Adm-assign-statement include/i-epc003.i Sí
END-UPDATE Tableio.i Adm-end-update include/i-epc010.i No
AFTER-END-UPDATE Tableio.i Adm-end-update include/i-epc027.i No
DELETE Tableio.i Adm-delete-record include/i-epc015.i Sí
AFTER-DELETE Tableio.i Adm-delete-record include/i-epc032.i Si

 para SmartBrowsers debe haber llamadas EPC en los siguientes eventos:

Evento SRC Local Include Trata Retorno?


VALUE-CHANGED Brschnge.i value-changed include/i-epc016.i No
AFTER-VALUE-CHANGED Brschnge.i value-changed include/i-epc033.i No
BEFORE-INITIALIZE Smart.i adm-initialize Include/i-epc034.i No
INITIALIZE Smart.i adm-initialize Include/i-epc017.i No
BEFORE-OPEN-QUERY Record.i adm-open-query Include/i-epc035.i No
AFTER-OPEN-QUERY Record.i adm-open-query Include/i-epc036.i No

 para Containers debe haber llamadas EPC en los siguientes eventos:

Evento SRC Local Include Trata


Retorno ?
BEFORE-INITIALIZE smart.i adm-initialize Include/i-epc024.i No
INITIALIZE smart.i adm-initialize Include/i-epc007.i No
BEFORE-ENABLE smart.i adm-enable Include/i-epc025.i No
ENABLE smart.i adm-enable Include/i-epc008.i No
BEFORE-DISABLE smart.i adm-disable Include/i-epc026.i No
DISABLE smart.i adm-disable Include/i-epc009.i No
CHANGE-PAGE Containr.i adm-change-page Include/i-epc014.i No
AFTER-CHANGE-PAGE Containr.i adm-change-page Include/i-epc031.i No
DESTROY smart.i adm-destroy include/i-epc100.i No

Observación: En el caso del container ser una ventaja de reporte, este sólo
presenta llamada para epc en los eventos change-page, before-initialize,
before-enable, enable e initialize.

 En el caso de EMS 5, los puntos de llamada están en los siguientes


eventos:

Evento Local Trata Retorno?


INITIALIZE Después de view de frame No
DISPLAY Después de display de frame No
ENABLE Después de enable de frame No
VALIDATE Después de llamada de pi de Sí
validación
Ejemplos

ASSIGN Después de pi de assign de campos Sí


BEFORE_DELETE Antes de eliminar registro Sí
AFTER_DELETE Después de eliminar el registro Si

Crear un botón nuevo en una window para llamar un subprograma a partir de este;
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.


def var c-objeto as char no-undo.

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 frame = p-wgh-frame
width = 4
height = 1.25
row = 1.26
label = "prueba"
col = 65
sensitive = yes
visible = yes
triggers:
ON CHOOSE PERSISTENT RUN
upc/testeupc1.p.
end triggers.
end.

Obs: El evento usado para el botón creado debe necesariamente llamar


un subprograma con persistent run y en caso de parámetros, usan
variables globales.

Crear un widget nuevo en una 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 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 var c-objeto as char no-undo.
xternal Program Call 11

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 button wh-button
assign frame = p-wgh-frame
width = 18
height = 1
label = "Asistencia 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 = "x(20)"
width = 12
height = 0.88
row = 2.7
col = 71
bgcolor = 1
fgcolor = 15
label = "Perfil Marketing:"
visible = yes
sensitive = 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 el handle de un 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. /* buscando
Field-Group */
ASSIGN h_Frame = h_Frame:FIRST-CHILD. /* buscando 1º
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 el nombre de un campo en una pantalla se


puede usar el comando <Ctrl-Alt-4> sobre el campo deseado. Este
comando retorna el nombre del campo y de la tabla a la que él
pertenece.
Accesar el valor de un widget;
Después de encontrar el handle del campo deseado, usando la lógica
del ítem III, haga lo siguiente:
xternal Program Call 13

assign c-valor = h-campo:screen-value.

Obs.: Recuerde que, si la variable o campo de tabla que va a recibir el


valor del widget no es del tipo character, el valor de screen-value debe
ser transformado para este tipo, pues screen-value del campo siempre
es character.

Alterar el valor de un widget;

Después de encontrar el handle del campo deseado, usando la lógica


del ítem III, haga lo siguiente:
assign h-campo:screen-value = “Nuevo Valor”.

Recuerde que mismo para campos no character, se debe usar “


”(comillas), pues el valor de screen-value es siempre character.

Ocultar un widget en una viewer;

Después de encontrar el handle del campo deseado, usando la lógica


del ítem III, haga lo siguiente:

assign h-campo:visible = no.

Crear una 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.
/* 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).
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 "nombre externo


de la nueva viewer ":U, /* Nombre de 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 /* Vd. debe


verificar si es la 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 /*


Vd. debe verificar si es la viewer principal */
not l-group-assign then do:
assign l-group-assign = yes.

RUN add-link IN adm-broker-hdl (INPUT h-object,


INPUT "Group-
Assign":U,
INPUT h-viewer).
xternal Program Call 15

end.
end.

RUN dispatch IN h-viewer ("initialize":U).

RUN select-page IN p-wgh-object (INPUT 1).


end.
end.

Llamar el zoom para un campo creado 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.

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
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"
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 el programa de zoom, que va a llamar un zoom construido en el


estándar de EMS 2.0, se debe hacer lo siguiente:
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}

Puntos de Llamada en ThinTemplate

Los puntos de llamada quedan vinculados a eventos de la interfaz, estos


eventos no representan necesariamente eventos Progress, pero sí puntos
estratégicos, dentro de la estructura de ThinTemplate. La llamada de EPC es
hecha por intermedio de la include method/svc/custom/custom.i, y ninguna de
las llamadas de EPC en interfaz trata retorno de error.

 para ThinMaintenance hay llamadas EPC en los siguientes eventos:

Evento Método Estándar


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
xternal Program Call 17

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 existen llamadas EPC en los


siguientes eventos:

Evento Método Estándar


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
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 existen llamadas EPC en los siguientes eventos:

Evento Método Estándar


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 existen llamadas EPC en los siguientes eventos:


Evento Método Estándar
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 existen llamadas EPC en los siguientes


eventos:

Evento Método Estándar


BEFORE-DESTROY-INTERFACE DESTROYINTERFACE
AFTER-DESTROY-INTERFACE DESTROYINTERFACE
BEFORE-DISPLAY DISPLAYFIELDS
AFTER-DISPLAY DISPLAYFIELDS
BEFORE-INITIALIZE INITIALIZEINTERFACE
AFTER-INITIALIZE INITIALIZEINTERFACE

 para ThinReport existen llamadas EPC en los siguientes eventos:

Evento Método Estándar


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 existen llamadas EPC en los siguientes eventos:

Evento Método Estándar


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 existen llamadas EPC en los siguientes eventos:

Evento Método Estándar


BEFORE-VALUE-CHANGED APPLYVALUECHANGED
AFTER-VALUE-CHANGED APPLYVALUECHANGED
BEFORE-DESTROY-INTERFACE DESTROYINTERFACE
xternal Program Call 19

AFTER-DESTROY-INTERFACE DESTROYINTERFACE
BEFORE-INITIALIZE INITIALIZEINTERFACE
AFTER-INITIALIZE INITIALIZEINTERFACE
BEFORE-CHANGE-PAGE CHANGEPAGE
AFTER-CHANGE-PAGE CHANGEPAGE

Ejemplos Crear un widget nuevo en una 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.

IF p-ind-event = "AFTER-INITIALIZE" THEN DO:

CREATE BUTTON wh-button


ASSIGN FRAME = p-wgh-frame
WIDTH = 15
HEIGHT = 1
LABEL = "PRUEBA"
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 = "Comentario:"
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 = "Comentario:"
VISIBLE = YES
SENSITIVE = NO
FONT = 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: En el evento (trigger) del botón creado se debe llamar un subprograma


con persistent run y en ese no usar parámetros, sólo variables globales.

Encontrar el handle de un 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 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-frame: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 la carpeta:
Sólo es posible habilitar la carpeta si el programa usa las páginas fPage0 y
fPage1.
def input param p-ind-event as char no-undo.
xternal Program Call 21

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.

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.
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 "Registro",
INPUT 1,
INPUT ?,
INPUT ?,
INPUT ?,
INPUT ?).
RUN setFolder IN h-folder (INPUT 1).
END.

Añadir una frame;


Sólo es posible añadir una frame cuando la carpeta esté habilitada.
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.

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.

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.

Llamar el zoom para un campo creado 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.

/*encontrar handle de la frame donde desea crear el campo*/

IF p-ind-event = "AFTER-INITIALIZE" THEN DO:

CREATE TEXT tx-label


ASSIGN FRAME = h-fPage2 /*handle da frame*/
FORMAT = "x(40)"
WIDTH = 15
SCREEN-VALUE = "Comentario:"
ROW = 2
COL = 10
VISIBLE = YES
xternal Program Call 23

FONT = 1.

CREATE FILL-IN wh-fill


ASSIGN FRAME = h-fPage2
SIDE-LABEL-HANDLE = tx-label:HANDLE
FORMAT = "x(20)"
NAME = "comentario"
WIDTH = 40
HEIGHT = 0.88
ROW = 1.7
COL = 18.5
LABEL = "Comentario:"
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).
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 el programa de zoom, que va a llamar un zoom construido en el estándar


ThinTemplate, se debe hacer lo siguiente:
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 corriente/actualizar registro de una 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.

{spbo/bosp001.i tt-Customer}

DEF VAR h-objeto AS HANDLE NO-UNDO.


DEF VAR c-comments AS CHAR NO-UNDO.

/*encontrar el handle de la frame donde desea crear el campo*/

IF p-ind-event = "AFTER-INITIALIZE" THEN DO:

CREATE TEXT tx-label


ASSIGN FRAME = h-fPage1 /*handle de la frame*/
FORMAT = "x(40)"
WIDTH = 15
SCREEN-VALUE = "Comentario:"
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 = "Comentario:"
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.
Ejemplos

xternal Program Call 25

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.

Puntos de Llamada en DBO

La llamada de la EPC es hecha por intermedio de la include


method/dboupd.i. Todas las llamadas de EPC en DBO tratan retorno de error.
En la EPC de DBO es posible ejecutar todos los métodos disponibles en
la DBO, pues el parámetro pasado es el handle de DBO.

 para las DBOs existen llamadas EPC en los siguientes eventos:

Evento Método Estándar


BeforeCreateRecord CREATERECORD
AfterCreateRecord CREATERECORD
BeforeDeleteRecord DELETERECORD
AfterDeleteRecord DELETERECORD
BeforeUpdateRecord UPDATERECORD
AfterUpdateRecord UPDATERECORD

Actualizar campo(s) de un registro vía EPC de DBO;

{include/i-epc200.i} /*Definición tt-EPC*/


{spbo/bosp001.i tt-Customer} /*Definición 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 = "Calle sin nombre".

RUN setRecord IN h-bo (INPUT TABLE tt-customer).


END.
END.

Validar campo(s) de un registro vía EPC de DBO (Generación de error);


{include/i-epc200.i} /*Definición tt-EPC*/
{spbo/bosp001.i tt-Customer} /*Definición 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"
tt-epc.cod-parameter = "EPC-ERROR"
tt-epc.val-parameter = "El campo comentario debe
ser llenado.".
END.
END.
END.
xternal Program Call 27

EPCs en Gatillos de Diccionarios de Datos


External Program Calls están disponibles en gatillos (triggers) de diccionario
de datos, en los gatillos de WRITE (grabación) y DELETE (eliminación) de
las tablas:

EPCs en Gatillos de WRITE

Para las UPCs, a través del procedimiento de Mantenimiento de Tablas


de Datasul-EMS, módulo Básico (btb/btb006aa.w), el usuario puede
determinar el camino y el nombre físico del programa de personalización a ser
ejecutado en el gatillo de WRITE de una determinada tabla del producto.
(tabla: ‘tab_dic_dtsul’ atributo: ‘nom_prog_upc_gat_write’).

Para las APPCs, también en la tabla ‘tab_dic_dtsul’, el usuario puede


determinar el camino y el nombre físico del programa de integración a ser
ejecutado en el gatillo de WRITE a través del atributo
‘nom_prog_appc_gat_write’.

Punto de Llamada

Evento Local Include Trata Retorno?


WRITE final de gatillo include/i-epc101.i Sí

Parámetros

Parámetro I/O Tipo de Dato Contenido


p-table buffer buffer de registro Buffer de registro después de alteraciones
p-old-table buffer buffer de registro Buffer de registro antes de alteraciones

Puede retornar al gatillo que lo llamó, a través del recurso RETURN-


VALUE, el valor ‘NOK’ indicando que el evento no debe ser aplicado,
retornando el error al programa que disparó el gatillo. Así, es posible a través
EPCs en Gatillos de
DELETE

de una EPC, evitar que un registro de una determinada tabla sea actualizado, e
interrumpir un procesamiento.

A través del procedimiento de Mantenimiento de Tablas del Banco de


Datos, módulo Básico, el usuario puede determinar el camino y el nombre
físico del programa a ser llamado en la UPC de los gatillos de DELETE de una
determinada tabla del producto. (tabla: tab_dic_dtsul
atributo:nom_prog_upc_gat_delete), vea el ejemplo:

Para las APPCs el atributo ‘nom_prog_appc_gat_delete’ en la tabla de


‘tab_dic_dtsul’ debe determinar el camino y el nombre físico del programa a
ser llamado en la APPC de los gatillos de DELETE de una determinada tabla
del producto.

Punto de Llamada

Evento Local Include Trata Retorno?


DELETE después validaciones y include/i-epc102.i Sí
antes de eliminación en cascada

Parámetros

Parámetro I/O Tipo de Dato Contenido


p-table Buffer buffer de registro Buffer de registro que será eliminado

Puede retornar al gatillo de DELETE que lo llamó, a través del recurso


RETURN-VALUE, el valor ‘NOK’ indicando que el evento no debe ser
aplicado, retornando error al programa que disparó el gatillo. Así, es posible a
través de una EPC, evitar que un registro de una determinada tabla sea
eliminado, pues posee relaciones con otros desarrollos específicos, por
ejemplo.
Sugestión:

xternal Program Call 29

EPCs en Puntos Estratégicos de Programas


Hay situaciones para personalizaciones e integraciones que no pueden
ser resolvidas a través de EPCs en interfaz de programas o en gatillos de
diccionario de datos, entonces son implementadas llamadas EPCs en puntos
estratégicos dentro de la lógica de estos programas de Datasul EMS
Framework.
Este tipo de EPC sólo puede ser implementada en programas que no
poseen interfaz con el usuario, cuando no hay forma de contornar la necesidad
con el uso de EPCs de diccionario de datos.
De la misma forma que para las EPCs de interfaz de programas, el
usuario debe definir el nombre y el camino del programa EPC a ser ejecutado
a través de los atributos ‘nom_prog_upc’ y ‘nom_prog_appc’ respectivamente
para UPC y APPC. Así para viabilizar una EPC, por ejemplo en el programa
de cálculo del precio medio (cep/ce0401rp.p), el usuario debe registrar el
subprograma, donde fue implementada la llamada EPC, en la tabla de
programas ‘prog_dtsul’.

Si hay otra situación de personalización, que no sea pueda ser resolvida a


través de EPCs, se propone:
 la construcción de un sucinto programa que sea el SETUP de la
personalización para cada uno de sus clientes (si es socio). Este programa,
a principio limpiaria el contenido de los campos:
‘prog_dtsul.nom_prog_upc’ y ‘tab_dic_dtsul.nom_prog_upc’ y después
haría el registro de las personalizaciones de aquel cliente.
 aplicar el programa SETUP de determinado cliente en la base siempre que
se ejecute una prueba con el ambiente de aquel cliente.

Parámetros

Parámetro I/O Tipo de Dato Contenido


p-ind-event Input Character indicador de evento
tt-epc i-o temp-table temporary table con tres atributos:
 cod-event (character) – indicador de evento,
siempre el mismo valor que p-ind-event;
 cod-parameter (character) – código de parámetro
indicando lo que significa el valor del parámetro;
 val-parameter (character) – valor de parámetro.

Los valores de los parámetros ‘p-ind-event’, ‘tt-epc.cod-event’ y ‘tt-


epc.cod-parameter’ son definidos en inglés y sin espacios en blanco entre las
palabras, replazando los espacios en blanco por el caracter trazo (-), pues el
producto es internacional y el idioma inglés es mundialmente aceptado.
Cualquier uno de los tipos de EPC puede retornar al programa llamador,
a través del recurso RETURN-VALUE, el valor ‘NOK’ indicando que el
procesamiento será interrumpido/cancelado para aquella interacción, o aún
tenga otro efecto definido sobre el programa llamador.

Ejemplo:
 en la fuente de un programa sin interfaz del producto EMS 2.0, la
llamada EPC podría ser implementada de la siguiente forma:

/* Include i-epc200.i: Definición Temp-Table tt-epc y de


los 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: Creación de registro para Temp-


Table tt-epc */
{include/i-epc200.i2 &CodEvent='"Single-Point"'
&CodParameter='"item.it-codigo"'
&ValueParameter="item.it-codigo"}

/* Include i-epc200.i2: Creación de registro para Temp-


Table tt-epc */
{include/i-epc200.i2 &CodEvent='"Single-Point"'
&CodParameter='"item rowid"'
&ValueParameter="string(rowid(item))"}

/* Include i-epc201.i: Llamada del programa de EPC */


{include/i-epc201.i "Single-Point"}

if return-value = "NOK" then


/* Ejemplo de tratamiento de retorno */
undo, leave.
end.

 Ya el programa de personalización/integración tendría el siguiente


tratamiento como base del siguiente código fuente:
/* Include i-epc200.i: Definición 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:

/* Ejemplo de uso de parámetros */


disp tt-epc.
end.
xternal Program Call 31

Ubicación de Programas Específicos


Objetivo
Especificar la ubicación para almacenaje de programas personalizados
por terceros.

Implementación
Esta ubicación debe ser hecha a partir de un directorio raíz que debe
tener el nombre de la empresa que desarrolló el programa específico. Los
directorios de los módulos y los nombres de los programas pueden tener el
mismo nombre de programas Datasul.
La diferencia queda en la llamada de estos programas, o sea, para
ejecutar un programa específico y sus subprogramas e includes, se debe
identificar en su llamada, el nombre del directorio específico, identificando así,
estos programas como no Datasul.
Este directorio raíz no debe estar bajo el directorio del producto, o sea,
no debe ser incluido en el directorio del producto Datasul instalado y, sí, en un
directorio de instalación propio.
En el registro de estos programas en el menú, se debe tener el nombre
de la empresa que creó el específico, además del nombre del programa como
la clave de identificación. Aún en el registro de programas, será necesario
poner el nombre de la empresa que construyó el específico antes del
<directorio>/<programa> deseado como nombre externo.
Para finalizar, el PROPATH debe contener siempre el directorio del
producto Datasul en primer lugar, o sea, antes del directorio donde están los
específicos. Para encontrar los programas del específico, basta añadir al
PROPATH, el directorio anterior al nombre de la empresa que desarrolló el
específico, después del directorio del producto Datasul.

Ejemplo
Si la empresa XYZ desarrolla programas para el módulo APP, la
ubicación de los programas específicos desarrollados deben quedar en:
C:\EMS20POR\...
C:\<directorio>\XYZ\APP\AP0101.W

Para ejecutar programas Datasul, haga:


RUN APP\AP0101.W

Para registrar el programa en el menú, haga:


Programa : XYZ/AP0101
Nombre externo: XYZ/APP/AP0101.W

Para registrar una UPC, haga:


Programa : XYZ/APP/AP0101.P

PROPATH queda:

PROPATH = "c:\<datasul>;c:\<directorio>;..."
Obs: Directorio XYZ está abajo de c:\<directorio>

Consideraciones Generales

A partir del momento en que una EPC es registrada para un programa o gatillo,
siempre que es ejecutado este programa o gatillo es hecha la llamada para la
EPC.
Siendo así, si la EPC está registrada de forma incorrecta o no existe, va a ser
generado un error Progress, (<programa> was not found (293)).
 en los programas llamados por las EPCs, en gatillos de diccionario de
datos, no debe ser solicitado cualquier interacción del usuario, o
presentado cualquier tipo de pantalla (frame) o caja de mensaje;
 debe ser hecho aún una documentación de como construir los programas
EPC, además de lo descrito arriba, y acompañar la documentación del
producto para los usuarios.
 Desaconsejamos que sean retirados cualesquiera objetos (browser, viewer)
de un programa de Datasul EMS usando EPCs.
 Se debe tomar cuidado con eventos para objetos del producto Datasul
EMS Framework, cuando se desea crear un nuevo evento para uno de
estos objetos, se debe contactar el módulo, pues se puede estar
sobreponiendo un evento que es importante para el producto.

Llamar una EPC de una 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.
xternal Program Call 33

Llamar una EPC de una 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 corregir TAB-ORDER en una EPC

Para ajustar tab-order en una DPC, se puede hacer de siguiente forma:

Por ejemplo, imagine la siguiente frame:

A: [ ]
B: [ ]
C: [ ]

Un programa de personalización debe insertar el fill-in D, que está al


lado de A. Por eso, cuando se presione TAB en el fill-in A, él deberá
posicionarse en el fill-in D.

varD:MOVE-AFTER-TAB-ITEM(varA:HANDLE).

También existe el método para mover el fill-in anterior en este caso:

varD:MOVE-BEFORE-TAB-ITEM(varA:HANDLE).

También podría gustarte