Vous êtes sur la page 1sur 18

Programacin Orientada a Objetos en Visual Basic

Resumen La programacin en Visual Basic se puede realizar de diversas formas o estilos. Este lenguaje nace como un ambiente de prototipacin rpida (RAD) para aplicaciones bajo el sistema operativo Microsoft Windows. La orientacin a objetos se incorpora como un elemento posterior al nacimiento del lenguaje y actualmente (versin 5) no est totalmente soportada. A pesar de lo anterior, Visual Basic permite la aplicacin de los conceptos de orientacin a objetos, aunque esto no corresponda a un mapeo directo. Ac se presenta una tcnica que permite programar en forma estndar, basndose un modelo de clases UML. Por otra parte los conceptos que se plantean son fcilmente aplicables a otros lenguajes de programacin visuales. Adems de cumplir con el paradigma de la orientacin a objetos, se presentan ac formas de programacin que cumplen con una arquitectura de tres capas. De esta forma, la lgica, en trminos de reglas del negocio, se aisla de los elementos de interfaz y de la forma de almacenamiento de los objetos. Bajo este tipo de arquitectura, es posible separar fsicamente estos componentes del negocio, pudindose centralizar en servidores especializados, a travs del uso de monitores transaccionales como Microsoft MTS. Arquitectura de 3 capas. El objetivo principal de este planteamiento es separar y, por lo tanto independizar, las reglas del negocio de las aplicaciones que las utilicen. De esta forma, es posible utilizar las mismas reglas del negocio para diferentes aplicaciones, corriendo sobre distintas plataformas. La capa de aplicacin corresponde a programas interactivos o procesos, que realicen alguna accin sobre los componentes del negocio. La capa Capa de intermedia estar formada por las clases del negocio, quienes interactan con Aplicacin el medio de almacenamiento que est repreentado en la capa de datos. Una arquitectura pura de tres capas no permite ninguna forma de comunicacin directa entre la aplicacin y la capa de datos; esto es, entre los Capa del programas de usuario y la base de datos. Los programas de aplicacin deben Negocio solicitar todos sus requerimientos a la capa del negocio, a travs de la invocacin de servicios, que corresponden a los mtodos definidos para cada clase. La separacin propuesta por este modelo de capas nos da una clara gua de la Capa de Datos forma en que podemos enfrentar la programacin de un sistema en Visual Basic. Algunos elementos del lenguaje Uso de propiedades en Visual Basic. Una propiedad se define en algunos lenguajes visuales como un atributo definido en una clase, para el cual existen funciones de entrada y salida. Esto nos permite presentar como servicios, atributos que se puedan derivar de frmulas o acceso a base de datos. Supongamos el siguiente ejemplo para una clase artculo:
Public Nombre As String Public Valor As Double Public Property Get ValorConIva as Double ValorConIva = Valor * 1.18

End Property

Para un objeto de la clase artculo, se podr consultar directamente Articulo.ValorConIva. Adems del Property Get, se cuenta con un Property Let que permite asignar valores a variables y un Property Set para asignar referencias a objetos. Objetos y referencias a objetos. Visual Basic permite la definicin de mdulos de clases. En cada uno de ellos se escribe la definicin de las variables y mtodos pblicos y privados de cada una de las clases. Esta definicin de clases acta luego como un nuevo tipo de dato para el que se pueden definir variables. Por ejemplo, si ya tenemos creada una clase Artculo, podemos definir una variable de ese tipo.
Dim Articulo As Articulo

Con esta definicin solo creamos una referencia a un Artculo, an no se ha creado realmente un objeto en memoria. El nombre de la variable puede (en Visual Basic) ser el mismo que el de la clase. Para crear un nuevo objeto y referenciarlo desde la variable Artculo, se utiliza la sentencia New, de la forma.
Set Articulo = New Articulo

Esto se podra haber hecho directamente en la declaracin:


Dim Articulo As New Articulo

La palabra reservada Set se utiliza para realizar asignaciones de referencias a objetos. Los objetos que se crean se mantienen en memoria hasta que se elimina la ltima referencia hacia ellos. La eliminacin de las referencias se hace asignndoles la constante Nothing.
Set Articulo = Nothing

