Upload
vanthuy
View
230
Download
2
Embed Size (px)
Citation preview
MANUAL DE PROGRAMACIÓN
MANUAL DEL DISTRIBUIDOR
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 1
Contenido
INTRODUCCIÓN A LA PROGRAMACIÓN ERP. .................................................................................. 4
Introducción ............................................................................................................................................... 4
Requerimientos ......................................................................................................................................... 4
Herramientas de desarrollo. ................................................................................................................... 4 Cómo instalar una librería o control OCX. ............................................................................................ 5
Metodología y estándares de desarrollo. ....................................................................................... 5
Nomenclatura de variables y funciones. ................................................................................................ 6 Nomenclatura de archivos. .................................................................................................................... 7 Aspecto general de la aplicación ........................................................................................................... 8
Programación orientada a objetos .................................................................................................. 12
PREPARAR EL ENTORNO ......................................................................................................................... 13
Máquina virtual ....................................................................................................................................... 13
Software necesario y licencias ........................................................................................................... 13
Ahora ERP ................................................................................................................................................. 14
Plantilla de proyectos ........................................................................................................................... 14
Crear un proyecto a partir de la plantilla ...................................................................................... 15
COMENZAR A PROGRAMAR NUESTRA APLICACIÓN .................................................................. 16
Inicio de la aplicación ........................................................................................................................... 16
Crear Proyecto de Inicio ...................................................................................................................... 16
Propiedades .......................................................................................................................................... 16 Código ................................................................................................................................................. 22
Creación de un proceso externo ...................................................................................................... 26
Descripción .......................................................................................................................................... 26 Propiedades del proyecto ..................................................................................................................... 26 Módulos, clases y formularios ............................................................................................................. 30 Procesos ............................................................................................................................................... 31 Codificación de clases, módulos y formularios ................................................................................... 37 Compilar el proyecto ........................................................................................................................... 45
OBJETOS EN EL SISTEMA ......................................................................................................................... 46
Introducción ............................................................................................................................................. 46
Definición de clases y objetos ........................................................................................................... 46
Relación Objeto – Objeto.................................................................................................................... 47
Definición de propiedades ................................................................................................................. 47
Creación de objetos .............................................................................................................................. 47
Pasos para definir un nuevo objeto ...................................................................................................... 48
Objetos del motor del sistema ......................................................................................................... 49
Objeto Conexión .................................................................................................................................. 49 Objeto OBJ .......................................................................................................................................... 52 Objeto Colecciones .............................................................................................................................. 53
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 2
Objeto IItem ......................................................................................................................................... 55
Manejo de objetos ................................................................................................................................. 64
Instanciar un nuevo objeto y completar sus propiedades. .................................................................... 65 Recuperar un objeto existente y agregarle un hijo. .............................................................................. 65
CONTROLES AHORA ................................................................................................................................. 67
Introducción ............................................................................................................................................. 67
Control EnlaceObjetos ......................................................................................................................... 67
Propiedades .......................................................................................................................................... 68 Métodos y funciones. ........................................................................................................................... 68 Ejemplo de cómo vincular un objeto al control EnlaceObjeto ............................................................ 69
Control TextoUsuario ............................................................................................................................ 71
Propiedades .......................................................................................................................................... 72 Eventos. ............................................................................................................................................... 73
Control TextoMultilinea. ...................................................................................................................... 73
Control LabelUsuario ............................................................................................................................ 74
Propiedades .......................................................................................................................................... 74 Eventos ................................................................................................................................................ 74
Control Botonera .................................................................................................................................... 74
Propiedades .......................................................................................................................................... 75 Eventos ................................................................................................................................................ 76 Métodos y funciones. ........................................................................................................................... 76 Ejemplo de agregar un botón de tipo Combo: ..................................................................................... 77
Control CheckBoxUser ......................................................................................................................... 78
Propiedades .......................................................................................................................................... 78 Eventos. ............................................................................................................................................... 79
Control cntMenuFormulario. ............................................................................................................. 80
Propiedades .......................................................................................................................................... 80 Eventos ................................................................................................................................................ 81 Métodos y funciones. ........................................................................................................................... 81 Ejemplo: Agregar menús desde formulario. ........................................................................................ 82 Ejemplo: Agregar menús desde tablas ................................................................................................. 83
Control ComboUsuarioMult............................................................................................................... 85
Propiedades .......................................................................................................................................... 85 Eventos. ............................................................................................................................................... 87
Control ComboUsuario ........................................................................................................................ 87
Propiedades .......................................................................................................................................... 87 Eventos ................................................................................................................................................ 89 Ejemplo: .............................................................................................................................................. 90
Control CntTab ........................................................................................................................................ 90
Ejemplo de creación de un CntTab con 2 pestañas .............................................................................. 91
Control cntGridUsuario ........................................................................................................................ 91
Propiedades .......................................................................................................................................... 91 Métodos y funciones ............................................................................................................................ 95 Eventos ................................................................................................................................................ 98 Objeto CampoGrid .............................................................................................................................. 99 Cosas importantes a tener en cuenta sobre los grids .......................................................................... 101 Ejemplo ARRAY sin origen de datos y campos sustitución.............................................................. 101 Ejemplo de grid sólo ARRAY usando Alias y campos calculados.................................................... 102 Ejemplo de grid de sólo lectura con Alias y filtro WHERE. ............................................................. 103 Ejemplo de grid con colecciones y asistentes F3. .............................................................................. 104
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 3
Ejemplo Grid con colecciones con cargando Objetos ....................................................................... 105
Formulario de mantenimiento ....................................................................................................106
EJEMPLO: CREACIÓN DE UN OBJETO EN EL SISTEMA ...............................................................108
Introducción ...........................................................................................................................................108
Creación de tablas ...............................................................................................................................109
Tabla ObjsPrueba .............................................................................................................................. 109 Tabla ObjsPrueba_Lineas .................................................................................................................. 110 Definición de Propiedades ................................................................................................................. 111 Definir el objeto en tabla ................................................................................................................... 111 Tabla Configurables .......................................................................................................................... 112 Triggers .............................................................................................................................................. 113 Vistas ................................................................................................................................................. 114
Definir objeto en librería ...................................................................................................................114
Método ValoresPredeterminados(). ................................................................................................... 122
Crear formulario del objeto..............................................................................................................122
Controles ............................................................................................................................................ 122 Código del formulario........................................................................................................................ 126 Crear ObjForms.cls ............................................................................................................................ 132
CONFECCIÓN DE FORMULARIOS ......................................................................................................135
Formularios .............................................................................................................................................135
Dimensión y ubicación de controles: ................................................................................................. 135 Redimensión automática: ................................................................................................................... 136
Controles de formulario: ...................................................................................................................137
Combo o Texto .................................................................................................................................. 137 Fecha: ................................................................................................................................................ 137 Hora: .................................................................................................................................................. 137 Numérico: .......................................................................................................................................... 137 Grid usuario: ..................................................................................................................................... 137 Botonera: ........................................................................................................................................... 140 Menús: ............................................................................................................................................... 143
Añadir objetos nuevos dinámicamente a al colección de objetos ....................................144
Uso ..................................................................................................................................................... 145 Funcionalidad .................................................................................................................................... 145
Funcionamiento CadenaDescrip ....................................................................................................146
F.A.Q. .............................................................................................................................................................147
Error del control Active x: No se puede cargar ‘C:\Plantilla\Externo\AhoraOCX.Ocx’--
¿Desea continuar cargando el proyecto? ...................................................................................147
Error de compilación: No se puede encontrar el proyecto o la biblioteca ....................148
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 4
INTRODUCCIÓN A LA PROGRAMACIÓN ERP.
Introducción
Cuando programamos aplicaciones personalizadas basadas contra un sistema ERP,
debemos tener en cuenta que sus desarrolladores utilizan un estándar conciso de
programación, así como herramientas y controles personalizados.
Primero deberemos preparar nuestro equipo con las herramientas básicas de
desarrollo, y muchas veces cambiar nuestra forma de programar, adaptándonos a los
estándares del fabricante. Esto último es importante a la hora de utilizar herramientas
que nos proporcionan, que actúan según determinados parámetros, prefijos o sufijos
incorporados al código o archivos que componen nuestros proyectos.
Requerimientos
Herramientas de desarrollo.
Para facilitar estas tareas, hemos desarrolado un punto llamado ‘PREPARAR EL
ENTORNO’. Si va a trabajar con nuestra máquina virtual, le recomendamos que vaya a
este punto y siga los puntos que se detallan en él.
Para comenzar a programar necesita tener instalado en su equipo las siguientes
herramientas de desarrollo:
Entorno ERP de Ahora Soluciones.
SQL Server 2005.
Visual Basic 6.0 (SP 6).
Crystal Reports 11.
Además deberán instalar librerías y controles tales como:
CEESIDll.dll
ctSchedule.ocx
gif89.dll
MSOUTL.OLB
NeroCom.dll
PVCombo.ocx
SQLDMO80.cnt
SQLDMO.DLL
Flex Grid 7 (ActiveX Controls).
Sheridan Developers ToolKit (Active Listbar).
Sheridan Developers ToolKit (Data Widget).
True Grid 6.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 5
TrueDBGrid 6.
Controles 3.0 Xtrem.
Controles Infragistic NetAdvantage51.
Para que su programa se integre correctamente con el ERP, necesitará incorporar los
siguientes objetos a su proyecto:
Hooks.bas
ConexionCargaLib.cls
Constantes.bas
Cómo instalar una librería o control OCX.
1. En primer lugar, deberá verificar que tiene permisos de administrador en
el equipo. Debe ser administrador del equipo para registrar una librería.
2. Copie el archivo con extensión DLL u OCX en la carpeta
“c:\WINDOWS\system32”
3. Abra el menú Inicio y vaya a la opción “Ejecutar”. En la pantalla de
ejecución escriba el comando REGSVR32, seguido de la ruta del archivo
entre comillas, como marca el ejemplo:
El uso es: Regsvr32 [/u] [/s] <nombre del fichero>.
Los parámetros opcionales [/u] [/s] significan lo siguiente:
[/u] - lo utilizamos cuando queremos "desregistrar" una DLL (o un .OCX) en vez de
registrarlo.
[/s] - modo "silencioso" - no despliega los mensajes durante la operación.
Metodología y estándares de desarrollo.
Los estándares nos ayudan a desarrollar de forma rápida y comprensible para cualquier
programador. Además de conseguir una lectura consistente de los códigos fuente, es
importante mantener el mismo estilo de programación en todo el código. Intente
escribir y dar formato a su código fuente de acuerdo al estándar, así será más sencillo
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 6
que otras personas mantengan esos archivos, y más fácil copiar porciones de un código
a otro.
Para programar aplicaciones integradas a un ERP como el de Ahora Soluciones, es
estrictamente necesario adaptarse al estándar de desarrollo del mismo, ya que existen
herramientas externas que nos pueden ayudar a resolver varios inconvenientes y que
funcionan de acuerdo a un estándar. Nos ayudan, por ejemplo, a recompilar nuestros
proyectos para que funcionen con una nueva versión del ERP.
Además de las normas básicas de codificación, como la indentación o la nomenclatura
de variables, veremos también la manera de dar nombre a nuestros proyectos y clases.
A continuación propondremos algunas, y otras se irán viendo a lo largo del manual o
con ejemplos.
Nomenclatura de variables y funciones.
Intente dar un nombre autoexplicativo a las funciones y sus variables e indentar el
código para que se pueda leer claramente.
Ejemplo:
Private function eliminarLineasConArticulosYCantRepetidas (aIdFactura As Long) as Boolean
On Error GoTo ElError
Dim lIdLinea As Long
Dim lObjLinea As Object
Dim lColLineasFactura As Collection
….
Set lColLineasFactura = dameLineasFactura (aIdFactura)
For Each lObjLinea In lColLineasFactura
…..
Next lObjLinea
….
Exit Function
ElError:
MsgBox Err.Description, vbCritical, "Error en la aplicación X"
End function
Llame a las variables locales con el prefijo “l” de local, a las variables en la
cabecera del módulo con el prefijo “p”, a las variables constantes con el prefijo “c”
y a las variables recibidas por parámetro con el prefijo “a”. De esta manera podrá
identificar claramente a qué variable está haciendo referencia.
Evite en lo posible variables públicas o globales.
Intente dividir el código de manera que no se encuentren funciones
extremadamente cargadas de líneas de código. Cuanto más corto es un
procedimiento, más fácil es de entender y de depurar.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 7
Nomenclatura de archivos.
Cuando creamos un nuevo proyecto, como por ejemplo uno de tipo DLL ActiveX, le
llamaremos “[Empresa]Externo” y el archivo se llamará
“[Empresa]Externo_[NombreProgramador].vbp”.
En el momento de generar el proyecto y compilarlo, lo haremos sobre uno al que
llamaremos “[Empresa]Externo_Compilar.vbp”. De esta manera, tendremos un solo
proyecto al que reconoceremos al momento de compilar, y podremos diferenciarlo de
aquellos en los que están trabajando los programadores.
Esta forma de trabajar puede cambiar en su entorno. Es sólo una de las muchas
opciones existentes a la hora de nombrar archivos cuando se comparte código fuente.
Ejemplo:
Proyecto a compilar
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 8
Proyecto con el que trabaja el programador
Aspecto general de la aplicación
Un elemento básico a tener en cuenta en todo desarrollo es la interfaz de usuario. El
aspecto general de la aplicación debe ser uniforme. Intente mantener el aspecto
general de su aplicación basándose en los formularios del ERP. Revise cuidadosamente
la ortografía tanto en los elementos fijos en pantalla (botones, etiquetas, barras de
título, etcétera) como en los mensajes de advertencia, error o confirmación. Debe
cuidar también la navegación en pantalla ordenando la tabulación entre controles
mediante la propiedad “TabIndex”.
Tenga en cuenta también, que sus formularios deben adaptarse a la mínima resolución
de pantalla exigida en el ERP. En la versión 4.0 es de 1024x768 píxeles.
A continuación, se muestran ejemplos con los formularios más comunes en el entorno.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 9
Formulario de mantenimiento de tabla
Se compone de una barra de título, una tabla o grid y una barra con botones en la base
de la ventana.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 10
Formulario con filtro
Se compone de un menú, una barra de título, un panel de filtro con los campos y los
botones de filtrado, una o varias grids con los resultados obtenidos de la filtración, y la
botonera en la base.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 11
Formulario de objeto
Se compone de una barra de menú, una barra de título, un panel con los datos de la
cabecera del objeto, un grid con las líneas pertenecientes al objeto, y la barra de
botones al pié.
Tablas
Siempre que cree una tabla en SQL, tenga en cuenta que, excepto las tablas de
configurables, todas contienen al final 4 campos comunes:
Campo Tipo de datos Permite nulos Especificación de identidad
IdDoc T_Id_Doc:int NO SI
InsertUpdate T_CEESI_Insert_Update:bit NO NO
Usuario T_CEESI_Usuario:varchar(20) NO NO
FechaInsertUpd
ate
T_CEESI_Fecha_Sistema:datet
ime
NO NO
SIEMPRE QUE CREE UNA TABLA, ASEGÚRESE DE CREAR LOS CAMPOS MENCIONADOS, LOS CUALES
DEBEN SER LOS ÚLTIMOS EN DECLARARSE. CUIDE LA INTEGRIDAD DE LOS DATOS CREANDO
BORRADOS EN CASCADA Y TRIGGERS.
Muchas veces, sucede que tenemos definido un objeto con su tabla, y necesitamos
agregar más campos. Para estos casos, lo correcto es crear una tabla anexa a la del
objeto, donde especificaremos los nuevos campos. La tabla debe llamarse
Conf_[Nombre de la tabla principal] y que ha de contener las mismas claves que la
tabla principal y los campos que deseamos agregarle. NO DEFINA LOS CAMPOS IdDoc,
InsertUpdate, Usuario y FechaInsertUpdate EN TABLAS CONFIGURABLES. Los campos
configurables se crean en el Admon. [Vea el manual de ADMON]
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 12
Siempre que hablemos de campos que estén definidos en éstas tablas, los llamaremos
campos configurables.
El motor del sistema y sus objetos manejarán los campos configurables de manera
automática.
Programación orientada a objetos
La aplicación está desarrollada basándose en objetos, es decir, que quien realice un
desarrollo contra el ERP de Ahora Soluciones, deberá tener conocimientos en lenguajes
de programación orientada a objetos. Si bien Visual Basic 6.0 no es un lenguaje
íntegramente orientado a objetos por carecer de conceptos como la herencia y el
polimorfismo, nuestro equipo de desarrollo simuló una herencia utilizando una Interfaz.
Es por esto que el motor de la base de datos se encuentra debidamente encapsulado,
definiendo los métodos y funciones en objetos.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 13
PREPARAR EL ENTORNO
Máquina virtual
Para facilitar el desarrollo de módulos externos, hemos preparado una máquina virtual
de Windows XP donde ya están instaladas tanto las librerías como el software necesario
para poder desarrollar sus módulos externos.
Nuestra máquina está virtualizada con VirtualBox, por lo que, si no lo tiene instalado en
su ordenador, deberá descargarlo e instalarlo antes de poder continuar. Descargue e
instale el paquete necesario según el sistema operativo anfitrión. En la página web de
VirtualBox hay documentación acerca de la configuración y uso de la máquina virtual.
Una vez tenga preparado Virtualbox instale el archivo .ova que le hemos facilitado. La
configuración de la red dependerá de su organización.
Contacte con el personal de sistemas de su empresa si tiene alguna duda en este
punto.
Software necesario y licencias
Debe tener en cuenta que, para poder usar la máquina de forma correcta, debe indicar
sus propias licencias
Sistema operativo: Microsoft Windows XP Profesional SP3
Ahora ERP (la versión para la que quiera desarrollar)
Software de desarrollo:
SQL Server 2005.
Visual Basic 6.0 (SP 6).
Crystal Reports 11.
Programa de compresión de archivos
Controles de VB:
CEESIDll.dll
ctSchedule.ocx
gif89.dll
MSOUTL.OLB
NeroCom.dll
PVCombo.ocx
SQLDMO80.cnt
SQLDMO.DLL
Flex Grid 7 (ActiveX Controls).
Sheridan Developers ToolKit (Active Listbar).
Sheridan Developers ToolKit (Data Widget).
True Grid 6.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 14
TrueDBGrid 6.
Controles 3.0 Xtrem.
Controles Infragistic NetAdvantage51.
Instamos a comprar su propio software y controles, así como cambiar las licencias de
la máquina.
Cabe indicar que la mejor opción para realizar sus propios desarrollos para distintas
versiones de nuestra aplicación Ahora ERP consiste en tener una máquina virtual por
versión. Habrá que tener instalado en cada una el MSI correspondiente a la versión
para la que quiere programar, así como la plantilla correspondiente para cada versión.
Otra opción es tener una única máquina virtual y en ella instalar o desinstalar el MSI
para el que se vaya a programar cada vez, así como cambiar la versión de la plantilla de
desarrollo cada vez. Sin embargo, esta última opción es más costosa de mantener y
puede provocar errores si no cambia correctamente el MSI o la plantilla de desarrollo.
Ahora ERP
Para evitar problemas con las rutas de las librerías de Ahora ERP, le recomendamos que
lo instale en la siguiente ruta: C:\Ahora3\
En caso contrario, podrán surgir algunos problemas con las rutas de las referencias de
su nuevo proyecto, que se solucionarían cambiando dichas referencias desde el
proyecto de visual basic, como se indica en las F.A.Q.
Plantilla de proyectos
Para facilitar el trabajo, hemos creado una plantilla de proyectos. Esta plantilla podría
cambiar de una versión de Ahora ERP a otra, por lo que, antes de empezar a
programar, le recomendamos que visite nuestro servidor de plantillas y compruebe que
las versiones de la plantilla y del MSI instalado en la máquina virtual coinciden.
Nuestra plantilla tiene la siguiente estructura:
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 15
Recomendamos guardar esta estructura de datos como plantilla y hacer una copia de la
carpeta cada vez que tenga que hacer un proyecto nuevo, así como hacer una copia de
seguridad por si en algún momento la sobrescribe poder recuperarla. En el peor de los
casos, siempre puede volver a descargarla del servidor de plantillas.
Crear un proyecto a partir de la plantilla
Para empezar a programar, necesitará abrir el archivo PlantillaExterno.vbp y comenzar
a añadir su código.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 16
COMENZAR A PROGRAMAR NUESTRA APLICACIÓN
Inicio de la aplicación
Una vez preparado el entorno, podremos comenzar a desarrollar nuestra aplicación
externa al ERP.
A continuación, explicaremos paso a paso la creación de un desarrollo externo.
También veremos también los usos de las principales librerías que contiene el motor de
la aplicación, así como sus métodos y funciones básicas necesarias para programar.
Crear Proyecto de Inicio
Propiedades Nuestro programa externo necesitará una aplicación de inicio que arranque el motor
del sistema de gestión. Por tanto, el primer paso será crear un proyecto de inicio. Éste
será común a todos los externos que utilice, por lo cual no es necesario que lo cree
siempre. Si ya está creado, añádalo a su grupo de proyectos donde genere el desarrollo
externo y establézcalo como inicial.
Puede usar nuestra plantilla para ello y saltarse este punto, aunque le recomendamos
su lectura para comprender mejor la estructura de nuestros proyectos.
1. Abra Visual Basic 6.0.
2. Cree un nuevo proyecto de tipo EXE ESTANDAR
3. Complete las propiedades pestaña a pestaña, como se muestra a
continuación:
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 17
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 18
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 19
4.
necesarias como se muestra a continuación. Tenga en cuenta que las
versiones de las librerías irán ascendiendo a medida que se vaya
actualizando el ERP.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 20
5. as librerías
necesarias como se muestra a continuación.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 21
6. Crear formulario de inicio.
Cree un nuevo formulario, llámelo FrmMain e inserte un objeto
SKinFramework.
7. A continuación cree un módulo y llámelo “Global” de manera que en el
árbol de proyectos, el proyecto de inicio se vea de la siguiente manera:
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 22
8. Por último, y antes de empezar a ver el código del formulario y del
módulo, si dentro de su grupo de proyectos tiene más de uno, debe
establecer el proyecto de inicio como inicial haciendo clic derecho y
seleccionando la opción.
Código
En todos los módulos, clases y formularios conviene requerir la definición de variables,
seleccione “Requerir declaración de variables”. Con esto se asegura de que, por
defecto, se creen los módulos con la instrucción Option Explicit en la cabecera del
módulo.
También establezca la opción Option Compare Text, para que las comparaciones de
texto no contemplen mayúsculas y minúsculas.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 23
Formulario Principal:
A todos los formularios, les crearemos una instrucción pública llamada “Carga” donde
definiremos los parámetros iniciales del mismo, y donde se establecerá el
funcionamiento inicial y su apertura. Siempre que creemos un objeto de tipo
formulario, lo llamaremos mediante su función “Carga”.
Como dijimos anteriormente, en el objeto del formulario pondremos un control
SKinFramework que servirá para cargar el estilo visual personalizado de la aplicación.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 24
Código del formulario principal:
A continuación haremos una breve presentación del código para presentar las clases de
servicios más importantes del sistema.
Función de inicio de formularios, lo aplicaremos
como estándar en todos.
Clase Conexión, perteneciente a AhoraSistema.dll. Es la clase más
usada, será nuestro manejador, ya que contiene las funciones más
importantes para: Realizar consultas a la base de datos, crear
objetos y colecciones y buscar objetos y colecciones.
Establece el estilo, la visualización personalizada del entorno.
Debe especificar la ruta de la carpeta de estilos
Inicia el explorador de objetos. Observe que a través del obj. Conexión hacemos
una llamada a un objeto a partir de su propiedad “IdLink”. El objeto se llama
Ahora_Links, el cual tiene asociado un proceso, que es el que se ejecuta. (Más
adelante explicaremos lo que son los nodos, los links y toda la gestión de
objetos).
Cierra el entorno y establece la conexión a NULL
La función dameValorCampo nos devuelve un Variant con el
campo solicitado en la instrucción SQL.
La función VGetNumber convierte un variante en un Long. En la
librería AhoraUtil podremos encontrar funciones de este estilo
que nos facilitarán el trabajo.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 25
Código del módulo:
Terminaremos presentando el código del módulo global que inicia y lanza nuestra
aplicación de gestión.
Conexión.Conecta lanza la pantalla
de inicio que se encarga de establecer
la conexión con la base de datos
Hace la llamada a nuestro formulario principal y
le pasa la conexión establecida en la pantalla de
inicio.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 26
Creación de un proceso externo
Descripción
Nuestro proyecto consistirá en la creación de un proceso que abrirá una pantalla con
los artículos de un proveedor. Será accesible desde el menú de gestión. La pantalla
tendrá un combo, un grid y una barra de botones. El combo deberá desplegar los
proveedores del sistema y al seleccionar uno, el grid nos enseñará sus artículos. La
barra de botones tendrá un botón de imprimir y otro de cerrar.
Propiedades del proyecto
Empezaremos creando un nuevo proyecto al que llamaremos PlantillaExterno.
Incorporamos los componentes y referencias necesarios y configuramos las
propiedades del proyecto como indican las imágenes.
Si va a utilizar la plantilla proporcionada correspondiente a la versión para la que
vamos a programar, puede pasar directamente a procesos, aunque es recomendable
que lea los puntos intermedios para conocer la estructura.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 27
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 28
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 29
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 30
Módulos, clases y formularios
Módulos
Incorporamos la última versión de Hooks (Hook.bas) y crearemos un módulo al que
llamaremos Principal (Principal.bas), que se encargará básicamente de instanciar la
conexión.
Formularios
Crearemos un nuevo formulario al que llamaremos frmControles (frmControles.frm).
Control: EnlaceObjetos
Nombre: Titulo
Control: cntPanel
Nombre: pnlProveedor
Control: ComboUsuarioMult
Nombre: cboIdProveedor
Control: cntGridUsuario
Nombre: grdArticulos
Control: cntBotonera
Nombre: Botonera
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 31
Clases
Incorporaremos la última versión de ConexionCargaLib (ConexionCargaLib.cls) y
crearemos una nueva clase llamada Procesos (Procesos.cls).
Cabe destacar que tanto Hooks.bas como ConexionCargaLib.cls deben ser siempre los
mismos en todos los proyectos. Cuando reciba una nueva versión de Hooks o de
ConexionCargaLib, actualice los proyectos y recompile las librerías para que vayan de
acuerdo con la última versión del sistema.
Procesos
Introducción
Para crear un proceso, debemos saber cómo actúa el motor del sistema.
Aprovecharemos el ejemplo actual para explicar algunos conceptos como proceso, link
y nodo.
Nosotros queremos hacer un proceso que sea llamado desde un link en el árbol del
“menú gestión”. Para ello necesitaremos crear una entrada o nodo en el árbol del
menú, y un link en esta entrada para que llame a nuestro proceso (que estará
contenido en nuestro proyecto de Visual Basic).
Árboles y Nodos
Un árbol es una estructura jerárquica de datos que imita la forma de un árbol (un
conjunto de nodos conectados). Un nodo es la unidad sobre la que se construye el
árbol y puede tener cero o más nodos hijos conectados a él. Se dice que un nodo a es
padre de un nodo b si existe un enlace desde a hasta b (en ese caso, también decimos
que b es hijo de a). Sólo puede haber un único nodo sin padres, que llamaremos raíz.
Un nodo que no tiene hijos se conoce como hoja. A los demás nodos (tienen padre y
uno o varios hijos), se les conoce como rama.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 32
En nuestro caso, nuestro árbol será el árbol de menú de inicio, cuyo nodo padre
(MENUMAIN) no es visible.
Tendremos que crear un nodo (MNUPRUEBA) que “cuelgue” de su padre
(MNUGESTION) y otro nodo (MNUPRUEBA_CTRL) que cuelgue de MNUPREUBA.
Para gestionar nuestros árboles, tenemos tablas donde se crean y vinculan los nodos.
Estas tablas son:
Ahora_Nodos: Tabla donde damos de alta los nodos
Ahora_Nodos_Relacion: Tabla donde relacionamos el nodo con su nodo padre.
Script de creación y colocación de un nodo en un árbol
Declare @Descrip varchar(50)
Declare @MENUNuevo varchar(15)
Declare @MENUPadre varchar(15)
Declare @Orden int
SET @MENUNuevo ='MNUPRUEBA'
SET @Descrip='Plantilla Pruebas'
SET @MENUPadre = 'MNUGESTION'
-- CREAR NODO MENU PRUEBA
IF NOT EXISTS( SELECT IdDoc FROM Ahora_Nodos WHERE IdNodo=@MENUNuevo)
INSERT INTO [Ahora_Nodos] ([IdNodo], [Activo],[Descrip], [Icono], [IdLink], [IdAhoraProceso],
[Expandido], [Visible], [Enabled], [Destacado])
VALUES (@MENUNuevo,1,@Descrip,123,NULL,NULL,0,1,1,0)
ELSE
PRINT 'Ya existe una entrada para el nodo '+ @MENUNuevo+'.'
IF NOT EXISTS (SELECT IdDoc FROM Ahora_Nodos_Relacion
WHERE IdNodo=@MENUNuevo AND IdNodoPadre=@MENUPadre)
BEGIN
SELECT @Orden =Max(Orden)+1 FROM Ahora_Nodos_Relacion WHERE
IdNodoPadre=@MENUPADRE
INSERT INTO Ahora_Nodos_Relacion(IdNodo,IdNodoPadre,Orden)
EXPLORADOR
MENUMAIN
MNUGESTION
MNUARCHIVO
MNUADMINISTRA2
MNULISTADOS
MNUGESCLIENTES
MNUPRUEBA
MNUPRUEBA_CTRL
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 33
VALUES (@MENUNuevo,@MENUPadre, @Orden)
END
ELSE
PRINT 'Ya existe la relación para para el nodo ' + @MENUNuevo + ' padre ' + @MENUPadre +
'.'
GO
Una vez hayamos ejecutado este script, si abrimos el ERP y vamos a Menú / Gestión,
veremos que se habrá creado una carpeta llamada “Plantilla Pruebas”. Sólo resta crear
el proceso y el nodo que lo llame.
Recuerde que también puede crear los nodos en el ADMON de manera fácil y segura.
Links
Un Link es un objeto que establece una relación hacia otro objeto. Los Links se
almacenan en la tabla Ahora_Links y hacen referencia a un objeto de una colección. Si
un nodo de un árbol contiene un Link, al hacer clic sobre él, lo que hace es ejecutar el
objeto relacionado, ya sea abriéndolo o (si es un proceso) ejecutándolo.
Tipos de proceso
Si queremos que una función pueda ser ejecutada desde cualquier otra librería,
simplemente nos bastará con crear el objeto proceso en la base de datos, y el propio
motor del ERP se encargará de ejecutarla cuando alguien la llame.
Para el sistema, un proceso es un objeto que describe un método o función pública
almacenada en una clase de una librería. La librería debe estar incorporada al ERP y el
proceso tiene que existir en la tabla Ahora_Procesos. Hay 4 tipos de procesos
definidos, de los cuales nos interesan sólo 2:
Procesos tipo 2 – Librería Rutinas
Son aquellos que existen en una librería y los ejecutamos directamente mediante
CONEXION.AhoraProceso ().
Ejemplo:
1. En nuestro proyecto de prueba, dentro de la clase Procesos, creamos la
siguiente función:
Option Explicit
Option Compare Text
Private Const cModuleName = "Procesos"
Public Function Mensaje(Optional aMensaje As String = "") As Boolean
On Error GoTo Error_
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 34
If aMensaje = "" Then
MsgBox "Hello World", vbInformation
Else
MsgBox aMensaje, vbInformation
End If
Mensaje = True
End_:
Exit Function
Error_:
gCn.Tr.Trace TError, cModuleName, " HelloWorld", , Err.Description
Resume End_
End Function
Como se puede apreciar, la función Mensaje lo que hace es mostrar un MSGBOX con el
texto que se recibe por parámetro.
2. Una vez hayamos creado la función Mensaje, creamos el objeto Proceso.:
Declare @IdAhoraProceso varchar(50)
Declare @Libreria varchar(50)
Declare @ClaseProc varchar(50)
Declare @MetodoProc varchar(50)
Declare @Descrip varchar(50)
Declare @Observ varchar(250)
SET @IdAhoraProceso='Plantilla_Mensaje'
SET @Libreria='PlantillaExterno'
SET @ClaseProc = 'Procesos'
SET @MetodoProc='Mensaje'
SET @Descrip='Mensaje'
SET @Observ =''
-- CREAR AHORA_PROCESO
IF NOT EXISTS (SELECT IdDoc FROM [Ahora_Procesos] WHERE
IdAhoraProceso=@IdAhoraProceso)
INSERT INTO [Ahora_Procesos]([IdAhoraProceso] ,[Descrip], [IdTipo], [Libreria], [Clase],
[Metodo],[IdLlamada], [RetornoTipo], [RetornoObjeto], [CheckParam], [Observaciones], [Macro])
VALUES (@IdAhoraProceso, @Descrip,2, @Libreria, @ClaseProc ,@MetodoProc,1,NULL,0,'False',
@Observ,0)
ELSE
PRINT 'Ya existe un proceso llamado ' + @IdAhoraProceso + '.'
3. Habiendo declarado la función y creado el objeto proceso, podremos
hacer referencia a la función desde cualquier otra aplicación integrada
en el ERP:
Option Explicit
Option Compare Text
Public gCn As Conexion
Public Function Prueba () As Boolean
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 35
On Error GoTo Error_
Prueba = gCn.AhoraProceso("Plantilla_Mensaje", False, "Prueba")
Exit Function
Error_:
gCn.Tr.Trace TError, cModuleName, " Prueba ", , Err.Description
Resume End_
End Function
Proceso tipo 3 – Tipo Macro
Son aquellos que se ejecutan automáticamente, mediante un Link, al hacer clic en un
nodo.
Es el tipo de proceso que necesitaremos para nuestro ejemplo.
Script de creación de un proceso unido a un link y a un nodo que lo ejecuta.
Declare @IdAhoraProceso varchar(50)
Declare @Libreria varchar(50)
Declare @ClaseProc varchar(50)
Declare @MetodoProc varchar(50)
Declare @Descrip varchar(50)
Declare @Observ varchar(250)
Declare @MENUNuevo varchar(15)
Declare @MENUPadre varchar(15)
Declare @Orden int
Declare @IdTecla int
Declare @IdDoc t_Id_Doc
Declare @IdLink int
SET @IdAhoraProceso='Plantilla_PruebaControles'
SET @Libreria='PlantillaExterno'
SET @ClaseProc = 'Procesos'
SET @MetodoProc='PruebaControles'
SET @Descrip='Prueba de Controles'
SET @Observ =''
SET @MENUNuevo = 'MNUPRUEBA_CTRL'
SET @MENUPadre = 'MNUPRUEBA'
-- CREAR AHORA_PROCESO (de tipo 3 ya que será llamado desde un link de Ahora_Macros'
IF NOT EXISTS (SELECT IdDoc FROM [Ahora_Procesos] WHERE
IdAhoraProceso=@IdAhoraProceso)
INSERT INTO [Ahora_Procesos] ([IdAhoraProceso] , [Descrip], [IdTipo], [Libreria], [Clase],
[Metodo], [IdLlamada], [RetornoTipo], [RetornoObjeto], [CheckParam], [Observaciones], [Macro])
VALUES (@IdAhoraProceso, @Descrip,3, @Libreria, @ClaseProc
,@MetodoProc,1,NULL,0,'False', @Observ,0)
ELSE
PRINT 'Ya existe un proceso llamado '+ @IdAhoraProceso +'.'
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 36
-- CREAR LINK QUE APUNTA AL AHORA_PROCESO
SELECT @IdDoc=IdDoc FROM Ahora_Procesos WHERE IdAhoraProceso=@IdAhoraProceso
SELECT @IdLink=IsNull(Max(IdLink),0) + 1 From Ahora_Links
IF NOT EXISTS(SELECT IdDoc FROM [Ahora_Links] WHERE Descrip=@Descrip AND
Coleccion='Ahora_Macros' AND IdDocObjeto=@IdDoc )
INSERT INTO [Ahora_Links]([IdLink],[Descrip],[Coleccion],[IdDocObjeto])
VALUES (@IdLink ,@Descrip,'Ahora_Macros',@IdDoc)
ELSE BEGIN
PRINT 'Ya existe un link llamado "'+ @Descrip +'" que apunte al proceso "' +
@IdAhoraProceso +'" (IdDocObjeto ' +CAST(@IdDoc as varchar)+').'
SELECT @IdLink=IdLink FROM [Ahora_Links] WHERE Descrip=@Descrip AND
Coleccion='Ahora_Macros' AND IdDocObjeto=@IdDoc
PRINT 'IdLink = ' + CAST(@IdLink as varchar)
END
-- CREAR NODO MENU
IF NOT EXISTS( SELECT IdDoc FROM Ahora_Nodos WHERE IdNodo=@MENUNuevo)
INSERT INTO [Ahora_Nodos]([IdNodo], [Activo], [Descrip], [Icono], [IdLink], [IdAhoraProceso],
[Expandido], [Visible], [Enabled], [Destacado])
VALUES(@MENUNuevo,1,@Descrip,123,@IdLink,NULL,0,1,1,0)
ELSE
PRINT 'Ya existe una entrada para el nodo '+ @MENUNuevo +'.'
-- PONER NODO EN EL ARBOL
IF NOT EXISTS (SELECT IdDoc FROM Ahora_Nodos_Relacion WHERE IdNodo=@MENUNuevo
AND IdNodoPadre=@MENUPadre) BEGIN
SELECT @Orden =ISNULL(Max(Orden),0)+1 FROM Ahora_Nodos_Relacion WHERE
IdNodoPadre=@MENUPADRE
INSERT INTO Ahora_Nodos_Relacion(IdNodo,IdNodoPadre,Orden)
VALUES (@MENUNuevo,@MENUPadre, @Orden)
END
ELSE
PRINT 'Ya existe la relación para para el nodo ' + @MENUNuevo + ' padre ' + @MENUPadre +
'.'
GO
Este script crea el nodo MNUPRUEBA_CTRL que cuelga de MNUPRUEBA. El nodo
contiene un Link y el Link contiene el proceso Prueba_Controles. El proceso
Prueba_Controles hace referencia a una función en la clase Procesos, que definiremos a
continuación. Cuando hagamos clic en el nodo del árbol ejecutará nuestra función
PruebaControles.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 37
Codificación de clases, módulos y formularios
Principal.bas
Es fundamental que tengamos definido este código en un módulo, ya que
ConexionCargaLib hace referencia a éstas declaraciones. Aquí se define el objeto
CONEXIÓN en nuestro proyecto y será visible desde toda la aplicación.
Option Explicit
Public gCn As Conexion
Public Sub EstableceConexion(aCon As Conexion)
If Not gCn Is Nothing Then
Exit Sub
End If
Set gCn = aCon
ConectaOCX gCn, App.Title
End Sub
Public Sub DesestableceConexion()
Set gCn = Nothing
ConectaOCX Nothing, App.Title
End Sub
Procesos.cls
En esta clase crearemos todos los métodos y funciones públicas que se llamarán desde
los procesos del sistema. Aquí tendremos que definir Pruebas_Controles, que será
llamado desde el nodo que creamos anteriormente. Básicamente el proceso consiste en
instanciar el formulario y llamar a su función carga ().
Option Explicit
Option Compare Text
Private Const cModuleName = "Procesos"
Public Function PruebaControles() As Boolean
Dim lFrm As frmControles
Dim lRes As Boolean
On Error GoTo Error_
lRes = gCn.AhoraProceso("Plantilla_Mensaje", False, "PRueBA")
Set lFrm = New frmControles
lFrm.Carga gCn.Sesion.MainForm
End_:
PruebaControles = True
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 38
Set lFrm = Nothing
Exit Function
Error_:
gCn.Tr.Trace TError, cModuleName, " PruebaControles", , Err.Description
Resume End_
End Function
frmControles.frm
Función Form_Load ()
En el evento LOAD del formulario inicializaremos la botonera.
Option Explicit
Option Compare Text
Private Const cModuleName = "frmControles"
Private Sub Form_Load()
On Error GoTo Error_
Botonera.SeguridadObjeto = eMenuImprimir
Botonera.BotonesMantenimiento = eBotMant_Cerrar
Botonera.HabilitaBotones
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " Form_Load", , Err.Description
Resume End_
End Sub
La botonera tiene 2 grupos de botones predefinidos: botones SeguridadObjeto
(Guardar, Nuevo, Eliminar, Imprimir y Asociados) y botones Mantenimiento (Aceptar,
Cancelar, Cerrar).
La instrucción que damos es para que cargue el botón Imprimir y el botón Cerrar. La
instrucción HabilitaBotones es para que aparezcan habilitados.
Función carga ()
Esta función es común en todos los formularios de la aplicación y se encarga de recibir
los parámetros necesarios para mostrar la ventana. Inicializa parámetros y controles, y
muestra el formulario. También cargamos los íconos del formulario y la barra de título.
Public Function Carga (Optional aPropietario As Object) As Boolean
Me.Caption = "Prueba de controles"
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 39
Me.Titulo.Caption = "Articulos de proveedor"
Me.Icon = gCn.DameIcono(123)
Set Me.Titulo.Icono = gCn.DameIcono(233)
Me.Titulo.MuestraIcono = True
cargarCombo
CargaGrdArticulos
gCn.Obj.FormShow Me, aPropietario
Carga = True
End Sub
La función gcn.dameIcono () recibe un IdIcono de tipo Long y nos devuelve una imagen
de la biblioteca de imágenes. Consulte la tabla Iconos para obtener la lista de Iconos
disponibles.
La función gCn.Obj.FormShow () muestra la pantalla y establece la relación padre – hijo
en los formularios. Es muy importante para el control de formularios modales.
Función cargaCombo ()
Se encarga de inicializar el combo cargando los datos de la tabla de proveedores. Este
control tiene la particularidad de que puede estar ligado a otro combo, permitiendo así
una búsqueda por 2 campos. En este caso, queremos que el primer combo muestre
una lista (IdProveedor-Proveedor) ordenada por IdProveedor y que el segundo combo
despliegue una lista (Proveedor-IdProveedor) ordenada por Proveedor.
Private Sub cargarCombo()
On Error GoTo Error_
Dim lCampos(1 To 2) As String 'Matríz de campos
Dim lCampos2(1 To 2) As String 'Matríz de campos
Dim lTipos(1 To 2) As eTiposCol_Cbo
Dim lWidth(1 To 2) As Single
Dim n As Long
With cboIdProveedor
lCampos(1) = "IdProveedor"
lCampos(2) = "Proveedor"
lTipos(1) = eTiposCol_Texto
lTipos(2) = eTiposCol_Texto
lWidth(1) = 1200
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 40
lWidth(2) = 2500
.Configura 0, lCampos, lTipos, lWidth, 1, _
"SELECT IdProveedor,Proveedor FROM vCombo_Proveedores ORDER BY IdProveedor", _
"Select IdProveedor From Prov_Datos Where IdProveedor =@1"
lCampos(1) = "Proveedor"
lCampos(2) = "IdProveedor"
lWidth(1) = 2500
lWidth(2) = 1200
‘Creamos el segundo combo
n = .AgregaCombo(lCampos, lTipos, lWidth, 2, _
"SELECT Proveedor,IdProveedor FROM vCombo_Proveedores ORDER BY Proveedor", _
"Select IdProveedor From Prov_Datos Where IdProveedor =@0")
.ColumnaEscalada = 1
.Resize
End With
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " Form_Load", , Err.Description
Resume End_
End Sub
Los combos pueden desplegar una lista de hasta 3 campos. Lo primero es definir una
matriz con los campos que queremos mostrar en la lista. Luego asignamos a la matriz
los nombres de los campos, que deben corresponderse con los nombres de columna
de la sentencia SQL.
Necesitaremos también una matriz para especificar los anchos de columnas de la lista y
los tipos de datos que contendrán. Cuando hacemos la llamada al método Configura()
del combo, ya tendremos un combo en pantalla. A continuación se muestra el
enunciado del método configura () del combo.
Sub Configura (aComboIndex As Integer, aCampos() As String, aTipos() As eTiposCol_Cbo,
aAnchuras() As Single, aCActiva As Integer, aDescripcion As String, Optional aSustitucion As
String = "")
El parámetro aDescripcion recibe una sentencia SQL, una consulta a la base de datos,
con las columnas que queremos que se vean en la lista. Si solamente tenemos un
combo, no sería necesario. El parámetro sustitución también es una sentencia SQL. Si
sólo queremos mostrar un combo no es necesario pasarle el parámetro “aSustitucion”.
Pero en nuestro caso, como vamos a vincular otro combo al primero, el nexo entre los
dos controles es el campo sustitución. Cuando uno de ellos cambia de valor, el otro se
actualiza según la SQL establecida. En nuestro caso es un “SELECT col1, col2 FROM
tabla WHERE col1 = @n” donde n = número de columna del otro combo. El valor @n
nos retorna el valor del registro seleccionado.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 41
Cuando el combo 1 cambia, el combo 2 se actualiza con el valor de la columna 0 del
primero, o sea IdProveedor.
Una vez configurado el primer combo, completamos los datos para el segundo y
llamamos a la instrucción AgregaCombo (). Nos creará el segundo combo vinculado.
Función Cargagrdarticulos ()
Inicializa el grid. Crea las columnas e indica la consulta que tiene que mostrar.
Private Sub CargaGrdArticulos(Optional aIdProveedor As String = "-1")
On Error GoTo Error_
Dim lStrVista As String
lStrVista = "(SELECT pa.IdProveedor, pa.IdArticulo, a.Descrip, a.IdDoc " & _
"FROM Prov_Articulos pa " & _
"INNER JOIN Articulos a on " & _
"pa.IdArticulo = a.IdArticulo) Vista"
With grdArticulos
If Not .Preparada Then
.Agregar = False
.Editar = False
.Eliminar = False
.CargaObjetos = False
.EditarPorObjeto = False
.Grid.FetchRowStyle = False
.Alias = "Vista"
.AgregaColumna "IdArticulo", 1000, "IdArticulo"
.AgregaColumna "Descrip", 3000, "Descripción"
.From = lStrVista
.Orden = ""
End If
.Where = "WHERE Vista.IdProveedor = " & SqlString(aIdProveedor) 'sqlString me añade
comillas
.Refresca = True
End With
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " CargagrdArticulos", , Err.Description
Resume End_
End Sub
Primero definimos la vista (sentencia select, vista o tabla) en la que se va a basar el grid
para mostrar los datos, será el origen de datos de la grid. Luego le indicamos los
permisos de agregado, edición y eliminación. Las propiedades cargaObjeto y
editarPorObjeto sólo se usan para cuando queremos que el origen de datos sea una
colección de objetos. Pero no será nuestro caso.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 42
La instrucción AgregaColumna recibe los parámetros de: Nombre de campo SELECT,
Ancho y Nombre de columna, entre otros, que son los obligatorios para poder crear
una columna en el grid
Una vez creadas las columnas, indicado el origen (From) y el WHERE, el grid formará su
origen de datos, una consulta parecida a la siguiente (siaIdProveedor = ‘-1’):
SELECT Vista. Idarticulo, Vista. Descrip FROM (SELECT pa.IdProveedor, pa.IdArticulo, a.Descrip,
a.IdDoc FROM Prov_Articulos pa INNER JOIN Articulos a on pa.IdArticulo = a.IdArticulo) Vista
WHERE Vista.IdProveedor = ‘-1’
Es importante que, en los casos en los que creamos una vista en la propia select, le
digamos al grid cuál será el Alias.
La primera vez que se ejecuta la función, la propiedad Preparada de la grid pasará a
TRUE, con lo cual no volverá a entrar en el bloque de creación de columnas y sólo
actualizará el WHERE de la consulta.
Evento Change del combo
Cuando seleccionan un proveedor en el combo, hay que listar sus artículos. Hacemos
invocamos CargaGrdArticulos y le pasamos el código de proveedor.
Private Sub cboIdProveedor_Change(aComboIndex As Integer)
CargaGrdArticulos Me.cboIdProveedor.Text
End Sub
Evento clic de la botonera
Cuando pulsen el botón Imprimir llamará a la función de imprimir, cuando pulse Cerrar
cerrará el formulario.
Private Sub Botonera_ToolClicked (aTool As AhoraOCX.AhoraTool)
On Error Resume Next
Select Case aTool.Name
Case cBotMant_Imprimir
Call Imprimir
Case cBotMant_Cerrar
Unload Me
End Select
End Sub
Imprimir un informe
Para imprimir el contenido del grid sólo tiene que llamar a la función imprimir del
control:
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 43
Me.grdArticulos.Imprimir
Si quiere que al darle al botón Imprimir llame a un informe de Crystal Reports, el
procedimiento cambia significativamente.
Cuando cree el listado de Crystal Reports debe guardarlo en una ruta especificada en el
sistema. Puede averiguar la ruta yendo al menú Administración – Configuración –
Parámetros de la aplicación. Una vez ahí, abra la ventana de parámetros dentro de la
carpeta Configuración – Directorios – PathListados, o ejecutando la siguiente consulta a
la base de datos:
SELECT Valor FROM CEESI_Configuracion WHERE Parametro = 'PATHLISTADOS'
Una vez esté guardado el report, hay que grabarlo en el sistema en la tabla
CEESI_Listados. Tenga en cuenta que, cuando el report no esté vinculado a un objeto
(Artículo, Proveedor, Albarán, etcétera) debe vincularlo al ObjetoGenerico.
A continuación pondremos nuestro report en el sistema mediante el siguiente script
SQL.
DECLARE @Objeto VARCHAR(50)
DECLARE @Listado VARCHAR(50)
DECLARE @Descrip VARCHAR(255)
DECLARE @Fichero VARCHAR(255)
DECLARE @Formulario BIT
DECLARE @NomFormulario VARCHAR(50)
SET @Objeto = 'ObjetoGenerico'
SET @Listado = 'Articulos de proveedor'
SET @Descrip = 'Pruebas'
SET @Fichero = 'Pruebas\ReportPrueba.rpt'
SET @Formulario = 1
SET @NomFormulario = 'frmControles'
IF NOT EXISTS (
SELECT IdDoc
FROM CEESI_Listados
WHERE Objeto LIKE @Objeto
AND Listado LIKE @Listado
AND Descrip LIKE @Descrip
AND Fichero LIKE @Fichero
AND Formulario = @Formulario
AND NomFormulario LIKE @NomFormulario )
INSERT INTO CEESI_Listados( Objeto,Listado, Descrip, Fichero, Formulario,
NomFormulario)
VALUES( @Objeto,@Listado,@Descrip,@Fichero,@Formulario,@NomFormulario)
ELSE
PRINT 'Registro para el listado especificado ya existe'
Y la función en el formulario quedaría de la siguiente manera:
Public Function Imprimir() As Boolean
Dim lSql As String
Dim lObjGen As Object
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 44
Dim lListado As String
On Error GoTo Error_
lSql = Me.grdArticulos.Where ‘Obtiene el filtrado del grid
lListado = "Articulos de proveedor"
Set lObjGen = gCn.Obj.DameObjStr("ObjetoGenerico") ‘Instancia un objeto genérico.
lObjGen.NomFormulario = Me.Name
lObjGen.Imprimir lSql, lListado ‘Llama al evento imprimir del objeto.
End_:
Exit Function
Error_:
gCn.Tr.Trace TError, cModuleName, " Imprimir ", , Err.Description
Resume End_
End Function
Evento Resize del Formulario
En Visual Basic 6, resulta un poco engorroso el programar las dimensiones de los
controles cuando un formulario cambia su tamaño. Para ello hemos creado con
algunos controles un sistema para aliviarnos la tediosa tarea de programar el evento
Form_Resize ().
Los controles que funcionan automáticamente con el sistema Form_Autoresize, tienen
unas propiedades especiales para inicializar en tiempo de diseño. Éstas son:
ResizeEnabled, ResizeH, ResizeV, y en el caso de los Grids y Tabs, ResizeRestanteH y
ResizeRestanteV.
1. Pondremos todos los controles que queremos que se ajusten automáticamente al
tamaño del formulario con su propiedad ResizeEnabled=TRUE.
2. Imaginemos nuestro formulario como una cuadrícula donde en cada cuadro están
los controles. En nuestro ejemplo tendremos todos los controles sobre la columna
H0, pero si tuviésemos, por ejemplo, que poner otro panel a la derecha de
pnlProveedor, lo pondríamos en H1-V1.
H0 H1 H2
V0 Titulo
V1 pnlProveedor
V2 grdArticulos
V3 Botonera
Las propiedades de los controles quedarían de la siguiente manera:
ResizeEnabled ResizeH ResizeV ResizeRestanteH ResizeRestanteV
Titulo TRUE 0 0
pnlProveedor TRUE 0 1 FALSE FALSE
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 45
grdArticulos TRUE 0 2 FALSE TRUE
Botonera TRUE 0 3
La propiedad ResizeRestante será TRUE sólo para el control que debe crecer ocupando
todo el espacio.
3. Programar el evento Form_Resize
Private Sub Form_Resize()
On Error Resume Next
Call Form_AutoResize(Me)
End Sub
Compilar el proyecto
1. Una vez terminado el proyecto, debemos asegurarnos que compile. Presionamos
CTRL+F5 para verificar que compila correctamente.
2. Abrimos solamente nuestro proyecto Plantilla_Externo y le damos a Guardar como…
creando un nuevo archivo PlantillaExterno_Compilar.vbp
3. Compilamos la dll (Menú Archivo – Generar Plantilla_Externo_Compilar.dll)
generando el archivo PlantillaExterno.dll.
4. Registramos la dll en los equipos que queremos que funcione (Debe ser
administrador del equipo)
5. Copie el archivo con extensión DLL en la carpeta correspondiente. Ejemplo:
“C:\Ahora3\Lib”
6. Haga clic en “Inicio” / “Ejecutar…” y en la pantalla de ejecución escriba el comando
REGSVR32 seguido de la ruta del archivo entre comillas.
El uso es: Regsvr32 [/u] [/s] <nombre del fichero>.
Los parámetros opcionales [/u] [/s] significan lo siguiente:
[/u] - lo utilizamos cuando queremos "desregistrar" una DLL (o un .OCX) en vez
de registrarlo.
[/s] - modo "silencioso" - no despliega los mensajes durante la operación.
7. Ejemplo: Para un archivo llamado PlantillaExterno.dll en C:\Ahora3\Lib, se
recomienda desregistrarla y luego registrarla, para evitar errores, por lo que lo
realizaremos en dos pasos.
8. REGSVR32 /u “C:\Ahora3\Lib \ PlantillaExterno.dll”
9. REGSVR32 “C:\Ahora3\Lib \ PlantillaExterno.dll”
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 46
OBJETOS EN EL SISTEMA
Introducción
Un objeto en POO (Programación Orientada a Objetos) representa alguna entidad de la
vida real, es decir, alguno de los objetos que pertenecen al negocio con que estamos
trabajando o al problema con el que nos estamos enfrentando, y con los que podemos
interactuar.
Podemos definir nuestro ERP como un gran buscador de objetos (Clientes,
Proveedores, Pedidos, Albaranes, etcétera).
Si queremos que un objeto de una clase interactúe y sea accesible en el ERP debemos
definirlo en tablas. Las tablas donde se definen y relacionan las clases son Objetos y
Objetos_Objetos.
La mejor manera para crear nuestros objetos es desde el ADMON [Consultar Manual de
ADMON y DDA].
Definición de clases y objetos
Toda clase que se defina debe tener asignada una tabla para sus objetos. Cada registro
de su tabla corresponderá a un objeto. Las columnas o campos de la tabla
corresponden a las características del objeto.
Por ejemplo para la clase Cliente, existe una tabla Clientes_Datos donde sus campos
(IdCliente, Cliente, RazónSocial, NIF, etc.) serán los atributos de los objetos, y cada
registro de la tabla un Cliente o mejor dicho, un Objeto Cliente.
Para cada clase definida deberá también definir una clase que sea su Colección, su
contenedor. Esto significa que para la clase Cliente existirá una clase Clientes de tipo
Colección.
Para la Clase Cliente habrá definido un registro en la tabla Objetos.
Para la Colección Clientes habrá definido un registro en la tabla Objetos de tipo
Colección y con HijoDefecto = ‘Cliente’.
EN DETERMINADAS CITAS Y MANUALES RELACIONADOS, TENGA EN CUENTA QUE MUCHAS VECES SE
HABLA DE UN OBJETO CUANDO REALMENTE SE REFIERE A LA CLASE (O DEFINICIÓN DE OBJETO).
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 47
Relación Objeto – Objeto
“Un Pedido tiene Lineas de Pedido”.
Este tipo de relaciones se verán reflejadas en la tabla Objetos_Objetos donde Pedido
será padre de Líneas de pedido.
En conclusión, para reflejar ésta relación debemos de tener:
Tabla para los objetos Pedido.
Tabla para los objetos Pedido_Linea.
Clase Pedido.
Clase Pedidos de tipo colección con HijoDefecto = ‘Pedido'.
Clase Pedido_Linea.
Clase Pedido_Lineas de tipo colección con HijoDefecto = ‘Pedido_Linea’.
Definición de propiedades
Todo objeto tiene que tener definidas las propiedades de su tabla en la tabla
Objetos_Propiedades. Es imprescindible para el funcionamiento del buscador.
Además, desde esta tabla le podremos dar un orden a las propiedades, activarlas,
desactivarlas, vincularles una cláusula SELECT, un formato, etc.
Creación de objetos
Tenemos cuatro formas de definir una Clase en el ERP:
1. Definirla en las tablas de objetos y dentro de una librería. Sus objetos, además de
servir de contenedor de datos, contienen funciones específicas. Son los más
complejos de programar.
2. Definirla sólo por tablas. Los objetos son simples contenedores de datos,
aunque pueden tener asociado un formulario. No es necesario programar para
crearlos ya que es posible hacerlo desde el ADMON. [Ver manual de dda]
3. Definirla sólo en una librería. Los objetos suelen utilizarse para resolver
algoritmos complejos, no se guardan en tablas permanentes.
Pedido
Linea de
pedido 1 n
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 48
4. Definirla virtualmente. La clase y sus objetos se crean dinámicamente en código
sin necesidad de declararlos en la tabla Objetos. Se utilizan para facilitar la
actualización y el guardado de datos, manipulando los registros de una tabla
cualquiera como si fueran objetos.
Antes de ponerse a definir objetos debe tener en cuenta cuántos pueden verse
involucrados en el problema y definir su relación así como también saber quién va a
tener acceso a ellos. Considere que debe configurar la seguridad de los objetos
creados. Desde el ADMON podrá asignar quién puede tener acceso a los objetos de la
Clase creada. Si tiene dudas revise el manual del ADMON y échele un vistazo al manual
de DDA.
Pasos para definir un nuevo objeto
(En este apartado, cuando hablemos de objeto nos referimos a su definición, la Clase)
Existe una funcionalidad en el ADMON, para definir tanto una colección como un
objeto nuevo y que éste tenga el mismo tratamiento que los demás objetos de la
aplicación.
1. Primero cree en SQL Server la tabla del objeto. No olvide agregar al final los
campos IdDoc, InsertUpdate, Usuario y FechaInsertUpdate.
2. Vaya al programa ADMON y dentro de la sección de configuración elija el nodo
Objetos. Al seleccionar cualquier objeto podremos ver su lista de propiedades
(descripción, SQL, Librería, Menú…), y en la parte inferior tenemos el botón Nuevo,
que necesitamos para crear el objetos y colecciones.
Indica que será visible desde el
buscador de objetos
Indica que se podrá crear un nuevo objeto
de forma directa en el formulario principal
Si la clase está definida en una librería,
indíquela
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 49
Al pulsarlo, accederemos al siguiente formulario:
Donde:
Objeto: Es el nombre del objeto que estamos creando. Debe de ser único.
Descripción: Es la descripción del objeto que verá el usuario en el explorador del
objetos
Tabla: Tabla donde se almacenarán los datos del objeto. Para la creación del
objeto esta tabla no hace falta que exista. La tabla hay que crearla manualmente
a través del servidor SQL.
3. Una vez creado el objeto, en esa misma ventana tenemos todas las propiedades del
objeto.
Es altamente recomendable, tanto para el objeto como para la colección, rellenar la
propiedad [Cadena descripción objeto] con campos que existan en la tabla usando los
corchetes para separa el texto literal de los campos.
Ejemplo: [IdBaja]-[IdEmpleado]-[FechaBaja]- Motivo: - [Descrip]
Ésta información se guarda en la tabla Objetos.
Ya tiene definido su Objeto. Mas adelante encontrará un ejemplo de cómo programar
su clase en una librería.
Objetos del motor del sistema
Objeto Conexión
Es una de las clases administradoras del ERP, por lo cual es instanciada una sola vez. A
través de este objeto tendremos acceso a las funciones más importantes. Haremos un
resumen de las más usadas.
A través de este objeto accederemos también a las propiedades de la conexión tales
como Delegación, Usuario, etcétera.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 50
Funciones de consulta
BDAActual
Descripción: Retorna la base de datos actual.
Parámetros: -
Retorno: Cadena.
BuscarPropiedad
Descripción: Retorna el valor de un campo especificado dada una consulta SQL.
Parámetros: Propiedad, instrucción SQL.
Retorno: Variant.
Existe
Descripción: Consulta si un dato existe en la tabla.
Parámetros: Campo, valor y la tabla donde queremos buscar, instrucción WHERE
opcional.
Retorno: Verdadero/Falso.
DameCamposSelect
Descripción: Retorna un array de cadena con los valores de la consulta SQL, sólo el
primer registro.
Parámetros: instrucción SQL, array con los campos.
Retorno: Verdadero/Falso.
ExisteSqlObj
Descripción: Consulta un Objeto de SQL (tabla, campo, procedimiento,
desencadenador, etc.).
Parámetros: Nombre de objeto SQL.
Retorno: Verdadero/Falso.
DameValorCampo
Descripción: Retorna un Variant con el valor del campo especificado.
Parámetros: instrucción SQL, Nombre del campo.
Retorno: Variant.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 51
Funciones de ejecución
Actualizavalorcampo
Descripción: Actualiza el valor de un campo dado en los registros especificados en la
consulta SQL.
Parámetros: instrucción SQL, la propiedad a modificar, el valor nuevo.
Retorno: Verdadero/Falso.
EjecutaStore
Descripción: Ejecuta un procedimiento almacenado en SQL Server.
Parámetros: Nombre de la store y una lista de parámetros en una matriz.
Retorno: Verdadero/Falso.
EjecutaStoreCol
Descripción: Ejecuta un procedimiento almacenado en SQL Server devolviendo en la
Collection los valores OUTPUT del procedimiento.
Parámetros: Nombre de la store y una Collection con los parámetros.
Retorno: Verdadero/Falso.
EjecutaStoreResult
Descripción: Ejecuta un procedimiento almacenado en SQL Server devolviendo en
una Matriz los valores que retorna. Muy útil cuando el procedimiento retorna una
consulta.
Parámetros: Nombre de la store y una lista de parámetros en una matriz.
Retorno: Recordset de tipo IRecordset.
ExecuteSql
Descripción: Ejecuta cualquier instrucción SQL que le pasemos.
Parámetros: Instrucción SQL, descripción de Error (opcional), número de error
(opcional),
Retorno: Verdadero/Falso.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 52
AhoraProceso
Descripción: Ejecuta un proceso Ahora_Proceso.
Parámetros: Nombre del proceso, parámetro de retorno, array con los parámetros
que pide el proceso.
Retorno: Valor que retorna el proceso.
BeginTrans/CommitTrans/ RollbackTrans
Descripción: Inicia, confirma o deshace la transacción.
Objeto OBJ
El objeto OBJ es un objeto encargado de administrar todos los objetos del sistema.
Contiene una colección con todos los objetos definidos (colección de objetos de tipo
Objeto). Con él, podremos también definir objetos simplemente indicándole un nombre
único y la tabla a la que hace referencia (objeto virtual).
OBJ es un objeto de tipo Objetos.
Se accede a él mediante el objeto Conexión: CONEXION.OBJ
Funciones más importantes
Add
Descripción: Añade un nuevo objeto a la colección y, además, comprueba si el objeto
es de reciente creación y lo añade a la base de datos.
Parámetros: Nombre de la clase (opcional).
Retorno: Objeto.
DameColeccion
Descripción: Busca en la colección los que cumplan la condición. Si no encuentra
ninguno, devuelve Nothing.
Parámetros: Nombre de la colección de objetos, Condición (puede ser un SELECT o
una cláusula WHERE)
Retorno: Objeto “Colecciones”.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 53
DameObjStr
Descripción: Retorna una nueva instancia de un objeto.
Parámetros: Clase.
Retorno: Objeto.
DameObjeto
Descripción: Retorna un objeto.
Parámetros: Nombre de la colección de objetos, Condición (puede ser un SELECT o
una cláusula WHERE), indicar si se aplican los filtros, indicar si se presenta la
colección si se encuentra más de un objeto que cumpla la condición.
Retorno: Objeto.
AñadirObjeto
Descripción: Crea una nueva clase sin necesidad de definirla en la tabla Objetos. Se
utiliza para manipular los registros de una tabla como si fueran objetos.
Parámetros: Nombre de Objeto (Clase), Indicar si es Colección, Tabla, Hijo Defecto.
Retorno: Objeto.
FormShow
Descripción: controla la apertura de un formulario.
Parámetros: Formulario a mostrar, Formulario Propietario.
Objeto Colecciones
Colecciones es una colección de Objetos. Su manejo es similar al objeto Collection de
Visual Basic.
Funciones más importantes
Add
Descripción: Añade un nuevo objeto a la colección y además comprueba si el objeto
es de reciente creación y lo añade a la base de datos.
Parámetros: Objeto.
Retorno: Objeto.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 54
Remove
Descripción: Elimina un Objeto de la colección pero no de la base de datos.
Parámetros: Objeto.
Delete
Descripción: Elimina un Objeto de la colección y de base de datos.
Parámetros: Objeto.
Retorno: Verdadero/Falso.
Count
Descripción: Retorna el número de objetos de la colección.
Parámetros:
Retorno: Número.
Colección
Descripción: Retorna una colección de objetos.
Parámetros:
Retorno: Collection.
Suma
Descripción: Recorre la todos los objetos de la colección y suma los valores de una
propiedad.
Parámetros: Propiedad.
Retorno: Número.
Refresh
Descripción: Vuelve a cargar los objetos que componen la colección.
Parámetros: -
Retorno: Verdadero/Falso.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 55
Update
Descripción: Actualiza los objetos de la colección en base de datos.
Parámetros: -
Retorno: Verdadero/Falso.
BuscarObjeto
Descripción: busca un objeto en la colección.
Parámetros: Nombre de la propiedad, valor de la propiedad.
Retorno: Objeto.
Objeto IItem
Todos los objetos que se instancian en la aplicación heredan del objeto IItem. IItem se
encarga de manipular el objeto para que pueda actualizarse, guardarse en su tabla y
borrarse.
Como Visual Basic no maneja el concepto de herencia, ésta se ha simulado mediante
una interfaz. Al crear la nueva clase en su librería implemente IItem y defina los
métodos y funciones de la interfaz. Diremos que todo objeto que se instancie será un
IItem.
Si usted desea que un objeto se comporte de manera diferente a como lo establece
esta interfaz, cambie el contenido de las funciones definidas.
Propiedades
Propiedades
Descripción: Nos devuelve el valor de un campo del objeto.
Parámetros: nombre del campo.
Retorno: Variant.
Descripcion
Descripción: Retorna la descripción del objeto, ésta se forma según lo indicado al
definir la clase.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 56
Padre
Descripción: si el objeto es hijo de otro, nos retorna el objeto de nivel superior.
Retorno: Objeto.
Tabla
Descripción: Retorna la tabla del objeto.
Retorno: Cadena.
Métodos
Show
Descripción: Llama al método carga del formulario especificado.
Parámetros: Propietario, Ventana Nueva (T/F), Modal (T/F).
Refresh
Descripción: Vuelve a cargar el objeto desde la base de datos actualizando los
controles vinculados.
Update
Descripción: Comprueba que el formulario se haya completado correctamente y
guarda el objeto.
Parámetros: devuelve error (Verdadero/Falso).
Retorno: Verdadero/Falso.
Delete
Descripción: Elimina el objeto.
Retorno: Verdadero/Falso.
Ejemplo de creación de una nueva clase que implementa la interfaz IItem.
1. Crear nuestro objeto (frmObjPrueba) y colección (frmObjsPrueba) en el ADMON.
2. Crear en nuestra librería un módulo de clase llamado frmObjPrueba.
3. Pegar el siguiente Código en el módulo.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 57
Option Explicit
Option Base 0
Option Compare Text
Implements Capturador
Implements IItem
Private pItem As IItem
''Capturador para entregar el padre
Private WithEvents ContainerSubObject As Capturador
Public Function Add() As IItem
Set Add = pItem.Add()
End Function
Public Sub AsignaClaves(lacoleccion As Collection)
pItem.AsignaClaves lacoleccion
End Sub
Public Property Get Campos(Cual As String) As Object
Set Campos = pItem.Campos(Cual)
End Property
Private Function Capturador_EventRaise(EventName As String, aObj As Variant) As Variant
Dim lCap As Capturador
Dim lBreak As Boolean
On Error GoTo Error_
Select Case EventName
Case Else
lBreak = False
#If debugmode Or DebugCallback Then
Debug.Print EventName
#End If
End Select
On Error Resume Next
Set lCap = Padre
If Not lCap Is Nothing And Not lBreak Then
Capturador_EventRaise = lCap.EventRaise(EventName, aObj)
End If
Set lCap = Nothing
Salir_:
Exit Function
Error_:
gCn.Tr.Trace TError, TypeName(Me), " Capturador_EventRaise", , Error$
Resume Salir_
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 58
Resume
End Function
Private Function Capturador_GetContainer() As Object
Set Capturador_GetContainer = ContainerSubObject.GetContainer
End Function
Public Function CargaObjAdicionales(Cual As Integer, Optional Otros As Object) As Boolean
CargaObjAdicionales = pItem.CargaObjAdicionales(Cual, Otros)
End Function
Private Sub Class_Initialize()
Set pItem = gCn.Obj.DameItem(TypeName(Me))
pItem.Modificado = False
ValoresPredeterminados
Set ContainerSubObject = gCn.GetContainerSubObject(pItem)
End Sub
Private Sub Class_Terminate()
Set ContainerSubObject = Nothing
Set pItem = Nothing
End Sub
Public Property Get ClassDebugID() As Long
ClassDebugID = pItem.ClassDebugID
End Property
Public Property Get Clave() As Variant
Clave = pItem.Clave
End Property
Public Property Get Claves() As Collection
Set Claves = pItem.Claves
End Property
Private Sub ContainerSubObject_DamePadre(ContainerObject As Object)
Set ContainerObject = Me
End Sub
Public Sub Data(Padre As Capturador, Vpropiedades As Collection, Optional Nuevo As Variant)
pItem.Data Padre, Vpropiedades, Nuevo
End Sub
Public Function Delete() As Boolean
Delete = pItem.Delete
End Function
Public Property Get Descripcion() As String
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 59
Descripcion = gCn.Obj.GeneraDescripcion(Me)
End Property
Public Property Let Disponible(Valor As Boolean)
pItem.Disponible = Valor
End Property
Public Property Get Disponible() As Boolean
Disponible = pItem.Disponible
End Property
Public Property Get Entorno() As ObEntorno
Set Entorno = pItem.Entorno
End Property
Public Property Get EsColeccion() As Boolean
EsColeccion = pItem.EsColeccion
End Property
Public Function Estado() As Integer
Estado = 1
End Function
Private Function IItem_Add() As AhoraSistema.IItem
Set IItem_Add = Add()
End Function
Private Sub IItem_AsignaClaves(lacoleccion As Collection)
AsignaClaves lacoleccion
End Sub
Private Property Get IItem_Campos(Cual As String) As AhoraSistema.CampoClave
Set IItem_Campos = Campos(Cual)
End Property
Private Function IItem_CargaObjAdicionales(Cual As Integer, Optional Otros As Object) As
Boolean
IItem_CargaObjAdicionales = CargaObjAdicionales(Cual, Otros)
End Function
Private Property Get IItem_ClassDebugID() As Long
IItem_ClassDebugID = ClassDebugID
End Property
Private Property Get IItem_Clave() As String
IItem_Clave = Clave
End Property
Private Property Get IItem_Claves() As Collection
Set IItem_Claves = Claves
End Property
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 60
Private Sub IItem_Data(Padre As AhoraSistema.Capturador, Vpropiedades As Collection,
Optional Nuevo As Variant)
Data Padre, Vpropiedades, Nuevo
End Sub
Private Function IItem_Delete(Optional aVerbose As Boolean = True) As Boolean
IItem_Delete = Delete()
End Function
Private Property Get IItem_Descripcion() As String
IItem_Descripcion = Descripcion
End Property
Private Property Let IItem_Disponible(RHS As Boolean)
Disponible = RHS
End Property
Private Property Get IItem_Disponible() As Boolean
IItem_Disponible = Disponible
End Property
Private Property Get IItem_Entorno() As AhoraSistema.ObEntorno
Set IItem_Entorno = Entorno
End Property
Private Property Get IItem_EsColeccion() As Boolean
IItem_EsColeccion = EsColeccion
End Property
Private Function IItem_Estado() As Integer
IItem_Estado = Estado
End Function
Private Property Get IItem_Eventos() As AhoraSistema.IItem_Events
Set IItem_Eventos = pItem.Eventos
End Property
Private Property Get IItem_Form() As Object
''Set IItem_Form = Pantalla
Set IItem_Form = pItem.Form
End Property
Private Sub IItem_Imprimir()
Imprimir
End Sub
Private Sub IItem_Menu()
Menu
End Sub
Private Property Let IItem_Modificado(RHS As Boolean)
Modificado = RHS
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 61
End Property
Private Property Get IItem_Modificado() As Boolean
IItem_Modificado = Modificado
End Property
Private Property Let IItem_Nuevo(RHS As Boolean)
Nuevo = RHS
End Property
Private Property Get IItem_Nuevo() As Boolean
IItem_Nuevo = Nuevo
End Property
Private Property Get IItem_Objeto() As Object
Set IItem_Objeto = Me
End Property
Private Property Get IItem_Objetos() As Collection
Set IItem_Objetos = Objetos
End Property
Private Property Let IItem_ObjetosDisp(RHS As Boolean)
pItem.ObjetosDisp = RHS
End Property
Private Property Get IItem_ObjetosDisp() As Boolean
IItem_ObjetosDisp = pItem.ObjetosDisp
End Property
Private Property Get IItem_OtrasPropiedades() As Collection
Set IItem_OtrasPropiedades = pItem.OtrasPropiedades
End Property
Private Property Let IItem_Padre(RHS As Object)
Padre = RHS
End Property
Private Property Get IItem_Padre() As Object
Set IItem_Padre = Padre
End Property
Private Property Let IItem_Propiedades(Cual As String, RHS As Variant)
Propiedades(Cual) = RHS
End Property
Private Property Get IItem_Propiedades(Cual As String) As Variant
IItem_Propiedades = Propiedades(Cual)
End Property
Private Sub IItem_Refresh(Optional pantallaIgnorarErr As Boolean = True)
Refresh pantallaIgnorarErr
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 62
End Sub
Private Sub IItem_Show(Optional Propietario As Object, Optional ventanaNueva As Boolean =
False, Optional aModal As Boolean = False)
Show Propietario, ventanaNueva, aModal
End Sub
Private Property Get IItem_SQL() As String
IItem_SQL = sql
End Property
Private Property Get IItem_Tabla() As String
IItem_Tabla = Tabla
End Property
Private Property Get IItem_TablaOtra() As String
IItem_TablaOtra = pItem.TablaOtra
End Property
Private Property Let IItem_Tipo(RHS As String)
pItem.Tipo = RHS
End Property
Private Property Get IItem_Tipo() As String
IItem_Tipo = Tipo
End Property
Private Property Let IItem_UltimoNivel(RHS As Boolean)
pItem.UltimoNivel = RHS
End Property
Private Property Get IItem_UltimoNivel() As Boolean
IItem_UltimoNivel = UltimoNivel
End Property
Private Function IItem_Update(Optional PantallaError As Boolean = False, Optional refrescar As
Boolean = True) As Boolean
IItem_Update = Update(PantallaError, refrescar)
End Function
Public Sub Imprimir()
pItem.Entorno.Imprimir Me
End Sub
Property Get Item() As AhoraSistema.IItem
Set Item = Me
End Property
Public Sub Menu()
pItem.Entorno.VerMenu Me, "mnuObjeto"
End Sub
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 63
Public Property Get Modificado() As Boolean
Modificado = pItem.Modificado
End Property
Public Property Let Modificado(Estado As Boolean)
pItem.Modificado = Estado
End Property
Public Property Get Nuevo() As Boolean
Nuevo = pItem.Nuevo
End Property
Public Property Let Nuevo(Estado As Boolean)
pItem.Nuevo = Estado
End Property
Public Property Get Objetos() As Object
Set Objetos = pItem.Objetos
End Property
Public Function OtrasPropiedades() As Collection
Set OtrasPropiedades = pItem.OtrasPropiedades
End Function
Public Property Let Padre(miPadre As Object)
pItem.Padre = miPadre
End Property
Public Property Get Padre() As Object
Set Padre = pItem.Padre
End Property
Public Property Get Propiedades(Cual As String) As Variant
Propiedades = pItem.Propiedades(Cual)
End Property
Public Property Let Propiedades(Cual As String, Valor As Variant)
pItem.Propiedades(Cual) = Valor
End Property
Public Sub Refresh(Optional pantallaIgnorarErr As Boolean = True)
pItem.Refresh pantallaIgnorarErr
End Sub
Public Sub Show(Optional Propietario As Object, Optional ventanaNueva As Boolean = False,
Optional aModal As Boolean = False)
''Dim lFrm As Form
''Set lFrm = Propietario
pItem.Show Propietario, ventanaNueva, aModal
End Sub
Public Property Get sql() As String
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 64
sql = pItem.sql
End Property
Public Property Get Tabla() As String
Tabla = pItem.Tabla
End Property
Property Get Tipo() As String
Tipo = TypeName(Me)
End Property
Public Property Get UltimoNivel() As Boolean
UltimoNivel = pItem.UltimoNivel
End Property
Public Function Update(Optional PantallaError As Boolean = False, Optional refrescar As Boolean
= True) As Boolean
Update = pItem.Update(PantallaError, refrescar)
End Function
Private Sub ValoresPredeterminados()
'' Poner valores por defecto aquí
End Sub
Manejo de objetos
Hemos visto cómo definir una nueva clase. A continuación veremos algún ejemplo de
cómo instanciar un objeto de una clase, modificar sus propiedades, guardarlo,
eliminarlo, etc.
Nuestro ejemplo será la clase Pedido.
Repasando lo visto anteriormente sabemos que:
Tenemos definida una clase Pedido y su colección Pedidos.
Un pedido contiene Líneas de pedido, así que estará definida la clase Pedido_Linea y
Pedidos_Lineas.
pedido contiene una colección de líneas de pedido.
La tabla donde se guardarán los pedidos se llama Pedidos_Cli_Cabecera y algunos de
sus campos son (IdPedido, IdEmpresa, SeriePedido, Fecha, IdCliente, etc.)
La tabla donde se guardarán las líneas de pedido se llama Pedidos_Cli_Lineas y
algunos de sus campos son (IdPedido, IdLinea, IdArticulo, Cantidad, Precio, etc.)
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 65
Instanciar un nuevo objeto y completar sus propiedades.
Imaginemos que queremos crear un nuevo pedido de la serie 8, ponerle la fecha de
hoy, asignarle el cliente 0012, guardarlo y mostrarlo.
Observe que el objeto contiene una colección de propiedades, que son exactamente
las mismas que la tabla del objeto.
Nos referiremos al objeto conexión como GCN.
Public Sub CrearObjPedido ()
On Error GoTo Error_
Dim lPedido As IItem
Set lPedido = gCn.Obj.DameObjStr("Pedido")'Creamos el nuevo objeto Pedido
'Asignación de propiedades del objeto
lPedido.Propiedades("SeriePedido") = 8
lPedido.Propiedades("Fecha") = Date
lPedido.Propiedades("IdCliente") = "00012"
If lPedido.Update Then 'se guarda el objeto en la tabla
'mostramos el objeto – se abre el formulario que tenga definido.
lPedido.Show
End If
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, TypeName(Me), " CrearObjPedido", , Err.Description
Resume End_
End Sub
En algunos objetos como el pedido no es necesario asignarle la clave (IdPedido)
porque lo tiene programado en el objeto. Otros, en cambio, no se podrían actualizar si
no se les asigna los campos obligatorios.
El evento SHOW del objeto buscará en la librería el formulario indicado al definir la
clase (tabla Objetos) y ejecutará la función Carga() del formulario.
Recuperar un objeto existente y agregarle un hijo. Recuperaremos un objeto pedido cuyo IdPedido = 10101 y le agregaremos una línea
de pedido.
Cuando un objeto contiene otros, accedemos a ellos mediante su colección “objetos”.
Por ejemplo: MiObjeto.Objetos(“nombreColección”)
Public Sub CrearObjPedidoConLineas ()
On Error GoTo Error_
Dim lPedido As IItem
Dim lLinea As IItem
'Obtengo el objeto pedido
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 66
Set lPedido = gCn.Obj.DameObjeto("Pedidos", "WHERE IdPedido = 10101")
'A la colección del pedido (lPedido.Objetos("Pedido_Lineas"))le agrego una nueva línea
Set lLinea = lPedido.Objetos("Pedido_Lineas").Add
'Asignación de propiedades de la línea
With lLinea
.Propiedades("IdArticulo") = "010014"
.Propiedades("Cantidad") = 5
.Propiedades("Precio_Euro") = 10
.Update
End With
If lPedido.Update Then
lPedido.Show
End If
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, TypeName(Me), " CrearObjPedidoClin", , Err.Description
Resume End_
End Sub
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 67
CONTROLES AHORA
Introducción
Para trabajar con los controles personalizados de AHORA (ahoraocx.ocx) en modo de
diseño, necesita tener instaladas las herramientas de desarrollo mencionadas al inicio
del manual. La mayoría de nuestros controles se pueden vincular directamente al
objeto, teniendo en cuenta las opciones de seguridad y facilitando la actualización de
los mismos en la base de datos. A continuación detallaremos las propiedades, eventos
y métodos más importantes.
Control EnlaceObjetos
Además de proveer, a modo gráfico, de una barra de título, tiene la capacidad de
controlar un objeto. Le podemos vincular un objeto además de otros controles, de
modo que, cuando actualicemos un campo en el formulario que esté relacionado con
el objeto que contiene, actualizará directamente al objeto.
Existen 2 maneras de trabajar con este control:
Modo título.
El control es utilizado sólo para establecer un título o cabecera del formulario. Se
emplea a menudo para formularios de mantenimiento directo de tablas o formularios
de búsqueda.
Modo Objeto.
El control es vinculado a un objeto y los demás controles que completan el formulario
también. Se pueden establecer 2 tipos de vínculos:
o Síncrono: Cuando actualizamos un campo vinculado actualiza la propiedad el
objeto que contiene.
o Asíncrono: Cuando actualizamos un campo vinculado no actualiza el objeto, sino
que lo hace cuando se le dé la instrucción.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 68
Propiedades
Caption
Descripción: Texto que aparecerá en pantalla. Si está vinculado a un objeto mostrará
su descripción.
Tipo: Texto.
Icono
Descripción: Imagen que mostrará. Debe activarse la propiedad MuestraIcono. Si está
vinculado a un objeto, automáticamente mostrará el ícono del objeto.
Tipo: StdPicture.
MuestraIcono
Descripción: Permite que se vea la imagen cargada.
Tipo: Verdadero/Falso.
ObjGlobal
Descripción: Objeto que le vinculamos.
Tipo: Objeto.
Sincrono
Descripción: Está activado por defecto. Permite que cuando se actualiza un control
vinculado se actualice inmediatamente la propiedad del objeto.
Tipo: Verdadero/Falso.
Métodos y funciones.
Carga
Descripción: vincula el objeto al control.
Parámetros: Objeto.
Retorno: Verdadero/Falso.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 69
Refresh
Descripción: Vuelve a cargar el objeto desde la base de datos actualizando los
controles vinculados.
Actualiza
Descripción: Comprueba que el formulario se haya completado correctamente y
guarda el objeto.
Parámetros: Devuelve error (Verdadero/Falso).
Retorno: Verdadero/Falso.
Remove
Descripción: Elimina el objeto vinculado.
Parámetros: Cerrar el formulario (True/False), crear objeto nuevo (T/F)
Retorno: Verdadero/Falso.
Clear
Descripción: Borra el contenido de los controles enlazados.
Parámetros: Actualiza objeto (Verdadero/Falso.)
Ejemplo de cómo vincular un objeto al control EnlaceObjeto
Vincularemos un pedido al formulario que tendrá un control EnlaceObjeto y un control
TextoUsuario.
Cuando cargue el formulario, recibirá un objeto Pedido y el mismo mostrará la
propiedad Fecha del objeto.
Las propiedades de los controles las podemos definir por código (en tiempo de
ejecución) o haciendo clic derecho en el control – Propiedades –
Control: EnlaceObjeto
Nombre: EObjeto
Control: TextoUsuario
Nombre: Fecha
Objeto Origen: EObjeto
Propiedad Objeto Origen: Fecha
Tipo Dato: Date
Formato: FechaCorta
Control: cntBotonera
Nombre: Botonera
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 70
Una vez establecidas las propiedades de los controles iremos al código del formulario.
En el método carga del formulario enlazaremos el objeto al control, y el resto lo hará
automáticamente.
Option Explicit
Option Compare Text
Private Const cModuleName = "frmControlesObjeto"
Public Function Carga(elObjeto As IItem, Optional aPropietario As Object) As Boolean
On Error GoTo Error_
Hourglass True
Load Me
With EObjeto
If Not .ObjGlobal Is Nothing Then
If .Modificado Then
If Not .Actualiza Then
Carga = False
GoTo End_
End If
End If
End If
If Not elObjeto Is Nothing Then
If .Carga(elObjeto) Then
MsgBox "El objeto está cargado!"
End If
End If
End With
If aPropietario Is Nothing Then
Set aPropietario = gCn.Sesion.MainForm
End If
gCn.Obj.FormShow
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 71
Carga = True
End_:
Hourglass False
Exit Function
Error_:
gCn.Tr.Trace TError, cModuleName, " Carga", , Err.Description
Carga = False
Resume End_
End Function
En el evento LOAD del formulario inicializaremos la botonera.
Private Sub Form_Load()
On Error GoTo Error_
botonera.SeguridadObjeto = eMenuGuardar
botonera.BotonesMantenimiento = eBotMant_Cerrar
botonera.HabilitaBotones
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " Form_Load", , Err.Description
Resume End_
End Sub
Cuando guardemos se actualizará el objeto de acuerdo con lo que hayamos modificado.
Private Sub Botonera_ToolClicked(aTool As AhoraOCX.AhoraTool)
On Error Resume Next
Select Case aTool.Name
Case cBotMant_Guardar
If EObjeto.Actualiza(True) Then
MsgBox "Objeto guardado con éxito", vbInformation, "Guardado"
End If
Case cBotMant_Cerrar
Unload Me
End Select
End Sub
Control TextoUsuario
Este control contiene una caja de texto unida a una etiqueta. De manera que, en un
solo control, tendremos la opción de poner la caja de texto con su etiqueta. También,
como vimos en el ejemplo anterior, el control es enlazable a EnlaceObjeto.
Al control le podremos indicar qué tipo de dato albergará y cómo debe mostrarlo, de
modo que con él nos ahorraremos validaciones de formato. Si indicamos que el control
es de tipo fecha, automáticamente mostrará un calendario para que el usuario
seleccione la fecha cómodamente.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 72
Propiedades
ObjOrigen
Descripción: Indica el nombre del control EnlaceObjeto asignado.
Tipo: Texto.
ObjPOrigen
Descripción: Es la propiedad del objeto (Ej. IdCliente, Nombre, Descripción, etc.).
Tipo: texto.
Necesario
Descripción: Indica que es necesario que se rellene.
Tipo: Verdadero/Falso.
TipoDato
Descripción: Numérico, moneda, Date, String o NIF.
Tipo: String.
Formato
Descripción: Para el tipo de dato que pongamos, tendremos una lista de formatos
para seleccionar, en el caso del tipo numérico seleccionaremos los decimales, si es
fecha seleccionaremos si es fecha corta, etc.
Tipo: String.
CaptionVisible
Descripción: Indica si queremos visualizar la etiqueta del control.
Tipo: Verdadero/Falso.
CaptionWidth
Descripción: Indicaremos el ancho de la etiqueta.
Tipo: Número.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 73
CaptionPosition
Descripción: Indicaremos la orientación de la etiqueta.
Tipo: Número
CaptionControl
Descripción: Pondremos el texto que queremos que aparezca en la etiqueta.
Tipo: Texto.
CaptionLink
Descripción: indicamos si queremos que la etiqueta se comporte como un enlace, al
hacerle clic llamará al evento Caption_Click.
Tipo: Verdadero/Falso.
Eventos.
Además de los eventos que suelen tener las cajas de texto, este control incorpora:
Caption_Click: se dispara cuando hacemos clic en el label del control.
AfterUpdate: se dispara después de modificar el dato contenido.
BeforeUpdate: se dispara antes que se modifique el dato contenido.
Control TextoMultilinea.
Es como el control TextoMultiusuario con la característica de ser multilínea.
Se utiliza para los campos de descripción extensos.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 74
Control LabelUsuario
Además de comportarse como un control label normal, incorpora la propiedad
Caption_Link que si está a TRUE simula un link, respondiendo al evento Caption_Click
en el momento que el usuario hace clic en él.
Propiedades
CaptionLink
Descripción: indicamos si queremos que la etiqueta se comporte como un enlace, al
hacerle clic llamará al evento Caption_Click.
Tipo: Verdadero/Falso.
Eventos
Además de los eventos que suelen tener las cajas de texto, este control incorpora:
Caption_Click: se dispara cuando hacemos clic en el label del control.
Control Botonera
El control dibuja una barra con botones. Los botones son objetos de tipo AhoraTool.
Tiene dos grupos de botones predefinidos: botones SeguridadObjeto (Guardar, Nuevo,
Eliminar, Imprimir y Asociados) y botones Mantenimiento (Aceptar, Cancelar, Cerrar). Si
no ponemos ninguna instrucción a la botonera, ésta cargará por defecto todos los
botones. También tenemos la opción de agregar manualmente los botones, en tiempo
de ejecución mediante la función Add.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 75
Propiedades
SeguridadObjeto
Son los botones que suelen usar en los formularios de objetos.
Descripción: Indicamos qué botón o botones del grupo SeguridadObjeto queremos
mostrar.
Tipo: Entero.
El orden es el siguiente:
- eMenuNinguno = 0
- eMenuVer = 1
- eMenuVer2 = 2
- eMenuRefrescar = 4
- eMenuAñadir = 8
- eMenuBorrar = 16
- eMenuImprimir = 32
- eMenuEnviar = 64
- eMenuGuardar = 128
- eMenusTodos = eMenuVer + eMenuVer2 + eMenuRefrescar + eMenuAñadir +
eMenuBorrar + eMenuImprimir + eMenuEnviar + eMenuGuardar
BotonesMantenimiento
Son botones que suelen enseñar en formularios de mantenimiento de tabla.
Descripción: Indicamos qué botón o botones del grupo BotonesMantenimiento
queremos mostrar.
Tipo: Entero.
El orden es el siguiente:
- eBotMant_Ninguno = 0
- eBotMant_Aceptar = 1
- eBotMant_Cancelar = 2
- eBotMant_AceptarCancelar = eBotMant_Aceptar + eBotMant_Cancelar
- eBotMant_Cerrar = 4
- eBotMant_AceptarCerrar = eBotMant_Aceptar + eBotMant_Cerrar
- eBotMant_CancelarCerrar = eBotMant_Cancelar + eBotMant_Cerrar
- eBotMant_AceptarCancelarCerrar = eBotMant_Aceptar + eBotMant_Cancelar +
eBotMant_Cerrar
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 76
Resize
Descripción: Indica que el control se ajustará a la pantalla automáticamente (ver
ejemplo).
Tipo: Verdadero/Falso
MetodoObjeto
Descripción: Es la manera que tenemos para indicarle al control cómo referenciar al
objeto. Por ejemplo, si tenemos un control EnlaceObjeto llamado EObjeto le
indicamos cómo llegar al objeto: “EObjeto.ObjGlobal”. De ésta manera la Botonera
podrá habilitar/deshabilitar los botones según el estado del objeto.
Tipo: STRING.
Eventos
ToolClicked(aTool As AhoraOCX.AhoraTool): se dispara cuando hacemos clic en un
botón de la botonera. El evento nos retorna el objeto botón al que le hicieron clic.
Métodos y funciones.
BotonAdd
Descripción: Agrega un botón a la botonera.
Parámetros: Caption del Botón, Id (String), Tipo de botón, Nuevo Grupo.
Retorno: Retorna el objeto AhoraTool creado.
Los tipos de botones son:
- eTipo_Menu_Boton
- eTipo_Menu_Check
- eTipo_Menu_Combo
- eTipo_Menu_Edit
- eTipo_Menu_Menu
Si se le indica NuevoGrupo pondrá una línea divisoria que separará el botón de los
anteriores.
ColTools
Descripción: Es la colección con los botones
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 77
HabilitaBotones
Descripción: Habilita los botones. Si tiene un objeto vinculado habilitará los botones
de acuerdo a la seguridad que tenga asignada o al estado del objeto. La botonera
sabe cuál es el objeto vinculado de acuerdo a la propiedad MetodoObjeto.
Retorno: Verdadero/Falso.
Boton
Descripción: nos retorna un botón de la botonera.
Parámetros: Id del botón (string).
Retorno: AhoraTool.
Ejemplo de agregar un botón de tipo Combo:
Private Sub Form_Load()
On Error GoTo Error_
Botonera.BotonAdd "Cambiar Descuentos", "botCambiarDtos", , eTipo_Menu_Combo, True,
eicoahora
Botonera.BotonAdd "Cambiar Dto. &1", "botDescuento1", "botCambiarDtos",
eTipo_Menu_Boton, True, eicoahora
Botonera.BotonAdd "Cambiar Dto. &2", "botDescuento2", "botCambiarDtos",
eTipo_Menu_Boton, , eicoahora
End_:
Exit Sub
Error_
gCn.Tr.Trace TError, cModuleName, " Form_Load", , Err.Description
Resume End_
End Sub
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 78
Control CheckBoxUser
Este control se comporta como un check box convencional, con la ventaja de que se
puede vincular a un objeto mediante el control EnlaceObjetos. También se puede
Propiedades
ObjOrigen
Descripción: Indica el nombre del control EnlaceObjeto asignado.
Tipo: Texto.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 79
ObjPOrigen
Descripción: Es la propiedad del objeto (Ej. IdCliente, Nombre, Descripción, etc.).
Tipo: texto.
TipoDato
Descripción: Numérico, moneda, Date, String o NIF.
Tipo: String.
CaptionVisible
Descripción: Indica si queremos visualizar la etiqueta del control.
Tipo: Verdadero/Falso.
CaptionWidth
Descripción: Indicaremos el ancho de la etiqueta.
Tipo: Número.
CaptionPosition
Descripción: Indicaremos la orientación de la etiqueta.
Tipo: Número
CaptionControl
Descripción: Pondremos el texto que queremos que aparezca en la etiqueta.
Tipo: Texto.
Eventos.
Contiene los eventos convencionales de este tipo de controles, como el Click,
KeyPress, etc.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 80
Control cntMenuFormulario.
Control de menús del formulario. Se le pueden agregar botones de menú de forma
manual (en tiempo de ejecución) o de forma estática (en la tabla Ahora_Menus).
Este control tiene la particularidad de cargar sus botones de acuerdo a los registros
establecidos en la tabla Ahora_Menus. La mejor manera de manejar los menús es
insertándolos en la tabla, ya que de ésta manera incrementamos la seguridad de
acceso a las funciones del formulario. El control sólo permitirá la visualización de los
botones del menú a los usuarios que lo tengan permitido. Desde el Admon podremos
asignar la seguridad a los menús de los formularios.
Un ítem del menú puede tener asociado un Ahora_Proceso para ejecutarlo. De manera
que, haciendo clic en el menú, se pueden ejecutar procesos de tipo Macro. Esto
también se configura por tabla.
El funcionamiento de los menús es similar a los de un árbol con sus nodos. Cuando
agregamos un botón (ítem) al menú debemos especificar cuál es su padre (cabecera o
raíz). Si no se especifica lo tomará como cabecera del menú.
Ejemplo: Archivo (padre) – Salir (hijo) | Edición (Padre) – Copiar (Hijo) – Pegar (Hijo).
Recuerde que también puede crear los menús del formulario desde el ADMON.
Propiedades
ActivarScripts
Descripción: Activa/Desactiva la ejecución de scripts de los ítems del menú.
Tipo: True/False.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 81
Eventos
ToolClick(aTool As AhoraOCX.AhoraTool): se dispara cuando hacemos clic en un
botón del menú. El evento nos retorna el objeto botón al que le hicieron clic.
Métodos y funciones.
MenuItemAdd
Descripción: Agrega un botón al menú.
Parámetros: Caption del Botón, Id (String), Tipo de botón, Padre (de qué menú
cuelga el botón si no se especifica se entiende que es Padre), Nuevo Grupo (línea
separadora), ResId (idIcono), Before (si queremos colocarlo antes de otro botón
especificamos el nombre del botón).
Retorno: Retorna el objeto AhoraTool creado.
Los tipos de botones son:
- eTipo_Menu_Boton (Botón convencional)
- eTipo_Menu_Check (botón de tipo check)
- eTipo_Menu_Combo (sólo para el control Botonera)
- eTipo_Menu_Edit (Botón con caja de texto para edición)
- eTipo_Menu_Menu (Botón de tipo menú de cabecera)
Si se le indica NuevoGrupo pondrá una línea divisoria que separará el botón de los
anteriores.
Ready
Descripción: (TRUE/FALSE) activa el control y lo muestra.
AñadeAcelerador
Descripción: Asigna una tecla rápida a un elemento del menú (las teclas están
definidas en la tabla Ahora_Menus_teclas).
Tools
Descripción: Retorna una colección de objetos AhoraTools.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 82
MenuFormulario()
Descripción: Si queremos que se carguen los menús desde tablas, le especificaremos
los parámetros al control.
Parámetros: Librería (String), Nombre del Formulario (String)
Ejemplo: Agregar menús desde formulario.
1. Siguiendo con el ejemplo, agregue a frmControles.frm un control
cntMenuFormulario y llámelo MenuMain.
2. Pegue el código.
Private Sub Form_Load()
On Error GoTo Error_
With Me.MenuMain
‘ -creamos el menú Archivo
.MenuItemAdd "Archivo", "mnuArchivo", "", eTipo_Menu_Menu
.MenuItemAdd "Cerrar", "mnuCerrar", "mnuArchivo", eTipo_Menu_Boton, , , eIcoCerrar
.MenuItemAdd "Mensaje", "mnuMensaje", "mnuArchivo", eTipo_Menu_Boton, , , eIcoAviso
‘ -creamos el menú Ver
.MenuItemAdd "Ver", "mnuVer", "", eTipo_Menu_Menu
.MenuItemAdd "Cliente", "mnuVerCli", "mnuVer", eTipo_Menu_Boton, , , eIcoCliente
.MenuItemAdd "Contacto", "menuVerContacto", "mnuVer", eTipo_Menu_Boton, , ,
eIcoContacto
‘ -Deshabilitamos el botón.
.Tools("menuVerContacto").Enabled = False
‘ -Activamos la barra de menús
.Ready = True
End With
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " Form_Load", , Err.Description
Resume End_
End Sub
‘-Programamos el evento click
Private Sub MenuMain_ToolClick(aTool As AhoraOCX.AhoraTool)
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 83
Select Case aTool.Name
Case "mnuMensaje"
MsgBox "¡HOLA!"
Case "mnuCerrar"
Unload Me
End Select
End Sub
Ejemplo: Agregar menús desde tablas
Crearemos un menú de cabecera llamado mnuArchivo y un submenú mnuCerrar que
cierre la pantalla.
1. Siguiendo con el ejemplo, agregue a frmControles.frm un control
cntMenuFormulario y llámelo MenuMain.
2. Ejecute el script de inserción de menús.
3. En el formulario borre todo lo referente al menú y pegue el código Visual Basic,
en el evento LOAD o en el Carga.
Script de inserción en tablas de menú. Crea Menú “Archivo” y un submenú “Cerrar”.
--***************************************************************
--Menú Archivo
DECLARE @Libreria varchar(50)
DECLARE @Formulario varchar(50)
DECLARE @Orden INT
DECLARE @Tipo INT
DECLARE @Nombre Varchar(50)
DECLARE @NomControlMenu Varchar(50)
DECLARE @Caption Varchar(50)
DECLARE @Padre Varchar(50)
SET @Libreria = 'PlantillaExterno'
SET @Formulario = 'frmControles'
SET @NomControlMenu = 'MenuMain'
SET @Nombre = 'mnuArchivo'
SET @Tipo = 1 --Menu_Menu
SET @Caption = '&Archivo'
--El orden nos indica la posición en el menú.
SELECT @Orden = ISNULL(MAX(Orden),0) + 1 FROM Ahora_menus WHERE Libreria = @Libreria
AND Formulario = @Formulario
if exists (select * from ahora_menus where formulario = @Formulario and
libreria = @Libreria and nombre = @Nombre)BEGIN
print 'ya existe ' + @Nombre
end
else begin
INSERT INTO Ahora_Menus
(Libreria,Formulario,Nombre,Tipo,IniciaGrupo,MenuPadre,Orden,Caption,Checked,[Enabl
ed],
Visible,Icono,Categoria,Sistema,OrdenBotonera,SeparadorBotonera,Estandar)
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 84
VALUES
(@Libreria,@Formulario,@Nombre,@Tipo,0,@Padre,@Orden,@Caption,0,1,1,NULL,'Exter
no',1,0,0,1)
end
GO
--CERRAR
DECLARE @Libreria varchar(50)
DECLARE @Formulario varchar(50)
DECLARE @Orden INT
DECLARE @Tipo INT
DECLARE @Icono INT
DECLARE @Nombre Varchar(50)
DECLARE @NomControlMenu Varchar(50)
DECLARE @Caption Varchar(50)
DECLARE @Padre Varchar(50)
SET @Libreria = 'PlantillaExterno'
SET @Formulario = 'frmControles'
SET @NomControlMenu = 'MenuMain'
SET @Nombre = 'mnuCerrar'
SET @Padre = 'mnuArchivo'
SET @Tipo = 0 --Menu_Boton
SET @Caption = '&Cerrar'
SET @Icono = 1031
--El orden nos indica la posición en el menú.
SELECT @Orden = ISNULL(MAX(Orden),0) + 1 FROM Ahora_menus WHERE Libreria = @Libreria
AND Formulario = @Formulario
if exists (select * from ahora_menus where formulario = @Formulario and
libreria = @Libreria and nombre = @Nombre)BEGIN
print 'ya existe ' + @Nombre
end
else begin
INSERT INTO Ahora_Menus
(Libreria,Formulario,Nombre,Tipo,IniciaGrupo,MenuPadre,Orden,Caption,Checked,[Enabl
ed],
Visible,Icono,Categoria,Sistema,OrdenBotonera,SeparadorBotonera,Estandar)
VALUES
(@Libreria,@Formulario,@Nombre,@Tipo,0,@Padre,@Orden,@Caption,0,1,1,@Icono,'Ext
erno',1,0,0,1)
end
GO
--***************************************************************
En el formulario pegue el siguiente código.
Private Sub Form_Load()
On Error GoTo Error_
Me.MenuMain.MenuFormulario "PlantillaExterno", Me.Name
Me.MenuMain.Ready = True
End_:
Exit Sub
Error_:
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 85
gCn.Tr.Trace TError, cModuleName, " Form_Load", , Err.Description
Resume End_
End Sub
Private Sub MenuMain_ToolClick(aTool As AhoraOCX.AhoraTool)
Select Case aTool.Name
Case "mnuCerrar"
Unload Me
End Select
End Sub
Recuerde que puede combinar la forma de insertar los ítems del menú por tablas y por
código, pero si su intención es que el acceso a los menús tenga un control de
seguridad, utilice siempre la inserción por tablas.
Para crear menús y/o asignarles seguridad de una manera fácil hágalo desde el
ADMON. [Ver manual de ADMON]
Control ComboUsuarioMult
Este control nos permite crear uno o varios combos vinculados pasándole solamente
una consulta. La lista desplegable puede tener un máximo de tres columnas. Además,
se puede vincular con un objeto a través del control EObjeto.
Para ver un ejemplo del control y su funcionamiento diríjase al ejemplo de función
carga combo en este mismo manual.
Propiedades
ObjOrigen
Descripción: Indica el nombre del control EnlaceObjeto asignado.
Tipo: Texto.
ObjPOrigen
Descripción: Es la propiedad del objeto (Ej. IdCliente, Nombre, Descripción, etc.).
Tipo: Texto.
Necesario
Descripción: Indica que es necesario que se rellene.
Tipo: Verdadero/Falso.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 86
TipoDato
Descripción: Numérico, Moneda, Date, String o NIF.
Tipo: String.
Formato
Descripción: Para el tipo de dato que pongamos, tendremos una lista de formatos
para seleccionar, en el caso del tipo numérico seleccionaremos los decimales, si es
fecha seleccionaremos el formato (si es fecha corta…), etc.
Tipo: String.
CaptionVisible
Descripción: Indica si queremos visualizar la etiqueta del control.
Tipo: Verdadero/Falso.
CaptionWidth
Descripción: Indicaremos el ancho de la etiqueta.
Tipo: Número.
CaptionPosition
Descripción: Indicaremos la orientación de la etiqueta.
Tipo: Número
CaptionControl
Descripción: Pondremos el texto que queremos que aparezca en la etiqueta.
Tipo: Texto.
CaptionLink
Descripción: Indicamos si queremos que la etiqueta se comporte como un enlace, al
hacerle clic llamará al evento Caption_Click.
Tipo: Verdadero/Falso.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 87
Eventos.
Además de los eventos que suelen tener las listas de este tipo, este control incorpora:
Caption_Click: Se dispara cuando hacemos clic en el label del control.
AfterUpdate: Se dispara después de modificar el dato contenido.
BeforeUpdate: Se dispara antes que se modifique el dato contenido.
Control ComboUsuario
Muy similar al anterior, pero con la desventaja de que es un solo control. No permite
crear un conjunto de combos anidados. La lista desplegable puede tener un máximo de
tres columnas. Además, se le puede vincular un objeto a través del control EObjeto.
La consulta que toma como origen de datos de la lista se especifica en la propiedad
Descripcion
Propiedades
ObjOrigen
Descripción: Indica el nombre del control EnlaceObjeto asignado.
Tipo: Texto.
ObjPOrigen
Descripción: Es la propiedad del objeto (Ej. IdCliente, Nombre, Descripción, etc.).
Tipo: Texto.
Necesario
Descripción: Indica que es necesario que se rellene.
Tipo: Verdadero/Falso.
TipoDato
Descripción: Numérico, Moneda, Date, String o NIF.
Tipo: String.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 88
Formato
Descripción: Para el tipo de dato que pongamos, tendremos una lista de formatos
para seleccionar, en el caso del tipo numérico seleccionaremos los decimales, si es
fecha seleccionaremos si es fecha corta, etcétera.
Tipo: String.
CaptionVisible
Descripción: Indica si queremos visualizar la etiqueta del control.
Tipo: Verdadero/Falso.
CaptionWidth
Descripción: Indicaremos el ancho de la etiqueta.
Tipo: Número.
CaptionPosition
Descripción: Indicaremos la orientación de la etiqueta.
Tipo: Número
CaptionControl
Descripción: Pondremos el texto que queremos que aparezca en la etiqueta.
Tipo: Texto.
CaptionLink
Descripción: Indicamos si queremos que la etiqueta se comporte como un enlace, al
hacerle clic llamará al evento Caption_Click.
Tipo: Verdadero/Falso.
Descripcion
Descripción: indicamos el origen de datos (una consulta SQL con las columnas que
queremos mostrar). LA PRIMERA COLUMNA DE LA CONSULTA ES LA QUE SE
VISUALIZARÁ EN EL CONTROL.
Tipo: String.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 89
C1Anchura
Descripción: Indicamos el ancho de la columna 1.
Tipo: Número.
C1Nombre
Descripción: Indicamos el nombre de la columna 1 que debe coincidir con el campo
1 de la consulta.
Tipo: String.
C1TipoDato
Descripción: Indica el tipo de datos de la columna.
Tipo: Número.
LAS ÚLTIMAS 3 PROPIEDADES SE REPITEN PARA LAS COLUMNAS 2 Y 3. LA PRIMERA COLUMNA
DEFINIDA ES LA QUE SE VISUALIZARÁ EN EL CONTROL.
CActiva
Descripción: Indica el número de columna que será tomada como principal. Puede
visualizarse el dato de la columna 2, pero el dato de la primera columna es el que se
capture en la propiedad Text del control.
Tipo: Número (1,2 ó 3).
Inicializa
Descripción: A través de ésta propiedad le indicamos en qué fila debe posicionarse,
le asignamos un valor de la columna CActiva.
Tipo: Variant.
Eventos
Además de los eventos que suelen tener las listas de este tipo, este control incorpora:
Caption_Click: Se dispara cuando hacemos clic en el label del control.
AfterUpdate: Se dispara después de modificar el dato contenido.
BeforeUpdate: Se dispara antes que se modifique el dato contenido.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 90
Ejemplo:
1. Inserte en el formulario un control de tipo ComboUsuario
2. Complete las propiedades como se muestran a continuación.
Descripción:
SELECT IdFamilia,Descrip FROM Articulos_Familias ORDER BY IdFamilia.
3. Automáticamente, al cargar el formulario, el control desplegará la lista de familias
de artículos.
RECUERDE QUE, SI DESEA QUE EL CAMPO QUE SE MUESTRE EN EL CONTROL SEA DESCRIP, EN VEZ DE
IDFAMILIA, DEBE CAMBIAR EL ORDEN DE LAS COLUMNAS EN LA CONSULTA Y EN LA ESPECIFICACIÓN DE
COLUMNAS.
Control CntTab
Es un contenedor de controles CntPanel o SSPanel que se divide por pestañas.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 91
Las pestañas se crean por código. A cada pestaña le asignaremos un control SSPanel o
CntPanel.
Ejemplo de creación de un CntTab con 2 pestañas
1. Ponga en el formulario 2 controles CntPanel y llámelos Pnl1 y Pnl2.
2. Añada controles dentro de los controles CntPanel.
3. Añada un control CntTab y llámelo MiTab.
4. Pegue el siguiente código en la función carga o en el evento LOAD del
formulario.
MiTab.InsertItem 0, "Panel 1", Pnl1.Hwnd, 1
MiTab.InsertItem 1, "Panel 2", Pnl2.Hwnd, 1
En el método InsertItem, especifique un IdPestaña, el caption de la pestaña y el
contenedor a asignar, el último parámetro corresponde a una imagen.
Si quiere deshabilitar una pestaña en particular lo hará de la siguiente forma:
MiTab.Item(0).Enabled = False
Control cntGridUsuario
Sin duda es el control más complejo de los controles personalizados.
Cuando definimos una grid lo hacemos indicando un origen de datos (vista, tabla o
colección de objetos) y definiendo sus columnas.
Hay varias maneras de trabajar con este control. Veamos unos cuantos ejemplos de
cómo utilizarlo.
Propiedades
Agregar
Descripción: Indica si la grid permite agregar registros.
Tipo: TRUE/FALSE.
Editar
Descripción: Indica si la grid permite editar registros.
Tipo: TRUE/FALSE.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 92
Eliminar
Descripción: Indica si la grid permite eliminar registros.
Tipo: TRUE/FALSE.
EditarPorObjeto
Descripción: Los datos son editados mediante objetos. La grid instancia el objeto lo
actualiza con los datos insertados y llama al método update del objeto. De esta
forma permite guardar datos configurables.
Tipo: TRUE/FALSE.
CargaObjetos
Descripción: Si CargaObjetos = True, el origen de datos es la colección, si no, los
datos se leen del FROM.
Tipo: TRUE/FALSE.
Colección
Descripción: Le pasaremos la colección de objetos como origen de datos. Para esto
necesitamos EditarPorObjeto = TRUE.
Tipo: Colección
From
Descripción: Indica la tabla, vista o consulta que se utilizará como origen de datos.
Intente siempre utilizar vistas o tablas directamente. Si desea emplear una consulta
combinando tablas, debe especificar un Alias. Cuente con que el control hace un
“SELECT columnas FROM” XXX. Especifique sólo el origen de datos.
Tipo: STRING.
Alias
Descripción: Si especificamos un FROM de tipo consulta empleando tablas
combinadas, esta propiedad indicará a las columnas del grid el Alias de tabla por
defecto.
Tipo: STRING. Ver ejemplo de grid usando alias.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 93
Grid.FetchRowStyle
Descripción: Indica que, cuando se refresque la grid, se activará el evento
GridFetchRowStyle. Se utiliza generalmente cuando necesitamos pintar las filas del
grid de acuerdo a algún valor dado.
Tipo: TRUE/FALSE. Ver ejemplo FetchRowStyle.
TablaObjeto
Descripción: Especifica la tabla en la que se van a guardar los datos del grid. Un grid
puede tener un origen de datos distinto a la tabla donde se almacena. Guardará
todos los datos que coincidan con los campos de la grid.
Tipo: STRING
Where
Descripción: Cláusula WHERE completa para filtrar el origen de datos.
Tipo: STRING
Orden
Descripción: Nombre de las columnas por las que queremos filtrar separadas por “,”.
Tipo: STRING
Preparada
Descripción: Devuelve TRUE cuando tiene columnas creadas. Se utiliza para saber si
la grid ya ha sido inicializada.
Tipo: BOOLEAN.
SoloArray
Descripción: Si el valor es TRUE especifica que queremos trabajar sin que el grid
actualice los datos en la tabla.
Tipo: BOOLEAN.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 94
Refresca
Descripción: Si el valor es TRUE especifica que se refresque el grid cada vez que se
inserte/modifique/elimine un registro.
Tipo: BOOLEAN.
NoUsarIdDocs
Descripción: Cuando utilizamos un origen de datos que carece del campo IdDoc
pondremos ésta propiedad a FALSE para que no dé error al actualizar, ya que el
control necesita de un campo Identidad para realizar las actualizaciones. Use esta
propiedad cuando quiera una grid en casos especiales de sólo consulta o sólo array.
Tipo: BOOLEAN.
ColumnaEscalada
Descripción: Establece la columna que debe crecer al maximizar el grid.
ColumnaEscalada=”NombreColumna”
Tipo: STRING.
ArrayDB
Descripción: Array en el que se basa la grid.
Tipo: XArrayDB.
ArrayValue (fila,columna)
Descripción: establece un valor dentro del array del grid.
Tipo: VARIANT.
SQLSelect
Descripción: Instrucción SQL completa que toma el grid como origen de datos. Es la
unión final de todas las instrucciones dadas (Columnas, FROM, WHERE, UNION)
Tipo: STRING.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 95
Campo (NombreCampo)
Descripción: Nos devuelve el objeto CampoGrid indicado.
Tipo: CampoGrid.
Métodos y funciones
AgregaColumna()
Este método crea las columnas en el grid. Son objetos de tipo CampoGrid y
accederemos a las columnas del grid mediante [NombreGrid].Campo
(“NombreDeCampo”).
Los campos de grid son un objeto de AhoraSistema.dll con muchas propiedades y
funciones especiales. Por ejemplo podremos hacer que un campo grid contenga un
combo, asignarle un tipo de datos, un valor por defecto al cargar o una instrucción por
defecto al guardarse.
Parámetros obligatorios:
Campo (STRING): Especifica el nombre del campo del origen de datos.
Ancho (LONG): Establece el ancho de la columna (en TWIPS).
Descripción (STRING): Especifica el nombre de la cabecera de la columna.
Parámetros Opcionales:
Locked (BOOLEAN): Indica que el campo se bloquea y no se puede modificar.
Combo (STRING): Consulta SQL con los campos que queremos que muestre el
combo. El primer campo es el que quedará en la celda al seleccionar el dato de la
lista y los restantes los que desplegará el combo. Ejemplo:
SELECT IdArticulo Art, IdArticulo, Descrip FROM Articulos
Si queremos que se quede la descripción lo haremos de la siguiente manera:
SELECT Descrip Desc, IdArticulo, Descrip FROM Articulos
La consulta también puede hacer referencia a un campo de la grid. Por ejemplo, si en el
grid tenemos un campo IdFamilia y queremos que el combo nos muestre sólo los
artículos de esa familia. Para hacer referencia a un campo de la grid, en la sentencia
SELECT lo especificamos con “@nombrecampo”. Ejemplo:
SELECT IdArticulo Art, IdArticulo, Descrip FROM Articulos WHERE IdFamilia = @IdFamila
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 96
RowRefreshCombo (BOOLEAN): Establece que se refresque el combo al cambiar de
celda, siempre y cuando la consulta del combo dependa de otro campo (como en el
ejemplo anterior).
Format (STRING): Indica el formato de visualización del campo. Ejemplo: "#,##0.000".
Puede utilizar las constantes de formato contenidas en AhoraConstantes.dll como:
o cFmt_Num0 (sin decimales).
o cFmt_Num1 (1 decimal).
o cFmt_Num2 (2 decimales).
o cFmt_Num3 (3 decimales).
o cFmt_Num4 (4 decimales).
o cFmt_Num5 (5 decimales).
o cFmt_Num6 (6 decimales).
o cFmt_Pts (Pesetas con 2 decimales).
o cFmt_Date (Fecha convencional).
o cFmt_DateM ("mm/dd/yyyy").
o cFmt_DateInt ("yyyymmdd").
o Etcetera.
Total (BOOLEAN): Indica si debe agregar un campo al final con la suma de los
campos la columna.
Valores (STRING): Sentencia SQL que especifica el valor del combo que queremos
que se vea en la celda. Por ejemplo, si quiero seleccionar del combo el IdArticulo y
que éste se almacene en tabla, pero mostrar en pantalla (y en la misma celda) la
descripción.
El combo quedaría de ésta manera:
SELECT IdArticulo Art, IdArticulo, Descrip FROM Articulos
Mientras que el parámetro valores sería:
SELECT IdArticulo, Descrip FROM Articulos
Así estaríamos guardando el IdArtículo seleccionado, pero en la celda se visualizaría la
descripción.
EsResourceID (BOOLEAN): Indica que el valor del campo será un Icono. Con lo cual
cargará en la celda la imagen correspondiente. Siempre depende de la propiedad
valor. Por ejemplo, para cargar un Icono, la SELECT debería ser: “SELECT Objeto Obj,
Objeto, Icono1 FROM Objetos”
ValorFiltro: OBSOLETO. NO USAR
Obligado (BOOLEAN): Indica que el campo es obligatorio. Si el usuario no lo
completa, saldrá un mensaje advirtiendo ésto.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 97
DatoEnCombo(campo,valor)
Busca un valor dado dentro del combo de un campo.
GetValue(nombreCampo)
Retorna el valor del campo dado de la fila activa.
GridClear
Borra el contenido de la grid.
LimpiaGrid
Borra el contenido de la grid y elimina las columnas creadas.
Imprimir
Imprime la grid.
MenuItemAdd
Inserta un botón en el menú popup de la grid. Es el mismo método de inserción de
botones de menú y botonera. Cuando se presiona un botón POPUP del grid, se activa
el evento MenuClick del Grid.
PasoExcel
Exporta a Excel el contenido de la grid.
Refrescar
Refresca la grid.
SetValue (Campo,Valor)
Modifica el campo por el valor dado, en la fila activa.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 98
Eventos
La mayoría de los eventos suelen tener un nombre autoexplicativo, y en su mayoría son
los que suelen tener las grids estándar. A continuación se detallarán algunos eventos
especiales.
MenuClick
Se dispara cuando hacemos clic en un botón del menú POPUP del grid.
GridLoad
Se dispara cuando se refresca la grid.
La grid se refresca cuando:
- Llamamos al método refrescar.
- Actualizamos un registro.
PropiedadValor
Cuando hace el GridLoad, por cada campo calculado (Campos que comienzan con @)
se lanza el evento.
Ejemplo:
Imagine que tenemos dos campos calculados (@campo1 y @campo2) y necesitamos
volver a calcularlos cada vez que se actualice un registro.
El evento nos proporciona el array de la grid, la propiedad o nombre del campo
calculado, el valor del campo y la fila.
Private Sub cntGridOrdenes_PropiedadValor(aPropiedad As String, aValor As Variant, aArray As
XArrayDBObject.XArrayDB, aRow As Long)
Dim lSQL As String
Dim lValor As String
Select Case aPropiedad
Case "@Campo1"
IF CLong(aArray(aRow, pColOrdenes("CampoX").ColIndex))>0 THEN
aValor = (aArray(aRow, pColOrdenes("CampoY").ColIndex))
ELSE
aValor = 0
END IF
Case "@Campo2", "@PeticionPres"
If IsBlank(aValor) Then
aValor = 0
End If
End Select
End Sub
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 99
GridFetchRowStyle
Se activa cuando se refresca la grid y está activa la propiedad Grid.FetchRowStyle.
Ejemplo
En este ejemplo, la grid tiene la propiedad GRID.FerchRowStile=TRUE.
Deseamos pintar de rojo las filas que tengan el campo color = 1.
Private Sub grdArticulos_GridFetchRowStyle(ByVal split As Integer, ByVal Bookmark As Variant,
RowStyle As TrueDBGrid60.StyleDisp)
With grdArticulos
If .ArrayDb(Bookmark, .Grid.Columns("Color").ColIndex) = 1 Then
RowStyle.ForeColor = vbRed
End If
End With
End Sub
Objeto CampoGrid
Es el campo, propiamente dicho del grid, es decir, donde se guardan las propiedades
mencionadas en el método AgregaColumna () del grid. Accedemos a los objetos del
grd de la forma [NombreGrid].Campo (NombreCampo).
Propiedades
Dijimos que el método AgregaColumna del grid lo que hacía era crear un objeto
CampoGrid con las propiedades que solicita. Además de las nombradas anteriormente
detallaremos algunas más.
Sustitucion
Descripción: Valor que tomará el campo cuando se actualice una celda de la misma
fila. Ver ejemplo de grid con sustitución.
Tipo: STRING
Booleano
Descripción: Dibuja un control CheckBox.
Tipo: BOOLEAN.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 100
CampoFecha
Descripción: Establece un control Fecha para el campo.
Tipo: BOOLEAN.
Métodos y Funciones.
AsignaAsistente
Descripción: Lanza un AhoraProceso llamado AhoraAsistente. Cuando se pulsa F3
despliega un formulario con filtro para buscar el dato. Este procedimiento sólo
define el formulario, y va acompañado del método AssistAddField () que definirá las
columnas de la grid del asistente. Vea el ejemplo de grid con asistente.
Parámetros Obligatorios
- Icono (LONG): Número de Icono que queremos que aparezca en el Form.
- From (STRING): Instrucción SQL, origen de datos.
- Where (STRING): Filtro SQL, puede ser una cadena vacía.
- Order (STRING): Lista de campos a ordenar separados por comas.
Parámetros Opcionales
- DataField(STRING): Nombre del campo grid. Si queremos que aparezca en el
campo del asistente.
- Width(LONG): Ancho del formulario.
- Heigth(LONG): Alto del formulario.
AssistAddField
Descripción: Método que define los campos de la grid del asistente F3.
Parámetros Obligatorios
- Field (STRING): Nombre del campo que queremos que aparezca en el grid.
Parámetros Opcionales
- Descrip(STRING): Descripción del campo.
- Type(LONG): Tipo de dato (string, etc).
- Size(LONG): Tamaño del campo.
- Autosize (BOOLEAN): para que el tamaño se ajuste automáticamente.
- DataField (BOOLEAN): Indica que es el campo que queremos que nos retorne. Si
no se especifica, el asistente nos devuelve el primero que declaremos.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 101
Cosas importantes a tener en cuenta sobre los grids
Utilizan un array de tipo XArrayDB para manejarse. Se puede referenciar mediante
[NombreGrid].ArrayDB.
Si queremos utilizar el grid sólo como un Array, sin que los cambios se vean
reflejados en tablas, debemos poner sus propiedades SoloArray = TRUE y Refresca =
False.
Si la propiedad Refresca = TRUE el grid se refrescará siempre que se actualice un
campo.
Si el grid permite insertar filas recuerde que puede controlar el valor de los campos a
insertar mediante la propiedad Default del campo. Se utiliza frecuentemente para
controlar la inserción de campos clave o campos incrementales. Ver ejemplo
Formulario de mantenimiento.
Puede definir asistentes para los campos, de modo que al pulsar F3 en una celda con
asistente le saldrá una pantalla de búsqueda. Vea el ejemplo de grid con asistentes
F3.
Ejemplo ARRAY sin origen de datos y campos sustitución
- Cuando no se desea cargar datos en el grid, simplemente que el usuario los
introduzca, no es necesario poner un origen de datos.
- Utilizaremos sustitución cuando se selecciona un artículo y queremos que se
actualice el campo Descripción, y viceversa.
- Al insertar un nuevo registro queremos que el campo cantidad por defecto sea
1.
Private Sub CargaGrdArticulosConSust()
'Crearemos un grid de sólo array para introducir artículos y cantidades
'Seleccionaremos los artículos de un combo
'Al seleccionar el artículo se actualzará la descripción y viceversa
On Error GoTo Error_
With grdArticulos
If Not .Preparada Then
.Agregar = True
.Editar = True
.Eliminar = True
.CargaObjetos = False
.EditarPorObjeto = False
.Grid.FetchRowStyle = False
'Agregamos columna con formato numérico (Ver lib Ahora_Constantes)
.AgregaColumna "Cantidad", 1000, "Cantidad", , , , cFmt_Num0
.AgregaColumna "IdArticulo", 1500, "Articulo", , _
"Select IdArticulo, IdArticulo, Descrip From Articulos"
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 102
.AgregaColumna "Descrip", 2500, "Descripcion", , _
"Select Descrip, Descrip, IdArticulo From Articulos"
.From = "" 'sin origen de datos porque los introducirá el usuario
.Where = ""
.Orden = ""
'Sustituciones
.Campo("IdArticulo").Sustitucion = _
"SELECT IdArticulo FROM Articulos WHERE Descrip = @Descrip"
.Campo("Descrip").Sustitucion = _
"SELECT Descrip FROM Articulos WHERE IdArticulo = @IdArticulo"
.Campo("Cantidad").Default = 1
.SoloArray = False
.Refresca = True
End If
.SoloArray = True
.Refresca = False
End With
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " CargaGrd1", , Err.Description
Resume End_
End Sub
Ejemplo de grid sólo ARRAY usando Alias y campos calculados. En este ejemplo el grid es de sólo edición y sólo queremos que se refresque cuando se
llame al método cargaGridSelecTarifas. Le pondremos un FROM porque queremos que
cargue datos por defecto.
Private Sub cargaGridSelecTarifas()
On Error GoTo Error_
With grdSelecTarifas
If Not .Preparada Then
.Agregar = False
.Editar = True
.Eliminar = False
.CargaObjetos = False
.Alias = "a"
‘Columna Marca (Columna Calculada) no existe en las tablas.
‘-Se especifica con @
.AgregaColumna "@Marca", 700, "Marca"
.AgregaColumna "IdDelegacion", 1000, "Delegacion", True
.AgregaColumna "IdLista", 500, "Lista", True
.AgregaColumna "Descrip", 1000, "Descripción", True
‘-Establecemos el tipo de datos y la sustitución
.Campo("@Marca").Booleano = True
.Campo("@Marca").Sustitucion = "Select 0"
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 103
.From = "(SELECT cc.IdDelegacion, lpc.IdLista, lpc.Descrip, lpc.IdDoc " & _
"FROM Listas_Precios_Cli lpc " & _
"INNER JOIN Ceesi_Configuracion cc ON " & _
"lpc.IdLista = cc.Valor WHERE cc.Parametro = 'LISTAPRECIOS_DEFECTO')a"
‘Queremos que sólo cargue tarifas para delegación actual.
‘GCN es el objeto conexión.
.Where = " WHERE a.IdDelegacion = " & gCn.IdDelegacion
.Orden = " IdDelegacion, IdLista"
End If
‘Cuando es un grid de solo Array el orden de refresco es el siguiente: si se cambia el orden da
error
.SoloArray = False
.Refresca = True ‘-Hacemos el refresco 1 vez.
.SoloArray = True
.Refresca = False ‘-Dejamos la grid como sólo array.
End With
End_:
Exit Sub
Error_:
Tr.Trace TError, cModuleName, " CargaGrdSelecTarifas", , Err.Description
Resume End_
End Sub
Ejemplo de grid de sólo lectura con Alias y filtro WHERE.
Private Sub CargaGrdArticulosDeProv(Optional aIdProveedor As String = "-1")
‘--Cuando se llame a este procedimiento se aplicará el filtro WHERE
‘--Y mostrará los artículos del proveedor especificado.
On Error GoTo Error_
Dim lStrVista As String
lStrVista = "(SELECT pa.IdProveedor, pa.IdArticulo, a.Descrip, a.IdDoc " & _
"FROM Prov_Articulos pa " & _
"INNER JOIN Articulos a on " & _
"pa.IdArticulo = a.IdArticulo) Vista"
With grdArticulosDeProv
If Not .Preparada Then
.Agregar = False
.Editar = False
.Eliminar = False
.CargaObjetos = False
.EditarPorObjeto = False
.Grid.FetchRowStyle = False
.Alias = "Vista"
.AgregaColumna "IdArticulo", 1000, "IdArticulo"
.AgregaColumna "Descrip", 3000, "Descripción"
.From = lStrVista
.Orden = ""
End If
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 104
.Where = "WHERE Vista.IdProveedor = " & SqlString(aIdProveedor)
‘--la func. sqlString me añade comillas
.Refresca = True
End With
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " CargaGrdArticulosDeProv", , Err.Description
Resume End_
End Sub
Ejemplo de grid con colecciones y asistentes F3.
Cuando la grid tiene la propiedad CargaObjeto=FALSE, al actualizar un registro
significa que NO estamos actualizando el objeto. La grid no podrá contener los campos
de la tabla configurables del objeto.
Private Sub gridLoad()
On Error GoTo Error_
With GrdLineas
If Not .Preparada Then
.Agregar = True
.Editar = True
.Eliminar = True
.CargaObjetos = False 'al estar a False necesitamos indicar la tabla donde guarda
.EditarPorObjeto = True
Set .Coleccion = EObjeto.ObjGlobal.Objetos("Trans_Prod_Lineas")
.From = "Transformac_Lineas"
.AgregaColumna "IdCodigo", 0, "IdCodigo"
.AgregaColumna "IdLinea", 0, "IdLinea"
.AgregaColumna "IdArticulo", 1875, "Id artículo", False, _
"SELECT IdArticulo, IdArticulo, Descrip FROM VCombo_Articulos Order By
IdArticulo"
.AgregaColumna "@Descrip", 1875, gCn.Traducir(734, "Descripción"), False, _
"SELECT Descrip, Descrip, IdArticulo FROM VCombo_Articulos Order By Descrip"
.AgregaColumna "Unidades", 1000, "Unidades", , , , cFmt_Num2
.AgregaColumna "Precio", 1000, "Precio", , , , cFmt_Eur, , , , , True
'Sustituciones
.Campo("IdArticulo").Sustitucion = _
"SELECT IdArticulo FROM VCombo_Articulos WHERE Descrip = @@Descrip"
.Campo("@Descrip").Sustitucion = _
"SELECT Descrip FROM VCombo_Articulos WHERE IdArticulo = @IdArticulo"
'Asistentes
With .Campo("IdArticulo")
.AsignaAsistente gCn.Obj.Objetos("Articulos").Entorno.Icono1, _
"vCombo_Articulos", "", "IdArticulo", "IdArticulo", 8000, , False
'Campos del asistente
.AssistAddField "IdArticulo", "Id Artículo", "String", 2000, , True
.AssistAddField "Descrip", gCn.Traducir(734, "Descripción"), "String", 4500
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 105
End With
With .Campo("@Descrip")
.AsignaAsistente gCn.Obj.Objetos("Articulos").Entorno.Icono1, _
"vCombo_Articulos", "", "Descrip", "Descrip", 8000, , False
'Campos del asistente
.AssistAddField "Descrip", gCn.Traducir(734, "Descripción"), "String", 4500
.AssistAddField "IdArticulo", "Id Artículo", "String", 2000, , True
End With
.ColumnaEscalada = "@Descrip"
End If
Set .Coleccion = EObjeto.ObjGlobal.Objetos("Trans_Prod_Lineas")
If Not pObjeto.Propiedades("IdCodigo") = 0 Then
.Where = "WHERE IdCodigo = " & EObjeto.ObjGlobal.Propiedades("IdCodigo"))
Else
.Where = "WHERE 1 = 0"
End If
.Refresca = True
End With
End_:
Exit Sub
Error_:
GCn.Tr.Trace TError, cModuleName, " gridLoad", , Err.Description
Resume End_
End Sub
Ejemplo Grid con colecciones con cargando Objetos
Cuando la grid tiene la propiedad CargaObjeto=TRUE, al actualizamos un registro
significa que estamos actualizando el objeto. Si el objeto tiene campos configurables
(por lo tanto una tabla Conf_[Objeto]) éstos se actualizarán si están reflejados en la
grid.
Private Sub GridLoad_Lineas(aFp As FormaPago)
On Error GoTo Error_
With grdLineas
If Not aFp.Nuevo Then
If Not .Preparada Then
.CargaObjetos = False
.EditarPorObjeto = True
Set .Coleccion = aFp.Objetos("FormaPago_Lineas")
.AgregaColumna "IdLinea", 500, gCn.Traducir(24619, "Nº"), True
.AgregaColumna "IdTipoEfecto", 1500, gCn.Traducir(913, "Tipo"), , _
"Select Tipo, Descrip From Efectos_Tipos Order By Descrip", True, , , _
"Select Tipo, Descrip From Efectos_Tipos Order By Descrip"
.AgregaColumna "Descrip", 2000, gCn.Traducir(734, "Descripción")
.AgregaColumna "Porcentaje", 800, "%", , , , cFmt_Num2, True
.AgregaColumna "NumVencimientos", 800, gCn.Traducir(4414, "Venc"), , , , cFmt_Num0
.AgregaColumna "PrimerVencimiento", 600, gCn.Traducir(4415, "1ª Venc"), , , , cFmt_Num0
.AgregaColumna "Periodo", 800, gCn.Traducir(4416, "Período"), , , , cFmt_Num0
With .Combo("IdTipoEfecto")
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 106
.ListField = .Columns(1).DataField
.DataField = .Columns(0).DataField
End With
.Refresca = True
Else
Set .Coleccion = aFp.Objetos("FormaPago_Lineas")
End If
Me.grdLineas.Visible = True
Else
grdLineas.Visible = False
End If
End With
Salir_:
Exit Sub
Error_:
Gcn.Tr.Trace TError, cFormName, " GridLoad_Lineas", , Err.Description
Resume Salir_
End Sub
Formulario de mantenimiento
Muchas veces necesitamos hacer un mantenimiento sobre alguna tabla utilizando un
formulario simple con una grid. Para esto tenemos una manera sencilla de crearlo
automáticamente utilizando un código sencillo.
Sabiendo definir una grid, podremos hacer uso de ésta gran ayuda.
Para acceder al formulario de mantenimiento necesitamos la librería
AhoraAsistentes.dll. Puede observar que la función lo que hace es instanciar el
formulario de mantenimiento y configurar su grid.
La función carga:
Public sub Mantenimiento(Optional aObj AS Object = Nothing)
On Error GoTo Errores
Dim lFrm As IMantenimiento ’—Definimos el formulario
Set lFrm = NewFrmMantenimiento(gCn)’—instanciamos el formulario pasándole la conexión.
gCn es la conexión
With lFrm.Grid("GrdMantenimiento")’—Creamos el grid pasándole por parámetro el nombre
.Agregar = True
.Editar = True
.Eliminar = True
.CargaObjetos = False
.EditarPorObjeto = False
.Grid.HeadLines = 2
.AgregaColumna "IdRevTipoInteres", 1200, "IdRevision"
.AgregaColumna "Descrip",1300,"Descripción", , , , , , , , ,True
.AgregaColumna "Meses", 800, "Meses"
’—Así, al insertar un nuevo registro, agregue el último ID+1
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 107
.Campo("IdRevTipoInteres").Default = "Select IsNull(Max(IdRevTipoInteres),0) +1 As Nuevo
From Intereses_Revisiones"
.ColumnaEscalada = "Descrip"
.From = "Intereses_Revisiones"
.Orden = "IdRevTipoInteres"
.Refresca = True
End With
lFrm.Form.Caption = "Mantenimiento de revisiones"
lFrm.carga aObj, True, eBotMant_Cerrar
Set lFrm = Nothing
Exit sub
Errores:
gCn.Tr.Trace TError, cModuleName, " Mantenimiento ", , Err.Description
End sub
Llamando a la función, obtendremos un formulario con un grid de mantenimiento de
tabla.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 108
EJEMPLO: CREACIÓN DE UN OBJETO EN EL SISTEMA
Introducción
Vamos a crear un objeto ObjPrueba que sea accesible desde el explorador de objetos.
Las propiedades del objeto serán: Numero, Descrip e IdCliente.
El objeto tendrá asociadas líneas con artículos.
Las propiedades de sus líneas serán: Numero (Numero del ObjPrueba), IdArticulo y
Cantidad.
Se definirá también una tabla de campos configurables para el objeto.
La tabla se llamará Conf_ObjsPrueba y definirá los campos: Telefono2 e IdEmpleado.
El formulario tendrá una cabecera con el número de objeto y su descripción y 2 fichas.
Una con los datos estándar y otra con los campos configurables. Tendrá una grid
donde se crearán sus líneas.
Acceso desde
buscador de objetos.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 109
Formulario.
Creación de tablas
Tabla ObjsPrueba
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ObjsPrueba]')
AND type in (N'U'))
DROP TABLE ObjsPrueba
go
CREATE TABLE [dbo].[ObjsPrueba](
[Numero] [int] NOT NULL,
[Descrip] [varchar](250) NOT NULL,
[Fecha] [dbo].[T_Fecha_Corta] NULL,
[IdCliente] t_id_cliente null,
[IdDoc] [dbo].[T_Id_Doc] IDENTITY(1,1) NOT NULL,
[InsertUpdate] [dbo].[T_CEESI_Insert_Update] NOT NULL,
[Usuario] [dbo].[T_CEESI_Usuario] NOT NULL,
[FechaInsertUpdate] [dbo].[T_CEESI_Fecha_Sistema] NOT NULL,
CONSTRAINT [PK_ObjsPrueba] PRIMARY KEY CLUSTERED
([Numero] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Zpermisos ObjsPrueba –-Asignamos permisos a la tabla
GO
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 110
Tabla ObjsPrueba_Lineas
Los registros de ésta tabla existirán siempre que exista el registro en la tabla
ObjPruebas. Por lo tanto, debemos hacer que se actualice y elimine en cascada. Si se
borra la referencia en ObjsPrueba, se debe eliminar el registro ObjsPrueba_Lineas.
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id =
OBJECT_ID(N'[dbo].[FK_ObjsPrueba_Lineas]') AND parent_object_id =
OBJECT_ID(N'[dbo].[ObjsPrueba_Lineas]'))
ALTER TABLE [dbo].[ObjsPrueba_Lineas] DROP CONSTRAINT [FK_ObjsPrueba_Lineas]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id =
OBJECT_ID(N'[dbo].[ObjsPrueba_Lineas]') AND type in (N'U'))
DROP TABLE ObjsPrueba_Lineas
GO
CREATE TABLE [ObjsPrueba_Lineas](
Numero int not null,
IdArticulo t_id_articulo,
Cantidad smallint not null,
[IdDoc] [dbo].[T_Id_Doc] IDENTITY(1,1) NOT NULL,
[InsertUpdate] [dbo].[T_CEESI_Insert_Update] NOT NULL,
[Usuario] [dbo].[T_CEESI_Usuario] NOT NULL,
[FechaInsertUpdate] [dbo].[T_CEESI_Fecha_Sistema] NOT NULL,
CONSTRAINT [PK_ObjsPrueba_Lineas] PRIMARY KEY CLUSTERED
(
[Numero] ASC,
IdArticulo ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [dbo].ObjsPrueba_Lineas WITH CHECK ADD CONSTRAINT
[FK_ObjsPrueba_Lineas] FOREIGN KEY([Numero])
REFERENCES [dbo].[ObjsPrueba] ([Numero]) ON UPDATE CASCADE ON DELETE CASCADE
Zpermisos ObjsPrueba_Lineas –-Asignamos permisos a la tabla
GO
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 111
Definición de Propiedades
--Objetos_Propiedades
DELETE FROM Objetos_Propiedades WHERE Objeto='ObjsPrueba'
go
INSERT INTO
Objetos_Propiedades(Objeto,Propiedad,Descrip,Seleccion,Orden,Visible,Locked,Obligado,Substit
ucion,Width,Defecto,Formato)
VALUES('ObjsPrueba','Numero','Número',null,null,1,0,0,null,1000,null,null)
INSERT INTO
Objetos_Propiedades(Objeto,Propiedad,Descrip,Seleccion,Orden,Visible,Locked,Obligado,Substit
ucion,Width,Defecto,Formato)
VALUES('ObjsPrueba','Descrip','Descripción',null,null,1,0,0,null,1000,null,null)
INSERT INTO
Objetos_Propiedades(Objeto,Propiedad,Descrip,Seleccion,Orden,Visible,Locked,Obligado,Substit
ucion,Width,Defecto,Formato)
VALUES('ObjsPrueba','Fecha','Fecha',null,null,1,0,0,null,1000,null,null)
GO
Definir el objeto en tabla Definimos el objeto y su colección. Lo mejor es hacerlo desde el Admon.
En el ejemplo anterior lo hemos definido desde el ADMON, a continuación mostramos cómo
definirlo por sentencias SQL. No le indicaremos la tabla de campos configurables, haremos el
ejemplo desde el ADMON.
DELETE FROM Objetos WHERE Objeto='ObjsPrueba' or Objeto='ObjPrueba' or
Objeto='ObjPrueba_Lineas' or Objeto='ObjPrueba_Linea'
GO
-- Objeto
INSERT INTO
Objetos(Objeto,Coleccion,Icono1,Icono2,Icono3,Raiz,Descrip,SQL,FiltroDefecto,HijoDefecto,Perm
iteFiltros,Orden,FormAsociado,
Limita,Menu,CadenaDescrip,Expandir,Ejercicio,Sistema,Activo,AltaDirecta,IdTipoDef,Tabla,TablaO
tra,EdicionGrid,Libreria,
ObjetoEventos,IdClasificacion)
VALUES( 'ObjPrueba',0,102,102,102,0,'Objeto de prueba','SELECT * FROM ObjsPrueba','SELECT *
FROM ObjsPrueba', null,0,null,'ObjFormObjPrueba',
0,0,'[Numero]-[Descrip]',1,0,0,1,1,null,'ObjsPrueba', null,null,'PlantillaExterno',null,5)
GO
--Coleción
INSERT INTO
Objetos(Objeto,Coleccion,Icono1,Icono2,Icono3,Raiz,Descrip,SQL,FiltroDefecto,HijoDefecto,Perm
iteFiltros,Orden,FormAsociado,
Limita,Menu,CadenaDescrip,Expandir,Ejercicio,Sistema,Activo,AltaDirecta,IdTipoDef,Tabla,TablaO
tra,EdicionGrid,Libreria,
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 112
ObjetoEventos,IdClasificacion)
VALUES ('ObjsPrueba',1,102,102,102,1,'Objetos de Prueba(Col)','SELECT * FROM
ObjsPrueba','SELECT * FROM ObjsPrueba','ObjPrueba',0,null,null,
100,16,'[Numero]-[Descrip]',1,0,0,1,1,null,'ObjsPrueba',null,null,'PlantillaExterno',null,5)
GO
Tabla Configurables
La crearemos desde el ADMON. Debe estar definido el objeto en la tabla
Objetos_Objetos.
1. Abra el ADMON
2. Vaya a Objetos y en la ficha de objetos seleccione “Objeto de Pueba”
y en el campo Tabla campos configurables escriba Conf_Objs_Prueba
y pulse el botón Guardar. Se creará la tabla de configurables.
3. Vaya a Campos Configurables y añada las propiedades como muestra
la siguiente imagen.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 113
Ya tenemos definido el objeto por tablas.
Triggers
Cuando se crea un objeto hay que crear el registro en la tabla de configurables.
IF EXISTS (SELECT * FROM sys.triggers WHERE object_id =
OBJECT_ID(N'[dbo].[ObjsPrueba_ITrig]'))
DROP TRIGGER [dbo].[ObjsPrueba_ITrig]
go
CREATE TRIGGER [dbo].[ObjsPrueba_ITrig]
ON [dbo].[ObjsPrueba]
FOR INSERT
AS
IF @@ROWCOUNT<>0 BEGIN
----------------------------------------------------------
-- Inserto un registro en CAMPOS CONFIGURABLES
----------------------------------------------------------
INSERT INTO Conf_ObjsPrueba ([Numero]) SELECT [Numero] FROM Inserted
End
Go
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 114
Vistas
Creamos la vista para el grid.
IF EXISTS (SELECT * FROM sys.objects WHERE object_id =
OBJECT_ID(N'[dbo].[VObjsPrueba_Lineas]') AND type in (N'V'))
drop view VObjsPrueba_Lineas
GO
create view VObjsPrueba_Lineas as
SELECT o.Numero, o.IdArticulo,a.Descrip, o.Cantidad, o.IdDoc
FROM [ObjsPrueba_Lineas] o left join Articulos a on o.IdArticulo = a.IdArticulo
GO
zpermisos VObjsPrueba_Lineas
Definir objeto en librería
En nuestro proyecto de pruebas PlantillaExterno, cree un nuevo módulo de clase
llamado ObjPrueba (ObjPrueba.cls)
Vamos a implementar la herencia con el objeto IItem.
Pegue el siguiente código.
Option Explicit
Option Base 0
Option Compare Text
Implements Capturador
Implements IItem
‘El IItem en que se base el Objeto
Private pItem As IItem
‘Capturador para entregar el padre
Private WithEvents ContainerSubObject As Capturador
Public Function Add() As IItem
Set Add = pItem.Add()
End Function
Public Sub AsignaClaves(lacoleccion As Collection)
pItem.AsignaClaves lacoleccion
End Sub
Public Property Get Campos(Cual As String) As Object
Set Campos = pItem.Campos(Cual)
End Property
Private Function Capturador_EventRaise(EventName As String, aObj As Variant) As Variant
Dim lCap As Capturador
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 115
Dim lBreak As Boolean
On Error GoTo Error_
Select Case EventName
Case Else
lBreak = False
#If debugmode Or DebugCallback Then
Debug.Print EventName
#End If
End Select
On Error Resume Next
Set lCap = Padre
If Not lCap Is Nothing And Not lBreak Then
Capturador_EventRaise = lCap.EventRaise(EventName, aObj)
End If
Set lCap = Nothing
Salir_:
Exit Function
Error_:
gCn.Tr.Trace TError, TypeName(Me), " Capturador_EventRaise", , Error$
Resume Salir_
Resume
End Function
Private Function Capturador_GetContainer() As Object
Set Capturador_GetContainer = ContainerSubObject.GetContainer
End Function
Public Function CargaObjAdicionales(Cual As Integer, Optional Otros As Object) As Boolean
CargaObjAdicionales = pItem.CargaObjAdicionales(Cual, Otros)
End Function
Private Sub Class_Initialize()
Set pItem = gCn.Obj.DameItem(TypeName(Me))
pItem.Modificado = False
ValoresPredeterminados
Set ContainerSubObject = gCn.GetContainerSubObject(pItem)
End Sub
Private Sub Class_Terminate()
Set ContainerSubObject = Nothing
Set pItem = Nothing
End Sub
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 116
Public Property Get ClassDebugID() As Long
ClassDebugID = pItem.ClassDebugID
End Property
Public Property Get Clave() As Variant
Clave = pItem.Clave
End Property
Public Property Get Claves() As Collection
Set Claves = pItem.Claves
End Property
Private Sub ContainerSubObject_DamePadre(ContainerObject As Object)
Set ContainerObject = Me
End Sub
Public Sub Data(Padre As Capturador, Vpropiedades As Collection, Optional Nuevo As Variant)
pItem.Data Padre, Vpropiedades, Nuevo
End Sub
Public Function Delete() As Boolean
Delete = pItem.Delete
End Function
Public Property Get Descripcion() As String
Descripcion = gCn.Obj.GeneraDescripcion(Me)
End Property
Public Property Let Disponible(Valor As Boolean)
pItem.Disponible = Valor
End Property
Public Property Get Disponible() As Boolean
Disponible = pItem.Disponible
End Property
Public Property Get Entorno() As ObEntorno
Set Entorno = pItem.Entorno
End Property
Public Property Get EsColeccion() As Boolean
EsColeccion = pItem.EsColeccion
End Property
Public Function Estado() As Integer
Estado = 1
End Function
Private Function IItem_Add() As AhoraSistema.IItem
Set IItem_Add = Add()
End Function
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 117
Private Sub IItem_AsignaClaves(lacoleccion As Collection)
AsignaClaves lacoleccion
End Sub
Private Property Get IItem_Campos(Cual As String) As AhoraSistema.CampoClave
Set IItem_Campos = Campos(Cual)
End Property
Private Function IItem_CargaObjAdicionales(Cual As Integer, Optional Otros As Object) As
Boolean
IItem_CargaObjAdicionales = CargaObjAdicionales(Cual, Otros)
End Function
Private Property Get IItem_ClassDebugID() As Long
IItem_ClassDebugID = ClassDebugID
End Property
Private Property Get IItem_Clave() As String
IItem_Clave = Clave
End Property
Private Property Get IItem_Claves() As Collection
Set IItem_Claves = Claves
End Property
Private Sub IItem_Data(Padre As AhoraSistema.Capturador, Vpropiedades As Collection,
Optional Nuevo As Variant)
Data Padre, Vpropiedades, Nuevo
End Sub
Private Function IItem_Delete(Optional aVerbose As Boolean = True) As Boolean
IItem_Delete = Delete()
End Function
Private Property Get IItem_Descripcion() As String
IItem_Descripcion = Descripcion
End Property
Private Property Let IItem_Disponible(RHS As Boolean)
Disponible = RHS
End Property
Private Property Get IItem_Disponible() As Boolean
IItem_Disponible = Disponible
End Property
Private Property Get IItem_Entorno() As AhoraSistema.ObEntorno
Set IItem_Entorno = Entorno
End Property
Private Property Get IItem_EsColeccion() As Boolean
IItem_EsColeccion = EsColeccion
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 118
End Property
Private Function IItem_Estado() As Integer
IItem_Estado = Estado
End Function
Private Property Get IItem_Eventos() As AhoraSistema.IItem_Events
Set IItem_Eventos = pItem.Eventos
End Property
Private Property Get IItem_Form() As Object
‘‘Set IItem_Form = Pantalla
Set IItem_Form = pItem.Form
End Property
Private Sub IItem_Imprimir()
Imprimir
End Sub
Private Sub IItem_Menu()
Menu
End Sub
Private Property Let IItem_Modificado(RHS As Boolean)
Modificado = RHS
End Property
Private Property Get IItem_Modificado() As Boolean
IItem_Modificado = Modificado
End Property
Private Property Let IItem_Nuevo(RHS As Boolean)
Nuevo = RHS
End Property
Private Property Get IItem_Nuevo() As Boolean
IItem_Nuevo = Nuevo
End Property
Private Property Get IItem_Objeto() As Object
Set IItem_Objeto = Me
End Property
Private Property Get IItem_Objetos() As Collection
Set IItem_Objetos = Objetos
End Property
Private Property Let IItem_ObjetosDisp(RHS As Boolean)
pItem.ObjetosDisp = RHS
End Property
Private Property Get IItem_ObjetosDisp() As Boolean
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 119
IItem_ObjetosDisp = pItem.ObjetosDisp
End Property
Private Property Get IItem_OtrasPropiedades() As Collection
Set IItem_OtrasPropiedades = pItem.OtrasPropiedades
End Property
Private Property Let IItem_Padre(RHS As Object)
Padre = RHS
End Property
Private Property Get IItem_Padre() As Object
Set IItem_Padre = Padre
End Property
Private Property Let IItem_Propiedades(Cual As String, RHS As Variant)
Propiedades(Cual) = RHS
End Property
Private Property Get IItem_Propiedades(Cual As String) As Variant
IItem_Propiedades = Propiedades(Cual)
End Property
Private Sub IItem_Refresh(Optional pantallaIgnorarErr As Boolean = True)
Refresh pantallaIgnorarErr
End Sub
Private Sub IItem_Show(Optional Propietario As Object, Optional ventanaNueva As Boolean =
False, Optional aModal As Boolean = False)
Show Propietario, ventanaNueva, aModal
End Sub
Private Property Get IItem_SQL() As String
IItem_SQL = sql
End Property
Private Property Get IItem_Tabla() As String
IItem_Tabla = Tabla
End Property
Private Property Get IItem_TablaOtra() As String
IItem_TablaOtra = pItem.TablaOtra
End Property
Private Property Let IItem_Tipo(RHS As String)
pItem.Tipo = RHS
End Property
Private Property Get IItem_Tipo() As String
IItem_Tipo = Tipo
End Property
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 120
Private Property Let IItem_UltimoNivel(RHS As Boolean)
pItem.UltimoNivel = RHS
End Property
Private Property Get IItem_UltimoNivel() As Boolean
IItem_UltimoNivel = UltimoNivel
End Property
Private Function IItem_Update(Optional PantallaError As Boolean = False, Optional refrescar As
Boolean = True) As Boolean
IItem_Update = Update(PantallaError, refrescar)
End Function
Public Sub Imprimir()
pItem.Entorno.Imprimir Me
End Sub
Property Get Item() As AhoraSistema.IItem
Set Item = Me
End Property
Public Sub Menu()
pItem.Entorno.VerMenu Me, "mnuObjeto"
End Sub
Public Property Get Modificado() As Boolean
Modificado = pItem.Modificado
End Property
Public Property Let Modificado(Estado As Boolean)
pItem.Modificado = Estado
End Property
Public Property Get Nuevo() As Boolean
Nuevo = pItem.Nuevo
End Property
Public Property Let Nuevo(Estado As Boolean)
pItem.Nuevo = Estado
End Property
Public Property Get Objetos() As Object
Set Objetos = pItem.Objetos
End Property
Public Function OtrasPropiedades() As Collection
Set OtrasPropiedades = pItem.OtrasPropiedades
End Function
Public Property Let Padre(miPadre As Object)
pItem.Padre = miPadre
End Property
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 121
Public Property Get Padre() As Object
Set Padre = pItem.Padre
End Property
Public Property Get Propiedades(Cual As String) As Variant
Propiedades = pItem.Propiedades(Cual)
End Property
Public Property Let Propiedades(Cual As String, Valor As Variant)
pItem.Propiedades(Cual) = Valor
End Property
Public Sub Refresh(Optional pantallaIgnorarErr As Boolean = True)
pItem.Refresh pantallaIgnorarErr
End Sub
Public Sub Show(Optional Propietario As Object, Optional ventanaNueva As Boolean = False,
Optional aModal As Boolean = False)
‘Dim lFrm As Form
‘Set lFrm = Propietario
pItem.Show Propietario, ventanaNueva, aModal
End Sub
Public Property Get sql() As String
sql = pItem.sql
End Property
Public Property Get Tabla() As String
Tabla = pItem.Tabla
End Property
Property Get Tipo() As String
Tipo = TypeName(Me)
End Property
Public Property Get UltimoNivel() As Boolean
UltimoNivel = pItem.UltimoNivel
End Property
Public Function Update(Optional PantallaError As Boolean = False, Optional refrescar As Boolean
= True) As Boolean
Update = pItem.Update(PantallaError, refrescar)
End Function
Private Sub ValoresPredeterminados()
‘ Poner valores por defecto aquí
End Sub
El objeto creado diremos que hereda de IItem. Los métodos definidos para el objeto
son los estándar, si desea que alguna función o método del objeto se comporte de
manera distinta, sólo tiene que modificarlo. Por ejemplo, si desea que cuando se cree
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 122
un objeto, se carguen valores predeterminados, sólo debe programar el método
ValoresPredeterminados(). Si queremos que el objeto cree automáticamente un ID,
modificaremos la función Update asignando un valor a la propiedad antes de
guardarse.
Método ValoresPredeterminados().
Queremos que cuando se cree un objeto nuevo, se cargue la fecha del día por defecto.
Procedemos a modificar el método ObjPrueba.cls.
Private Sub ValoresPredeterminados()
‘ Poner valores por defecto aquí
Me.Propiedades (“Fecha”) = Date
End Sub
Así como personalizamos este método, podemos hacer lo mismo con otros, y definir
nuevas funciones para nuestro objeto.
Crear formulario del objeto
Controles
1 - Cree un nuevo formulario frmObjPrueba (frmObjPrueba.frm).
Inserte los siguientes controles:
cntMenuFormulario (mnuMain).
EnlaceObjeto (EObjeto).
cntPanel (FraDatos)
Dentro de FraDatos insertar:
o TextoUsuario (Numero)
o TextoMultulinea (Descrip)
cntTab (TabDatos).
CntGridUsuario (grdLineas)
SSPanel (panDatos)
Dentro de panDatos insertar:
o TextoUsuario (Fecha)
o ComboUsuario (IdCliente)
SSPanel (panConfig) modificando la propiedad Autosize = 3-ChildToPanel
Dentro de panConfig insertar:
o cntPropiedades (cntPropConfig)
cntBotonera (Botonera)
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 123
2 - Vincular controles al enlace objeto y asigne las siguientes propiedades:
Propiedades del control EObjeto:
ResizeH=0
ResizeV=1
ResizeEnabled = TRUE
Propiedades del control fraDatos:
ResizeH=1
ResizeV=2
ResizeEnabled = TRUE
Propiedades del control TabDatos:
ResizeH=2
ResizeV=2
ResizeEnabled = TRUE
ResizeRestanteH = TRUE
ResizeRestanteV= FALSE
Propiedades del control Número:
Clic derecho en el control Número para acceder a las
propiedades del control.
Complete los datos como muestra la imagen:
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 124
CaptionControl = Número
CaptionVisible = TRUE
CaptionWidth = 1000
Propiedades del control Descrip:
Clic derecho en el control Descrip para acceder a las
propiedades del control.
Complete los datos como muestra la imagen
CaptionControl = Descripción.
CaptionVisible = TRUE
CaptionWidth = 3400
CaptionPosition = 1 – eCaptionPositionTop
Propiedades del control Fecha:
Clic derecho en el control Fecha para acceder a las
propiedades del control.
Complete los datos como muestra la imagen:
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 125
CaptionControl = Fecha.
CaptionVisible = TRUE
CaptionWidth = 1000
Propiedades del control IdCliente:
Clic derecho en el control IdCliente para acceder a las
propiedades del control.
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 126
Complete los datos como muestran las imágenes:
CaptionControl = IdCliente.
CaptionVisible = TRUE
CaptionWidth = 1000
Propiedades del control Botonera:
ResizeH=0
ResizeV=10
ResizeEnabled = TRUE
Código del formulario.
Option Explicit
Option Compare Text
Private Const cModuleName = "frmObjPrueba"
'Numerar los tabs
Private Enum TabEnum
eTabDatos = 0
eTabConfigurables
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 127
End Enum
Public Function Carga(elObjeto As IItem, Optional aPropietario As Object) As Boolean
On Error GoTo Error_
'Función Carga
Hourglass True
Load Me
With EObjeto
If Not .ObjGlobal Is Nothing Then
If .Modificado Then
If Not .Actualiza Then
Carga = False
GoTo End_
End If
End If
End If
If Not elObjeto Is Nothing Then
If .Carga(elObjeto) Then
Call CargaGrdLineas
Call CargaOtrasPropiedades(elObjeto)
End If
End If
End With
If aPropietario Is Nothing Then
Set aPropietario = gCn.Sesion.MainForm
End If
gCn.Obj.FormShow Me, aPropietario
Carga = True
End_:
Hourglass False
Exit Function
Error_:
gCn.Tr.Trace TError, cModuleName, " Carga", , Err.Description
Carga = False
Resume End_
End Function
Private Sub CargaGrdLineas()
On Error GoTo Error_
With grdLineas
If Not .Preparada Then
.Agregar = True
.Editar = True
.Eliminar = True
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 128
.CargaObjetos = False
.EditarPorObjeto = True
.EditarPorObjetoyVista = True
.Configurable = True
Set .Coleccion = EObjeto.ObjGlobal.Objetos("ObjPrueba_Lineas")
.From = "VObjsPrueba_Lineas"
.AgregaColumna "Numero", 0, "Numero"
.AgregaColumna "IdArticulo", 2000, "Id Artículo", , "SELECT IdArticulo
Id_Articulo,IdArticulo,Descrip from Varticulos_maquinas"
.AgregaColumna "Descrip", 5000, "Descrip"
.AgregaColumna "Cantidad", 1000, "Cantidad"
.Orden = "IdDoc"
End If
.Where = "WHERE Numero=" & SqlNumero(EObjeto.ObjGlobal.Propiedades("Numero"))
.RefrescaSinLoad = True
.refrescar
.Enabled = Not EObjeto.ObjGlobal.Nuevo
End With
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " CargaGrdLineas", , Err.Description
Resume End_
Resume
End Sub
Private Sub Botonera_ToolClicked(aTool As AhoraOCX.AhoraTool)
On Error GoTo Error_
Select Case aTool.Name
Case cBotMant_Guardar
Call Guardar
Case cBotMant_Eliminar
Call Eliminar
Case cBotMant_Imprimir
Call Imprimir
Case cBotMant_Nuevo
Call Nuevo
Case cBotMant_Cerrar
Call Cerrar
End Select
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " Botonera_ToolClicked", , Err.Description
Resume End_
End Sub
Private Sub Form_Load()
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 129
On Error GoTo Error_
Botonera.SeguridadObjeto = eMenuAñadir + eMenuGuardar + eMenuBorrar
Botonera.BotonesMantenimiento = eBotMant_Cerrar
Botonera.HabilitaBotones
TabDatos.InsertItem 0, "Datos", panDatos.Hwnd, 1
TabDatos.InsertItem 1, "Configurables", panConfig.Hwnd, 1
mnuMain.MenuItemAdd "&Archivo", "mnuArchivo", "", eTipo_Menu_Menu
mnuMain.MenuItemAdd "&Hola", "mnuHola", "mnuArchivo", eTipo_Menu_Boton, , , eicoahora
mnuMain.MenuItemAdd "&Cerrar", "mnuCerrar", "mnuArchivo", eTipo_Menu_Boton, True
mnuMain.Ready = True
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " Form_Load", , Err.Description
Resume End_
End Sub
Private Sub Form_Resize()
On Error Resume Next
Form_AutoResize Me
End Sub
Private Sub Guardar()
On Error GoTo Error_
Hourglass True
With EObjeto
If .Actualiza(False) Then
Call CargaGrdLineas
Call CargaOtrasPropiedades(Me.EObjeto.ObjGlobal)
Else
Hourglass False
Exit Sub
End If
End With
EObjeto.Refresh
End_:
Hourglass False
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " BotGuardar_Click", , Err.Description
Resume End_
End Sub
Private Sub Cerrar()
Unload Me
End Sub
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 130
Private Sub Eliminar()
Dim lObj As IItem
On Error GoTo Error_
Hourglass True
If EObjeto.Remove Then
Set lObj = EObjeto.ObjGlobal
lObj.Show
End If
Hourglass False
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " Eliminar", , Err.Description
Resume End_
End Sub
Private Sub Imprimir()
On Error Resume Next
Hourglass True
EObjeto.ObjGlobal.Imprimir
Hourglass False
End Sub
Private Sub Nuevo()
Dim lItem As IItem
On Error GoTo Error_
With EObjeto
If .Modificado Then
If Not .Actualiza Then
Exit Sub
End If
End If
Hourglass True
'crea un nuevo objeto
Set lItem = .ObjGlobal.Add
End With
lItem.Show
End_:
Hourglass False
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " BotNuevo_Click", , Err.Description
Resume End_
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 131
End Sub
Private Sub CargaOtrasPropiedades(aObjeto As IItem)
'Cargar el grid de propiedades del objeto
On Error GoTo Error_
If aObjeto.Nuevo Then
'Tiene que existir el objeto en tabla para poder modificar sus propiedades
TabDatos.Item(eTabConfigurables).Enabled = False
cntPropConfig.Carga aObjeto
Else
TabDatos.Item(eTabConfigurables).Enabled = True
cntPropConfig.Carga aObjeto
End If
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " CargaOtrosPropiedades", , Err.Description
Resume End_
End Sub
Private Sub Form_Unload(Cancel As Integer)
'Si cierra el formulario controlar si se ha modificado el objeto.
Dim lMsg As String
On Error GoTo Error_
With EObjeto
If .Modificado Then
lMsg = "Los datos de la cabecera del contrato han sido modificados. ¿Desea guardar los
cambios?"
If MsgBox(lMsg, vbYesNo + vbQuestion + vbDefaultButton1, "Contratos...") = vbYes Then
If Not .Actualiza(True) Then
Cancel = True
Exit Sub
End If
End If
End If
End With
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " Form_Unload", , Err.Description
Resume End_
End Sub
Private Sub mnuMain_ToolClick(aTool As AhoraOCX.AhoraTool)
On Error GoTo Error_
Select Case aTool.Name
Case "mnuHola"
MsgBox "Hola", vbExclamation
Case "mnuCerrar"
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 132
Call Cerrar
End Select
End_:
Exit Sub
Error_:
gCn.Tr.Trace TError, cModuleName, " mnuMain_ToolClick", , Err.Description
Resume End_
End Sub
Crear ObjForms.cls
Para que el sistema gestione correctamente los formularios de los objetos, debe crear
la clase ObjForms (ObjForms.cls) y un proceso de llamada al formulario.
Al definir el objeto pondremos como Formulario Asociado el IdAhoraProcceso (en este
caso es ObjFormObjPrueba).
En la clase ObjForms definimos el proceso que llama al formulario correspondiente.
El sistema llamará al ahora proceso y devolverá el formulario.
Proceso:
-- AhoraProceso para poder obtener el formulario del objeto ObjPrueba
DELETE FROM [Ahora_Procesos] where [IdAhoraProceso]='ObjFormObjPrueba'
GO
INSERT INTO
[Ahora_Procesos]([IdAhoraProceso],[Descrip],[IdTipo],[Libreria],[Clase],[Metodo],[IdLlamada],[Ret
ornoTipo],[RetornoObjeto],
[CheckParam],[Observaciones],[Macro],[Net])
VALUES('ObjFormObjPrueba','ObjFormObjPrueba',4,'PlantillaExterno','ObjForms','DameFrmObjPr
ueba',1,'Object',1,
0,NULL,0,0)
GO
Código Objforms.Cls
Option Explicit
Option Compare Text
Private Const cModuleName = "ObjForms"
Public Function DameFrmObjPrueba(Optional aNuevo As Boolean) As Object
Set DameFrmObjPrueba = DameObjForm("frmObjPrueba", aNuevo)
End Function
Private Function DameObjForm(aFormName As String, Optional aNuevo As Boolean) As Object
Dim lNuevo As Boolean
On Error Resume Next
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 133
If Not aNuevo Then
If IsLoaded(aFormName) Then Set DameObjForm = SelectForm(aFormName)
End If
If DameObjForm Is Nothing Then
Select Case UCase(aFormName)
Case UCase("frmObjPrueba")
Set DameObjForm = New frmObjPrueba
Case Else
End Select
End If
End Function
Private Function IsLoaded(ByVal frmName As String) As Boolean
Dim Form As Form
On Error GoTo Error_
IsLoaded = False
For Each Form In Forms
If Form.Name = frmName Then
IsLoaded = True
Exit Function
End If
Next
End_:
Exit Function
Error_:
gCn.Tr.Trace TError, cModuleName, " IsLoaded", , Err.Description
Resume End_
End Function
Private Function SelectForm(frmName As String, Optional GetFirst As Boolean = False) As Form
Dim lForm As Form
On Error GoTo Error_
For Each lForm In Forms
If lForm.Name = frmName Then
If lForm.Visible Then
Set SelectForm = lForm
If GetFirst Then Exit Function
Else
Set SelectForm = lForm
SelectForm.Show
If GetFirst Then Exit Function
End If
End If
Next
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 134
End_:
Exit Function
Error_:
gCn.Tr.Trace TError, cModuleName, " SelectForm", , Err.Description
Resume End_
End Function
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 135
CONFECCIÓN DE FORMULARIOS
El objetivo de este apartado es definir cómo se deben diseñar los distintos formularios
para que todos tengan el mismo estilo. Se va a definir como debe ser el aspecto y las
funcionalidades comunes a todos ellos.
Formularios
Dimensión y ubicación de controles:
Todos los formularios que se realicen deben ser redimensionables.
Criterios de dimensión y ubicación:
cResTituloBottom
cResTituloTop
cResGeneralSepH
cResGeneralSepV
cResBotoneraTop
cResBotoneraBottom
cResBotoneraLats *
cResGeneralLats *
cResTituloLats *
De acuerdo con la imagen, se han definido una serie de constantes públicas que
estandarizan la ubicación y distancia de los controles entre sí dentro de un formulario,
son:
cResTituloTop: 15
cResTituloLats *: 0
cResTituloBottom: 15
cResGeneralSepV: 30
cResGeneralSepH: 15
cResGeneralSepLats *: 30
cResBotoneraTop: 15
cResBotoneraLats *: 0
cResBotoneraBottom: 0
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 136
Salvo excepción, todos los formularios deben tener un Titulo (EObjeto) y una Botonera
(cntBotonera).
* Se aplica tanto por la izquierda como por la derecha.
Redimensión automática:
Se ha diseñado un “sistema de redimensión automática” para formularios y controles
que progresivamente si irá ampliando hasta lograr un sistema 99% automatizado.
Características:
1) Se utiliza:
Private Sub Form_Resize()
On Error Resume Next
Form_AutoResize Me
End Sub
2) Los controles preparados para ello son:
barMenus (No tiene propiedades para ello pero se gestiona)
EnlaceObjetos
cntPanel
cntGridUsuario
cntTab
cntFiltroUsuario
cntStatusBar
cntBotonera
3) Las propiedades de los controles para aplicarla:
ResizeEnabled: (True/False) Indica si el control efectuará autodimensión.
ResizeV: (0...n) Indica el orden vertical de colocación de arriba a abajo.
ResizeH: (0...n) Para una misma ubicación vertical, indica el orden horizontal de
colocación de izquierda a derecha.
4) Una serie de controles deben tener la posibilidad de “redimensionarse al
restante”, es decir, a la dimensión del formulario o contenedor padre menos la
suma de las dimensiones de todos los demás controles. Estos son:
cntPanel
cntGridUsuario
cntTab
Y las propiedades que lo permiten son:
ResizeRestanteV: (True/False)
ResizeRestanteH: (True/False)
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 137
5) Algunos controles están preparados para ajustar los controles que puedan
contener, son:
cntPanel con la propiedad: ResizeInterior: (True/False)
Controles de formulario:
Combo o Texto
Todos los combos de usuario en todos los formularios deben tener las siguientes
funcionalidades con las teclas.
F3: Si la combo (o texto) tiene Link-> Asistente, lo lanza. La combo o texto debe
tener la propiedad CaptionLink=TRUE
May+F2 : Abre el Zoom con el contenido del campo.
F5: Refresca la combo
Doble Click :Si la combo tiene un objeto lo muestra,
Fecha:
F3: Abre el formulario Calendario y deben tener la propiedad CaptionLink =True
Siempre debe tener formato “dd/mm/yyyy” a no ser que lleve fecha y hora que
será “dd/mm/yyyy hh:mm:ss”
Hora:
El control debe aceptar 5 o 7 caracteres y se debe de comprobar que una vez
formateado corresponde con: hh:mm o hh:mm:ss.
Numérico:
Debe ir alineado a la derecha y formateado.
Grid usuario:
Combos:
1. Las columnas que tienen combos pueden tener o no búsqueda sensitiva. Es una
propiedad (grid.campo(“IdArticulo”).BuscaSense = True )
2. Si no tiene búsqueda sensitiva, al abrir la combo se cargan todos los registros.
3. Si la columna tiene la propiedad de refresco de combo en cada línea, esta
propiedad se recalcula cada vez que se abre la combo: Se calcula el número de
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 138
registros de la combo:
Existe un parámetro: MAXCOMBOITEMS. Si este parámetro está a 0, no se
tendrá en cuenta.
Si el nº de registros supera MAXCOMBOITEMS, entonces sólo se mostrarán lo
que especifique el parámetro LIMITADOSCOMBOITEMS.
4. Para configurar las combos:
Combo: Select de la combo
ComboRefresh: Booleano, indica si la combo se refresca al cambiar de
registro.
ComboInner: Tiene el formato “Vista;CampoEnlace;CampoOrden” o
“Vista;CampoEnlace”
ComboWhere: Puede llevar campos referentes al mismo registro (como
en la sustitución,ej: @IdPedido )
Ejemplo:
Combo: “SELECT IdArticulo,IdArticulo IdArt ,Descrip FROM
vCombo_Articulos
ComboRefresh: True
ComboInner: “vCombo_Materiales;IdArticulo;IdArticulo”
ComboWhere: “IdArticulo IN (SELECT IdArticulo FROM
Pedidos_cli_Lineas
WHERE Idpedido=@IdPedido )”
5. Además debemos poder acceder al objeto mediante Doble Click
AL IGUAL QUE EN LA PARTE SUPERIOR, LOS CAMPOS, DEPENDIENDO DEL TIPO DE DATOS, DEBEN
LLEVAR LAS MISMAS REGLAS DE FORMATO QUE SE ESPECIFICAN ARRIBA.
IMPORTANTE:
Las Grids que tengan combos de artículos tienen funcionalidad con las teclas:
F3: que abre el asistente normal de artículos
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 139
F2: que abre el formulario siguiente,
Hay que asegurarse que en todos los formularios en los que se pueda insertar más de
un artículo en la rejilla salga este formulario mediante la tecla F2.
May+F2: al igual que en los controles de cabecera, si pulsamos May+F2 debería
salir el formulario de Zoom con el contenido del campo en el que estamos.
Headtip:
Los campos tienen la propiedad headtip para establecer el tip que queremos que
aparezca cuando ponemos el ratón en la cabecera. Si no se establece nada saldrá el
mensaje de “Hacer clic para ordenar…”
Caption
Para manejar el caption hay tres propiedades: MuestraCaption, ConcatenaCaption y
CaptionBase
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 140
Si MuestraCaption es false no se muestra nada
Si ConcatenaCaption =True: Se pone en el caption: El CaptionBase & [Número de
registros]
Si ConcatenaCaption =False: Se pone en el caption: El CaptionBase
Si la grid es de objetos: se añade la descripción de la colección
Edición por objetos
Si se EditaPorObjetos (=True) y se activa también EditarPorObjetoyVista a True,
entonces la lectura de los campos se hará de la vista que pone en el campo EdicionGrid
de la tabla Objetos en el registro de la colección. Si no se ha configurado esta vista se
leerá (From) de la tabla o vista que especifique el código.
Procesos asociados a los menús
El tool que devuelve el menú, tiene un IdAhoraProceso. Si se especifica, al pulsar el
menú de la grid se lanza el proceso con un primer parámetro la grid, y de segundo una
colección de parámetros que lleva como último parámetro el iddoc de la línea y si no
hay 0.
Si se quieren rellenar más parámetros tendrá que ser en el gridmousedown y establecer
una collection con los parámetros que se quieran en lToolMenu.ColParametrosProceso.
CntReport:
Si queremos pintar con colores las líneas del cntReport en la vista de la colección tiene
que haber un campo llamado exactamente ColorObj que contendrá el código del color
de esa línea.
Botonera:
Formularios de objetos:
Todos los formularios de objetos deben tener necesariamente:
Guardar: guarda si se ha modificado
Nuevo : deja preparado el formulario para una nueva entrada
Eliminar: Elimina el objeto cargado
Imprimir: Para imprimir los listados asociados a la colección
Asociados: sólo sale si el objeto tiene objetos asociados (objetos_objetos)
Notas: Sólo sale si el objeto tiene una tabla de notas
Cerrar: Cierra el formulario
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 141
Ejemplo de formulario de objeto:
Formularios de mantenimientos sencillos:
Éstos suelen tener únicamente el botón cerrar:
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 142
Formularios con marcados de registros:
Los formularios en los que aparecen una o más grids para seleccionar registros
deberían llevar:
Marcar Todos
Desmarcar Todos
Marcar Grid Activa (sólo si hay más de una grid)
Desmarcar Grid Activa (solo si hay más de una grid)
Cerrar
Ejemplo:
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 143
En este caso está en el menú, pero debería estar en la botonera.
Menús:
Teclas aceleradoras en menús de formulario.
En la tabla Ahora_Menus y en la tabla Ceesi_Menus (para procesos de objeto) se ha
incluido un nuevo campo: IdTecla
Hace referencia a la tabla Ahora_Menus_Teclas que tiene la siguiente estructura:
IdTecla Clave
Ctrl Booleano que indica si hay que pulsar Ctrl
Shift Booleano que indica si hay que pulsar Shift
Alt Booleano que indica si hay que pulsar Alt
Funcion Booleano que indica si es una tecla de función
Valor Si es función el número : 1,8,12..
Si no un carácter : T
Ejemplos:
IdTecla Ctrl Shift Alt Funcion Valor
F10: 1 False False False True 10
CTRL+A 2 True False False False A
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 144
Restricción AHORA_MENUS
La tabla Ahora_Menus tiene el campo “Estandar” de tipo bit, que estará activo para
todos los menús base de la aplicación.
Los menús con este campo activo no podrán borrarse ni editar sus campos librería,
formulario, nombre, estandar y el campo tipo si esta en “tipo=2”. (Implementado en
Triggers)
Estos cambios son realizados para evitar que, por error o desconocimiento, se
modifiquen datos de esta tabla pudiendo causar errores en la aplicación por uso de
dichos menús en el código.
Seguridad
La seguridad de los menús de los formularios (Ahora_Menus) controla la visibilidad o
no del menú, pero siempre se carga en el formulario. Por tanto, si el código lo hace
visible se verá, diga lo que diga la seguridad. Por eso es conveniente en código
habilitarlos/deshabilitarlos...
Hay dos formas para ocultar/mostrar un menú desde su configuración (ADMON)
1. En el campo Seguridad se guarda el nombre de un objeto o colección. Si este
objeto o colección no tienen permisos de Show para el usuario entonces el
menú no se visualiza.
2. Seguridad por grupos (Como los listados).
Inicialmente todos los menús tienen como grupo de seguridad el grupo
‘GRUPOAHORA’. De hecho el trigger de Insert de Ahora_Menus inserta este
grupo en Ahora_Seguridad_Entidades_Asignación.
Desde el admon., podemos modificar los grupos asociados al menú. Si
pertenece a algún grupo la sesión del usuario podrá ver el menú.
Añadir objetos nuevos dinámicamente a al colección de objetos
Se ha añadido una funcionalidad en AhoraSistema.Objeto. Esta función se llama
AñadirObjeto.
Public Function AñadirObjeto(aNombreObjeto As String, Optional aEsColeccion As
Boolean = False, Optional aTabla As String = "", Optional aHijoDefecto As String = "")
As Objeto
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 145
Uso
Supongamos que queremos tratar una tabla/vista como si fuera un Objeto pero no
tenemos creados todos los registros necesarios en la BD, ni los queremos tener.
Los motivos podrían ser que se quiere guardar a través de stores para tener mayor
control sobre él, o que le quieren añadir permisos, o que, simplemente, se busca poder
manejarlo como si fuera un objeto (para evitar escribir én código instrucciones de
INSERT, UPDATE o DELETE). Los objetos se actualizan y borran a través de sus stores si
las encuentran o, en caso contrario, saben actualizar/borrar su tabla.
Como parámetros, se han añadido los básicos, pero, como la función devuelve el
Objeto, podemos seguir configurándolo, ya que las propiedades del Objeto son los
campos de la tabla Objetos.
Funcionalidad
Vamos a ver un ejemplo con la tabla CEESI_Procesos_Arbol.
En la BD existen las stores pCEESI_Procesos_Arbol_I, pCEESI_Procesos_Arbol_U y
pCEESI_Procesos_Arbol_D pero no existe ningún registro en la tabla Objetos que
maneje esta tabla.
Para poder utilizar CEESI_Procesos_Arbol como si fuera un objeto se usaría la
instrucción:
gCn.Obj.AñadirObjeto "CEESI_Procesos_Arbol"
Como la tabla se llama igual, no hay que establecer más parámetros. Con esta
intrucción podríamos ejecutar código como el siguiente:
Dim lItem As IItem
Set lItem = gCn.Obj.DameObjStr("CEESI_Procesos_Arbol")
lItem.Propiedades("IdArbolPadre") = aNodePadre
lItem.Propiedades("DescripcionArbol") = aTitulo
lItem.Update
Para recuperar objetos, debemos añadir la colección a Objetos con:
gCn.Obj.AñadirObjeto "CEESI_Procesos_Arboles", True, "CEESI_Procesos_Arbol",
"CEESI_Procesos_Arbol"
Así podemos recuperar objetos de la manera habitual:
Dim lItem As IItem
Set lItem = gCn.Obj.DameObjeto("CEESI_Procesos_Arboles", "Where IdArbol=1")
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 146
Funcionamiento CadenaDescrip
En la Tabla Objetos, en el campo CadenaDescrip podemos especificar un patrón para la
descripción del objeto.
Cuando se establece en una colección: Los campos entre [] o entre {} deben ser
campos de la vista de la colección.
Cuando se establece en un objeto: Los campos entre [] o entre {} deben ser campos del
objeto o si empieza por SELECT, puede ser una consulta basada, o no, en propiedades
del objeto. La utilización de corchetes o llaves es indiferente salvo en el caso en el que
se aniden que deben ser diferentes.
Ejemplo:
Colección Facturas
(Sql: SELECT * FROM vFacturas_Cli_Cab)
CadenaDescrip = Factura [NumFactura] del cliente [Cliente]
Objeto Factura:
(Sql:SELECT * From Facturas_cli_Cab)
CadenaDescrip=Factura [NumFactura] del cliente {Select Cliente FROM Clientes_Datos WHERE
Idcliente=[IdCliente]}
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 147
F.A.Q.
A continuación, se detallan varios mensajes, tanto de error como de advertencia, que
pueden aparecer durante el desarrollo, así como una propuesta para solucionarlo.
Error del control Active x: No se puede cargar ‘C:\Plantilla\Externo\AhoraOCX.Ocx’--
¿Desea continuar cargando el proyecto?
Error del control Active X:
Para solucionar este error, seleccione Sí, y, una vez cargado el proyecto, realice los
siguientes pasos
1. Proyecto Componentes
2.
3. En la siguiente ventana, seleccione, en la lista de controles, la versión para la que va
a desarrollar. Si su versión no estuviera en esta lista, haga clic en Examinar y busque
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 148
el archivo AhoraOCX.Ocx en la carpeta Lib de su aplicación Ahora ERP.
4. Haga clic en Aceptar y, para comprobar que los cambios funcionan, guarde su
proyecto, ciérrelo y vuélvalo a abrir.
Error de compilación: No se puede encontrar el proyecto o la biblioteca
Error al compilar
Para solucionar este error, pulse en Aceptar y realice los siguientes pasos:
1. Se abrirá automáticamente la siguiente ventana(si desea volver a abrirla
manualmente, haga click en Proyecto referencias):
MANUAL DE PROGRAMACIÓN | PLATAFORMA ENTERPRISE PÁGINA | 149
2. Fíjese que en la lista de referencias disponibles hay algunas marcadas con ‘FALTA’.
Esto nos indica que dichas referencias no están correctamente vinculadas. Esto es
debido a que no está utilizando la misma versión de MSI y de plantilla. Asegúrese
de usar la misma versión.