Con la versión 6 de Visual Basic, se pueden usar tipos definidos por el usuario de forma pública como parámetros de las funciones, propiedades y procedimientos (subs), tanto en módulos BAS como en módulos de clases (CLS), además de poder usarse también como tipo de datos devuelto por una función.
NOTA (18/Nov/98):
En VB5, no recuerdo si también en VB4, las funciones públicas declaradas en módulos BAS, permitían devolver tipos definidos por el usuario y también aceptarlos como parámetro de un procedimiento...
Esta nota no la puse antes, porque "nunca" he usado tipos definidos como parámetro ni como valor devuelto por una función, es decir que ni lo sabia...
Agradezco a Harvey Triana por haberme "hecho" leer la ayuda del VB5...
Creo que algunas veces me tendría que aplicar yo el "parche" y hacer lo que recomiendo a otros... je, jeVamos a ver algunos ejemplos para comprobar que es cierto... (que no siempre es bueno creerse todo lo que nos dicen...)
Usar los tipos definidos públicamente como parámetros de funciones:
Procedimientos públicos declarados en módulos BAS.
Métodos (procedimientos) y propiedades de módulos de clases (CLS)
Usar tipos definidos como el tipo devuelto por una función:
En módulos BAS
En módulos de clase (CLS)
Usar los tipos definidos públicamente como parámetros de funciones:
En primer lugar, esto servirá para el resto de los ejemplos, hay que declarar el tipo que se va a usar en los distintos módulos normales y de clases, para ello tendrás que insertar en el proyecto un módulo estándard (BAS) y añadir esta declaración:
'Tipo con Strings de longitud fija y variable Public Type tColega Nombre As String * 50 'Nombre del colega email As String * 50 ' Url As String 'Página Web AñoNac As Long 'Año de nacimiento Modificado As Date 'Fecha de último acceso End Type
Parámetros en procedimientos públicos declarados en módulos BAS.
Ahora vamos a usar el tipo definido anteriormente como parámetro de un procedimiento (un SUB y una función), declarados en un módulo estándard (BAS)
Tendremos una función que devuelve la Edad del colega, se pasa como parámetro una variable del tipo tColega.
Veamos el código de esta función:
Public Function Edad(elColega As tColega) As Long 'Devuelve la edad del colega que se ha pasado como parámetro 'y actualiza la fecha de modificación. Dim tEdad As Long tEdad = Year(Now) - elColega.AñoNac elColega.Modificado = Now Edad = tEdad End Function
Función en módulo BAS que devuelve un tipo definido:
Esta función nos permitirá crear nuevos datos, en este caso la función devolverá un tipo tColega.
Public Function NuevoColega( _ ByVal sNombre As String, ByVal lngAñoNac As Long, _ ByVal sEmail As String, ByVal sUrl As String) As tColega 'Devuelve un elemento del tipo tColega 'Se usan los datos pasados como parámetro 'Usamos una variable temporal para asignar los datos Dim tmpColega As tColega With tmpColega .Nombre = sNombre .AñoNac = lngAñoNac .email = sEmail .Url = sUrl .Modificado = Now End With 'Devolver el dato NuevoColega = tmpColega End Function
Los tipos definidos en los módulos de clase (CLS):
Para usar los tipos definidos por el usuario en los módulos de clases, se puede hacer de dos formas:
- Si el módulo CLS no es público, es decir: pertenece al proyecto en el que se usa esa clase.
- Si el módulo pertenece a un componente público, por ejemplo una DLL ActiveX.
Si el módulo de clase (CLS) no es público,
es decir: pertenece al proyecto en el que se usa esa clase.En las clases privadas se usan de igual forma que en los módulos BAS, pero con la diferencia de que las funciones, Subs o propiedades que la usen NO PUEDEN SER PÚBLICAS, eso no quiere decir que tengan que ser PRIVADAS, ya que desde la versión 5 existe otro tipo de "visibilidad" de los métodos y propiedades de las clases, y por extensión de cualquier tipo de módulo usado en Visual Basic, que es: FRIEND.
Un procedimiento declarado como Friend es "casi" público, pero sólo dentro del propio proyecto, ya que si realmente fuesen públicos podrían ser accesible desde otro proyecto, cosa que no ocurre con los procedimientos "amigos"...Osea que se usan de igual forma que los ejemplos mostrados para usar en un módulo BAS, salvo que en lugar de declararse como Public se declaran como Friend, además en un módulo de clase NO se puede declarar un Tipo Definido de forma pública, siempre tienen que ser Privados.
Por tanto las funciones quedarían así:
Friend Function Edad2(elColega As tColega) As Long 'Devuelve la edad del colega que se ha pasado como parámetro 'y actualiza la fecha de modificación. Dim tEdad As Long tEdad = Year(Now) - elColega.AñoNac elColega.Modificado = Now Edad2 = tEdad End Function Friend Function NuevoColega2( _ ByVal sNombre As String, ByVal lngAñoNac As Long, _ ByVal sEmail As String, ByVal sUrl As String) As tColega 'Devuelve un elemento del tipo tColega, 'que es el declarado en el módulo BAS. 'Se usan los datos pasados como parámetro 'Usamos una variable temporal para asignar los datos Dim tmpColega As tColega With tmpColega .Nombre = sNombre .AñoNac = lngAñoNac .email = sEmail .Url = sUrl .Modificado = Now End With 'Devolver el dato NuevoColega2 = tmpColega End FunctionPara usarlo desde un formulario habría que hacerlo así:
' 'Declaración de la clase de prueba Private m_colega As ctestUDT 'En el Form_Load: 'Creamos el objeto... Set m_colega = New ctestUDT 'Crear un par de colegas para tenerlos en el listBox 'Es conveniente que antes de hacer el Redim Preserve 'el array esté ya dimensionado... 'ya que he leido en algún sitio que puede dar ERROR numColegas = numColegas + 1 ReDim Preserve variosColegas(0 To numColegas) 'Usando el método de la clase: variosColegas(numColegas) = _ m_colega.NuevoColega2( _ "Guille", 1957, "[email protected]", _ "http://www.elguille.info/") 'Usamos el método de la clase Label1(5) = " Edad:" & m_colega.Edad2(variosColegas(queColega)) & " tacos" 'Mostrar el colega número "i" With variosColegas(i) List1.AddItem .Nombre & vbTab & .AñoNac & vbTab & _ .email & vbTab & _ Left$(.Url & Space$(64), 64) & vbTab & _ Format$(.Modificado, "dd/mmm/yyyy hh:mm:ss") End With
Si el módulo de clase pertenece a un componente público, por ejemplo una DLL ActiveX.
Cuando se crea un componente ActiveX, el tipo definido por el usuario debe declararse público en un módulo de clase, la peguilla es que no puede tener cadenas de longitud fija, pero eso es un mal menor.
En estos casos, si que se pueden tener propiedades y métodos públicos, (además de los privados y Friends), que devuelvan tipos definidos.Veamos cómo hacerlo.
Hay que crear un proyecto ActiveX DLL, (por ejemplo), incluir un módulo BAS con una procedimiento público llamado Main y un módulo de clase, por defecto tendrá la propiedad Instancing con valor 5-MultiUse), en el que estarán las funciones y propiedades a usar en ese "componente"; por supuesto también estará el tipo definido...
Vamos a ver el código (la clase al completo y una parte del form de prueba)
'------------------------------------------------------------------ 'Módulo CLS para usar Tipos definidos públicamente (18/Nov/98) ' '--- Esta clase forma parte de una ActiveX DLL --- ' '©Guillermo 'guille' Som, 1998 '------------------------------------------------------------------ Option Explicit 'Los tipos definidos en clases públicas no pueden tener cadenas 'de longitud fija Public Type tColega Nombre As String 'Nombre del colega email As String ' Url As String 'Página Web AñoNac As Long 'Año de nacimiento Modificado As Date 'Fecha de último acceso End Type Private tmpColega As tColega Public Property Get UltimoColega() As tColega 'Devolver el último colega que se ha añadido UltimoColega = tmpColega End Property Public Function NuevoColega3( _ ByVal sNombre As String, ByVal lngAñoNac As Long, _ ByVal sEmail As String, ByVal sUrl As String) As tColega 'Devuelve un elemento del tipo tColega, 'que es el declarado en el módulo BAS. 'Se usan los datos pasados como parámetro 'Usamos una variable temporal para asignar los datos '---ahora está declarada a nivel de módulo ' para guardar el último que se ha añadido--- 'Dim tmpColega As tColega With tmpColega .Nombre = sNombre .AñoNac = lngAñoNac .email = sEmail .Url = sUrl .Modificado = Now End With 'Devolver el dato NuevoColega3 = tmpColega End Function Public Function Edad3(elColega As tColega) As Long 'Devuelve la edad del colega que se ha pasado como parámetro 'y actualiza la fecha de modificación. Dim tEdad As Long tEdad = Year(Now) - elColega.AñoNac elColega.Modificado = Now Edad3 = tEdad End Function' 'Declaración de la clase de prueba. '--- Hay que tener una referencia a la librería ActiveX DLL Private m_colega As cUDT3 'En el form_Load: 'Creamos el objeto... Set m_colega = New cUDT3 'Añadimos algunos datos... 'Es conveniente que antes de hacer el Redim Preserve 'el array esté ya dimensionado... 'ya que he leido en algún sitio que puede dar ERROR numColegas = numColegas + 1 ReDim Preserve variosColegas(0 To numColegas) 'Usando el método de la clase: variosColegas(numColegas) = _ m_colega.NuevoColega3( _ "Guille", 1957, "[email protected]", _ "http://www.elguille.info/") 'Para añadir los datos a un ListBox, se puede hacer algo como esto: Private Sub MostrarColegas() Dim i As Long List1.Clear 'Mostrar los colegas For i = 1 To numColegas With variosColegas(i) 'Como ahora son cadenas de longitud variable, 'hay que formatear lo que se muestra: List1.AddItem _ Left$(.Nombre & Space$(50), 50) & vbTab & _ Format$(.AñoNac, "0000") & vbTab & _ Left$(.email & Space$(50), 50) & vbTab & _ Left$(.Url & Space$(64), 64) & vbTab & _ Format$(.Modificado, "dd/mmm/yyyy hh:mm:ss") End With Next End Sub
Si quieres bajarte los listados de ejemplos, pincha en estos links:
Ejemplo para usar en VB5, UDT_vb5.zip 3.94 KB Ejemplo usando módulo BAS, (igual que el de VB5), UDT1.zip 3.95 KB Ejemplo usando clase privada, UDT2.zip 5.14 KB Ejemplo usando clase pública, ActiveX DLL, UDT3.zip 5.51 KB Todos los ejemplos, UDT.zip 18.9 KB
Características del lenguaje | Visual Basic 6: Nuevas características |