Cuando un objeto es retornado por algn servicio no es necesario crearlo antes de llamarlo. El cdigo dentro del mtodo debe crearlo antes de retornarlo.
Dim Movimiento As Movimiento, Bodega As New Bodega Set Movimiento = Bodega.BuscaPrimerMovimiento(Now, Now-6) Set Movimiento = Nothing

Public Function Bodega.BuscaPrimerMovimiento(FechaInicio As Date, FechaTermino As Date) As Movimiento Dim Mov As New Movimiento ... Conectar a B.D. y buscar el 1 movimiento Set BuscaPrimerMovimiento = Mov Retornar Mov Set Mov = Nothing End Function

Al asignarle Nothing a Mov, el objeto no se destruye ya que queda una referencia activa hacia l (BuscaPrimerMovimiento). Uso de colecciones Una coleccin es un tipo de objeto definido en el lenguaje. Este objeto es capaz de contener otras variables tipo Variant, las que a su vez pueden ser otros objetos. Los servicios que contiene una coleccin son Add, Remove y Count. Adems es posible buscar elementos dentro de una coleccin a travs de una clave que se debe dar en el momento en que stos se agregan (como parmetro en el mtodo Add). Otro servicio especial de las colecciones es un iterador el que permite recorrer sus objetos mediante sentencias for each. Por ejemplo:
Dim A1 As New Articulo, A2 As New Articulo, A3 As New Articulo .. Inicializacin de A1,A2 y A3. Dim Col As New Collection

Dim A As Articulo Col.Add A1 Col.Add A2 Col.Add A3 Set A1 = Nothing Set A2 = Nothing Set A3 = Nothing For Each A In Col Suma = Suma + A.Valor Next Set Col = Nothing

La variable A no se inicializa (New), ya que se le asignan referencias a objetos que ya existen en la coleccin. Por otra parte, las variables A1, A2 y A3 se pueden asignar a Nothing sin que se destruyan los objetos, porque estos ya estn creados dentro de la coleccin y sern destruidos slo cuando sta se destruya (Set Col = Nothing). Conexin desde Visual Basic a la Base de Datos. Existen varias formas de conectar una aplicacin Visual Basic a un servidor de base de datos. Ac se presenta la bilioteca Remote Data Objects 2.0 (rdo). Para que un proyecto en Visual Basic pueda utilizar los objetos de rdo, es necesario referenciar a esta biblioteca. Esto se hace agregando una referencia desde la opcin Proyecto|Referencias hacia Microsoft Remote Data Objects 2.0. Esta bilioteca utiliza fuentes de dato definidas en el sistema operativo (Panel de Control ODBC). Esta bilioteca de objetos para acceso a datos remotos, se distribuye con la versin Enterprise de Visual Basic 5.0. Si tenemos una fuente de datos llamada Bodega que apunta a una base de datos en Microsoft SQL Server, en la que hay un usuario con identificacin sa y sin clave de acceso, la cadena de conexin hacia esa fuente de datos est dada por:
dsn=Bodega;uid=sa;pwd=

Esta cadena de conexin indica los parmetros para que un objeto rdoConnection se conecte a la base de datos requerida. Los objetos ms utilizados de la biblioteca rdo son rdoConnection, rdoQuery y rdoResultSet. Supongamos que en la base de datos de bodega existe una tabla llamada Bodega con un campo cdigo y uno descripcin. El cdigo necesario para encontrar una bodega es el siguiente:
Dim Conex As New rdoConnection Dim Q As New rdoQuery Dim R As rdoResultset Conex.Connect = "dsn=Bodega;uid=sa;pwd=" On Error GoTo ErrorEnConexion Conex.EstablishConnection rdDriverNoPrompt On Error GoTo 0 Set Q.ActiveConnection = Conex Q.SQL = "Select * from Bodega where Codigo = ?"

Q(0).Type = rdTypeCHAR Q(0).Value = "B01" Set R = Q.OpenResultset If Not R.EOF Then MsgBox "La bodega es " & R.rdoColumns("Descripcion").Value Else MsgBox "No se encontr la bodega" End If Set R = Nothing Set Q = Nothing Set Conex = Nothing Exit Sub ErrorEnConexion: MsgBox "Error al conectarse: " & Err.Description

