Power Builder

Herramientas administrativas. Manipulación de datos. POO (Programación Orientada a Objetos). Aplicaciones funcionales. Scripts

  • Enviado por: Gerardo Barquero R
  • Idioma: castellano
  • País: Costa Rica Costa Rica
  • 46 páginas

publicidad
cursos destacados
Flappy Bird en HTML5 y JS
Flappy Bird en HTML5 y JS
En esta serie vamos a ver como podemos crear nuestro propio juego al estilo de Flappy Bird, con ayuda del canvas en...
Ver más información

Tutoriales de Lenguaje C
Tutoriales de Lenguaje C
Regresando con uno de los lenguajes más potentes que existen: el tradicional C, lenguaje caracterizado por ser de uso...
Ver más información


Curso de Programación VI (Power Builder)

(Apuntes de clase y F1 de la herramienta)

ULACIT ´2000

Creado: 18 de mayo de 2000

Modificado: 9 de Julio de 2000

Introducción

El uso de esta herramienta de desarrollo de software está destinada hacia el lenguaje de manipulación (DML) en cerca de un 80%. Por lo que su interacción con motores de bases de datos es muy extensa; principalmente a través del objeto Data Windows que posteriormente se discutirá ampliamente.

Un detalle importante en relación a los S I es que, siempre que se pueda las reglas del negocio deben estar presentes en la definición de los modelos de datos, para de esta manera hacer más ágiles las modificaciones que a futuro se le tengan que hacer a los S I de la organización.

Ahora bien, con relación a los motores de bases de datos, es importante destacar que un motor puede ser accesado desde una herramienta de diseño como lo es Power Builder de dos formas:

  • Driver nativos: aquí se necesita que tanto fabricante del DBMS como el desarrolador de la herramienta se pongan en contacto para incluir en la herramienta de desarrollo los drivers nativos del Sistema Gestor. Esto tiene la ventaja que entonces al sistema gestor le serán explotadas casi el 100% de sus vondades.

  • Driver ODBC: por otra parte, si no hay contacto entre los proveedores, se puede hacer uso del sistema Gestor mediante conexiones ODBC (Open Data Base Conection -Conexiones Abiertas de Base de Datos-), la deficencia aquí es que no se aprovecha el 100% tanto de la herraimienta de desarrollo como del sistema gestor.

Nativo

DDL

Driver SQL DML

DCL

ODBC

Toda aplicación en Powel Builder está respaldada en al menos una o más librerías (.pbl). por lo que se podría afirmar que una aplicación es en realidad un conjunto de una o más librerías.Menú inicial de la Herramienta

  • Picture listBox:

Incluye el conjunto de todas las demás opciones que podemos ver en la barra de menú

  • Aplicación:

Power Builder a iniciar cada sesión abre por default la ultima aplición sobre la que se ha estado trabajando

  • Proyect:

Permite tomar una o varias librerías.

Aquí cabe el comentario que para el desarrollo de proyectos es posible (recomendado) guardar todos los objetos visuales(formularios, gráficos, ect) en un .pbl y todos lo objetos(código) no visuales en otro .pbl.

  • Window:

Es el famoso formulario, que premie entre otras cosas comenzar una aplicación.

  • User Object:

Son objetos definidos por el usuario, pueden bien ser ventanas de tipo general, las cuales se puedan usar en distintas aplicaciones, etc.

En este punto hay que distinguir que los objetos definidos por el usuario pueden ser de dos tipos: 1) de clase y 2) Visuales. Además dentro de cada categoría se pueden escoger si son del tipo estándar -ya tienen la clase definida- o personalizados -aquí el programador se encarga de su definición por completo-

  • Menú:

Se usan principalmente para enlazar ventanas, y mantener la seguridad dentro de la aplicación.

Es decisión del desarrollador en qué momentos desea crear el menú de la aplicación lo cual lo puede hacer en el inicio o bien al final del desarrollo de la aplicación.

  • Structure:

Objeto que permite definir variables de tipos de datos (el famoso Record de otras herramientas).

