Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Herramienta de desarrollo de aplicaciones Cliente – Servidor para ambiente Windows, posee muchas áreas de
trabajo para el desarrollo de los objetos o elementos que conforman una aplicación, cada objeto que se crea en
la aplicación o proyecto generalmente debe estar guardado en un archivo de librería o biblioteca(*.pbl) donde
será almacenado para su utilización.
Se pueden tener abierta múltiples áreas de desarrollo, pudiendo cambiarse de una a otra a través del menú
Windows, donde aparece con una marca el área donde está actualmente y el elemento en el que se está
trabajando.
OBJETOS
1. Ventana, la cual puede tener controles (botones, datawindows etc) y estos tiene propiedades como
Name, text, si es visible o no etc. para encontrarlas hacemos doble click sobre el control. El control
puede tener asociados diferentes comportamientos que encontramos haciendo clic derecho y luego
clic en Script, aquí encontramos diferentes eventos que podemos programar por ejemplo que hacer si
dan clic sobre el control, o si lo abrimos o lo cerramos los eventos son diferentes según el control,
por ejemplo un botón tiene el evento clic, una ventana tiene el evento abrir o cerrar, un datawindow
tiene el evento itemchanged o updatestart (este se usa en caso de validaciones en el ingreso de datos)
2. DataWindow, se asocia a un control de dw y se crea en otro lado. Para crear el objeto hay varias
maneras:
c. Si lo vamos a crear, en la barra menú está un icono para DW y clic en el botón New
Estando en el objeto, en el modo diseño, vemos la gráfica y en data source vemos sql fuente, el sql
puede ser gráfico, pero no todo se puede graficar por lo tanto lo utilizamos poco.
Para pasar de un modo a otro, clic sobe el icono sql en la barra de iconos.
Estando en modo fuente para definir los argumentos que necesitamos en el dw object, clic en Design
de la barra menú, Retrival Argument. Cuando lo estamos definiendo le dmos un nombre y un tipo.
Este argumento definido se usa en el sql fuente asi :nombreargumento.
Cuando estamos haciendo el sql fuente y queremos probar que no tiene errores:
Nombre:
Documento:
Dirección:
Teléfono:
f. Group: Casi no se utiliza, permite hacer filas de agrupación por ejemplo en un listado
de facturas podría agruparse por empresa y mostrar el total de factura por empresa.
h. N-up: Parecido al grip pero se repite en la misma hoja la información por ejemplo:
Factura Fecha Valor Factura Fecha Valor
i. OLE 2.0: Object Linking and Embedding, por ejemplo, cuando en un campo de una
tabla guardamos un texto de Word, estos campos se definen como binario pero tienen el
inconveniente de ser muy grandes.
5. Luego seleccionamos la tabla y nos muestra la tabla y seleccionamos los campos que queremos
que aparezcan, en la barra menú seleccionamos la opción Design y luego Convert to syntax.
- Consulta de Librerías: como sabemos cómo inicia el nombre de nuestro objeto a buscar
clic en la primera fila de entrada y escribimos: like w_aa_% y clic en Consultar
EJERCICIO
4. Si elimine o agregue argumentos o parámetros clic en Design en la barra menú y luego Retrieval
Arguments
6. Clic en guardar
INTRODUCCION
SQLCA
Message
Una función.
HERENCIA.
Lo mejor son solo dos niveles de herencia, no se recomienda cambiar el nombre de los controles en los hijos.
AMBIENTE DE DESARROLLO
SQLCA:
sqlca.dbms= ODBC
Sqlca.dbparm=
a. 0 ok y encontré
c. número negativos que son los errores. Este número depende la BD a la que estemos
conectados son diferente si es Oracle o sybase etc.
Message:
Al abrir una nueva ventana, podemos enviar parámetros por ej.: registro = Message.SringParm, si se necesita
enviar más de un parámetro se concatenan separados por un + y así en la nueva ventana se pueden separar.
a.i.2. ObjectParm
a.i.3. LongParm
Si tenemos la ventana w_1 que llama a la ventana w_2 y vamos a pasar parámetros lo hacemos asi
OpenwithParm(w_2,parámetro) y en la w_2 en el evento Open traemos el parámetro asi registro =
Message.StringParm.
Si necesitamos pasar más de un parámetro debemos hacerlo concatenando y separando con el signo +
Si necesitamos pasar registro y concepto parámetro = registro+ ‘+’+concepto y en el evento Open usamos la
función
f_decifra_parametros(arreglo,nroparametros)
Arreglo(1) el nro del registro
Arreglo(2) el concepto
Nro_parametros = 2
SCRIPTS
1. Instrucciones PB
2. Funciones:
a. mid(string,start (,length)) Retorna una cadena que contiene un número especificado de
caracteres, comenzando de una posición indicada.
3. Sentencias SQL, cuando se necesita invocar una variable se debe colocar :nombrevariable
TIPS:
Y para desconctarnos
Disconnet;
Si usamos otra BD se debe definir otro objeto de transacción por ejemplo sqlca1.
Cuando se usa en dw se hace asi: dw_1.Settransobject(sqlca) y desde SQL sería asi: Select nombre into
:nombre from no_empleado where cedula = :cedula (using sqlca ) lo hace por defecto.
Cuando se programa para la web se debe conectar y desconectar en cada ventana, algo similar debió
progamarse en la aplicación módulo de historia clínica para reconectarse porque Postgres detecta
inactividad y mata el proceso automáticamente.
Muchas veces se requiere hacer una w o un dw similar a otro ya hecho, para esto debemos abrir el
objeto y por la opción File de la barra del menú y luego Save as, colocar el nombre adecuado y
guardar en la librería que corresponda.
Cuando en una ventana tenemos un dw pero se debe ejecutar un select diferente según la opción que escojan
hay dos soluciones posibles:
1. Elaborar dos dw y en cada uno correr el select correspondiente Ej: Where concepto = ‘LABO’ o
Where concepto in ( ‘RMAG, ‘IMAG’). Es más fácil de hacer.
if rb_sin_servicios.checked=true then
dw_1.DataObject='d_factura_pagos_glosas_sin_serv_imp'
else
dw_1.DataObject='d_factura_pagos_glosas_imp'
end If
dw_1.SetTransObject(sqlca)
2. Cambiar la sintaxis del SQL en el botón Consultar. Es más fácil de mantener. Ver ejemplo en la
librería AUDITOR2 ventana w_facturas_pagos_glosas_imp.
if rb_todas.checked=true then
instruccion_sql= dw_1.GetSQLSelect()
select replace(:instruccion_sql,'( factura.saldo > 0 ) and ',' ') into
:instruccion_sql_nueva from parametro;
if sqlca.sqlcode <> 0 then
Messagebox('Error','En replace de factura.saldo > 0 '+sqlca.sqlerrtext)
Return
End If
dw_1.Object.DataWindow.Table.Select=instruccion_sql_nueva
En el evento OPEN se debe colocar dw_1.SetTransObject(Sqlca) y siempre que se hace un DataObject hay
que hacer un SetTransObject
OBJETO APLICACIÓN: Los eventos más usados son Open y Close. Nuestro objeto aplicación que se
llama Clínica o sihos, está ubicado en la librería Ventana.
USER OBJECTS: Sirve para reutilizar código por ejemplo un dw que contiene varios controles como
botones para Insertar, Guardar y Salir
FUNCIONES: Reusabilidad del código. Cuando un código es muy extenso se puede agrupar una parte en una
función y así se puede entender mejor. Pueden devolver o no un valor mediante la instrucción Return()
VENTANAS: Las ventanas pueden ser de deferentes tipos, por ejemplos las PopUp queda abierta y se puede
continuar con la que la abrió. Main, MDI, Respuesta.
Eventos de las ventanas: Open, Close, Activate (cuando está activa), rbottondown (si le dan clic derecho)
CONTROLES: Los mas usados son los datawindows dw, Commandbutton, singleLineEdit, EditMask,
StaticText, Radiobutton.
Los controles tienen Propiedades como nombre, tamaño, posición, letra ect y Eventos como Click, doble
click, click derecho y son diferentes según el control. Uno de los mas usados en el dw es itemchanged y un
SingleLinedit es Modify.
Algunos dw se usan solo para procesos y no los debe ver el usuario por esto se les inactiva la propiedad
Visible
Para poder verlos en la barra menú vamos a la opción Design / Option / Show Invisible
En el control CommandButton se puede activar la propiedad Default o Cancel que se activarían con las teclas
ENTER o ESC respectivamente.
En programación es posible tomar o modificar las propiedades de los controles por ejemplo, cb_1.visible =
true
Normalmente no le cambiamos el nombre a los controles pero si los vamos a manipular en la programación lo
hacemos para que se pueda entender el código. Por ejemplo sl_1 es un texto que se necesita en la
programación le cambiamos el nombre por sl_nombre y así es entendible y en el código quedaría
nombre = sl_nombre.text
Estándares de los DW
Capturas de pantalla debe ser Freeform, las etiquetas van sin borde, los campos de captura color blanco y
borde 3d lowered, el fondo de la ventana debe ser Silver y donde se presenta información por ejemplo un
título debe ser sin borde, color silver y tab order 0.
Cuando se modifica un DW y se van a agregar campos no se mantienen ciertos valores default y hay que
corregirlos.
Los campos que se adicionaron en la parte de diseño quedan con TAB ORDER en 0 y esto hace que no se
puedan modificar así que siempre hay que modificar los TAB ORDER.
Cuando el texto de la ventana se puede imprimir en las propiedades Position del control hay que seleccionar
Autosize Height y en Slide UP Directly Above
Cuando se va a hacer mantenimiento de una tabla que tiene pocos registros y pocas columnas
Insertar
Modificar
Borrar
Actualizar
Salir
Cuando tiene muchos registros y muchos campos se crea un botón Construir Consulta y otro Reiniciar
Consulta y el botón Adicionar abre una nueva ventana donde se llenan los campos.
Construir consulta
Reiniciar consulta
POWERSCRIPT
Tipos de datos:
Blod: binarios
Boolean: true o false
Char: un solo carácter
Date o DateTime
Etc.
Recomendaciones: Usar Double y no Real, Usar Long en vez de Int
Variables
Para definir una variable
Tipodato Variable1, variable2=0
Es posible darle un valor inicial cuando se define la variable. Por defecto el valor de los datos numéricos es 0
y para los booleanos es False
Instancia: Se pueden utilizar en cualquier script de los objetos de una ventana. Para crearlas o verlas
por Declare en la barra menú y luego Instance Variables…
Globales: Se pueden utilizar en toda la aplicación. Por ejemplo Usuario, periodo o compañía.
Shared (Recordantes): Se pueden utilizar en cualquier script de los objetos de una ventana pero
tienen la particularidad que mantienen el valor. Para crearlas o verlas por Declare en la barra menú y
luego Shared Variables…
Flujos de control
If ..Then…Else…Endif
For…Next
Do Until…Loop
Do While …Loop
Cursores: Tratar de no úsalos porque son poco eficientes lo mejor es usar un dw así:
Contador = rowcount()
For i = 1 to contador
Código
Next
En el código dentro del for es posible modificar los valores del dw con la instrucción Setitem. Y para evaluar
si cambio
If dw_1.Update() = 1 then
Commit;
Else
Rollback;
Endif
NOTA: Siempre que se ejecute una instrucción SQL se debe verificar evaluando sqlcode y debemos tener en
cuenta no permitir bloqueos por ejemplo:
Select cuenta from co_cuenta where cuenta like ‘4.%’;
If sqlcode <> o
MessageBox(error….)
Rollback;
Endif
Aquí se puede presentar bloqueos mientras se muestra el mensaje y el usuario no cierra esa
ventana lo correcto es así:
Select cuenta from co_cuenta where cuenta like ‘4.%’;
If sqlcode <> o
Mensaje = sqlca.sqlErrText //se toma el mensaje de error xq al ejecutar el rollback este
cambia
Rollback;
MessageBox(…,mensaje)
Endif
Para hacer validaciones de los campos se pueden programar en los eventos de un dw:
1. ItemChanged
2. UpdateStart, ya que antes del .update mira este evento
Crear o abrir carpeta por cada mes EJ: 01 ENERO, 02 FEBRERO, 03 MARZO, ..
Dentro de la carpeta del mes, crear una carpeta con el siguiente nombre:
ACT_AAAA_MM_DD_descripcion_de_lo_que_se_hizo
Dentro de la carpeta anterior crear una carpeta por cada librería que contiene la actualización que
se realizó. En cada una se colocan los objetos que les corresponden y que se modificaron.
PUBLICAR LA ACTUALIZACION
Desde mi PC en PB, Librerias, Export del objeto(s) actualizado(s) y lo guardamos en la carpeta de la librería
dentro de la carpeta de la actualización.
Nos conectamos al PC de soporte del cliente que solicitó la actualización, para ejemplo vamos al consorcio
CNRUU.
Pasamos el objeto actualizado al pc de soporte
En PB, librerías, Import, buscamos al objeto actualizado, en el destino verificar que se elija la
librería que se actualizó. Cuando hay dos aplicaciones, debemos primero abrir la aplicacion
donde se va a hacer la actualización, luego ejecutarla, nos sale un error pero a la siguiente vez
que la ejecutemos corre ok.
Compilamos: Clic der sobre la librería y Build Runtime Library. Dice que no la puede
reconstruir porque está abierta pero no es problema
Copiamos el .pbd. Por ejemplo, como vamos a publicar en el consorcio CNRUU hay que
copiarlo en dos lugares 192.168.51.200 F:\aplicaciones\menu\icosalud\sihos y a
10.10.7.26 /var/sihosupdate/sihos con WINscp (usuario: root, password: N0N3*4K.2014)
Ejecutamos la aplicación para verificar la actualización.
TIPS DE PROGRAMACION EN PB
Dw_1.GetChild(‘tipo_activo’,dwc_tipo_activo)
Dwc_tipo_activo.SetTransObject(sqlca)
If dwc_tipo_activo.Retrieve(parametros) <=0 then
fila=dwc_tipo_activo.InsertRow(0)
dwc_tipo_activo.SetItem(fila,1,Setnull(nulo))
end if
En el event OPEN de la ventana y antes del retrieve al dw que contiene el dddw con argumento escribir el
siguiente código:
Parent.TriggerEvent(‘ue_dddw’)
Si es con parametro
Parent.Trigger Event ue_dddw(parametro)
w_control_facturacion_x_periodo_fegr_imp
w_pacientes_discapacidad_imp
Manejo de intervalos de tiempo
string intervalo
intervalo = string(nro_dias_hcl) +' days'
fecha_dt = dw_1.GetItemDatetime(1,'fecha')
select :fecha_dt - cast(:intervalo as interval) into :fecha_inicial from parametro;
En Citas
Filtro en un reporte
Contabilidad - Balance de prueba x auxiliar
W_balance_prueba_auxiliar_imp
En Auditor2 : w_factura_glosa_dinamico_imp
En el script
path = dw_1.GetItemString(fila11,'path_destino')
archivo = dw_1.GetItemString(fila11,'archivo')
f_reemplaza_caracter(path,'!','\')
path = path+'\'+archivo
long hwnd
string filname
hwnd=handle(parent)
shellexecuteA(hwnd,'open',path,'','',1)
W_tercero_abrir_agenda_mtto
select fecha_hora, duracion, fecha_hora + cast(cast(duracion as text)||' minutes' as interval) as fecha_f from
cita where tercero = '1098640933' ;
select count(*) from agenda
where tercero = '1098640933' and
fecha_hora <= '2018/07/19 6:45' and
fecha_hora + cast(cast(duracion as text)||' minutes' as interval) > '2018/07/19 6:45' and
fecha_hora < '2018/07/19 7:00' and
fecha_hora + cast(cast(duracion as text)||' minutes' as interval) >= '2018/07/19 7:00' ;
Mostrar varias filas como una sola
En la aplicación de Cali,
d_evolucion_imp.... interpretacion de resultados mostrando los resultados
SELECT examen_fisico.registro ,
examen_fisico.fecha ,
examen_fisico.variab ,
examen_fisico.valor_numerico ,
'RESULTADOS:'||chr(10)||(select text_concat(a.texto) as resultados
from
(SELECT servicio.descripcion|| ' ' ||
text_concat(RTRIM(variables_examen.nombre)
||': '|| resultado_examen.valor||' '||resultado_examen.texto ) as texto
FROM resultado_examen , variables_examen, servicio_detalle, servicio
WHERE ( resultado_examen.concepto = variables_examen.concepto )
and
( resultado_examen.servicio = variables_examen.servicio ) and
( resultado_examen.caracteristica = variables_examen.caracteristica ) and
( resultado_examen.concepto = servicio_detalle.concepto ) and
( resultado_examen.servicio = servicio_detalle.servicio ) and
( resultado_examen.numero_servicio = servicio_detalle.numero_servicio ) and
( resultado_examen.concepto = servicio.concepto ) and
( resultado_examen.servicio = servicio.servicio ) and
( resultado_examen.valor is not null AND trim(resultado_examen.valor)
<> '' ) and
( servicio_detalle.registro = :registro ) and
( servicio_detalle.ind_interpretado = 'S' ) and
( servicio_Detalle.fecha_progreso_interpretado =
:fecha )
GROUP BY servicio.descripcion
union all
SELECT servicio.descripcion|| ' ' ||rtrim(resultado_examen_texto.texto)
FROM resultado_examen_texto, servicio_detalle, servicio
WHERE ( resultado_examen_texto.concepto = servicio_detalle.concepto ) AND
( resultado_examen_texto.servicio = servicio_detalle.servicio ) AND
( resultado_examen_texto.numero_servicio =
servicio_detalle.numero_servicio ) and
( resultado_examen_texto.concepto = servicio.concepto )
and
( resultado_examen_texto.servicio = servicio.servicio ) and
( servicio_detalle.registro = :registro ) and
( servicio_detalle.ind_interpretado = 'S' ) and
( servicio_Detalle.fecha_progreso_interpretado = :fecha )
) as a)||'INTERPRETACION:'||chr(10)||examen_fisico.valor as valor ,
variab.nombre ,
variab.secuencia ,
variab.ind_numerico
as resultados
FROM examen_fisico , variab
WHERE ( examen_fisico.variab = variab.variab ) and
( examen_fisico.registro = :registro ) and
( examen_fisico.fecha = :fecha ) and
( variab.tipo = :tipo ) and
( examen_fisico.valor is not null ) and
( trim(examen_fisico.valor) <> '' ) and
( variab.ind_numerico <> 'S' ) and
( variab.ciclo_impresion = :ciclo_impresion ) and
( coalesce(variab.ind_interpreta_resultado,'N') = 'S' )
union all
SELECT examen_fisico.registro ,
examen_fisico.fecha ,
examen_fisico.variab ,
examen_fisico.valor_numerico ,
case when examen_fisico.respuesta is not null then examen_fisico.respuesta ||'. '|| examen_fisico.valor
else examen_fisico.valor end as valor,
variab.nombre ,
variab.secuencia ,
variab.ind_numerico
FROM examen_fisico , variab
WHERE ( examen_fisico.variab = variab.variab ) and
( examen_fisico.registro = :registro ) and
( examen_fisico.fecha = :fecha ) and
( variab.tipo = :tipo) and
( examen_fisico.valor is not null ) and
( trim(examen_fisico.valor) <> '' ) and
( variab.ind_numerico <> 'S' ) and
( variab.ciclo_impresion = :ciclo_impresion ) and
( coalesce(variab.ind_interpreta_resultado,'N') = 'N' )
ORDER BY 7 ASC
Problema con la rueda (wheel )del mouse
message.processed = TRUE
RETURN 1
END IF
EN el evento open
Dw_1.Object.Datawindow.Print.Preview = “yes”
array_to_string
select concepto,
where
servicio_detalle.concepto = concepto.concepto and
En este caso solo se necesita ejecutar un comando SQL cambiando el nombre del campo a crear en una tabla
case 'A'
case 'C'
case 'N'
case 'F'
case 'B'
end choose
En este caso además de ejecutar una secuencia sql cambiando el nombre del campo a traer se necesita además
recuperar el dato que devuelve....
ls_select = "Select "+nombre_campo+" from pyp_registro where registro = '"+registro+"' and fecha =
'"+string(fecha_dt)+"'"
return
end if
DECLARE micursor DYNAMIC CURSOR FOR sqlsa;
CLOSE micursor;
EN la wf_retrieve
dw_1.AcceptText()
dw_1.setcolumn(5)
texto=dw_1.Gettext()
if upper(mid(texto,1,4))<>'LIKE' then
if trim(texto) <>'' then
texto='LIKE %'+trim(UPPER(texto))+'%'
End If
End If
dw_1.SetText(texto)
COLORES
black = 0
white = 16777215
red = 255
fuchsia = 16711935
lime = 65280
yellow = 65535
blue = 16711680
aqua = 16776960
maroon = 128
purple = 8388736
green = 32768
olive = 32896
navy = 8388608
teal = 8421376
gray = 8421504
silver = 12632256
mint = 12639424
sky = 15780518
cream = 15793151
medium_gray = 10789024
Usando la funcion FIND