A un objeto Query es posible indicarle una consulta con parmetros, como en el ejemplo anterior. En este caso, se le debe indicar un valor a cada uno de ellos y es conveniente tambin indicarle un tipo de dato definido en ODBC. La asignacin del tipo y valor se realiza directamente sobre el objeto Query, usando el orden del parmetro como sub ndice que comienza desde cero. En el ejemplo anterior, Q(0).Type y Q(0).Value. Es posible recorrer conjuntos de resultados provenientes de una consulta empleando el servicio MoveNext de los objetos ResultSet, en conjunto con el mtodo EOF. Programacin de la Capa del Negocio. La capa del negocio contendr las clases del sistema y no interactuar directamente con los usuarios. Por ello, en el cdigo que se programe para representar a las clases y sus servicios no se deben realizar llamadas a funciones que resulten en efectos visuales o interactivos, como abrir formularios o mensajes de aviso. Se usar el siguiente ejemplo para demostrar los diferentes aspectos de la programacin orientada a objetos en Visual Basic.

Modelo de Clases

Modelo de Datos E-R

Debido a que se programa una capa intermedia que se desea utilizar desde diferentes tipos de aplicaciones, desde Visual Basic creamos un nuevo proyecto del tipo ActiveX dll. De esta forma las clases pblicas que se definan en l podrn ser creadas y utilizadas desde otros proyectos Visual Basic, desde macros Word o Exel, desde pginas Web va ASP, o cualquier ambiente que soporte el estndar ActiveX. Por cada una de las clases definidas en el sistema, se crea su correspondiente mdulo de clases en el proyecto que creamos. El nombre de las clases no puede ser igual al nombre del proyecto. En cada mdulo de clases definiremos variables pblicas, variables privadas, propiedades y mtodos. En primer lugar, en cada clase podemos declarar una variable para mantener una referencia a la conexin a la Base de Datos. Declaramos entonces al inicio de cada clase:
Dim Conex As rdoConnection

Esta variable deber ser asignada desde la aplicacin u otras clases cada vez que se creen nuevos objetos y se usen sus servicios. Por cada uno de los atributos definidos en el modelo de clases, podemos declarar una variable pblica en el mdulo de la clase correspondiente. Por otro lado, por cada uno de los campos de la tabla asociada en el modelo de datos que se utilice como clave fornea hacia otra tabla, declaramos atributos privados. La declaracin de variables de la clase Movimiento quedara entonces como:
Conexin a Base de Datos Public Conex As rdoConnection Atributos pblicos de la clase Public FechaHora As Date Public Cantidad As Long Atributos privados para representar relaciones Private BodegaCodigo As Long Private ArticuloCodigo As Long

Las clases se instanciarn (asignarn valores a sus variables) desde objetos del tipo ResultSet. Podemos entonces crear en todas las clases un servicio public que instancie sus atributos desde un ResultSet abierto y posicionado sobre una fila. Escribimos entonces para cada una de las clases un servicio LlenaDesdeResultSet. En el caso de la clase Movimiento, el servicio sera:
Public Sub LlenaDesdeResultSet(ByRef RS As ResultSet) If Not RS.EOF Then FechaHora = RS.rdoColumns(FechaHora) Cantidad = RS.rdoColumns(Cantidad) BodegaCodigo = RS.rdoColumns(BodegaCodigo) ArticuloCodigo = RS.rdoColumns(ArticuloCodigo) End If End Sub

Cada una de las clases necesitar crear, destruir, modificar y leer sus objetos. Por ello podemos crear estos cuatro servicios para todas las clases, aunque no estn definidos en el modelo. En el caso de la clase Movimiento: CreaObjeto: Se supone que las variables del objeto ya estn instanciadas con los valores del nuevo objeto que se desea crear.
Public Sub CreaObjeto()

Dim Q As New rdoQuery Dim stSQL As String Set Q.ActiveConnection = Conex stSQL = INSERT INTO Movimiento (FechaHora, Cantidad, stSQL = stSQL & BodegaCodigo, ArticuloCodigo) VALUES ( stSQL = stSQL & ?,?,?,?) Q.SQL = stSQL Q(0).Type = rdTypeTIMESTAMP Q(0).Value = FechaHora Q(1).Type = rdTypeNUMERIC Q(1).Value = Cantidad Q(2).Type = rdTypeNUMERIC Q(2).Value = BodegaCodigo Q(3).Type = rdTypeNUMERIC Q(3).Value = ArticuloCodigo Q.Execute Set Q = Nothing End Sub