Existen dos tipo de estructuras:

  • Generales: Se definen desde el ícono de la barra de menú - sin tener ningún formulario abierto- , estárán disponibles para toda la aplicación; por ejemplo si crearamos una estructura en este punto estaría disponible para toda la aplicación

  • Locales: Se define desde el menú Declare (Declare | window structures) si se crea una estructura con un formulario abierto está estará disponible solo en el ámbito de ese formulario.

    • Function:

    Las que se encuentran disponibles desde aquí son funciones que han sido definidas, como de alcance global (= public) por la aplicación que se tiene en uso.

    • Data Window:

    Aquí nos encontramos con dos connotaciones el control Data Window y el objeto Data Window. El segundo será de gran uso para enlazar los requerimientos del control data Window, el cual se crea desde este ícono.

    • Query:

    Permite construir consultas sobre uno o varios esquemas de la base de datos. La consulta luego de salvada es almacenada como un objeto más de la aplicación; por lo que hay que asignarlo a una librería, ect.

    *No tocar sin acceso a una base de datos.

    • Pipeline:

    Permite hacer migraciones de datos. El importar tanto como exportar se puede hacer desde aquí.

    La migración la hace tabla por tabla. Si la tabla existe actualiza los registros.

    Se debe tener mucho cuidado con la integridad; es preferible durante la migración quitar la integridad de las tablas involucradas si no se tiene un conocimiento profundo de lo que se está haciendo.

    • ODBC:

    Permite ver conexiones odbc ya hechas, o bien crearlas editarlas o incluso eliminar conexiones ya definidas

    • DB Profile:

    Cuando una base de datos ya tiene la conexión ODBC, o si en su defecto se tiene el driver nativo, se le puede ya entonces gererar perfiles (= Profile) sobre la misma)

    Además se pueden generar o modificar conexiones OBDC, desde aquí pero esto no es recomendado

    Es desde aquí que se puede por medio no de código conectar a un modelo de datos.

    Se tienen divididos los diferentes drivers nativos incluidos en Power Builder, y además las conexiones ODBC generadas por medio del generador de conexiones odbc (de la herramienta o el proporcionado por el sistema operativo)

    • Table:

    Wizard para la generación o alteración de tablas.

    No tocar si no se tiene acceso a ningún modelo de datos.

    • Data Base

    Se conecta a la úlltima base de datos que se usó

    Con una aplicación abierta en el conect del menú file tambien aparecen los esquemas de de datos que se puede accesar (=abrir)

    Es mejor escoger la conexión desde el DB Profile.

    • Browser:

    Forma rádida de ver los objetos de la aplicación actual.

    Es un formulario con diferentes leguetas que presenta todos los objetos definidos y creados en la aplicación actual.

    • Library:

    Muestra las diferentes librerías de la aplicación.

    Este objeto permite entre otras cosas exportar librerías de diferentes versiones, regenerar librerías, y ver y modificar ciertas propiedades de diferentes objetos.

    Dentro de una misma librería se pueden tener varias aplicaciones.

    • Edtit:

    Para librerías

    • OLE:

    Permite agregar objetos del tipo OLE

    • Run:

    Permite correr toda la aplicación.

    • Debug

    Permite depurar la aplición

    • Run Window:

    Permite correr solo la ventana abierta. Si se tienes que hacer acceso a datos de algún modelo esta opción no estará disponible.

    Más allá del menú inicial de la herramienta

    Una ves que se tiene abierta la última aplicación sobre la cual se trabajó - el menú de trabajo se amplía -, y lo que se desea es crear una nueva aplicación, o bien abrir otra aplicación, se puede hacer esto desde el menú File, escogiendo New, o también sobre el ícono new de la barra de menú.

    • Nueva aplicación:

    Lo primero que hace es pedir información sobre la librería que respaldará la aplicación, que por uso general se le da el mismo nombre que posteriormente se le dará a la aplicación.

    Posteriormente pide la información requerida para la aplicación en cuestión:

    • Nombre de la aplicación

    • Comentarios de la librería que la reapalda

    • Comentario de la aplicación propiamente dicha

    • Librerías asociadas a la aplicaición.

    Una vez que se ha clicado sobre el botón “OK” se genera un cuadro de diálogo que pregunta si se quiere genrerar una plantilla base para la aplicaición que se está generando.

    Si se responde que sí, se corre un wizard que generará tal plantilla misma que incluirá algunas ventanas básicas, un menú para la aplicación y un área de cominicación con sql (a traes de la variable SQLCA), el cuel posee el código necesario para conectar con cualquier motor de base de datos, pero por default pegará la ultima con la que se trabajó.

    Tal vez aquí es importante destacar que en Power Builder, así como muchos otros lenguajes de 4GL, todo objeto tiene dos aspectos que destacar:

    • Propiedades

    • Script

    • Propiedades del objeto APLICACIÓN:

    Si se pulsa sobre el ícono propiedades o con click derecho sobre el ratón, se puede ver en modo de lectura algunas de ellas las propiedades del objeto aplicación. Si se desea modifocar alguna que aparezca en modo de lectura se debe hacer dando click sobre el ícono Library el cual ya fue discutido en la sección anterior.

    Algunas propiedades por destacar:

    • General:

    Aquí se musetra el conjunto de propiedades que se definieron al crear la aplicación más algunas otras que el mismo PB definió en el momento también de generar la aplicación en cuestión.

    • Icon: el seleccionado aquí será el que se muestre en el ejecutable de la aplicación, una vez que esta haya sido compilada. Los que trae por defecto Power Builder están ubicados en: Archivos de programa PowerSoft ArtGal

    • Variable Types: cada una de las variables aquí definidas cumle con una función específica y algunas trabajas tambien en conjunto:

    • SQLCA: (área de comunicación con SQL), Esta variables tienes todos los parámetros necesarios para conectarse con cualquier motor de base de datos.

    Si solo se va a conectar con una base de datos en la aplicación no se hace necesario dedinir más variables Transaction.

    E.g: connect using SQLCA

    ODBC o no

    Usuario

    Password

    Base de datos

    Nombre de base de datos

    • SQLDA: (dinamic area)

    • SQLSA: (static area) donde queda la instrucción SQL

    Las dos variables definidas anteriormente trabajan juntas para obtener consultas dinámicas, osea en las que el usuario define que campos quiere extraer y de que tablas

    • Error: para pasar mensaje de error del motor de la base de datos a Power Builder.

    Se pueden capturar los errores más comunes en una tabla más del modelo de datos, para determinar las acciones a seguir cuando el usuario cometa tal error.

    Por ejemplo se le podría informar al usuario que esta introduciendo un número de factura que ya existe (sería poco ilustrativo para el usuario si se le dice que está intentando duplicar un refistro de PK!!)

    En los demás errores solo se le avisa al usuario para que contacte con el departamento de sistemas de la organización.

    El error se captura en la variable DbError.

    • Message: en la progrmación orientada a objetos se pueden enviar mensajes entre objetos (parámetros, etc). Esta es la forma de hacerla de PB. Esta variable se usa junto a una función llamada Power Object. (se menda a traves del Power Object un mensage de una ventana a otra por ejemlo.)

    • Libraries:

    Presenta el conjunto de librerías que tiene asociada la aplicaición sobre la que se está trabajando.

    • Resto de las propiedades:

    Se refieren a la forma de presentar los diferentes textos y etiquetas y demás mensajes en tiempo tanto de diseño como de ejecución.

    Algunas de estas propiedades se pueden cambiar en tiempo de ejecución también.

    La gran mayorías de los objeto en la programción orientada a objetos posee tre características:

    • Propiedades: las características propias de cada objeto, muchas veces manipulables en run time.

    • Métodos: Forma en que va a operar el objeto Son procedimientos asociados a los controles; es decir rutinas ya establecidas que podemos invocar desde nuestras aplicaciones para que se realice alguna operación sobre el control

    En PB hay dos tipos de métodos, los generados por el usuario y los que genera PB. La diferencia entre ambos es que a los primeros hay que invocarlos mientras que los segundos no.

    • Eventos: son el conjunto de instrucciones que se disparan al ejercer una acción sobre el objeto.

    Un evento es el conjunto de acciones que pueden ser motivadas por el propio usuario o por el mismo sistema operativo

    Cada objeto dispone de un conjunto específico de eventos, de los cuales el analista/programador solo tiene que encargarse de escribir el código necesario para hacer el evento funcional para los requerimientos de la aplicación, es el sistema operativo es quien se encarga de determinar cuando se produce tal o cual evento.

    Haciendo Aplicaciones Funcionales

    El objeto Ventana:

    Una forma de agregar una ventana a una aplicación es clicando sobre el ícono de Window que aparece en la barra de menú.

    Presenta el cuadro de diálogo Select Window, del que se puede hacer varias cosas:

    • Agregar una nueva ventana. (New)

    • Abrir una ventana ya existente en la aplicación

    • Agregar una ventana de otra librería (Other)

    De las ventanas ya existentes se puede ver el comentario asignado a cada una de ellas en el área que el cuadro de diálogo preporciona para ello.

    Se puede también heredar una ventana. En este punto es importante hacer notar que una cosa es la herencia y otra muy distinta el copiar una ventana; pues cuando se hereda y se hace un cambio en la ventana principal el mismo se reflejará en la ventana subordinada.

    Trabajando con una nueva ventana

    Si del cuadro de diálogo lo que se escogió fue crear una nueva ventana, la misma aparecerá sobre el área de trabajo de PB, no es necesario darle nombre en un inicio, pero si es recomendado salvarla de una vez para tener el objeto protegido por cualquier eventualidad que se pueda presentar.

    Una ventana como cuaquier otro objeto dispone de una serie de propiedades de las cuales quizá la que merezca discutirse para no dejar espacio a la confución es la propiedad del tipo de ventana:

    • Main: primer ventana que interactua con el usuario, por fuerza debe llevar marco y título. Puede tambien poseer un menú, son del tipo MDI

    • MDI: son contenedores de ventanas tipo child

    MDI frame:

    MDI frame Microhelp

    • Child: ventanas que no pueden salirse del marco de la MDI que la contiene. Si se cierra el padre se cierra el hijo también

    • Popup: para desplegar listas de valores. Son diferentes a los menú emergentes.. Este tipo de ventana si se puede salir del marco de la tipo MDI que le contiene y si se cierra el padre la Popup puede quedar abierta.

    • Message: para interactuar con el usuario. Detienen la corrida de la aplicación hasta que se cierre.

    Dos detalles importantes a manera de comentario es que hay que tener mucho cuidado con el tamaño y color de las ventanas; hay que recordar que no todo el mundo dispone de monitores de 14' ó 16' en 256 ó 512 colores. Muchas veces nos encontraremos con monitores bastante más pequeños como los que poseen los agentes repartidores y que por lo general son de tipo monocramáticos.

    En este sentido trabajar con colores bastante suaves y con una resolucion bastante baja. Lo anterior se puede controlar las propiedades de la ventana, las cuales se pueden observar clicando dos veces sobre la ventana. La propiedad que controla esto se localiza en la lengüeta llamada Position. Se podría tener un tamaño definido de ventana (como un machote- con coordenadas y tamaño, además de colores amistosos - ) y luego solo copiarlo cada ves que se necesite un formulario.

    Otra propiedad para destacar sobre las venatnas es Tool Bar; que se refiere a la ubicación dentro de la ventana de un menú que se tenga asociado a ella.

    Las propiedades de una ventana las podemos ver clicando dos veces sobre la ventana, dando click derecho sobre la misma y escojiendo propiedades, en el menú Edit escojiendo propiedades, secogiendo el ícono de properties sobre la barra de menú, entre otros.

    Por otra parte el objeto ventana también dispone de una serie de eventos a los que se les puede dar un código (=script) funcional.

    La forma de agregar código a una ventana es dar click derecho y escoger Script con el mouse, o bien en el menu Edit escoger Script, o bien escoger el ícono de script sobre la barra de menú, entre otras.

    Algunos otros íconos que se generan al tener abierta una ventana

    Los íconos que se describirán son los que se musetran cuado se tienes visible el formulario

    • New: genera una nueva ventana

    • Open: presenta el cuadro de diálogo que se presenta cuando se da click sobre el ícono Window

    • Save: salva la ventana actual

    • Picture ListBox: presenta los objetos de ventana que se pueden agregar a la ventna que se encuentra activa

    • Undo: remueve la ultima acción efectuada sobre la ventana

    • Clear:

    • Align left edges: aopciones para alinear

    • Script: muestra el script de la control activo

    • BackGround Color: color de fondo

    • ForeGround Color: color de relleno

    • No border: elimina bordes

    • Properties: del control activo

    • Tab order: para determinar el orden en que se le irá dando el foco a cada control de la ventana activa

    • Preview: mustra como se verá la ventana activa según las propiedades actuales

    • Close: cierra la ventana activa

    Controles de ventana y sus prefijos

    Control

    Prefijo

    Command Button

    Cb_

    Picture Button

    Pb_

    Check box

    Cbx_

    Radio Button

    Rb_

    Static Text

    St_

    Picture

    P_

    Group Box

    Gb_

    Line

    Ln_

    Oval

    Oval_

    Rectangle

    R_

    Round Rectangle

    Rr_

    Single Line Edit

    Sle_

    Edit Mask

    Em_

    Multi Line Edit

    Mle

    Rich Text Edit

    Rte_

    Hscroll bar

    Hsb_

    Vscroll bar

    Vsb_

    DropDown List Box

    Ddlb_

    DropDown Picture List Box

    Ddplb_

    List Box

    Lb_

    List View

    Lv_

    Tree View

    Tv_

    Tab

    Tab_

    Data Window

    Dw_

    Graph

    Gr_

    OLE

    Ole_

    User Object

    Uo_

    Window

    W_

    SCRIPTS (Script Painter)

    Ya se ha visto lo poner código sobre la aplicación (en el evento open), pero no se ha discutino nada acerca del mismo.

    Variables

    La mayoría de los lenguajes de 4GL soportan el concepto de ámbito de las variables. El ambito describe dónde se puede usar la variable.

    Este concepto es importante. El ámbito permite a un analista/progrmador escribir una función o suceso sin escribir sobre las variables en otra zona de la aplicación, incluso si las variables tienen el mismo nombre.

    Hay 4 niveles de ámbito en Power Builder:

  • Ambito Local: las variables de ambito local (o simplemente varialbes locales), son variables que se declaran en el script. Muchas variables definidas por el analista/programador que se emplean en el script son variables locales, que solo existen en el interior del suceso o función en la que están definidas. El valor que adquiera la variable se pierde una ves que salga del suceso o función

  • Ambito de réplica: las varibles de réplica son las que se permiten el acceso al objeto completo. Si se declara una como variable de réplica de un objeto, cada suceso, función o control tiene acceso a la variable.

  • Para declararla de pulsa Declare | Instance replica, y aparece cuadro de dialogo Declare | Instance Variables

    Las variables de réplica se salen de su ámbito suando se cierra y se reinicializa al volver a abrirlo

  • Ambito compartido: con una aplicación de tipo MDI se puede abrir más de una ventana del mimo tipo (en otras palabras, se pueden abrir dos ventanas w_item al mismo tiempo). Estas versiones multiples de la misma ventana se llaman réplicas de esa ventana. Las variables compartidas son varialbes cuyas funciones, sucesos controles de cada réplica de un objeto pueden compartirse.

  • Para declarar una varialbe compartida se pulsa Declare | Shared Variables, y se detalla la varialbe compartida

  • Ambito global: la aplicación completa puede acceder a las varialbes globales. Estas variables nunca se salen de ámbito hasta que se cierra la aplicación.

  • No se deberías usar variables globales si se emplea otro tipo de variables, usándolas se viola el principio de encapsulación; en otras palabras, si se establece una variable global en un suceso, otro suceso la puede reinicializar sin que el primero se llegue a dar cuenta de ello.

    Para declarar una variable global se pulsa Declre | Global variables y luego se detalla la misma.

    La forma de declarar variables de tipo local en un determinado evento es el siguiente:

    Tipo_de_dato nombre_variable{ [número de elementos] }

    Cuando se abre la ventana de script sea de una ventana o de un objeto de ventana, aparte del área de trabajo, existen el la parte superior de la misma cinco cajas de pegado de listas, con las cuales se pueden pegar rápidamente variables y objetos de uso frecuente al codificar los scripts

    • Paste instance: esta caja despliega todas las declaraciones de variable de réplica. Con una doble pulsación sobre una variable de réplica se puede pegar en el script

    • Paste global: esta caja permite pegar en el texto cualquier variable de ámbito global

    • Paste object: esta caja permite pegar objetos que estén relacionados con el script que se está escribiendo; por ejemplo botones de comando, list boxes, etc.

    • Paste Argument:

    • Select event: da la opción de seleccionar un evento del ojbeto al que se le desea agregar código. Cuando un evento de un objeto espedcfico posee código, aparece una marca sobre la esquina izquierda del evento

    Comentarios:

    En PB existen dos formas de agregar comentrios a una aplicación.

    • // para un comentrio de una línea

    • /* lineas de comentarios */ para comentarios de más de una línea

    Dentro del Script Painter, existen tres objetos que son muy funcionales a la hara de agregarcódigo a la aplicación; los describimos acontinunación:

  • Paste function: permite agregar (cada vez) uno de los tres tipos de funciones que PB soporta.

    • Built-in: cualquiera de las funciones que tiene interconstruidas PB

    • User-defined: alguna función definida por el progrmador

    • External: alguna función externa a Power Builder y que se ha extraido hasta aquí por medio de una librería asosiada a la aplicación

  • Paste SQL: para declarar por medio de un ayudante alguna consulta sobre un modelo de datos

  • Paste statement: para pegar en el script cualquier sentencia ya predefinida de PB, como un cilco una sentencia If then o if then else, etc.

  • Como se puede notar con estas herramientas practicamente podemos generar código PB sin conocer la estructura de su sintaxis!!!.

    Algunos íconos útiles para este momento:

    • Select all: seleciona todo el texto que se encuetre en el script

    • Comment: pone como comentario todo lo que se encuentre seleccionado. Si no hay texto sellecionado pone como comentario el código de la línea en la que se encuentre el cursor

    • UnComment: quita la selección hecha anteriormente.

    • Find: para buscar algún texto.

    • Find next: busca la siguiente ocurrencia

    • Replace: reemplaza algún texto seleccionado por otro que se proporcione

    • Compile: compila la vnetana actual

    • Select object: selecciona un objeto en particular

    • Browse Object: determina las características de un objeto que se encentre seleccionado

    • Return: vuelve al formulario.

    Creación de Funciones Definidas por el Programador

    Power Builder ofrece al progamador la posibilidad de crear funciones definidas por el mismo. Para agregar una función definida por el usuario se escoje el menú DECLRE y ahí se escoje Windows functions lo que dará como resltado un cuadro de diálogo cuyo propósito es pegar una función definida por el usuario en el script del control que esté activo o bien agregar una nuevo función a nuestra aplicación; eventulamente se pueden elininar funciones ya previamente definidas.

    Una ves que se haya escogido NEW de las opciones que preseta el cuadro de diálogo se debe dar la definición de la función tomando en cuenta lo siguiente:

    • Definir el nombre de la función

    • Definir el tipo de acceso que se tendrá; en donde

    • Public: será a nivel de aplicación

    • Private: será a nivel de objeto que contenga la fúnción

    • Protected:será que solo el objeto que contenga la función y sus decendientes

    • Definir el tipo de datos que la función devolverá

    • La lista de posibles argumentos de la función se definen como sigue:

    • Name: el nombre del argumento

    • Type: el tipo de dato del argumento

    • Pass by: la forma en que el parámetro será pasado a la función; donde:

    • Value: indica que será pasada una copia del valor del argumento

    • Reference: envía un indicador del valor real del argumento pudiendo este ser cambiado por la función

    • ReadOnly: envía un indicador del valor real del argumento pero con la restricción de que este no podrá ser modificado por la función. Aquí el argumento es tratado como una constante y no se tiene que gastar recursos en una nueva copia de la variable como es el caso del argumento por valor

    Por otra parte desde el ícono FUNCTION también se pueden definir funciones (de tipo global); se hace de la misma forma que se hace desde el menú Declare. Un aspecto que es de notar en este punto es que todo objeto que aquí se envoque debe ser declarado (controles de ventana incluidos). En este mismo sentido si dentro de la funcion se usan algún control de ventana este se debe declarar como parámetro-. Las funciones declaradas desde aquí (desde el ícono), serán disponibles para toda la apliación y por tanto se podrán ver en el Built-in del ícono Paste Fuction.

    Ahora bien una vez definidas, las funciones se pueden invocar (si están bien definidas claro!) para que cumplan su objetivo. Para invocar una función desde un evento de un control de ventana, se debe poner el nobre de la función seguido de los argumentos (caso que los tuviera)

    CONFIGURACIÓN DE ODBC

    Power Builder ofrece la posibilidad de crear la configuración para conexiones ODBC (ícono Configure ODBC del la barra de menú), pero desde aquí no es posible determinar la versión del driver del motor de la base de datos con el que se está haciendo la conexión, por tanto no se puede estar seguro si la misma proporcionará los resultados esperados, pues si el motor de la base de datos es de una versión más reciente que el driver que se posee para la conexión ODBC no dará un resultado adecuado.

    Ante esta perpectiva lo adecuado es hacer la conexión desde un producto (de cualquier marca, incluso el que está proporcionado por el sistema operativo -caso que esté usando windows 9x o windows nt - en la parte del Panel de control -Control Panel-) para conexiones ODBC.

    Desde un producto para conexiones ODBC, se puede en la gran mayoría de los casos escoger la versión del driver que corresponda con la versión del sistema gestor que se esté usando.

    Ahora bien ya en el producto ODBC, lo que se tiene que definir es el DSN (Data Souse Name), para lo que se siguen los siguientes pasos:

    • Buscar el diver que corresponda a la versión del DBMS que se esté usando.

    Inicialmente, lo que presentan los productos ODBC, es la lengüeta con los DSN que ya han sido previamente definidos, por lo que si se quiere agregar una nuevo se debe escoger Agregar... (Add...), que está en la misma lengüeta.

    • Luego escoger la opción de Finalizar; con lo cual se presenta un cuador de diálogo que proporciona la oportunidad de configurar el DSN, según el driver que es haya escogido.

    Independientemente del driver que se escoja, se debe completar el compo del Data Source Name, que es el que se refiere a la base de datos que se le esta haciendo la conexión ODBC. Adicionalmente se pueden completar el usuario y password, pero esto en un ambiente cliente servidor carecería de sentido

    Una vez que se haya completado el Data Source Name, se esgoje la opción de Terminar para que se cree el y User DSN.

    MANEJO DEL DB PROFILE

    Esta herramienta, que ya brevemente se discutió en la introducción a Power Builder, da la oportunidad de confugurar Profiles (= Perfiles), que vienen a ser como una vista que se tiene de una base de datos en particular.

    Los profiles se crean sea sobre un diriver nativo, o sobre un DSN creado mediante ODBC, permite tener (sobre la misma DB), diferentes enfoques para que diferentes analistas se conecten a la misma base de datos pero con diferentes características de acceso a la misma. Esto aplica en casos de que una misma estación de trabajo tenga que ser compartida por diferentes analistas. Con esto queremos decir que desde PB se pueden crear vaios profiles sobre la misma base de datos.

    NOTA: si recien se ha cerrado el DSN, todavía no aparece ningún perfil en el DB Profile, puesto que ovbiamente no se he definido ninguno; pero en el Configure Data Base ya aparece en el DSN que se definió. También se puede destacar que si se borra en perfil el DSN aún permanece

    Una vez que se ha determinado que existe el DSN al que se le quiere hacer el perfil se debe abrir el db Profile.

    Los pasos para crear un perfil son los siguientes:

    • Determinar el driver nativo o Odbc según se quiere hacer el perfil

    • Escoger New

    Uno de los parámetros más importantes para desarrollar perfiles, es el Catálogo de tablas de PB.

    El catálogo de tablas, permite definir propiedad extendidas que entre otra cosa son para:

    • Combos: (el no aparezca en un combo Bach -que es lo que está almacenado en la db- sino que aparezca Bachiller por ejemplo)

    • Máscaras:

    • Validaciones:

    El catálogo se crea bajo un Usuario común, por lo que se dispone para varios analistas. El catálogo está compuesto por 5 tablas que se definen bajo el usuario que trabaja sobre el catálogo, puediendo compartirse como ya se dijo.

    • En la lengüeta CONNECTION, completar la siguiente información:

    • Profile name: el nombre escogido para el perfil

    • Data Source: que corresponde al DSN que le estáhaciendo el perfil

    • Deahabilitar el usuario y password

    • En la lengüeta SYSTEM, definir la siguiente información: (es aquí donde se crea el catálogo de cuentas)

    • PB catalog table owner: el usuario -con derechos sobre la base de datos-, que será propietario del catálogo.

    • Table Criteria: es código sql, que se pone sobre el catálogo que se va a definir.

    • La ficha PREVIEW del cuadro Database Profile Setup muestra la sintaxis database Conection para establecer las propiedades de un objeto de transacción. Se puede usar este sintaxis en el script (por ejemplo en el script del suceso Open de la aplicación).

    • La primera vez que se conecta a la base de datos y se tiene acceso a crear datos, se crean las 5 tablas del catálogo

    Cabe recordar que el dueño de las tablas que se crean en el catálogo es el Dueño del Catálogo definido desde del db Profile y por Default quedan en el DbSpace de System. -esto en el caso de Sybase-

    Por otra parte al borrar el perfil de la base de datos no se borran las tablas de que han creado.

    Si por algún motivo se pierden las tablas que conforman el catálogo, se pierden todas las referencias a las propiedades extendidas que se tengan sobre un modelo en particular; por lo que hay por tanto que estar respaldándolas como cualquier otra tabla importante del modelo. El catálogo solo se crea una vez.

    ARCHIVOS INI

    Es uno de los medios para conectarse a bases de datos a través de código. Presentan la característica de que si se encuentran en el cliente se debe tener una logística para distribuirlos a los demás clientes.

    Además se debe tener mucho cuidado del lugar donde quedan los .ini puesto que como son archivos ascii, cualquier persona podría meter mano con dolo.

    El enfoque que se presenta como alternativo es tener un servidor que sirva como nexo entre los clientes y el servidor de base de datos; ambos enfoques se presentan en la siguiente figura; mostrando de diferente color el servidor que serviría de enlace.

    Los archivos ini, como es conocido, trabajan por secciones; mismas que empiezan por un corchete y dentro de cada sección se determinan las variables necesarias junto con sus valores.

    Un caso típico de archivo .ini puede ser el siguiente

    [DATABASE]

    DBMS = ODBC

    DBPARM = ConnectString='dsn=Proyecto'

    USERID =

    DBPASS =

    LOGID =

    LOGPASS =

    SERVERNAME =

    ;mismo que podría servir de enlace para conectar una aplcación PB con un sistema de gestión de bases de datos.

    Donde:

    • DBMS: es ODBC o el driver nativo del sistema gestor que se valla a usar

    • DBPARM: puede contener toda la información concernniente a la conexión usando el parámetro ConnectString; es decir el DSN, Usuario y Password.

    • USERID: repersenta el usuario

    • DBPASS: representael password

    • LOGID:

    • LOGPASS:

    • SERVERNAME: representa el nombre de servidor en cuestión.

    Configuración del SQLCA

    Se hace mediante una window, en un botón que tenga el código necesario para la conección.

    El código que podría presentarse en esta venatana se presenta a conticuación:

    int nfile1

    sle_usuario.SetFocus()

    if Trim(sle_usuario.Text) = '' then

    beep(1)

    messageBox("Error","Usuario Invalido !",Exclamation!)

    sle_usuario.Text = ''

    sle_usuario.SetFocus()

    Return

    End if

    if Trim(sle_clave.Text) = '' then

    beep(1)

    messageBox("Error","Clave Invalida !",Exclamation!)

    sle_clave.Text = ''

    sle_clave.SetFocus()

    Return

    End if

    //leer archivo labs.ini

    // FileOPen abre un archivo: StreamModel = leer hileras

    // Read = como solo lectura

    //retorna un número de archivo, si falla retorna -1

    nfile1 = FileOpen("c:\mis documentos\power builder\clase 03\labs.ini",StreamMode!,Read!)

    if nfile1 = -1 then

    MessageBox("Error","No Existe Archivo *.INI",Exclamation!)

    Halt Close

    else

    FileClose(nfile1)

    End if

    //se leen los parametros del labs.ini

    // ProfileString permite recuperar parámetros de un .ini

    // SetProfileString permite modificar parámetros de un .ini

    // Lo que retorna el ProfileString, es una cadena. La cadena contenida en la variable de la sección a la cual se le hace referencia.

    SQLCA.DBPARM = Profilestring("c:\mis documentos\power builder\clase 03\labs.ini","database","dbparm","")

    // El comando anterior empieza a descargar el .ini:

    //La instrucción anterior le dice que habra el archivo .ini en la sección //“database” y la variable “dbparm”.

    //Lo que hace la instrucción anterior es

    //tomar el dbparm del del .ini y se lo pone al dbparm de SQLCA

    // La instrucción siguiente lo que hace es tomar todo lo contenido en la variable //DbParm de SQLCA (`ConnectString='dsn=Dsn_ejemplo') y quitarle la //ultima comilla, después le agrega el contenido de los textboxes (usuario y //password) y finalmente le asigna de nuevo la comilla que le quitó.

    SQLCA.DBPARM = LEFT(SQLCA.DBPARM, LEN(SQLCA.DBPARM)-1)+";"+ &

    "UID="+trim(sle_usuario.text)+";" + &

    "PWD="+trim(sle_clave.text)+";'"

    // El resultado almacenado en SqlCa.Dbparm sería: ConnectString = `Dsn= proyecto; Uid= Nombre_Usuario; Pwd= Palabra_paso;'

    //El resto del código del SqlCa solo garantiza que el .ini es igual que el código //del programa pera ya no es necesario; exepto el SqlCa.Dbms

    SQLCA.DBMS = Profilestring("c:\mis documentos\power builder\clase 03\labs.ini","database","dbms","")

    SQLCA.DATABASE = Profilestring("c:\mis documentos\power builder\clase 03\labs.ini","database","database","")

    SQLCA.USERID = Profilestring("c:\mis documentos\power builder\clase 03\labs.ini","database","userid","")

    SQLCA.DBPASS = Profilestring("c:\mis documentos\power builder\clase 03\labs.ini","database","dbpass","")

    SQLCA.LOGID = Profilestring("c:\mis documentos\power builder\clase 03\labs.ini","database","logid","")

    SQLCA.LOGPASS = Profilestring("c:\mis documentos\power builder\clase 03\labs.ini","database","logpass","")

    SQLCA.SERVERNAME = Profilestring("c:\mis documentos\power builder\clase 03\labs.ini","database","servername","")

    //Esta línea de código garantiza que se haya escogido sea el driver nativo o la //conexión ODBC que corresponda.

    If trim(SQLCA.DBMS) = "" THEN

    MessageBox("Error","No Existe Archivo DBMS",Exclamation!)

    Halt Close

    End If

    Setpointer(Hourglass!)

    //Conect es un comando de sql incrustado, después de esta sentencia PB le da el //control de la aplicación para la conexión con la base de datos al sistema gestor //que se haya escogido.

    // en PB todo el sql que se introduzca debe decir ... using SqlCa o la variable de //trasacción que se tenga definida para tal efecto.

    connect Using SQLCA; //no esta en PB pbScrit es un Sql Incrustado. ;

    //obligado internamente open odbc para que abra el //drivers

    Setpointer(Arrow!)

    //La función SqlCode de SqlCA determina como se produjo la conexión con la //base de datos.

    //Los valores que retona son:

    // 0 cuando la conexión tubo éxito

    // - 1 cuando existe algún problema en la base de datos

    // 100 cuando una consulta debió retornar un registro pero retornó //más de uno.

    IF SQLCA.SQLCODE <> 0 THEN

    beep(1)

    messageBox("Error","-No hizo acceso a base datos !",Exclamation!)

    sle_usuario.Text = ''

    sle_usuario.SetFocus()

    return

    Else

    messageBox("OK","-Acceso Correcto Bienvenido !",Exclamation!)

    END IF

    w_entrada.hide()

    Open(w_cursores)

    // Fin de código del evento cliked de la ventana entrada.

    Variables de Transacción

    En la introducción al inicio de este manual, y en la sección anterior ya se ha abordado el tema de las variables de transacción; al menos de la que Power builder trae como Default (SQLCA). La Structured Query Language Comunication Area -Área de Comunicación del Lenguaje Estructurado de Consultas-, es suficiente si nuestra aplicación solo necesita comunicarse con una sola base de datos.

    En la tabla siguiente se pressentan las propiedades de los objetos de transacción retornados por la base de datos.

    ATRIBUTO

    TIPO DE DATO

    DESCRIPCIÓN

    SqlCode

    Largo

    El éxito o fallo del código de la operación SQL más reciente:

    0 = éxito

    100 = no retorna resultado (más de un registro)

    - 1 = Error (se usa SQLDBCode para ver detalles)

    SqlNRows

    Largo

    El número de filas afectadas

    SQLDBCode

    Largo

    El ´codigo de error del vendedor de la base de datos

    SQLErrText

    Cadena

    El menasje de error del vendedor de la base de datos

    SQLReturnData

    Cadena

    El dato de retorno específico de DBMS

    Como ya se he dicho si nuestra aplicación solo necesita conectarse a una base de datos con el Transaction que por defoul trae Powr Builder es suciente (=SQLCA); pero en los casos en que sea necesario que nuestras aplicaciones interactúen con más de una base de datos. El caso típico aquí es el ejemplo de los agentes de ventas; quienes portan su propia base de datos en su PC y al final del día pasan las transaccioes al servidor de la organización; aquí se debe (al final del día por ejemplo) estar conectado al mismo tiempo a la base de datos centralizada y la personal.

    Ya aquí estamos en necesidad de definir al menos una varialble de tranascción más aparte del SQLCA. Incluso podemos definir otro transaction diferente si no queremos usar el SQLCA, pero en realidad carece de sentido pues SQLCA trae ya implícito lo necesario para comunicarse con SQL.

    Definición del transaction (mediante código)

    Transaction MiTransaction

    MiTransaction = CREATE transaction

    MiTransaction.DBMS = 'ODBC' ... una vez creada hay que definir las varialbes de transacción de igual forma que como se hace con la SQLCA

    Eliminación de la transaction

    Una vez que la transaction ha cumplido con su objetivo, se debe destruir la variable de transacción para liberar recursos del sistema.

    La eliminación de la variable de transacción se hace mediante el comando DESTROY.

    Ejemplo: DESTROY MiTransaction

    Orden Lógico:

    Para trabajar con una variable de transacción que no sea la SQLCA, se debe seguir un orden específico a fin de no ocacionar problemas al usuario en tiempo de ejecución:

    Pasos:

  • Definir la variable de transacción

  • Conectarse al sistema de gestión

  • Ejecutar el codigo necesario

  • Desconectarse del sistema de gestión

  • Destruir el transaction que se haya definido

  • Manejo de menúes

    Agregar un menú

    La forma más prácita de hacer lo es mediente el pintor de menú de la PowerBar. Aquí dentro de las opciones más destacadas que presenta son:

    • Agergar un nuevo menú

    • Escoger una menú ya existente en la librería actual (to modified it)

    • Heredar un menú de la librería actual

    • Escoger una librería diferente para agregar un menú que ya exista, mismo que se puede salvar como una menú de la librería actual para luego heredarlo, modificarlo, etc.

    Trabajando con un nuevo menú

    • Insertar las barras principales: cada barra principal que se inserte en el nuevo menú, será capaz de contener como es lógico, elementos dentro de ella. Pero en primer lugar hay que darle un nombre a cada una de ellas (ejemplo archivo, Edición, ect). Esto se hace en el Menú Bar Items. El ícono insert de la barra de menú, es quien nos ayuda en esta labor. Por otra parte el ícono move es quien nos permite desplazarnos entre las diferentes barras una vez éstas ya definidas. Opcionalmente se pueden borrar barras ya perviamente definidas mediente el empleo del ícono delete que se encuentra en la misma barra de herramientas. Se pueden agregar otra barra también clicando a la par de la última barra que se tiene..

    • Elementos de cada barra: el siguiente paso es insertar las opciones de cada barra principal previamente definida; para esto nos valemos del Menu for en el que una vez que se alla escogido la barra correspondiente; el nombre de la misma se añadirá al caption de Menu for (por ejemplo dirá algo así como Menu For Archivo). La barra se puede escoger clicando sobre el título de la misma o mediante el scroll que aparece en la parte posterios a éstas.

    Ahora bien, una barra principal puede estar compuesta por un número indefinido de opciones dentro de ella; por lo que lo que hay que hacer para agregar cada nueva opción es dar <enter> sobre el textbox de la opción actual una vez ésta definida. Se pueden agregar dentro de cada barra tantas opciones como sea necesario. Una forma de desplazarse por las opciones de cada barra es con las direccionales o el uso del mouse, etc.

    • Inserción de barras separadoras: para agregar una barra separadora dentro de un menú en particular solo se debe agregar un guión medio ( - ), en el lugar correspondiente al nombre de la opción del menú que se tenga escogido (en el nombre del Menu Object Text).

    • Agregar más niveles a una opción de menú determinada: es posible al igual que en otros lenguajes de programación definir dentro de una opción de menú determinada otras opciones más. El ejemplo típico de esto es la opción Imprimir de un menú Archivo que presenta dentro de ella algunas otras opciones tales como definir impresora, imprimir docuemento, etc. En Power Builder hacer esto requiere solo de usar el ícono Next Level que se encuentra en la barra de herramientas; una vez hecho esto el definir las opciones de ese subnemú se hace de la misma forma que se definieron en el nivel previo. Pueden existir tantos niveles como sea necesario. Se puede entonces desplazarse entre niveles con los íconos Next Level y Prior Level.

    • Definir teclas de acelerator y shortCut: es conveniente agregar a cada menú sus respectivas teclas de acelerator y shortCut apegandose a un estándar. Para definir acelerator, se antepone un Ampersan (&) a alguna letra de la opción a la que se le está agregando el acelerator. De esta forma el usuario podra desplegar la respectiva opción del menú mediante la combinación de ALT + la letra que se haya escogido como acelerator; los acelerators trabajan nivel a nivel; así que si por ejemplo se tiene una “A” como acelerator para archivo y una “S” para la opción Salir del menú archivo, si se quiera salir del formulario en cuestión mediente teclas de acelerator, se debe oprimir primero ALT + A y luego ALT + S. Por otra parte para agregar shortCuts, se debe escoger la combinación deseada de teclas en la lengüeta ShortCur (aquí hay que asegurarse que el shortCut se le está agregando a la opción de menú deseada). Un usario que desee por ejemlpo otener ayuda en linea que típicamente se encuentra en el menú ayuda y en la sección Help context de éste la puede accesar solo opriendo la tecla “F1”.

    • Barra de herramientas: es la cuarta lenguega de las propiedades del men y trabaja en conjunto con la lengüeta Pictures, en la toolbar se define el texto que puede o no aparecer sobre el ícono que se define en la lenguega Pictures.

    Cabe apuntar que el lengüeta General(si la ventana es MDI, se puede definir un MDIMicroHelp el texto que aparece sobre el atatus bar)

    • Cógido a las opciones del menú: un menú solo es funcional una vez que este posee el código necesario para volver operativas todas sus definiciones. La forma de agregar código a una opción determinada del menú es clicando sobre el ícono Script una vez que se haya escogido la opción a la que se le desea agregar código. Una vez dentro de la ventana de código se debe escoger el evento que activará dicho código pues Power Builder posee más de un evento que puede hacer posible la ejecución de un código en particular; este evento por lo general siempre ha sido el Clicked pero aquí existe la posibilidad de invocar otro evento que desencadene dicho códogo.

    Un factor que es muy importante hacer notar es que el código de los menúes se debe hacer tan general como se pueda, pues un menú en particular puede ser heredado a otro formulario, aplicación o inclusive librerías; por lo que lo ideal sería por ejemplo tener en la aplicación dentro de la que se piensa ejecutar el menú un evento definido por el usuario que realice todo el trabajo de código y dentro del código del menú solo se debería llamar dicho evento. Por ejemplo tener definido un evento que realice todo el trabajo de impresión para un caso en particular y despues dentro del codigo de la opción Imprimir del menú solo llamar ese evento (definido bajo un nombre tambien estandar), de esta manera podremos usar un menú en particular en cualquier aplicación mediante la herencia.

    Copiar un menú

    Los pasos necesarios para copiar un menú de otra aplicación se pueden presentar tal com sigue

    • Escoger el ícono Menu de la barra de herramientas.

    • Esgoger la opción Other del cuadro de díalogo que se presenta

    • Escoger la librería adecuada según el path donde se encuentre el menu

    • Seleccionar el menú deseado de la librería en mención

    • Mediante la opción Save As del menú archivo de Power Builder darle el nombre y uvicáción adecuada dentro de la librería que se quiere pegar.

    • En este punto ya existe un menú independiente del que se tiene en la otra librería.

    Heredar un menú:

    Para heredar un menú Power Builder pregunta de cual librería se desea hacer la herencia y se salva. Para agregarlo a una ventana, ésta tiene que ser Main o MDI.

    La principal diferencia entre un menú heredado y otro copiado esque este último no se le puede modifcar nada previo, se puede modificar los cambios hechos en él, pero no se puede modificar nada que no haya sido hecho sobre él.

    Sucesos definidos por el usuario

    Se pueden definir en Power Builder argumentos para sucesos no planeados. Generalmente se declaran los argumentos para sucesos de definición de usuario cuando se declara por primera vez el suceso, para ello se selecciona Declare| User Event. se escribe el nombre del suceso y luego se dan la lista de parámetros que el suceso incluirá. Hay que declarar los argumentos antes de declarar el Event ID caso contrario se provacará un error.

    Ahora bien, una vez definido el nombre del evento [y sus argumentos], es posible agregarle el código que lo vuelva operacional escogiendo dicho evento desde la ventana se Script del control en el que fue declarado el evento.

    El evento puede ser invocado como consecuencia de la activación de un evento predefinido de un control de ventana mediante un TriggerEvent.

    Uso del TriggerEvent: es un método que poseen ciertos objetos visuales o de clase, el cual tiene como finalidad ejecutar el código del evento que se indique del control que lo invoque. Por ejemplo se puede invocar el código de un evento predefinido o de un evento definido por el usuario; el ejemplo siguiente activaría el evento clicked de cb_OK que es un botón de comando: cb_OK.TriggerEvent(Clicked!); adicionalmente puede tener una lista de parámetros más amplia pero la sintaxis que se describió es la minina para que este evento sea operativo

    Uso de treeviews

    Windows usa este tipo de vistas para representar los directorios o subdirectorios de una unidad de disco en particular

    Pasos para el uso de treeviews

    • definir las figuras que se van a usar en la página de propiedades del treeview. (desde luego un arbol que solo tenga texto no necesita usar figuras, pero es por estética)

    • codificar un PowerScript para añadir nudos al árbol, lo que probablemente se hace mejor con una función y así se codifica el powerScrip una solo vez.

    • Ejemplo de uso de treeviews

    En el ejemlpo siguiente se emplean tres funciones para procesar un treeview. La primera, of_add_to_treview (ver listado siguiente) declara un treeviewitem, que es un nudo de un arbol; luego rellena ese item y lo añade al treeview usando la función (intríseca) InsertItemLast.

    La definición del encabezado de la función que posteriormente se verá es como sigue:

    • Name: of_add_to_treeview

    • Access: public

    • Return: long

    • Argumets:

  • Atv_treeview treeview value

  • As_label string value

  • Aa_data any value

  • Al_handle long value

  • CUERPO DE LA FUNCION:

    Treeviewitem ltvi_new

    long ll_newhandle

    ltvi_new.label = as_label

    ltvi_new.data = aa_data

    ll_newhandle = atv_treeview.insertitemlast(al_handle, ltvi_new)

    if ll_newhandle < 1 then

    messagebox('Treeview Error', &

    'InsertLastItem error on the oof_add_person ' + &

    'function of w_Treeview')

    End if

    return ll_newhandle

    Si un gestor de otro nodo se envía al treeview, InserItemLast añade el nuevo nudo como una sud-división del nodo gestor. Si se envía 0 como gestor, InsertLastItem añade el nuevo nudo como un nudo raiz (sin matriz).

    En la ventana w_treeview (objeto dentro del cual se debe declarar la función anterior), la función de ventana of_buildtree (definida a continuación), llama a of_add_to_ treeview para construir el arbol

    La definición del encabezado de la función que posteriormente se verá es como sigue:

    • Name: of_buildtree

    • Access: public

    • Return: any

    • Argumets:

  • Tv_1 treeview value

  • CUERPO DE LA FUCION

    long ll_company_handle

    long ll_office_handle

    ll_company_handle = &

    of_add_to_treeview (tv_1, "Make More Money, Inc.", 1, 0)

    ll_office_handle = &

    of_add_to_treeview (tv_1, "East Coast Division", &

    2, ll_company_handle)

    of_add_to_treeview (tv_1, "Jack Horner", &

    1, ll_office_handle)

    of_add_to_treeview (tv_1, "Mary Q. Contrary", &

    2, ll_office_handle)

    ll_office_handle = &

    of_add_to_treeview (tv_1, "West Coast Division", &

    3, ll_company_handle)

    of_add_to_treeview (tv_1, "L. boo Peep", &

    1, ll_office_handle)

    of_add_to_treeview (tv_1, "I. John Henry", &

    2, ll_office_handle)

    ll_office_handle = &

    of_add_to_treeview (tv_1, "Intl. Division", &

    4, ll_company_handle)

    of_add_to_treeview (tv_1, "K. Cole", &

    1, ll_office_handle)

    of_add_to_treeview (tv_1, "Ali Babba", &

    2, ll_office_handle)

    of_add_to_treeview (tv_1, "Santa clause", &

    3, ll_office_handle)

    tv_1.SetLevelPictures(1,2,1,0,0)

    tv_1.SetLevelPictures(2,3,1,0,0)

    tv_1.SetLevelPictures(3,4,4,0,0)

    return ''

    por otra parte evento que es usado para capturar cualquir cambio en el arbol es el SelectionChanged en el se puede decir uándo ha cambiado en usuario el nudo actual seleccionado. El script que sirve de ejemplo se puede dictar así como sigue:

    TreeviewItem ltvi_olditem

    TreeviewItem ltvi_newitem

    string level_name[] = {"Company", "Sales oficce", "Employee"}

    string ls_message

    getitem (oldhandle, ltvi_olditem)

    getitem (newhandle, ltvi_newitem)

    if ltvi_olditem.level > 0 then //First time through

    messagebox("Treeview Change", &

    "Old Selection: " +&

    char(13) + level_name[ltvi_olditem.level] + &

    " Name:" + ltvi_olditem.label + &

    "~r" + level_name[ltvi_olditem.level] + &

    " ID: " + string(ltvi_olditem.data) +&

    "~r~rNewSelection: " + &

    "~r" + level_name[ltvi_newitem.level] + &

    " Name:" + ltvi_newitem.label + &

    "~r" + level_name[ltvi_olditem.level] + &

    " ID: " + string(ltvi_newitem.data))

    end if

    en el anterior script los argumentos oldhandle y newhadle se han enviado al evento SelectionChanged. Con el código precedente, cada vez que un treeview cambia los nudos, se aber un cuadro de mensage con un texto que indica los cambios.

    Acceso a datos desde Power Builder

    Si bien es cierto en este documento ya hemos tratado el el tema de las conexiones con modelos de datos e incluso hemos dado las pautas para crear Transactions diferentes al SQLCA, el acceso a datos de esos modelos no se ha tocado y ha llegado el momento para hablar del tema.

    En reiterados casos ya se ha mencionado que se debería comprobar el SQLCode cada vez que se accede a la base de datos, si no es 0, se puede saber que existe un error y se puede actuar en consecuencia.

    Cláusula Select

    La cláusula seclect dentro de Power Builder tiene dos formas generales de poder ser usada:

  • Aquella que retorna solo un registro (donde SQLca.SQLCode = 0)

  • Aquella donde se retorna más de un registro (donde SQLca.SQLCode = 100), a este tipo de select se le considera con el uso de CURSORES

  • Select para un registro para los casos en que se esté seguro de que la consulta al modelo de datos no retornará más de un registro, la sintaxis del script en el PowerScript de PowerBuilder para la consulta será casi igual a un SQL estandar excepto que cada campo que se retorne se debe descargar en una variable del programa declarada previamente (no se permiten descargas a controles de ventana), dentro de la sección INTO. A cada variable de descarga se le debe anteponer dos puntos (”:”).

    El script siguiente determinaría el nombre salario y departamento de trabajo para la persona que más gane dentro de un modelo de datos de dos tablas, a saber Empleado y Departamento.

    //se definen las variables que servirande descarga

    string name, dep

    long sal

    SELECT salario, nombre, desdep &

    INTO :sal, :name, :dep &

    FROM departamento D, empleado E &

    where D.coddep = E.coddep &

    and Salario = (select max(salario) &

    from empleado )

    using SQLCa; // se usa el transaction por default

    //si se presentara algún error...

    If sqlca.sqlcode <> 0 then

    messagebox ("ERROR", "Se presentó un error al intentar recuperar” + &

    “ el registro" ,StopSign!)

    Return //...se retorna

    end if

    //si se tiene éxito, entonces se presentan los resultados en los label

    st_3.text = name

    st_5.text = string(sal)

    st_7.text = dep

    Select para más de un registro (“Cursores”) en SQL embebido (= incrustado) se producirá un error si se tratade recuperar más de una fila; aun así habrá ocaciones que se quiera recuperar muchas filas que cumplan ciertos criterios, para este caso se debe usar un cursor. Un cursor es una tabla temporal que SQL establece en todas las filas que cumplen ciertos criterios, así que se puede acceder a esas filas de una en una.

    Uso de cursores

    • El mandato declare: antes de usar un cursor, primero hay declararlo con el mandato DECLARE

    Ejemplo: declare cursor_name

    • La claúsula select: una ves declarado lo que sigue es la claúsula select que se apoye en el select incluida la sentencia que determina cuál transaction se usa.

    Ejemplo: cursor for select_statement using transaction;

    • El mandato open: ahora lo que falta es solo abrir su posterior uso

    Ejemplo: open cursor_name;

    • El mandato Fetch: después de abierto el cursor hay que traer (= fetch) cada fila. Fetch es quien permite procesar cada fila, para ahora sí por cada fila descargar los campos que haya recuperado la instrucción select. Al igual que el select para un solo registro se debe descargar cada campo en una variable de progama anteponiéndole a este dos puntos (“:”).

    Ejemplo: fetch cursor name

    Into host_variable_list;

    • El mandato clase: el último paso de uso de un cursor es cerrarlo. El cierre de un cursor libera la memoria usada por las tablas temporales y permite reabrir el cursor bajo nuevos criterios de selección

    Ejemplo: close cursor name;

    EJEMPLO COMPLETO DE CURSOR:

    //se declara el cursor con su claúsula select

    DECLARE dep CURSOR FOR SELECT coddep &

    FROM DEPARTAMENTO &

    ORDER BY 1 DESC &

    USING SQLCA; //en la variable de transacción

    //

    //se declara la variable de descarga (= host variable -variable anfitrina-)

    STRING DEPARTAMENTO

    //se abre el cursor

    OPEN dep;

    //se determina si el cursor se ha completado con éxito (= 0), es hasta aquí que se evalúa //el resultado de la consulta (ojo el resultado no la consulta)

    IF SQLCA.SQLCode <> 0 THEN

    MessageBox("Estado","Error abriendo cursor "+SQLCA.SQLErrText)

    RETURN

    END IF

    //descarga el primer registro en departamento

    FETCH dep INTO :departamento;

    //seguirá descargando mientras se retorne un registro (= mientras haya registros //por leer)

    DO WHILE SQLCA.SQLCode=0

    //agrega el resultado almacenado en la variable anfitriona a un //DropDownListbox

    ddlb_1.AddItem(departamento)

    //Continúa con el siguiente registro, si no existe SQLCA.SQLCode //retornará diferente de 0 y no se iterará de nuevo, evitando así el error.

    FETCH dep INTO :departamento;

    LOOP

    CLOSE dep;

    DataWindows

    Los data windows son como controles limitados a los datos, incoppran interfaces de usuario tales como editores de una línea y campos de texto estáticos. Pero a diferencia de éstos los DataWindows son tratados como un solo objeto.

    En algunos casos un Datawindow permite toda la sintaxis SQL en otros casos no toda.

    El pintor de datos windows tiene realmente tres ventanas principales. La priemera (= el SQL Painter), es donde se define el dato fuente para el datawindows, así como su estilo de presentación. La segunda ventana (=diseñador de DataWindows),es donde se delinea su formato usando argumentos de informe; hay 4 argumentos en la mayoría de los DataWindows, a saber, encabezamiento, detalle, pie y resumen. La ultima ventana es la de vista perliminar, donde se puede observar el DataWindows con los datos recuperados desde el modelo de datos.

    Para abrir el Pintor de DataWindows, se realizan los siguientes pasos:

  • Se pulsa el botón DataWindowsde la powerBar para abrir el cuador de diálogo Abrir DataWindows

  • Se puede crear un nuevo DataWindows o modificar uno ya existente

  • En el cuadrode diálogo New DataWindows se seleccciona el DataSource y presentation Style, tambien se puede fijar la DataWindows Option

  • SQL Painter:

    Una vez que se ha escogido el tipode consulta que se pienza hacer y el estilo de presentación es hora de selecccionar las tablas que se desea que sean parte del control DataWindows que se está creando.

    Después de seleccionar las tablas de la consulta se deben escoger los campos de esas tablas que aparecerán el el resultado del DataWindows. Se puede además escoger aquí el criterio de selección de los campos.

    Diseñador de DataWindos: (es diferente dependiendo del DataSource escogido)

    Una vez que se pulsado OK, se abre el diseñador de DataWindows, internamente ya se tiene el estilo de presentación que previamente se ha escogido; usando el ratón, simplemente hay que arrastrar los campos adónde se quiera que aparezcan dentrol del DataWindows.

    Una vez que se han hecho los ajustes necesarios dentro del diseñador, es tiempo de guardar el trabajo; para ello se pulsa dos veces en el cuadro de control del menú del pintor, PowerBuilder preguntará si efectivamente se desea guardar el trabajo realizado.

    NOTA: para mostrar solo un detalle a lavez, se debe correr hacia abajo las franjas de los diferentes componentes (detail, summary, etc.)

    Se puede, en cualquier momento hacer un preview para ver como va quedando el resultado de la clausula select que se está diseñando.

    Además se puede, en el pintor de SQL, mediante el menú: Design Convert to syntax, ver o modificar, el código de la consulta que se tiene hasta el momento. Para volver al modo gráfico se escoge Design convert to graphics.

    Columnas para la cláusula Select escogida

    Si se está en el diseñador de DataWindows en le modo gráfico, bajo las tablas que se tengan escogidas, aparecen varias lengüetas propias de SQL, que se describen ahora:

    • Sort: permite hacer que la conslta aparezca en forma ordenada. Para ello, se escoge la columna por la que se quiere hacer el ordenamiento y se traslada hacia el campo que aparece a mano derecha de las mismas; una vez aquí se puede escoger si el ordenamiento se desea hacer ascendiente o descendentemente.

    • Where: condición cual se desea que cumpla la consulta, se pueden usar además de los conocidos Like, between, is, etc operadores de tipo relacional. Varias condiciones pueden estar unidas mediante operadores lógicos.

    Es aquí donde podemos pasar parámetros traídos del programa al DataWindow, los agregamos mediante el menú: Design Retrieval Arguments...; de esta forma establecemos un vínculo entre el DataWindow y el programa de aplicación.

    Los agregamos a la clausula where como se agregan variables anfitrionas, es decir, se les antepone “:”. Para eleminar argumentos se escoge de nuevo Design Retrieval Arguments... y se elinina el argumento. Se puede elininar una condición completa, escogiendo el boton derecho del mouse y clicando en Clear.

    • Group: para agrupamientos

    • Having: condición del agrupamiento.

    • Compute: son columnas calculadas para la consulta que se está haciendo.

    • Sintax: es el código de la consulta según hasta el momento. (Desde aquí no se puede modificar)

    Filtros

    Se definen mediante Rows Filter... Lo que hacen es ocultar las columnas que cumplan con la condición del filtro, pero no las elimina del DataWindow, por tanto no reducen el trafico en la red.

    NOTA: una vez que se da por OK en esta parte se entra al diseño del DataWindows,

    Se puede modificar la presentación de los datos (pero no modificar el estilo de presentación, pues este solo se puede modificar con código en RunTime), o incluso se puede mofificar el select que se haya esgogido, mediante el uso del ícono SQL de la PowerBar.

    Diseño de un DataWindos con varios segmentos (una factura)

    Los pasos iniciales son iguales, se debe crear un nuevo Datawindows para luego escoger el tipo de consulta y la forma de presentación de ésta.

    Ahora bien, una factura típica tiene varios componentes:

  • Información del encabezamiento: situado en la parte superior; aquí la información a almacenar será detalles como el número de la factura, lugar de compra, fecha, nombre de la persona encargada de la compra, puesto dela persona que realice la compra.

  • Información del detalle: consiste en el número de línea, la descripción del artículo, la cantidad ordenada y precio unitario y el precio total por línea.

  • Inforación del pie: normalmente puede incluir comentarios, cargos varios por impuestos y la cantidad total a pagar.

  • Entonces para introducir, mostrar o imprimir una factura, se deben crear tres datawindows; a saber la cabecera, el detalle y el pie.

    Por cada columna númerica que se escoja Power Builder genera un sum() de la misma.

    Propiedades de actualización de un objeto Datawindows

    Para ingresar a la propiedades de actualización de un DataWindows se debe escoger de la PowerBar: Rows | Update Properties...

    Ya una vez aquí, en un Datawindows, solo se puede actualizar una tabla a la vez, debido a que probablemente se tengan seleccionado datos de diversas tablas, Power Builder no sabe cuál es la que hay que actualizar.

    Lo primero es activar Allow Updates para que los usuarios de la aplicación puedan actualizar este DataWindow. Luego se selecciona la tabla que se desea actualizar Table to Update

    A continuación se pulsa sobre las columnas que se quieren actualizar de la tabla seleccionada.

    Tambien se pueden elegir opciones para la clausula Where que el DataWindow utilizará en la actualizaciones o cancelaciones del mismo. Estas opciones son importantes en el supuesto de múltiples usuarios, que pueden estár actualizando una misma tabla al mismo tiempo. Pulsando Key and Updatable columns, o bien Key and modified columns se amplia la protección -un usuario no puede escribir sobre una tabla que otro esté actualizando

    En el Group de key modification se dispone de opciones de actualizar Delete then Insert o Update para cambiar el valor de la clave principal. En este group si se escoje delete then insert Power Builder primero eliminará la tupla a la que se refiere y posteriormente hará un insert con los nuevos valores insertados; si bien hay que considerar el efecto de actualizaciones y cancelaciones en cascada cuando se toma esta opción. Usar Update para cambiar la clave puede ser más rápido para actualizar, pero puede ser más lento para el proceso secuencial subsiguiente.

    Finalmente, se toma la clave principal (= clave única) para la tabla que se está actualizando. Si se ha definido una clave principal para la tabla actualizable, se pulsa primary Key y se deja a Power Builder que tome por si mismo la columnas de clave principal.

    Pulsando OK se vuelve al pintor de DataWindow; una vez listo todo el proceso de diseño del DataWindow, éste puede ser guardado.

    Data sources: (aquí iremos describiendo cada uno conforme se necesiten)

    • Quick select: solo permite relacionar tablas que tenga relación directa; o sea, por medio de llaves foráneas

    • SQL select: permite cualquier tipo de relación entre tablas incluso para aquellas en las que no existe ninguna relación

    • Queries: es muy parecido al SQL select, la única diferencia entre los dos es que se pueden emplear queries como una fuente de datos predefinida para distintos DataWindows en lugar de definir el SQL select en cada DataWindows. Una Query es como un SQL select reutilizable que se emplea para contruir muchos DataWindows. Un DataWindows se puede incluso guardar como una Query en el pintor SQL dentro del pintor de DataWindows.

    • External: cuando se usan fuentes de datosexternas para un Datawindows, generalmente se le da contenido a éste por medio de PowerScript, toda vez que hay un SQL select asociado a él. Cuando se empieza la contrucción de un Datawindows usando una fuente de datos externa, se abre el cuadro de diálogo Result Set Description, se definen ahí los campos y lo que son su tipo y su logitud, luego se continúa la contrucción como si se estuviera un Quick Select o un SQL select como fuente de datos. Los Datawindows con fuentes de datos externas son útiles cuando se necesita mostrar o introducir datos que no están almacenados en una base de datos relacional

    • Stored procedure: son extremadamente populares para los DataWindows de solo-mostrar que pueden ser usados si el sistema de gestión de que contiene la base de datos los soporta. Algunas bases de datos tienen procedimientos almacenados altamente eficientes. Con frecuencia se puede mejorar la velocidad de la aplicaición situando algunas de las sentencias SQL en estos procedimientos almacenados. Se pueden usar Procedimientos almacenados dentro de DataWindows si y éstos lo que devuelven es una consulta Select.

    Estilos de presentación: (aquí iremos describiendo cada uno conforme se necesiten)

    • Freeform: se usa frecuentemente para las ventanas de entrada de datos. Normalmente solo se muestra una fila a la vez y no tiene información de encabezamiento ni de resumen. Es un DataWindows sin formato (Sin formato =Freeform).

    Este tipo de DataWindowsse uas para talbas únicas o entradas de datos de una solo línea

    • Tabular: muestra típicamente varias filas de información a la vez. Es normal que este estilo tenga un segmento de encabezamiento que contenga los títulos de las columnas (en vez de etiquetas en el segmentos de detalle, como en el caso de los estilo libre) también suele tener un pie de página y filas de resumen al final del informe. Una factura es un excelente ejemplo de un DataWindows tabular, ya qie muestra muchas filas a la vez (líneas de la factura) y tiene información de encabezamiento (nombres de clientes, compañias, fecha, etc.) así como una información de resumen (impuestos,de scuentos, total.). con este estilo de presentación los títulos de columnas aparecen en el segmento de encabezamiento, mientras que las columnas aparecen en el detalle. La única diferencia entre un DataWindows de estilo tablar y otro sin setilo es la forma de disponer los objetos (=columnas y texto) al crearlos.

    • Compuesto: no se puede usar para mantenimiento

    • CrossTab: se puede usar para mantenimento, la representación es tipo matriz

    • Graph: tipo gráfico

    • Group: no se puede usar para mantenimentos y se usa para agrupamientos

    • Label:

    • N-Up: si se puede usar par amantenimientos y aprovecha al máximo el papel cuando se pasa a impresión.

    • Ole: para incrustados

    • RTF: para formatos enriquecidos.

    Objetos informatizados: en DataWindows se usan para crear columnas que no estén presentes en la tabla pero que se requieren para algún proceso o manipulación por parte del usuario. En el PainterBar está reprentado por un símbolo de +/= (+/=), una vez que se ha escogido el objeto informatizado se debe escoger la parte del DataWindow en donde se quiere que aparezca el objeto y una vez hacho esto aparece la página de propiedades Compute Object y en ella se puede introducir una expresión para el objeto informatizado, como ya se detallará. Tambien se puede escoger el símobolo de sumatoria (= ") pero aquí antes de escoger el objeto informatizado, se debe escoger alguna columna que sirva de referencia a la función que vamos a crear. Por defecto se crea un sum() para todas las columnas escogidas y la pone como summary sobre el Datawindows, pero lego de esto se puede situar en cualquier lugar, así como modificar la expresión que dará com resultado.

    Para modificar la expresión se debe escoger las propiedades del objeto informatizado y después modifcar el texto “Expresión ” por la expresión requerida. Pulsando el botón “More” en esa misma lengüeta, se pueden escoger una gran cantidad de funciones preconstuidas para dar formato a la expresión, solo hay que tener cuidado pues el formato de esas funciones difiere un poco de lo usual.

    Por ejemplo si para validar un If lo hacemos usualmete así: If <cond> then; en ese tip de funciones el formato es If(cond, true, false); donde cond representa la condición propiamente dicha con su consecente posible resultado, true especifica el resultado a mostrar si se cumple la condición y false el resultado a mostrar si no se cumple.

    Objeto DataWindows # Control DataWindows

    A veces esite confusión sobre la terminología cuando se hablade DataWindows. Desde el inicio de este documento se ha mecionado la diferencia entre le objeto DataWindows (= todos los que se crean dede el ícono de la PinterBar) y el control DataWindows. La lista siguiente puede aclarar alguna ambiguedad del del tema

    • Un objeto DataWindows es la que se pinta usando el pintor de DataWindows. No son visibles estos objetos hasta que se han asociado a un control de ventana. Se los conoce con el nombre genérico de DataWindows (por ejemplo: “crear un DataWindow para la entrada de datos de una tabla de artículos”)

    • Un control de DataWindows es un control de ventana, al que algunas veces se le llama DataWindow (por ejemplo, “añadir algún PowerScript al suceso de DataWindow ItemChanged”). Estos controles no son útiles salvo que estén asociados a un objeto DataWindow.

    • Un objeto de usuario de DataWindow es un control de DataWindow antecedente creado en el pintor de objetos de usuario. Estos objetos tambien son conocidos como DataWindows (por ejemplo, se necesita heredar un DataWindows antecedente) o controles DataWindows

    • Los objetos dataWindows muestan texto, figuras, columnas, etc. Dentro del pintor de DataWindow estos objetos son también objetos dentro de un DataWindow (por ejemplo, “añadir un objeto informatizado a un Datawindow en particular”)

    Asociación de Controles DataWindow con ObjetosDataWindow

    En los términos más simples se puede crear una ventana y luego dentro de ella ir creando controles DataWindow y asociarles a cada control un objeto según sea necesario. Opcionalmente se puede definir un DataWindow definido por el usuario de tipo objeto y asociarle a cada instancia de este tipo de control un bjeto DataWindow.

    NOTA: el sufijo para el objeto DataWindow es solamente “D” y para el control DataWindow se usa “DW”.

    Editar campos del DataWindow

    Para definir o revisar un estilo de edición, basta con pulsar doble chlick sobre la columna del DataWindow que se quiere editar, luego ahí se elige la ficha cual se quiere editar, existen varias entre las que podemos citar:

  • Edit: dentro de las propiedades más importantes que podemos encontrar aquí está STYLE, donde se define el formato para la columna, por defecto es EDIT , que es un campo SLE, ademas entre los más destacables podemos citar el DDDW, DDLB; ambos se discutirán el la siguiente sección de DataWindows desplegables.

  • Format: (= utilización de formatos de muestra), estos formatos son similares a los EditMask, la principal diferencia es que los formatos de muestra cambian la forma en que el valor de una columna se muestra en un informe, mientras que los EditMask cambian la forma que los datos se introducen en el formulario. Si se está usando un formato de cadena hay que usar el signo “@” para que se pueda mostrar cualquier carácter. En una columna numérica se usa el signo “#”; en formatos numéricos tambien se pueden introducir formatos en los que los números negativos aparezcan en rojo: e.g: #,##0.00; [red] #,##0.00. cuando se introducen los datos en una columan estos no cambian hasta que el campo pierde la atención.

  • Validation: (utilización de reglas de validación): evitan que una columna pierda el foco si el valor introducido no es adecuado. El texto introducido en la columna se recupera con la función gettext(), de ahí en adelante se puede hacer la validación necesaria y mostran un mensage en caso que se produzca un erro a la regla

  • Expressions: (empleo de expresiones condicionales) supongamos que se desea cambiar el color de la columna si el valor en ella es menor de 10 por ejemplo. Para ellos se pulsa 2 veces sobre la propiedad color, con lo cual aparece el cuadro de diálogo Modify expression, donde se introduce la validación correspondiente, que en este caso podría ser: if (nombre_columna < 10, rgb(255,0,0), 0) rgb red, green, blue

  • Las demás lenguetas son comunes a todos los controles: general, font, pointer, etc.

  • DataWindows desplegables

    Con frecuencia se necesitarán cajas de lista desplegables para contener valores desde las tablas del modelo de datos. Es mejor poner una lista desplegable con los códigos de los clientes a obligar al usuario a memorizar cada uno de los códigos de todos los usuarios.

    Para que Power Builder pueda recuperar la lista despleglable desde una tabla, las listas se construyen usando los DataWondows desplegables. En lugar de usar un tabla de difícil código, el Drop-Down DataWindow (=DDDW) recupera su lista de valores de datos y los muestra por medio de un DataWindow; por lo que el DDDW es un DataWindow descendiente o lo que es lo mismo un DataWindow dentro de otro.

    Para añadir un DDDW el estilo de edición de una columna lo primero que hay que hacer es crear el DataWindow usado para mostrar la lista de valores. Normalmente, los DataWindows se construyen con el estilo tabular. Primero se selecciona la columna de dato y muestra en la lista desplegable.

    Una vez definida la consulta que servirá como soporte al DataWindows anidado se cancelan todos los titulares de columna y todas las columnas que no se quieran mostrar. Supongamos que lo que desea mostrar el nombre de los empleado de una compañía X; si la clave primaria es el código pues se eliminan todos los encabezados de columna además del código del empleado. Si lo que se desea es mostrar más de un valor (=contenido del DDDW) y no se desea que el Datawindow que contiene el DDDW pierda estética(=definir una caja de texto de 50 char, para mostrar solo el código), lo que se debe hacer es ampliar el ancho del DDDW con relación al Datawindow (=Width of DropDown), con esto se consegirá que al clicar (=en tiempo de RunTime o Preview) sobre la columna que posea el DDDW ésta se expanda de manera que muestra toda la información que se necesite.

    Aunque se elimine una columna en el diseñador de DataWindow ésta permanecerá en el SQL Select y en el conjunto de resultados del DataWindow, pero no se verá nunca más.

    El prefijo para este tipo de DataWindow es D_DDDW

    Una vez salvado el DataWindow, se vuelve al Item DataWindow, se selecciona una columna, se abren las propiedades de edición y se elige DropDownDW como estilo en la lenguega Edit.

    Hecho se debe editar el campo que contendra el DDDW. El estilo de este campo debe de ser DropDownListBox. Aquí se predeterminan las propiedades del campo, se elige el Datawindow que se quiere asociar con esa columna (=el DDDW), despues de eligir esto, se pulsa sobre la columna de datos que se mostratará al usuario y luego el valor que se pasará al programa internamente. El valor del dato se sitúa en el búffer de datawindow cuando un valor de muestra se selecciona en la lista. Luego de esto, se completa el resto de las propiedades del datawindow; éstas son identicas a las de las cajas de lista (= ya que se dijo que un DDDW se un tipo de caja de lista). Lo único que falta es pulsar OK.

    NOTA: Para ejecutar el DDDW hay que introducirle datos en la tabla a la que hace referencia

    Como ya se dijo, obviamente el campo en el que se desplegarán los valores resultantes de la consulta debe ser un DropDownListBox.

    A los DataWindow desplegables se les llama también DataWindow descendientes (= Child DataWindow)

    Empleo del pintor DataBase para definir formatos de muestra, estilos de edición y reglas de validación

    El en depositario de Power Builder para la base de datos se pueden guardar formatos de muestra, estilos de edición y reglas de validación, aplicables dentro de las propiedades de las columnas en los DataWindows.

    Para ello una vez habiendo escogido el ícono DataBase en la Powerbar (sin seleccionar tabla alguna), se escoje en el menú Disign la opción deseada , a saber:

    • Edit style maintenance

    • Display format maintenance

    • Validation maintenance

    Definición de diferentes columnas por defecto

    Se pueden tambien definir estilos de edición, formatos de muestra, reglas de validación y valores por defecto para las columnas, tanto en el pintor de datawindows como en el DataBase

    Definición de valores por defecto usando el pintor de DataBase (= Propiedades extendidas): en el pintor de base de datos se abre la tabla (con lo que se abre el cuadro de diálogo Alter Table) y ahí se definen las propiedades adecuadas. Es en este mismo cuadro de diálogo que podemos también usar los formatos de muestra, reglas de validación, y estilos de definición que definimos en la sección anterior. Tambien es posible cambiar los valores por defecto, pulsando en botón derecho del mouse sobre la columna de la tabla y encogiendo aquí Properties.

    Fijación una propiedad extendida

    Se puede crear una propiedad extendida para luego agregarla a alguna columna de alguna tabla del modelo de datos o bien esgoger la columna y acto seguido crear la propiedad extendida sobre esa columna. Suponiendo que se ha previamente seleccionado una columna presionado el botón derecho del mouse y clicado sobre Properties, estos son lospasos que se deben seguir para crear una propiedad extendida:

    • Abrir la lengüeta Edit Style

    • (si lo que se quiere es agregar una propiedad que ya existe solo se escoge y acabado el asunto)

    • escoger New (para crear la propiedad)

    • Deterninar el nombre para lapropiedad extendida (para poder agregarla luego a más columnas)

    • Escoger el estilo de presentación que se desea para la propiedad. En este punto lo más usual es escoger un DDDW para cargarle los valores de el obtenidos pero también se podría generar como un check o un boton de radio, etc. Vamos a partir del supuesto que se está generando sobre un DDDW

    • Escoger el DDDW que servirá de soporte a la columna

    • Escoger el valor que mostrará al usuario

    • Escoger el valor que internamente se pasará al sistema de gestión

    • Las demás propiedades son similares a otras ya antes descritas; en este caso a las de un DDLB.

    Si dentro de un DataWindow no se desea usar una propiedad definida a una columna, se escoge la columna (del DataWindow) y se va a las propiedades de la misma, ahí se define el estilo de presentación bajo el cual quiere mostrarse la columna.

    Eliminación de una propiedad extendida

    Para ello se escoge el menú Design Edit Style Maintenance ahí se deternina cual propiedad quiere ser eliminada o bien mofificada.

    NOTA: cuando se añade una definición por defecto a la base de datos se aplicará solamente a los DataWindows que se creen en los sucesivo y no a los que ya están creados. Para los ya existentes, se puede usar la utilidad “DataWindow Extended Attributes Synchronizer (DWEAS)”, para sincronizar las propiedades de la columna del DataWindow con las de la columna de la base de datos.

    Definición de valores por defecto usando las especificaciones de columna en Row: (sobre el DataWindow) seleccionando Rows| Column specifications..., es posible también fijas valores por defecto para las columnas en el dataWindows.

    Aquí es posible fijar el valor inicial, la expresión de validación, un mensaje para validar y la columna de la base de datos relativa a la columna del Datawindow. Este cuador de diálogo es uno de los mejores medios para manipular los valores por defecto.

    Resumen de DataWindows

    • Paso 1

    • Origen

    • Estilo

    • Paso 2

    • Instrucción SQL

    • Paso 3

    • Diseño del dataWindows

    Manipulación de datos usando DataWindows

  • Iniciar

  • Causa que un control Datawindow o almacen de datos use un objeto de transacción que el programador el indique. El objeto transacción provee la información necesaria para comunicarse con la base de datos.

    La sintaxis que se usa para iniciar es por lo general:

    nomre_dw.SetTansobject(nombre_transacción); lo cual se indica en el

    evento open de la ventana donde está el control DataWindow; y lo que causa es como se dijo que se active el objeto transacción con relación al control DataWindow.

  • Recuperación de datos en el DataWindows

  • Al usar la función Retrieve() de DataWindow se limpia el búfer de este y se edita un SQL Select de Datawindow para la base de datos. El conjunto de resultados retornados desde la base de datos se almacena sobre el cliente en el búfer de DataWindow.

    Por ejemplo si se declarara un evento de usuario llamado ue_retrieve en un control DataWindow el código pordria ser como sigue:

    This . retrieve( )

    This . setfocus( )

    Si por el contrario se deseara llamar la función retrieve desde un botón de comando por ejemplo se podría usar:

    Nombre_dw.retrieve(); si se tuveran argumentos definidos cuando se diseño el DataWindow en la sección Retreval Arguments..., los mismos se indican como argumentos de la función nombre_dw.retrieve(lista_argumentos[,...])

    Si se incluye un argumento para la recuperación y posteriormente se desean hacer actualizaciones sobre el resultado devuelto no es necesario indicar el where como argumento otra vez pues el data window trabaja con el resultado revuelto por el evento de recuperación.

    NOTA: para modificar algún registro obtenido por el datawindow se modifica su valor directamente del resultado devuelto por el retrieve(). Luego en el evento que se tenga dispuesto para la actualización de la base de datos los cambios se harán permanentes.

  • Inserción de filas en un DataWindow

  • La función InsertRow( ) de DataWindow añade una nueva fila al DataWindow antes de la fila especificada, si ésta es cero, la nueva fial se añade al final del donjunto de resultado.

    Un suceso de definición de usuario tal como ue_insertrow, podría insertar una fila en el DataWindow con la llamada de función Insertrow(0). Se podría usar este método para insertar una nueva línea dentro de una factura, con un código como este:

    Long ll_row

    Ll_row = This . InsertRow(0)

    This . ScrollToRow(ll_row)

    This . SetColumn(1)

    This . Setfocus()

    Si se desea hacer la llamada a la función InsertRow, dentro de un boton de comando el código a introducir sería algo como este:

    Long ll_row

    Ll_row = nombre_dw. InsertRow(0)

    Nombre_dw. ScrollToRow(ll_row)

    Nombre_dw. SetColumn(1)

    Nombre_dw. Setfocus()

    Si la función InsertRow se llama sin ninguna otra función, el usuario debe hacer el scroll hasta la fila que PowerBuider disoponga para tal efecto, es por ello que se usan las funciones scrollToRow, SetColumn, y SetFocus().

  • Cancelación de filas en un DataWindow

  • Es importante confirmar una petición antes de cancelar una fila. Un código como el que sigue sobre un evento definido por el usuario que podría llamarse ue_deleterow, sobre la ventana que contiene el DataWindow

    Int li_rc

    Li_rc = messaggeBox(`Delete requested', &

    `Are you sure you wnt to delete row' + &

    string(This.getRow()) + `?', &

    StopSign!, yesno!, 2)

    If li_rc = 1 then

    This . DeleteRow(0)

    End if

    If this . Rowcount() = 0 then

    This . event ue_insertRow()

    End if

    Setfocus(This)

    Si se desea llamar la función deleteRow() desde un boton de comando la sintaxis puede ser como sigue:

    Nombre_dw.deleteRow(0), para eliminar la fila actual, o se especifica cual es la línea que se desea eliminar.

  • Actualización de la base de datos

  • La función UpDate() de DataWindow actualiza la base de datos con los cambios efectuados en el DataWindow. Un evento de usuario que bien podría llamarse ue_update de un Control DataWindow con un código como este podría cumplir esta función

    This. Update()

    This . Setfocus

    Si la función se desea llamar desde un botón de comando el código siguiente podría ser útil:

    If nombre_dw.update() > 0 then

    Commit using sqlca;

    If sqlca.sqlcode < 0 then

    ...falló el commit

    End if

    Else

    Rollback using sqlca;

    End if

    Aquí es importante destacar que la función update() trabaja como se ha dicho sobre el objeto datawindow que se indique. Esta función devuelve dos valores 1 cuando tiene éxito y -1 cuando fracasa; por lo que se necesita hacer permanentes los cambios en la base de datos mediante un commit y devolverla a us estado original mediante rollback si el commit falla. El update bien puede fallar por la intgridad de la base de datos ya que antes del update todo se mantiene en un buffer y es hasta el update que Power Builder valida contra la base de datos.

    Lo que se puede hacer para evitar posibles fallos en la función Update() es traspasar la integridad de la base de datos hacia las validaciones de las columnas del DataWindows o a las reglas de validación de las columnas de una tabla, para de esta manera obtener un aviso en el momento de la violación y no hasta que se ejecute el update().

    La función Print() de DataWindow imprime el contenido del búfer principal de DataWindow tal como se haya formateado en el pintor de DataWindow. Acontinuación se muestra el código para un evento que bien puede llamarse ue_Print

    This . accepText()

    This . print()

    This . setfocus()

    Driver Nativo

    Power Builder no solo puede comunicarse son sistemas gestores por medio de conexiones ODBC; sino que posee una serie de drivers nativos de diferentes sistemas gestores, a saber Informix, SQL Server, Oracle, Sybase, para hacer más eficiente su comunicación con los sistemas gestores que ya hemos mencionado.

    La configuración de un perfil de driver Nativo es muy similar a la configuración de un perfil para conexión mediante ODBC.

    Para crear un perfil mediante un dirver nativo, se escoge el ícono de perfil de la PowerBar y se escoge el sistema de gestión con el que se desea que la aplicación se comunique, una vez hecho esto, se escoge New del menú que se presenta.

    Con esto se consigue abrir el cuadro de diálogo Database Profie Setup. La principal diferencia entre éste y uno para conexión ODBC es la lengüeta conexión la cual pasamos a describir a continuación:

    • Profile Name

    • Connect Information

    • Sever nombre del servidor donde se encuentra instalada la base de datos

    • Log Id un usuario válido

    • Password el password que corresponda al Log Id

    • DataBase nombre de la base de datos (solo el nombre sin extensión)

    • Language lenguaje que se desea usar en la comunicación a SQL Server

    • Other

    • Isolation Level: nivel de aislamiento

    • Autocommit mode: autocommit despues de cada transacción

    • Commit on disconnect: commit despues de que desconecte la aplicación

    • Prompt for database information: Select this checkbox to be prompted for connection information when creating or selecting a profile to access a database.

    • Generate trace Select this checkbox to start the Database Trace tool in order to trace your connection.

    NOTA: Se puede trabajar por medio de driver nativo y además tener un archivo .Ini para la conexión de n usuarios.

    La principal diferencia entre los preview de una conexión de Driver nativo y una con ODBC, es que en driver nativo no se hace uso del DBPARM, que en conexiones con ODBC, con una cadena de conexión podíamos almacenar todos los parámetros necesarios para realizar la conexión, almacenábamos el nombre del DSN, usuario, password, ect.

    Ejemplo de preview con ODBC:

    // Profile Perfil_empleado

    SQLCA.DBMS = "ODBC"

    SQLCA.AutoCommit = False

    SQLCA.DBParm = "ConnectString='DSN=DSN_Empleado;UID=MakerTables;PWD=MakerTables;',PBCatalogOwner='MakerTables'"

    En cambio en el preview con dirver nativo se presenta una conexión como la siguiente:

    // Profile prf_Pubs_Nativo

    SQLCA.DBMS = "MSS Microsoft SQL Server 6.x"

    SQLCA.Database = "pubs"

    SQLCA.ServerName = "Gerardo"

    SQLCA.LogId = "sa"

    SQLCA.LogPass = "**"

    SQLCA.AutoCommit = False

    SQLCA.DBParm = ""

    Es ovbio, sin embargo lo apuntamos, en un ambiente de cliente servidor, tanto el usuario como el password se deben cargar en RunTime.

    Análisis de la aplicación Clase10

    La estructura general de la aplicación es tres ventanas (=w_ entrada, w_principal y w_mant), dos menúes (m_principal y m_mantenimiento -heredado de m_principal-), una estrucuctura -que en buena medida es parte fundamental de la aplicación- y varios data windows.

    Por otra parte la idea que está detrás de la aplicación es con solo un par de ventanas como las mensionadas, poder dar mantenimento a todas las tablas que una aplicación puedad tener, mediante el uso de funciones propias de Power builder que permiten entre otras cosas crear las ventanas que se necesiten en tiempo de ejeucción, pudiendo de esta manera eliminarlas, tambien en tiempo de ejecución, de una manera completamente transparente al usuario.

    Estructura: param_mant

    Está compuesta por dos campos de tipo string:

    • data object: es el nombre del objeto data windows que se usara para captura

    • Title: es el titulo que se desea para la ventana del mantenimiento

    En estas aplicación se posible tener abiertas (al mismo tiempo) diferentes ventanas del mismo tipo; es decir, diferentes ventanas por ejemplo para darle mantemimiento a una tabla de empleados al mismo tiempo. Es bajo este supuesto que se declara en la ventana w_principal, como varialbe de instancia, un arreglo del tipo w_mant

    Función: wf_abrir_mant ventana w_principal

    Lo que pretende es abrir una ventana, creada dinámicamente del arreglo de ventanas explicado antes, para dar mantenimento a una tabla en particular que pudiera ser cualquiera del modelo de datos, que esté respaldada en una datawindow ya definido. Para determinar el datawindows que debe dar mantenimiento a la ventana que se debe crear, esta función es llamada desde una opcion de menú que, también previamente definido, pase como parámetro en la estructura antes definida que datawindows se usará y el título que se pondrá a la ventana que se desea crear.

    Dentro de esta función está la función OpenSheetWithParm que lo que hace es abrir una hoja (=ventana) dentro de un MDI y almacenar un parámetro en la variables global message. Los parámetros que no son opcionales son:

    • Sheetrefvar La ventana que se desea abrir

    • Parameter El parámetro que respaldará a message

    • Mdiframe El objeto MDI dentro del cual se abrirá

    • Position El número de la opcion de menú dentro de MDI en la cual se pondrá el título de la sheet que se abrirá

    Otra de las funciones por rescatar dentro de esta función de ventana es GetActiveSheet que recupera la hoja activa dentro del MDI en el cual se ecuantra

    Ventana: w_mant: es la usada para dar mantenimiento a tantas tablas, como datawindows se tenga definido para ellas.

    Está compuesta gráficamente por dos objetos, a saber dos controles datawindows, que darán la opción tanto de dar mantemimiento como de servir de qbe a las mismas tablas que se les dé mantemimiento.

    Se debe hacer la diferencia entre dar mantenimiento y servir de consulta, mediante la utilización de dos datawindows idénticos solo con la diferencia del nombre; lo cual por facilidad de manejo sus nombres pueden diferir solo por un sifijo agregado al datawindow que servirá de consulta; hecho estó una vez que se tenga abierto el datrawindows de mantenimiento y se quiera una consulta sobre el mismo el menú que la llama solo la debe difereir agregandole al nombre de datawindow que se tenga abierto el sufijo que indicará el datawindow que se quiera para consulta.

    En lo que respecta a consultas PowerBuilder deja que la prmer fila del resultado que devolverá se use solo para ordenamiento según desee el usuario.

    En el evento open de esta ventana lo primero que se hace es agregarle a una variable de instancia (= p), definida dentro de w_mant, que es del tipo param_mant, el valor que contenga la varible global message este valor es el parámero que se pasó cuando se llamó a la función OpensheetWithParm() y como quien llama a la función es el menú mantenimiento de departmentos su valor será

    p.dataobject = "d_dep_01"

    p.Title = "MANTENIMIENTO DE DEPARTAMENTOS"

    por tanto en este evento lo que se hace es según esos parámetros, cargar el título de la ventana y el objeto datawindows que dará soporte al mantenimiento.

    Ejemplo:

    This.title = parametros.Title

    dw_1.dataobject = parametros.dataobject

    Algunas funciones dentro de los controles datawindows

    • ItemChanged determina cambios en alguna columna del datawindows

    • Getrow() determina la fila actual en la que se encuentra el cursor.

    • GetItemNumber determina de cual fila se está trayendo el valor

    • Setcolumn() se posiciona (internamente) en una column específica

    • SetItem() agrega un valor específico al datawindows

    • AcepText refresca los cambios hechos en el dataWindows

    Ejemplos:

    • Dw_1.acceptText()

    • DW_1.GetRow()

    • Dw_1.GetIemNumber(row, column) ver GetItemString, etc.

    • Dw_1.Setcolumn(column)

    • Dw_1.SetItem( row, column, value )

    NOTA: Para ventanas que tienen implícito mas de un datawindows se puede tratar toda la ventana como una sola transacción; ejemplo de esto es una factura donde se podría trabajar directamente con las tablas por medios de datawindows; aquí lo único que se debe ocultar al ussario es elenlace que debe existir entre el encabezado y el detalle de la factura; este enlace (en el datawindow del detalle se puede poner como no visible y asignarle el valor correspondiiente por medio de programación.)

    NOTA: Setiar la columna se refiere a pasarle valores por medio de los valores obtenidos en otras columnas.

    Ojo con el manejo de este objeto, pues sin un conocimiento serio de la herramienta se podrían dañar las librerías de Windows.

    Ver más adelante en este mismo resumen la explicación de por qué, no se recomienda generar conexiones ODBC desde el DBPROFILE o desde el CONFIGRE ODBC

    Requiere tener el evento open de la aplicación con algún código valido. E.i: Open(nombre_ventana)

    para agregar código a una aplicación se puede escoger el ícono script es la barra de menú, entre varias otras opciones que hay para acceder al script de la aplicación.

    El nombre de la aplicación no puede contener blancos

    Hay aún otra forma de tener acceso a las propiedades de la aplicación y es clicando en el menú Entry y luego en properties.

    Otra forma de agregar una ventana (ya existente a la aplicación es clicando sobre el icono Library. Esto permite ir y escoger alguna ventana - no solo de la aplicación activa - y agregarla a la aplicación activa)

    Se usará indistintamente en el resto de este resumen el término formulario del de ventana

    Es muy importante tener en cuenta los prefijos que maneja PB, porque muchos objetos no funcionan si en el nombre no se les proporciona el prefijo adecuado. Para ver la liste de prefijos clicar en el menú Design y luego sobre Options. La lista de prefijos se encuentra en las lengüetas Prefixes1 y Prefixes2.

    El resto de prefijos se pueden encontrar en el apéndice A (convenciones sobre los nombres) del libro Power Builder 6

    PB no permite abandonar una ventana de código que posea errores de compilación, entonces si se tiene que salir de una ventana que tenga errores de código se debe marcar todo el código del evento como comentario y salvar la ventana. Luego se podrá volver al evento en cuestión y depurarlo

    Si la versión del driver es mayor a la versión del sistema gestor que se use no tiene perjuicio, lo que importa es que la versión del driver contenida en el producto ODBC no sea menor a la del DBMS

    Se puede mover un elemento de menú de lugar usando la mano que aparece sobre la PowerBar

    El script para la actualización se escribirá más adelante, ver páginas 41-42 de este mismo documento.

    Si lo que se desea es que este DataWindow se muestre siempre que se accesa esta columna lo que se debe hacer es crear una propiedad extendida sobre la columna con el pintor de base de datos. Ver “Propiedades extendidas” en este mismo documento.

    Ver sección Editar campos del DataWindow, en la página anterior.

    El servidor de ULACIT se representa como: @tns.labs TNS = tnsnames, que es una cadena de configuración del servidor. Para más información: Oracle NetWork Adm tnsnames.ora.

    SQL AnyWhere

    Server Oracle

    Algún modelo de datos

    Destino del modelo de datos

    Son variables de SQLCA

    Aplicación

    Cód. de error

    Flujo normal

    CLIENTE

    En ambientes cliente servidor, se requiere instalar en el cliente una versión mínima del DBMS, que en el caso de Oracle es Oracle/client

    Server

    SERVER

    ODBC

    SqlCa

    .Ini

    CLIENTE

    .Ini

    Se define la variable de transacción

    Window

    Ctrol DW

    Object DW

    Clase

    Transaction

    (SQLCA)

    Drivers

    [&

    Red]

    Data Base

    Iniciar

    Recuperar

    Insertar

    Actualizar

    Borrar

    Etc.