Professional Documents
Culture Documents
CAPTULO 181
ndice de contenido
TIPOS, COLECCIONES Y CLASES..................................................................................................2
INTRODUCCIN...........................................................................................................................2
TIPOS..............................................................................................................................................2
COLECCIONES..............................................................................................................................6
DEFINIR UNA COLECCIN....................................................................................................6
AADIR ELEMENTOS A UNA COLECCIN........................................................................7
CONTAR ELEMENTOS DE UNA COLECCIN....................................................................7
ELIMINAR ELEMENTOS DE UNA COLECCIN.................................................................7
RECORRER LOS ELEMENTOS DE UNA COLECCIN.......................................................8
UN EJEMPLO CON TODO LO ANTERIOR............................................................................8
CLASES...........................................................................................................................................9
TRABAJANDO CON LAS CLASES...........................................................................................11
EXPORTANDO EL MDULO DE CLASE............................................................................12
SEGUIMOS CON EL TRABAJO CON CLASES...................................................................13
UTILIZANDO LAS PROPIEDADES: PROCEDIMIENTO PROPERTY..............................16
PROPERTY LET..................................................................................................................16
PROPERTY GET.................................................................................................................16
PROPERTY SET..................................................................................................................17
APLIQUEMOS EL PROCEDIMIENTO PROPERTY........................................................17
UNAS BREVES EXPLICACIONES TERICAS BASADAS EN TODO LO ANTERIOR. 21
UN EJEMPLO INTEGRNDOLO CON ACCESS.....................................................................23
PARA FINALIZAR ESTE CAPTULO........................................................................................31
1
Vistame en http://siliconproject.com.ar/neckkito/
TIPOS, COLECCIONES Y CLASES
INTRODUCCIN
El objetivo de este captulo es llegar a comprender las
clases. Sin embargo, para ello es necesario asimilar dos
conceptos clave: los tipos y las colecciones. Si bien no son
lo mismo (lgicamente) las ideas que subyacen en cada uno
de ellos nos allanarn el camino para llegar a las clases.
Es por esto por lo que empezaremos desarrollando los que son los tipos, cmo se definen, etc.,
y haremos lo mismo con las colecciones (que, adems, ya nos debera sonar de algo si
hemos seguido todo este curso hasta aqu).
Como utilizaremos los conceptos explicados cuando hablbamos de matrices, si notis que
tenis un momento de debilidad memorstica, quiz sera interesante que tuvierais a mano el
captulo 9, donde se habla de ellas.
Os advierto que este captulo quiz pueda resultaros algo complejo, sobre todo en la parte final
del mismo y en especial en el apartado Un ejemplo integrndolo con Access, bsicamente
porque se mezclan no slo cosas de este captulo sino elementos que hemos ido explicando (y
aprendiendo, supongo ) durante este curso. Pensad que la finalidad es podernos construir
nuestro propio mdulo de clase (todo un lujazo para nuestra aplicacin).
Empecemos pues.
TIPOS
Nuestro buen amigo Access nos dice, refirindose a la instruccin Type, lo siguiente: <<Se usa
en el nivel de mdulo para definir un tipo de datos definido por el usuario que contiene uno o
ms elementos>>.
2
Vistame en http://siliconproject.com.ar/neckkito/
Pues los elementos deben ser definidos dentro de un procedimiento.
Como hemos comentado antes, la definicin de los tipos debe ir en la cabecera del mdulo
(debajo de Option Compare Database / Option Explicit). As, los elementos que componen
nuestro tipo sern dos:
Como veis, las variables que indican la definicin de los elementos son, en este caso, de tipo
texto String. Adems, hemos indicado su longitud mxima (a travs de * 10 y * 25).
Como es el primer ejemplo fcil slo vamos a rellenar los datos de un color. Como comentaba
antes, una vez entendido lo que hace nuestro cdigo pondremos un ejemplo ms complejo.
Para rellenar los elementos del tipo vamos a utilizar un procedimiento pblico, que llamaremos
rellenaCodigos. Lo escribiramos as, inmediatamente debajo de nuestra definicin de tipo
personalizado CodigoColor:
3
Vistame en http://siliconproject.com.ar/neckkito/
MsgBox vColor.nombre & vColor.significado, vbInformation, "DATOS"
End Sub
Fijaos en que:
Compliquemos un poco ms la cosa. Supongamos que tenemos un listado de pases con sus
monedas. El listado que utilizaremos ser el siguiente:
1- USA - Dlar
2- Espaa - Euro
3- Japn - Yen
Nos crearemos, en nuestro mdulo, un nuevo tipo, al que llamaremos Monedas, de la manera
siguiente:
4
Vistame en http://siliconproject.com.ar/neckkito/
'Declaramos las variables
Dim vCod As Variant
'Solicitamos al usuario un cdigo de pas
vCod = InputBox("Introduzca cdigo del pas (nmero
del 1 al 3)", "CDIGO PAS", "1")
'Llamamos al procedimiento usaMoneda()
Call usaMoneda(vCod)
End Sub
Tambin pensad que podemos reutilizar nuestra definicin de tipo para otras acciones (si lo
planificamos bien nos puede salir una definicin de tipos bastante universal).
Por ejemplo, si creamos otro procedimiento para saber en qu moneda debemos pagar a un
cliente, sabiendo su cdigo de cliente, slo deberamos escribir un procedimiento especfico
para ello, sin tener que volver a definir otro tipo.
Para finalizar, tened en cuenta que hemos utilizado matrices estticas para definir los ndices
de los datos. No habra ningn problema en utilizar matrices dinmicas si no conocemos, de
antemano, el nmero de elementos que va a haber en la matriz.
5
Vistame en http://siliconproject.com.ar/neckkito/
COLECCIONES
Durante todo el curso hemos estado viendo, en
determinados captulos, distintas colecciones. A modo de
recordatorio, hemos visto la coleccin Fields() de un
recordset, o la coleccin Properties de los controles. En
definitiva, que si nos paramos a pensar un poco podremos
llegar a afirmar aquella frase de en ocasiones veo
colecciones.
<<Un objeto Collection es un conjunto ordenado de elementos a los que se puede hacer
referencia como una unidad.
Comentarios
El objeto Collection permite hacer referencia de forma sencilla a un grupo de elementos
relacionados como un nico objeto. Los elementos o miembros de una coleccin slo tienen
que estar relacionados por el hecho de existir en la coleccin. Los miembros de una coleccin
no tienen que compartir el mismo tipo de dato>>.
Veamos:
Con todo lo anterior ya vemos que podemos crearnos nuestras propias colecciones.
y definirla as:
6
Vistame en http://siliconproject.com.ar/neckkito/
Nos debera sonar tambin la idea de que esos dos pasos podemos
resumirlos en uno, declarando la coleccin de la siguiente manera:
La estructura sera:
nomColeccin.Add Elemento
o bien
Por ejemplo, si yo quiero aadir mi coche Porshe Carrera a la coleccin escribira lo siguiente:
Si, adems, quisiera identificar ese coche con una palabra clave, podra aadirla tambin con el
ADD. Por ejemplo, supongamos que mi clave para el Porshe Carrera es PorCar; luego
escribira:
nomColeccion.Count
Es decir:
misCoches.Count
Los elementos de una coleccin tienen todos un ndice, que vendra a ser el identificador de la
posicin que ocupan en la coleccin. Sabiendo esto, y tambin sabiendo que podemos eliminar
un elemento por su palabra clave, la estructura para eliminar sera:
nomColeccion.Remove (ndice)
o bien
7
Vistame en http://siliconproject.com.ar/neckkito/
nomColeccion.Remove (clave)
misCoches.Remove (6)
o as
misCoches.Remove (PorCar)
8
Vistame en http://siliconproject.com.ar/neckkito/
'----------------------------------------------
'Borramos el primer coche
misCoches.Remove (1)
MsgBox "Oh! No recordaba que el primer coche lo vend
por un pastn" _
& vbCrLf & vbCrLf & "Ahora slo tengo " &
misCoches.Count & " 'cochecitos'", _
vbExclamation, "#COCHES"
MsgBox "Quiero decir, que el coche que vend fue el " &
cocheBorrado, vbInformation, "VENDIDO"
End Sub
Y slo nos queda, en cualquier formulario, aadirle este cdigo a un botn de comando:
Si analizis el primer cdigo veris cmo he manipulado la coleccin y sus propiedades segn
lo que os he estado explicando en apartados anteriores. No creo que tenga mayor dificultad
para nuestros ya entrenados cerebros
Slo quisiera llamaros la atencin sobre algo que no habamos comentado an, y que es la
propiedad ITEM. Fijaos que cuando asigno valor a la variable <cocheBorrado> lo hago a travs
de su clave, as:
cocheBorrado = misCoches("PorCar")
Pero si no tuviera clave, o mi gua fuese el ndice del elemento en la coleccin, podra utilizar
esta otra expresin:
cocheBorrado = misCoches.Item(1)
CLASES
Nuestro amigo Access nos define una clase como <<Definicin formal de un objeto. La clase
acta como plantilla desde la que se crea una instancia de un objeto en tiempo de ejecucin.
La clase define las propiedades del objeto y los mtodos utilizados para controlar su
comportamiento>>.
Veamos:
Define un objeto. Eso significara que lo que nos permite crear son objetos, y en los
captulos anteriores hemos visto algunas de las muchas cosas que se pueden hacer con
los objetos.
Acta como plantilla desde la que se crea una instancia de un objeto. Ya sabemos que
lo que nos estamos creando es una plantilla, y que gracias a esa plantilla vamos a crear
una instancia del objeto. Y qu significa esto? Que nosotros no vamos a trabajar con la
plantilla directamente cuando creemos un objeto, sino que vamos a trabajar con una
instancia.
9
Vistame en http://siliconproject.com.ar/neckkito/
Quiz lo anterior pueda resultar un poco confuso, pero un
ejemplo grfico creo que nos ayudar: supongamos que yo
creo una clase que se llama rectngulo. Cuando necesito
un objeto rectngulo llamo a la clase y creo el objeto. En
realidad creo una instancia del objeto: todo el trabajo que
realice se har sobre esa instancia, no sobre la plantilla. Es
decir:
Se crea una instancia del objeto en tiempo de ejecucin. Lo que significa, para
entendernos, que se crea mientras tenemos Access en marcha.
La clase define las propiedades del objeto y los mtodos utilizados para controlar su
comportamiento. Ya sabemos pues que el objeto tendr propiedades y mtodos, y que
podremos establecer sus valores para que la instancia se comporte segn nuestros
deseos.
Aunque no hayamos sido conscientes con los ejemplos que hemos ido aprendiendo durante
este curso estbamos realizando este proceso. Por poner un ejemplo fresco, recordamos el
captulo dedicado al Scripting Runtime, en concreto el ejemplo de nuestro diccionario
(captulo 17)?
'Declaramos las variables
Dim abv As Object
'Creamos el objeto abv
Set abv = CreateObject("Scripting.Dictionary")
'Aadimos los significados de las abreviaturas
abv.Add "DDCG", "Dar de comer al gato"
fncMiTip = abv.Item(vAbreviado)
10
Vistame en http://siliconproject.com.ar/neckkito/
instancia del objeto de la clase Scripting.Dictionary. La
estbamos creando, evidentemente, en tiempo de ejecucin
(no parbamos Access para poder crear dicho objeto) y, a
continuacin, manipulbamos, en este caso, un mtodo de
la clase, que era ADD, y una propiedad, en este caso, ITEM.
Voy a explicar el proceso relacionndolo con los puntos anteriores, para que podis seguir
mejor el hilo de la explicacin.
Para cumplir el punto nos vamos al editor de VB y en el men Insertar aadimos un mdulo
de clase. Lo guardamos como clsVehic.
Para cumplir los puntos y vamos a definir las caractersticas que necesitaremos. Para ello
escribimos en nuestro mdulo de clase lo siguiente:
Para cumplir con el punto vamos a necesitar unas funciones que nos calcularan los
resultados. La primera funcin nos unir el nombre con su tipo; la segunda funcin nos
calcular cunto costara llenar el depsito en el momento actual (es decir, que el proceso nos
pedir el importe del litro de combustible en el momento en que necesitemos ese dato).
11
Vistame en http://siliconproject.com.ar/neckkito/
If costeDeposito > 150 Then
MsgBox "Qu caro! Mejor dejar el vehculo
aparcado!", vbExclamation, "UFFF"
End If
End Function
Ya tenemos pues nuestro mdulo de clase creado con todas las caractersticas que
necesitbamos. Ese mdulo de clase lo podramos exportar para poder utilizarlo en diferentes
bases de datos que tuviramos sobre vehculos.
Se nos abrir una ventana que nos pedir dnde queremos guardarlo. Como es un mdulo de
clase tendr la extensin cls.
12
Vistame en http://siliconproject.com.ar/neckkito/
Si quisiramos realizar una importacin de clase el proceso sera el mismo (situndonos en
cualquier espacio en blanco en la ventana de proyecto): haramos click derecho y elegiramos
la opcin Importar archivo...
3 No tengo ni idea de las caractersticas tcnicas de los vehculos que voy a introducir. De hecho es posible que introduzca alguna
salvajada. En definitiva, que me lo voy inventando a medida que escribo. Por ello, no tomis estos valores como referencias
reales.
13
Vistame en http://siliconproject.com.ar/neckkito/
.cilindrada = 3000
.capacDep = 80.5
End With
'Lo aadimos a nuestra coleccin
colMisVehic.Add unVehiculo, "PorCar"
'Rellenamos el siguiente vehculo
Set unVehiculo = New clsVehic
With unVehiculo
.claseVehic = "Coche"
.nombre = "Mercedes"
.tipo = "CLK"
.cilindrada = 2800
.capacDep = 85.7
End With
colMisVehic.Add unVehiculo, "MerCLK"
'Rellenamos el siguiente vehculo
Set unVehiculo = New clsVehic
With unVehiculo
.claseVehic = "Moto"
.nombre = "Suzuki"
.tipo = "Bandid"
.cilindrada = 650
.capacDep = 30.3
End With
colMisVehic.Add unVehiculo, "SuzBan"
'Rellenamos el siguiente vehculo
Set unVehiculo = New clsVehic
With unVehiculo
.claseVehic = "Moto"
.nombre = "Ducati"
.tipo = "Storm"
.cilindrada = 1200
.capacDep = 46.2
End With
colMisVehic.Add unVehiculo, "DucSto"
'Rellenamos el siguiente vehculo
Set unVehiculo = New clsVehic
With unVehiculo
.claseVehic = "Camin"
.nombre = "Mercedes"
.tipo = "Pegaso"
.cilindrada = 4000
.capacDep = 120.7
End With
colMisVehic.Add unVehiculo, "MerPeg"
'Ya podemos mostrar la informacin de la coleccin a peticin del usuario
'No comento esta parte de cdigo porque deberamos entenderla ya perfectamente
Dim vClaseVehic As Variant
Dim vPrecioCombustible As Variant
Peticion:
vClaseVehic = InputBox("Seleccione qu informacin desea: 1-Coches; 2-Motos;" _
& " 3-Camiones; 0-Todos", "INFORMACIN VEHCULOS", 0)
If StrPtr(vClaseVehic) = 0 Then GoTo BorraColeccion
If Not IsNumeric(vClaseVehic) Then
MsgBox "El valor introducido no es vlido", vbCritical, "INCORRECTO"
GoTo Peticion
End If
If vClaseVehic < 0 Or vClaseVehic > 3 Then
MsgBox "El valor introducido no es vlido", vbCritical, "INCORRECTO"
GoTo Peticion
End If
'Por simplificar suponemos que todos utilizan el mismo tipo de combustible
vPrecioCombustible = InputBox("Introduzca el precio por litro de combustible", "PRECIO")
'Tambin, por simplificar, no introduzco elementos de control para el valor introducido
'Si quisirais utilizarlos os podis guiar por los elementos de control que he utilizado
'en el primer InputBox
If StrPtr(vPrecioCombustible) = 0 Then GoTo BorraColeccion
Select Case vClaseVehic
Case 0
For Each elemVehic In colMisVehic
MsgBox "El vehculo tiene las siguientes caractersticas:" & vbCrLf & vbCrLf _
14
Vistame en http://siliconproject.com.ar/neckkito/
& "Clase: " & elemVehic.claseVehic & vbCrLf _
& "Nombre: " & elemVehic.nomVehic & vbCrLf _
& "Cilindrada: " & elemVehic.cilindrada & vbCrLf _
& "Capacidad del depsito: " & elemVehic.capacDep & vbCrLf _
& "Precio de llenado del depsito: " & elemVehic.costeDeposito(vPrecioCombustible), _
vbInformation, "DATOS"
Next elemVehic
Case 1
For Each elemVehic In colMisVehic
If elemVehic.claseVehic = "Coche" Then
MsgBox "El vehculo tiene las siguientes caractersticas:" & vbCrLf & vbCrLf _
& "Clase: " & elemVehic.claseVehic & vbCrLf _
& "Nombre: " & elemVehic.nomVehic & vbCrLf _
& "Cilindrada: " & elemVehic.cilindrada & vbCrLf _
& "Capacidad del depsito: " & elemVehic.capacDep & vbCrLf _
& "Precio de llenado del depsito: " & elemVehic.costeDeposito(vPrecioCombustible), _
vbInformation, "DATOS"
End If
Next elemVehic
Case 2
For Each elemVehic In colMisVehic
If elemVehic.claseVehic = "Moto" Then
MsgBox "El vehculo tiene las siguientes caractersticas:" & vbCrLf & vbCrLf _
& "Clase: " & elemVehic.claseVehic & vbCrLf _
& "Nombre: " & elemVehic.nomVehic & vbCrLf _
& "Cilindrada: " & elemVehic.cilindrada & vbCrLf _
& "Capacidad del depsito: " & elemVehic.capacDep & vbCrLf _
& "Precio de llenado del depsito: " & elemVehic.costeDeposito(vPrecioCombustible), _
vbInformation, "DATOS"
End If
Next elemVehic
Case 3
For Each elemVehic In colMisVehic
If elemVehic.claseVehic = "Camin" Then
MsgBox "El vehculo tiene las siguientes caractersticas:" & vbCrLf & vbCrLf _
& "Clase: " & elemVehic.claseVehic & vbCrLf _
& "Nombre: " & elemVehic.nomVehic & vbCrLf _
& "Cilindrada: " & elemVehic.cilindrada & vbCrLf _
& "Capacidad del depsito: " & elemVehic.capacDep & vbCrLf _
& "Precio de llenado del depsito: " & elemVehic.costeDeposito(vPrecioCombustible), _
vbInformation, "DATOS"
End If
Next elemVehic
End Select
'Borramos los elementos de la coleccin
BorraColeccion:
Dim i As Long
For i = colMisVehic.Count To 1 Step -1 'Realizamos una cuenta atrs
colMisVehic.Remove (i)
Next i
End Sub
1.- Definimos las colecciones y los objetos, y los relacionamos, mediante dicha definicin, con
el mdulo de clase que hemos creado.
2.- Rellenamos los datos del elementos y lo aadimos a la coleccin.
3.- Repetimos el proceso de rellenado con todos los elementos que queramos.
4.- Solicitamos la informacin al usuario
5.- En funcin de lo que quiere ver el usuario (coche, moto o camin), para lo cual utilizamos
un SELECT CASE...END SELECT, recorremos los elementos de la coleccin a travs de un
bloque FOR EACH...NEXT
6.- En dicho bloque operamos con las propiedades de la clase que hemos creado (es decir, las
variables de nuestro tipo) y con los mtodos (es decir, con las dos funciones que habamos
definido en el mdulo de clase). En este caso la operacin es mostrar un MsgBox con la
informacin pertinente.
15
Vistame en http://siliconproject.com.ar/neckkito/
7.- Finalizado el proceso, borramos todos los elementos de la coleccin para dejarla vaca.
La pregunta que nos podra dar origen a esta explicacin es: qu pasa si el valor asignado a
capacidad del depsito de combustible no es correcta? Es decir, que, por error, introducimos
una capacidad de 10000 litros (que yo sepa, no hay ningn vehculo, dentro de los tipos de
vehculos sobre los que estamos trabajando, que pueda tener un depsito as: habra ms
depsito que vehculo!).
Tambin nos permite que una propiedad de una clase adopte un comportamiento determinado
en funcin de los parmetros que reciba.
PROPERTY LET
Mediante la instruccin PROPERTY LET generamos el cdigo encargado de gestionar las
caractersticas de la propiedad del elemento definido en la clase.
PROPERTY GET
Para poder obtener el valor asignado a la propiedad utilizaremos la instruccin PROPERTY GET.
16
Vistame en http://siliconproject.com.ar/neckkito/
Hablando en abstracto, podramos comparar un PROPERTY GET con una funcin, dado que
devuelve un valor.
Su estructura sera:
Public Property Get nombre(argumentos) As <tipo>
'Codigo
End Property
PROPERTY SET
Podemos asignar una propiedad mediante el property set. En este caso me remitir a la ayuda
de Access, que indica que utilizamos el PROPERTY SET para asignar una referencia a un objeto.
Manos a la obra...
Vamos a suponer que no hay vehculo (de los nuestros) que pueda tener un depsito superior
a los 500 litros. Aprovecharemos para comprobar tambin que no se nos haya colado un
depsito con capacidad negativa. El resto de elementos del cdigo sern los mismos.
En ese nuevo mdulo de clase escribimos el siguiente cdigo (ojo, marco en negrita lo nuevo;
el resto es como ya lo habamos escrito en el ejemplo del apartado anterior):
17
Vistame en http://siliconproject.com.ar/neckkito/
Select Case capacidad
'Si la capacidad es superior a 500 litros
Case Is > capacidadMax
Err.Raise 666, "clsVehic2", "La capacidad del depsito de
combustible no es real"
'Si la capacidad es negativa
Case Is < 0
Err.Raise 667, "clsVehic2", "La capacidad del depsito no
puede ser menor que cero"
Case Else
'Si no el valor es considerado correcto
p_capacDep = capacidad
End Select
End Property
La variable que nos hace de puente entre Property Let y Property Get la hemos
llamado p_capacDep, pero, atencin, la hemos definido como Private, para que su
mbito de actuacin sea slo a nivel de clase (es decir, que no es accesible desde otros
mdulos).
Sigamos: debemos crearnos un nuevo mdulo estndar para generar la coleccin que nos dar
la informacin de nuestros vehculos. A este nuevo mdulo lo llamaremos mdlVehic2. Para
simplificar slo rellenaremos un vehculo por tipo y los listaremos, sin pedir otra cosa al usuario
18
Vistame en http://siliconproject.com.ar/neckkito/
que el precio del combustible.
Option Compare Database
Option Explicit
19
Vistame en http://siliconproject.com.ar/neckkito/
BorraColeccion:
Dim i As Long
For i = colMisVehic.Count To 1 Step -1 'Realizamos una cuenta atrs
colMisVehic.Remove (i)
Next i
End Sub
Si hacemos click sobre ese botn (con el formulario en vista formulario) se nos solicitar el
precio del litro de combustible y nos enumerar, a travs de MsgBox, nuestros vehculos con
sus caractersticas.
Si ahora modificamos la capacidad del depsito de nuestro Porshe (la idea es que nos
equivocamos involuntariamente al determinar dicha capacidad) y escribimos:
With unVehiculo
.claseVehic = "Coche"
.nombre = "Porshe"
.tipo = "Carrera"
.cilindrada = 3000
.capacDep = 800.5
End With
.capacDep = -80.5
20
Vistame en http://siliconproject.com.ar/neckkito/
UNAS BREVES EXPLICACIONES TERICAS BASADAS EN TODO LO
ANTERIOR
Para profundizar en el marco terico en base al ejemplo anterior vamos a ponernos metafsicos
y vamos a hablar del alma y del cuerpo. Me vais a permitir esta pequea licencia porque me
viene que ni pintada para que podamos entender lo que os quiero transmitir. Adems, quin
os iba a decir que la religin servira para explicar VBA?5
Supongamos que existe una esencia universal (llammosle Dios, el Uno, el Todo...), y
supongamos que una persona humana, al nacer, est compuesto por un cuerpo fsico y un
alma que, en realidad, es una parte de dicha esencia universal. Es decir, que dicha alma es
individualizable pero al mismo tiempo es parte de un Todo.
Pues bien, nuestra clase sera esa esencia universal. A partir de ah podemos crear las
personas (=objetos) que necesitemos. Si yo creo el objeto <miVehiculo> y creo el objeto
<tuVehiculo> el cuerpo fsico de <miVehiculo> es diferente y diferenciable de <tuVehiculo>,
pero sus almas, aunque diferentes, son partes de una esencia universal (= clase).
Bajemos un nivel: mi cdigo VB y yo tomamos una gran decisin: vamos a tener un hijo. A
este hijo le vamos a poner de nombre <elHijoVehculo>.
La pregunta que nos hacemos en este punto es: existe <elHijoVehculo>? Y la respuesta es:
s existe a nivel mental, porque mi cdigo y yo as lo hemos decidido, pero an no existe a
nivel fsico porque an no ha sido concebido.
Y por fin vamos a poner sobre la mesa y en conjuncin todo este planteamiento con lo que
acabamos de programar en el ejemplo anterior:
1.- Creamos la esencia universal Eso se refleja en la creacin de la clase (creacin del
mdulo de clase).
5 Os ruego que tomis esta explicacin nicamente como lo que es: una explicacin. En ningn momento pretendo entrar en
valoraciones, ni crticas, ni desprecios, ni comparaciones. Al contrario, estos temas merecen todo mi respeto. Por favor, que nadie
le busque cinco pies al gato porque lejos de m est actuar con un nimo negativo, sino ser lo ms claro posible en la explicacin.
21
Vistame en http://siliconproject.com.ar/neckkito/
3.- Concebimos <elHijoVehculo> Eso se produce cuando hacemos
With elHijoVehiculo
.Pelo = Peln
.Nariz = Como la del padre
.Peso = 3 Kg
.Lloro = Muy llorn
End With
En definitiva, que a travs de todo lo anterior ya deberamos tener muy claro todo el proceso y,
si nos falla algo, tendremos una gua de pasos para detectar en qu fase podra estar el
error.
Imaginemos que yo tengo una clase, clsBebe, y defino un ejemplar de clase as:
With miBebe
.Caracter = Dulce
.Ojos = Llorones
End with
Caso A: rellenando directamente las propiedades (sin el Set miBebe = New clsBebe)
With miBebe
22
Vistame en http://siliconproject.com.ar/neckkito/
.Caracter = Grun
.Ojos = Desafiantes
End with
Caso A NO hemos obtenido otro beb, sino que lo que hemos hecho es mostrar mi beb en
su adolescencia
Es decir, que en el caso A no hemos creado uno nuevo, sino que, en el mismo beb, hemos
cambiado sus propiedades.
En el caso B tenamos un beb; a continuacin este ya ha dejado de existir para ser sustituido
por otro miBebe, con otras propiedades diferentes.
Vemos la diferencia?
Para mayor abundamiento os propongo que en el cdigo anterior (en el procedimiento Public
Sub misVehiculos) convirtis en comentarios todos los <Set unVehiculo = New clsVehic>,
exceptuando el primero, y ejecutis el cdigo. As podris ver qu grata sorpresa nos llevamos.
Dado que quiz ya entremos en terrenos algo complejos os recomiendo que no slo analicis
los cdigos que vendrn, sino tambin cmo se realiza el planteamiento del problema. Ni que
decir tiene que si el cdigo es tcnicamente perfecto pero el problema no est bien planteado y
planificado los resultados no van a ser satisfactorios.
He aqu el problema:
Vayamos analizando los elementos de que disponemos al tiempo que creamos nuestras tablas
en Access.
En primer lugar, crearemos una tabla que nos recoger los modelos y las caractersticas que
23
Vistame en http://siliconproject.com.ar/neckkito/
necesitamos. A esa tabla la llamaremos TAutos. Tendr la siguiente estructura (algunos
campos se podran haber desglosado en dos o ms, pero los he unificado a efectos de
simplificar al mximo y no hacer el ejemplo engorroso en demasa):
Fijaos que para los campos [GamaAuto], [TerrenoAuto] y [TipoCombAuto] lo ideal hubiera sido
crearnos tablas auxiliares con la informacin, y que nuestra TAuto hubiera chupado los datos
de dichas tablas auxiliares. Sin embargo, a efectos de simplificacin, nosotros escribiremos los
valores directamente.
Hagamos notar que el consumo medio se refiere al consumo en litros cada 100 kilmetros (por
si no quedaba claro qu significaba ese valor).
24
Vistame en http://siliconproject.com.ar/neckkito/
Nuestro cliente nos indicar cuntos das va a necesitar el vehculo Requeriremos de
una tabla auxiliar que nos d los precios por da, segn la gama, y que un trabajador
nuestro actualizar tan pronto como la empresa decida modificar esos
precios.
25
Vistame en http://siliconproject.com.ar/neckkito/
Espero que, hasta aqu, no nos hayamos perdido... je, je...
Veris que he programado un procedimiento PROPERTY para comprobar que no pueda haber
un consumo medio negativo o igual a cero.
Eso lo podra haber controlado a travs del campo [ConsumMedioAuto] de la tabla TAutos, con
una regla de validacin, pero como la idea es practicar las clases lo controlaremos desde aqu.
Como vemos, nuestra clase recoger toda la informacin que queremos proporcionar al cliente.
26
Vistame en http://siliconproject.com.ar/neckkito/
Para clarificar ideas digamos que:
Siguiente fase: creemos un mdulo estndar. A ese mdulo estandar lo llamaremos mdlAuto.
Qu va a hacer ese mdulo? Lo que va a hacer es un doble proceso, adornado con algunas
operaciones adicionales:
Uno: va a recoger toda la informacin de nuestra tabla TAutos y nos va a rellenar los datos
correspondientes a la clase
Dos: va a plasmar esos datos en una tabla temporal, para tener una base donde filtrar segn
las necesidades del cliente y a travs de la cual podremos preparar un informe para
entregrselo a nuestro seguro consumidor.
'Defino la BD de trabajo
Set dbs = CurrentDb
'En primer lugar debemos comprobar si la tabla ya existe. Si existe debemos
'borrarla para que no nos d error de cdigo
For Each tbl In CurrentData.AllTables
If tbl.Name = nomTablaAux Then
DoCmd.DeleteObject acTable, nomTablaAux
Exit For
End If
Next tbl
'Creamos la estructura de la tabla a travs de una SQL. La escribo estructurada
'en lneas para que apreciemos perfectamente los campos que se crearn
'Para relacionarlo con el cdigo posterior, tened en cuenta que:
27
Vistame en http://siliconproject.com.ar/neckkito/
'Nombre -> Ser el Field(0); Gama -> Ser el Field(1); ... ; PrecioAlquiler ->
'Ser el Field(6)
miSql = "CREATE TABLE " & nomTablaAux & " (" _
& "Nombre STRING," _
& "Gama STRING," _
& "Terreno STRING," _
& "TipoCombustible STRING," _
& "PrevGtoComb CURRENCY," _
& "Sobreprima CURRENCY," _
& "PrecioAlquiler CURRENCY" _
& ")"
'Creamos la tabla a travs de la ejecucin de la SQL
dbs.Execute miSql
Fijaos en cmo se me ha ocurrido articular el proceso: como un obrero en medio de dos cintas
de montaje: por una de las cintas (rstIN) llega un paquete (la tabla TAutos), nuestro obrero (la
clase) le pone los lacitos para dejarlo guapo y lo deposita sobre la otra cinta (rstOUT) listo
28
Vistame en http://siliconproject.com.ar/neckkito/
para servir.
...
'Relleno los datos 'fijos' con la informacin del registro
...
para dichos datos 'fijos', y con los datos variables hemos necesitado, simplemente recuperar el
valor de los argumentos a travs de las variables buscoXXX y pasrselos al mtodo, a travs
de las lneas
Tambin fijaos en que los datos externos, que deben ser proporcionados por nuestro cliente
(previsin de kilmetros a recorrer y das que quiere alquilar el vehculo) y que, lgicamente,
no sabemos a priori, los paso como argumentos del procedimiento, a travs de
Sigamos: para el proceso que sigue vamos a necesitar que la tabla auxiliar TAuxInfoCliente
est creada. Para ello creamos, en el mismo mdulo de trabajo mdlAuto, un procedimiento que
eliminaremos tras su ejecucin (o, si no queremos eliminarlo, podemos convertir en
comentario), y que ser el mismo del cdigo anterior con unas ligersimas modificaciones
(prcticamente es un copy-paste de un fragmento del cdigo anterior; os marco en negrita lo
que se debe cambiar, que est hacia el final del cdigo):
29
Vistame en http://siliconproject.com.ar/neckkito/
Private Sub creoTablaPorPrimeraVez()
'Creamos la estructura de la tabla a travs de una SQL.
miSql = "CREATE TABLE " & nomTablaAux & " (" _
& "Nombre STRING," _
& "Gama STRING," _
& "Terreno STRING," _
& "TipoCombustible STRING," _
& "PrevGtoComb CURRENCY," _
& "Sobreprima CURRENCY," _
& "PrecioAlquiler CURRENCY" _
& ")"
'Creamos la tabla a travs de la ejecucin de la SQL
CurrentDb.Execute miSql
End Sub
Nos situamos sobre ese Sub y pulsamos F5. Nuestra tabla se crear. Ya podemos borrar el
cdigo, o convertirlo en comentario. Tened en cuenta que:
Y ya llegamos a la fase en el que el usuario tendr una participacin activa. Vamos a crearnos
un formulario en blanco que llamaremos FInfoCliente. Yo lo crear con TextBox para simplificar,
pero lgicamente ya sabramos crear otros controles, como cuadros combinados o cuadros de
lista, para hacerlo ms atractivo y eficiente de cara al usuario. Lo que haremos ser lo
siguiente:
30
Vistame en http://siliconproject.com.ar/neckkito/
Por cierto, y por si alguien no lo sabe, para establecer el texto de la ayuda contextual debemos
ir a las propiedades del control Otras Texto de Ayuda del control
Private Sub cmdAbreRAuxInfoCliente_Click()
'Declaramos las variables
Dim vGama As String, vTerreno As String
Dim vKm As Long, vDias As Integer
Dim filtroDeseosCliente As String
'Asignamos valor a las variables
vGama = Me.txtGama.Value
vTerreno = Me.txtTerreno.Value
vKm = Me.txtKm.Value
vDias = Me.txtDiasAlq.Value
'Llamamos al procedimiento creoTAux, asignndole los parmetros requeridos
Call creoTAux(vKm, vDias)
'Creo el filtro para abrir el informe
filtroDeseosCliente = "[Gama]='" & vGama & "' AND [Terreno]='" & vTerreno & "'"
'Abro el informe, filtrndolo por las peticiones del cliente
DoCmd.OpenReport "RAuxInfoCliente", acViewPreview, , filtroDeseosCliente
End Sub
Y creo que ya est. Esta vez no dir aquello de... fcil, verdad?
Alguien me podra objetar: para desarrollar este ltimo ejemplo se podran haber utilizado
otros mtodos, y quiz no tan complicados, y yo dir: Totalmente de acuerdo... si slo nos
centramos en el ejemplo. Pero la gracia de lo anterior es que nuestra futura aplicacin no es
slo darle la informacin que hemos comentado al cliente, sino que, hipotticamente, la BD
nos servira para gestionar nuestro negocio. Y la pregunta es: Si, por ejemplo, tenemos que
emitir una factura al cliente, deberamos volver a calcular todo de nuevo mediante cdigo? O,
si por ejemplo, un histrico nos muestra una media de das que se alquila un coche de una
determinada gama, y una media de kilmetros que realiza dicho automvil, y queremos sacar
una previsin de cara al ao siguiente, debemos volver a realizar por tercera vez todos los
clculos? No es mejor tener los clculos y datos clave recogidos en nuestra clase, y acceder
a ella cuando los necesitemos? Porque as slo necesitamos programar dichos clculos una sola
vez, no es cierto?
En fin... que creo que, segn cmo sea nuestro proyecto, la utilizacin de clases es un recurso
31
Vistame en http://siliconproject.com.ar/neckkito/
muy til... y ahora ya sabemos cmo manejarlo.
Espero que lo que hayis podido aprender de este captulo os sea til.
Un saludo y...
suerte!
32
Vistame en http://siliconproject.com.ar/neckkito/