DestruyeObjeto: Si la clase es una agregacin de otras, se puede antes de eliminar el registro de la base de datos, llamar al servicio DestruyeObjeto para cada uno de los objetos componentes. Esto representa el hecho que al eliminar un todo, se eliminan tambin sus partes. Lo mismo se debe realizar en herencias (al eliminar los padres).
Public Sub DestruyeObjeto() Dim Q As New rdoQuery Dim stSQL As String Set Q.ActiveConnection = Conex stSQL = DELETE FROM Movimiento WHERE stSQL = stSQL & FechaHora = ? stSQL = stSQL & AND BodegaCodigo = ? stSQL = stSQL & AND ArticuloCodigo = ? Q.SQL = stSQL Q(0).Type = rdTypeTIMESTAMP Q(0).Value = FechaHora Q(1).Type = rdTypeNUMERIC Q(1).Value = BodegaCodigo Q(2).Type = rdTypeNUMERIC Q(2).Value = ArticuloCodigo Q.Execute Set Q = Nothing End Sub

SalvaEstado: Se denomina el estado de un objeto a la tupla de valores de sus atributos en un cierto momento. Al modificar un objeto se actualiza el registro en la base de datos con el estado o valores de los atributos del objeto en memoria. Se actualizan slo los campos que no son parte de la clave primaria.
Public Sub SalvaEstado()

Dim Q As New rdoQuery Dim stSQL As String Set Q.ActiveConnection = Conex stSQL = UPDATE Movimiento stSQL = stSQL = SET Cantidad = ? WHERE stSQL = stSQL & FechaHora = ? stSQL = stSQL & AND BodegaCodigo = ? stSQL = stSQL & AND ArticuloCodigo = ? Q.SQL = stSQL Q(0).Type = rdTypeNUMERIC Q(0).Value = Cantidad Q(1).Type = rdTypeTIMESTAMP Q(1).Value = FechaHora Q(2).Type = rdTypeNUMERIC Q(2).Value = BodegaCodigo Q(3).Type = rdTypeNUMERIC Q(3).Value = ArticuloCodigo Q.Execute Set Q = Nothing End Sub

RecuperaEstado: Conociendo los atributos que forman la clave primaria (Oid u Object Id.) de un objeto, es posible recuperar el valor del resto de ellos.
Public Sub RecuperaEstado() Dim Q As New rdoQuery Dim RS As rdoResultSet Dim stSQL As String Set Q.ActiveConnection = Conex stSQL = SELECT * FROM Movimiento stSQL = stSQL & FechaHora = ? stSQL = stSQL & AND BodegaCodigo = ? stSQL = stSQL & AND ArticuloCodigo = ? Q.SQL = stSQL Q(0).Type = rdTypeTIMESTAMP Q(0).Value = FechaHora Q(1).Type = rdTypeNUMERIC Q(1).Value = BodegaCodigo Q(2).Type = rdTypeNUMERIC Q(2).Value = ArticuloCodigo Set RS = Q.OpenResultSet Me.LlenaDesdeResultSet RS Set RS = Nothing Set Q = Nothing End Sub

Con la definicin de estos cuatro servicios, la persistencia de los objetos se puede manejar desde las aplicaciones (u otros servicios) sin necesidad de realizar consultas SQL. 9

Se desea que la capa intermedia represente fielmente al modelo de clases que define la estructura del sistema. Por ello, para cada una de las relaciones de una clase, vamos a crear propiedades en ella, que permitan a las aplicaciones o servicios de otras clases navegar por el modelo. Las relaciones en un modelo de clases se definen con nombres de roles, dependiendo de la direccin de la navegacin. Si en el modelo no se han definido, podemos suponer que se utilizan los mismos nombres de las clases, en singular o plural, dependiendo de la cardinalidad. Por ejemplo, desde Bodega a Movimiento el nombre sera Movimientos y desde Movimiento a Bodega, Bodega. Ocupando estos nombres de relaciones, escribiremos propiedades que permitan retornar l o los objetos relacionados. Para la clase Movimiento:
Public Property Get Bodega As Bodega Dim Q As New rdoQuery Dim RS As rdoResultSet Dim ObjetoRelacionado As New Bodega Set Q.ActiveConnection = Conex Q.SQL = SELECT * FROM Bodega WHERE Codigo = ? Q(0).Type = rdTypeNUMERIC Q(0).Value = Me.BodegaCodigo Set RS = Q.OpenResultSet Set ObjetoRelacionado.Conex = Me.Conex ObjetoRelacionado.LlenaDesdeResultSet RS Set Bodega = ObjetoRelacionado Set ObjetoRelacionado = Nothing Set RS = Nothing Set Q = Nothing End Property

Para la clase Bodega:


Public Property Get Movimientos As Collection Dim Col As New Collection Dim Q As New rdoQuery Dim RS As rdoResultSet Dim ObjetoRelacionado As Movimiento Q.SQL = SELECT * FROM Movimiento WHERE BodegaCodigo = ? Q(0).Type = rdTypeNUMERIC Q(0).Value = Me.BodegaCodigo Set RS = Q.OpenResultSet Do While Not RS.EOF Set ObjetoRelacionado = New Movimiento Set ObjetoRelacionado.Conex = Me.Conex ObjetoRelacionado.LlenaDesdeResultSet RS Col.Add ObjetoRelacionado RS.MoveNext Set ObjetoRelacionado = Nothing Loop Set RS = Nothing Set Q = Nothing End Property

10

Para el caso de especializaciones o herencias, se pueden utilizar como nombre para las propiedades: Padre desde la clase hija a la padre, y el nombre de la clase hija en la direccin contraria. En este ltimo caso y en las asociaciones que aceptan cardinalidad cero, la propiedad debe ocuparse de que los objetos relacionados no existan, pudiendo retornar objetos nulos (asignndoles la constante Nothing). Utilizando estas propiedades, se puede accesar en forma muy fcil a los objetos relacionados a alguno en particular. Si se escribieran estas propiedades para todas las relaciones del modelo, las navegaciones compuestas resultan en forma natural, como en el siguiente ejemplo:
Dim Bodega As New Bodega Dim Conex As New rdoConnection Conex.Connect = dsn=Bodega;uid=sa;pwd= Conex. EstablishConnection rdDriverNoPrompt Set Bodega.Conex = Conex Bodega.Codigo = B01 Bodega.RecuperaEstado MsgBox La descripcin de la bodega es & Boodega.Descripcion Dim Mov As Movimiento For Each Mov In Bodega.Movimientos If Not Mov.Entrada Is Nothing Then MsgBox Entrada: & Mov.FechaHora MsgBox Articulo: & Mov.Articulo.Descripcion Msgbox Proveedor: & Mov.Entrada.Proveedor.Descripcion Else MsgBox Salida: & Mov.FechaHora MsgBox Articulo: & Mov.Articulo.Descripcion Msgbox Destino: & Mov.Salida.Destinatario.Descripcion End If Next

Las propiedades que escribimos nos permiten consultar por objetos relacionados, pero hay ocaciones en que es necesario asignar valores a estos objetos. Por ejemplo, antes de crear un Movimiento, es necesario asignar la Bodega y El Artculo ya que (como es agregacin) forman parte de su Oid. Para ello, para las relaciones con origen en una clase (cardinalidad 0..* => 1) creamos propiedades que permitan asignar el objeto relacionado. Lo mismo se debe realizar para permitir la asignacin del objeto padre cada vez que se crea un hijo. En la clase Movimiento:
Public Property Set Bodega(Objeto As Bodega) Se asigna al atributo privado que mantiene la relacin BodegaCodigo = Objeto.Codigo End Property Public Property Set Articulo(Objeto As Articulo) ArticuloCodigo = Objeto.Codigo End Property

Entonces, antes de crear un nuevo movimiento, se asignan los objetos relacionados. Por ejemplo, si queremos crear un nuevo movimiento de entrada para una bodega, artculo y proveedor ya instanciados, podemos escribir:

11

Dim Mov As New Movimiento, Ent As New Entrada Set Mov.Conex = Conex Mov.Cantidad = 5 Set Mov.Bodega = BodegaInstanciada Set Mov.Articulo = ArticuloInstanciado Mov.CreaObjeto Set Ent.Conex = Conex Set Ent.Padre = Mov Set Ent.Proveedor = ProveedorInstanciado Ent.CreaObjeto Set Mov = Nothing Set Ent = Nothing

El lenguaje Visual Basic no soporta la herencia de objetos; sin embargo, sta se puede simular utilizando funciones espejo. Si tenemos una propiedad llamada Padre que retorne el objeto asociado de la clase padre, podemos escribir en el hijo, propiedades que representes a los atributos, servicios y relaciones de la clase padre. En el ejemplo anterior, para la clase Entrada:
Public Property Get FechaHora As Date FechaHora = Padre.FechaHora End Property Public Property Get Cantidad As Long Cantidad = Padre.Cantidad End Property Public Property Get Bodega As Bodega Se usa set porque en una referencia a un objeto Set Bodega = Padre.Bodega End Property Public Property Get Articulo As Articulo Set Articulo = Padre.Articulo End Property

Si la clase padre a su vez heredara de otra ms, sera necesario en la nieta declarar funciones espejo para representar los atributos, relaciones y servicios de la clase abuela. El resto de los servicios de las clases se escriben utilizando las propiedades y servicios de persistencia que antes se definieron. En el ejemplo anterior, se necesita defnir los servicios de Entrada y Salida de artculos para la clase Bodega.
Public Sub Entrada(Articulo As Articulo, Cantidad As Long, Proveedor As Proveedor) Dim Mov As New Movimiento Dim Ent As New Entrada Dim Sto As New Stock Crear objeto Movimiento en la bodega Set Mov.Conex = Me.Conex Set Mov.Bodega = Me Set Mov.Articulo = Articulo Mov.FechaHora = Now Mov.Cantidad = Cantidad Mov.CreaObjeto

12

Crear el objeto Entrada como hijo de Mov Set Ent.Conex = Me.Conex Set Ent.Padre = Mov Set Ent.Proveedor = Proveedor Ent.CreaObjeto Crear o actualizar stock del artculo Buscar si existe. Si existe sumar a la cantidad sino crearlo. Set Sto.Conex = Me.Conex Set Sto.Articulo = Articulo Set Sto.Bodega = Me Sto.Cantidad = -99 si lo encuentra, cantidad va a cambiar Sto.RecuperaEstado If Sto.Cantidad = -99 Then No lo encontr Sto.Cantidad = Cantidad Sto.CreaObjeto Else Lo encontr Sto.Cantidad = Sto.Cantidad + Cantidad Sto.SalvaEstado End If Destruir variables Set Sto = Nothing Set Ent = Nothing Set Mov = Nothing End Sub Public Sub Salida(Articulo As Articulo, Cantidad As Cantidad, Destinatario As Destinatario) Dim Sto As New Stock Dim Mov As New Movimiento Dim Sal As New Salida Buscar stock para ver si hay disponibilidad Set Sto.Conex = Me.Conex Set Sto.Bodega = Me Set Sto.Articulo = Articulo Sto.Cantidad = 0 Si no lo encuentra, queda en cero Sto.RecuperaEstado If Sto.Cantidad < Cantidad Then Err.Raise vbObjectError, "Bodega", "No hay stock suficiente para satisfacer la salida del artculo" End If Sto.Cantidad = Sto.Cantidad Cantidad Sto.SalvaEstado Crear objeto Movimiento en la bodega Set Mov.Conex = Me.Conex Set Mov.Bodega = Me Set Mov.Articulo = Articulo Mov.FechaHora = Now Mov.Cantidad = Cantidad Mov.CreaObjeto Crear el objeto Salida como hijo de Mov Set Sal.Conex = Me.Conex Set Sal.Padre = Mov Set Sal.Destinatario = Destinatario Sal.CreaObjeto

13

Limpiar Set Sal = Set Sto = Set Mov = End Sub

variables Nothing Nothing Nothing

Como se est construyendo bajo una arquitectura de tres capas, el servicio Salida no puede desplegar un mensaje cuando la cantidad requerida es mayor que la disponible. La forma de avisar los errores es empleando el estndar que provee ActiveX, a travs del objeto Err. Este error puede ser capturado (usando On Error Goto) desde la aplicacin que invoca el servicio y es ella la encargada de avisarlo al usuario. Es conveniente crear algunos servicios especiales en las clases que faciliten la construccin de interfaces. Por cada clase podemos crear propiedades (Get y Set) que permitan recuperar y asignar la identificacin de los objetos para poder referenciarlos desde las aplicaciones. Definamos popiedades llamadas Oid para cada una de las clases. En el caso de Movimiento:
Public Property Get Oid() As Collection Set Oid = New Collection Oid.Add FechaHora Oid.Add BodegaCodigo Oid.Add ArticuloCodigo End Property Public Property Set Oid(Id As Collection) FechaHora = Id(1) BodegaCodigo = Id(2) ArticuloCodigo = Id(3) End Property

Una aplicacin puede declarar una variable tipo coleccin u object para almacenar la clave de un objeto y luego asignrsela a ste de vuelta para recuperar su estado. Otros servicios tiles para la construccin de interfaces seran aquellos que retornan colecciones de objetos para mostrar en algn control. Debido nuevamente a la arquitectura de tres capas, no deseamos que la aplicacin accese a la base de datos, pero podemos construir servicios en la capa intermedia que nos retornen grupos de objetos para mostrarlos en las ventanas, y permitir que el usuario los seleccione. Por ejemplo, podemos construir un servicio Todas en la clase bodega, de la forma:
Public Function Todas As Collection Dim Q As New rdoQuery Dim RS As rdoResultSet Dim B As Bodega Set Todas = New Collection Set Q.ActiveConnection = Me.Conex Q.SQL = SELECT * FROM Bodega Set RS = Q.OpenResultSet Do While Not RS.Eof Set B = New Bodega Set B.Conex = Me.Conex B.LlenaDesdeResultSet RS Todas.Add B Set B = Nothing Loop Set RS = Nothing

14

Set Q = Nothing End Function

15

Programacin de la Capa de Aplicacin. La capa de aplicacin corresponde a la interfaz con el usuario. Ella puede slo accesar a objetos de la capa del negocio y no directamente a la base de datos, por lo que no se debra escribir consultas SQL o reglas del negocio dentro de los eventos de controles o elementos de interfaz. Para la construccin de una aplicacin, partimos con un nuevo proyecto en Visual Basic del tipo Standard EXE. Dentro del ambiente integrado de programacin, podemos tener abiertos ms de un proyecto a la vez, en un grupo de proyectos. Podemos agregar un proyecto nuevo File|Add project al grupo y de esta forma tener en un mismo ambiente la capa intermedia (ActiveX dll) y la aplicacin (Standard EXE). Seleccionando el proyecto de la aplicacin agregamos una referencia hacia el proyecto de las clases (Project|References). De esta forma, la capa intermedia constituye una biblioteca para la aplicacin. Desde el formulario principal de la aplicacin podemos crear una conexin pblica (un objeto rdoConecction). Esta conexin se ir asignando a los objetos y otros formularios, a medida que se vayan creando. Mantencin de objetos. Una de las tareas comunes a todos los sistemas corresponde a la mantencin de los datos que actan como maestros. En el ejemplo anterior, podemos realizar la mantencin de las bodegas en el siguiente formulario: El control principal es un listbox desde donde el usuario seleccionar un objeto. Podemos declarar una variable del formulario, de la clase Bodega, que en todo momento est instanciada con la seleccin del usuario. Al abrirse el formulario podemos llenar el listbox con el resultado del servicio Todas de Bodega y actualizar la variable del formulario cada vez que se produce un evento de cambio de fila en el control. Los botones de la parte superior pueden abrir otros formularion que ejecuten los servicios CreaObjeto, DestruyeObjeto y EliminaObjeto que se definieron para cada clase. El cdigo contenido en el formulario anterior es el siguiente:
Public Conex As rdoConnection Private Bodega As Bodega Private Todas As Collection Private Sub cmdAgregar_Click() Set frmAgregarBodega.Conex = Conex frmAgregarBodega.Show 1 ActualizaListaBodegas End Sub Private Sub cmdEliminar_Click() If MsgBox(" Confirma la eliminacin de la bodega seleccionada ?", vbYesNo) = vbYes Then Bodega.DestruyeObjeto ActualizaListaBodegas

16

End If End Sub Private Sub cmdModificar_Click() Set frmModificarBodega.Conex = Conex Set frmModificarBodega.Bodega = Bodega frmModificarBodega.Show 1 ActualizaListaBodegas End Sub

Private Sub Form_Load() ActualizaListaBodegas End Sub Private Sub ActualizaListaBodegas() Dim B As New Bodega Set B.Conex = Conex Set Todas = Bodega.Todas Set B = Nothing ListaBodegas.Clear For Each B In Todas ListaBodegas.AddItem B.Descripcion Next End Sub Private Sub ListaBodegas_Click() If Item >= 0 Then Set Bodega = Todas(Item) Else Set Bodega = Nothing End If cmdModificar.Enabled = Not Bodega Is Nothing cmdEliminar.Enabled = Not Bodega Is Nothing End Sub

Los formularios para Agregar y Modificar una bodega tendrn el cdigo necesario en su botn de Aceptar para llamar a los servicios CreaObjeto y DestruyeObjeto, respectivamente. Si un formulario necesita ejecutar servicios que como parmetros reciban otros objetos, stos ltimos se pueden seleccionar desde listas o ComboBox como en el ejemplo anterior. Adems de los controles listbox, se pueden utilizar controles como el FlexGrid o el ListView que permiten mostrar ms columnas. Estas otras columnas pueden mostrar otros atributos del objeto o atributos de objetos relacionados, usando las propiedades que se programaron en la capa intermedia. Por ejemplo, si se muestran los movimientos a una bodega, las columnas se podran llenar con el siguiente cdigo:
Set Movimientos = Bodega.Movimientos For Each Mov In Movimientos Fila=Fila+1 Grilla.String(Fila,1) = Movimiento.Fecha Grilla.String(Fila,2) = Movimiento.Cantidad Grilla.String(Fila,3) = Movimiento.Articulo.Descripcion If Not Mov.Entrada Is Nothing Then Grilla.String(Fila,4)= Movimiento.Entrada.Proveedor.Descripcion

17

Else Grilla.String(Fila,4)= Movimiento.Salida.Destinatario.Descripcion End If Next

Utilizacin de la capa intermedia desde pginas web. El servidor web de Microsoft, Internet Information Server (o IIS) soporta el uso de ASP (Active Server Pages). Esto significa que las pginas pueden contener scripts que sern ejecutados en el servidor, antes de retornar informacin al browser. Este cdigo que ejecutar el servidor podr hacer uso de los servicios de la capa intermedia que definimos. Existen algunas diferencias entre la programacin de pginas ASP y aplicaciones Visual Basic Cliente / Servidor. En ASP se cuenta con tres objetos principales que sirven para comunicar entre s las diferentes pginas que conforman un sitio. El objeto Session permite declarar variables (que pueden ser objetos) que se conocen en todas las pginas durante la conexin de un usuario. Ac se pueden, por ejemplo, guardar valores o referencias a objetos que sirven de parmetros de entrada a cada pgina. El objeto Request permite rescatar los valores de entrada de las pginas, a travs del nombre que se le dio en HTML a los campos (editores y listas). Usando objeto Response se puede retornar cdigo HTML hacia el browser. Debido a que no se conoce la cantidad de usuarios que se conectarn a la base de datos y la cantidad de conexiones son un recurso limitado, es ms conveniente pasarle a cada clase la cadena de conexin (y no el objeto conexin) para que ella se conecte a la base de datos antes de realizar cualquier consulta. De esta forma, todas las clases podran tener una variable pblica llamada ConexString, adems de la conexin Conex y un servicio Conecta de la forma:
Private Sub Conecta If Conex Is Nothing Then Set Conex = New rdoConnection Conex.Connect = ConexString Conex.EstablishConnection rdDriverNoPrompt End If End Sub

Entonces, al inicio de cada servicio, las clases pueden siempre llamar a Conecta. La sentencia New se reemplaza por la creacin directa de los objetos, usando CreateObject. Por ejemplo, si en el caso anterior llamamos al proyecto ClasesBodegas que contiene una clase Bodega, la creacin de un objeto y su conexin a la base de datos, sera de la forma:
Dim Bod Set Bod = CreateObject(ClasesBodegas.Bodega) Bod.ConexString = dsn=Bodega;uid=sa;pwd= Response.Write Bod.StockComoHTML(Session(Articulo)) Set Bod = Nothing

18

Vous aimerez peut-être aussi