VBA – Módulos de clase
In this Article
- Módulos de Clase VBA – Introducción
- Inserción de un módulo de clase
- Creación de un objeto
- Creación de una Colección
- Utilización de su nuevo objeto
- Resumen de la creación de un objeto utilizando un módulo de clase
- Uso de un Módulo de Clase para Crear un Repositorio de Variables
- Convirtiendo su Objeto en un Add-In
Este tutorial le enseñará sobre los Módulos de Clase en VBA. Aprenderá qué son y cómo utilizarlos.
Módulos de Clase VBA – Introducción
Cuando usted inserta módulos en el Editor de Visual Basic (VBE) para introducir su código, puede haber notado que también puede insertar lo que se llama un ‘Módulo de Clase’.
Módulos de Clase vs. Módulos
Los módulos de clase funcionan de una manera muy diferente a los módulos ordinarios en el sentido de que facilitan la creación de un Modelo de Objeto de Componente (COM) que luego puede ser utilizado dentro de su código VBA normal.
Efectivamente, usted crea un objeto que funciona de la misma manera que un objeto incorporado de Excel como ‘Worksheets’. En el objeto Worksheets, tiene una serie de propiedades y métodos que le permiten obtener el número de hojas de trabajo dentro de un libro de trabajo o cada nombre individual de una hoja de trabajo, o numerosas otras informaciones.
Cuando creas un nuevo Objeto de esta manera, estás creando un bloque de construcción que puede ser utilizado en cualquier lugar dentro de VBA. El objeto tiene una serie de propiedades y métodos a los que puede acceder su código VBA desde cualquier lugar del libro de trabajo sin tener que volver a escribir el código.
Además de referirse a su nuevo objeto desde un módulo VBA estándar, también puede utilizarlo en el código detrás de un Formulario que es parte de su aplicación personalizada.
También puede utilizarlo cuando haya colocado controles Active X en una hoja de cálculo, como un botón de comando o un desplegable. Todos estos controles utilizan VBA, y su nuevo objeto puede incorporarse fácilmente al código de eventos de estos controles.
También puede convertir su objeto en un complemento de Excel. Su objeto estará automáticamente disponible para otros usuarios que tengan ese complemento cargado. Esto añade su propia arquitectura de varios niveles a su aplicación de Excel.
Excel es una aplicación de varios niveles. Está la capa de servicios al cliente, que maneja la ventana de la hoja de trabajo con la que el usuario está familiarizado. El modelo de objetos de Excel es la siguiente capa por debajo. Presione F2 en un módulo VBA y podrá ver el enorme número de objetos y miembros de esos objetos que son el motor de Excel. Tenga en cuenta que su nuevo objeto también se mostrará aquí.
Finalmente, debajo de todo esto, tienes la capa de servicios de datos que contiene todos los datos que has introducido en las hojas de trabajo y celdas. Excel accede a esto utilizando el modelo de objetos de Excel.
La creación de un módulo de clase le permite ampliar el módulo de objetos de Excel con sus propios objetos y miembros personalizados.
Este artículo le explica cómo crear una jerarquía simple de objetos utilizando Módulos de Clase.
Ventajas del uso de los módulos de clase
- Puede desarrollar un bloque de construcción robusto que puede ser utilizado en cualquier número de aplicaciones de Excel diferentes
- Una vez que se ha probado a fondo, se puede confiar en que siempre producirá los resultados correctos de la misma manera que los objetos de Excel incorporados
- Si se actualiza el código en otra parte de la aplicación, el nuevo objeto seguirá funcionando de la misma manera
- Se puede utilizar el nuevo objeto en otras aplicaciones de Excel como complemento
- Los objetos pueden ser reutilizados en otras aplicaciones y ayuda a la depuración
Desventajas del uso de módulos de clase
- Pueden ser difíciles de crear y entender.
- Las convenciones de nomenclatura son muy importantes porque esto es lo que verá cuando utilice su objeto dentro de un módulo normal.
- Si no ha creado un módulo de clase antes, pueden ser difíciles de entender y hay una curva de aprendizaje empinada
- Imposible hacer cambios en tiempo de ejecución – tiene que volver a configurar el proyecto.
- Si las propiedades y las variables privadas tienen el mismo nombre, pueden producirse bucles infinitos que den lugar a errores
Inserción de un módulo de clase
Seleccione Insertar | Módulo de Clase en el menú VBE (Editor de Visual Basic). El nuevo Módulo de Clase se llamará automáticamente ‘Clase 1’, pero es necesario cambiarlo inmediatamente por el nombre que vaya a utilizar para su objeto
Usted cambia el nombre en la ventana de Propiedades donde la flecha está apuntando. Simplemente escriba su nuevo nombre, y éste cambiará en la colección de Módulos de Clase.
Si la ventana de Propiedades no es visible, seleccione Ver | Propiedades en el menú VBE o pulse F4.
Llame a su nuevo módulo de clase ‘MyItem’ y haga doble clic en el nombre en la vista de árbol en el Explorador de Proyectos para mostrar la ventana de código para él.
Creación de un objeto
Este ejemplo creará un objeto de nivel superior llamado ‘MyItems’ con un objeto miembro debajo llamado ‘MyItem’ que contendrá los datos individuales de cada elemento. Una vez creado, funcionará de la misma manera que un objeto Excel incorporado. Por ejemplo, hay un objeto llamado ‘Worksheets’ que es una colección de cada hoja de trabajo dentro de su libro. También hay un objeto llamado ‘Sheet’ que representa cada hoja de trabajo individual dentro de su libro de trabajo, y contiene todas las propiedades y métodos para cada hoja de trabajo. Este objeto se relaciona con el objeto de colección «Worksheets».
Puede iterar a través de la colección ‘Worksheets’, viendo cada ‘Sheet’ por turno. De la misma manera, podrá iterar por la colección ‘MyItems’ viendo las propiedades que ha creado en el miembro ‘Myitem’.
Lo primero que hay que hacer es crear el subobjeto para el nivel de miembros que contendrá los elementos reales dentro de la colección del objeto de nivel superior. Esto es el equivalente a los miembros (por ejemplo, nombre, visible, recuento) dentro del objeto ‘Sheet’ en Excel. Este código se introduce en el módulo de clase llamado ‘MyItem’.
Los módulos de clase tienen propiedades y métodos. Las propiedades son efectivamente como las variables, en el sentido de que mantienen los valores de los datos como las variables, y los métodos son como las sub-rutinas o funciones.
En el subobjeto vamos a crear dos propiedades para el objeto – Item y Detail
Inicialmente hay que declarar dos variables de tipo string para mantener los valores de las propiedades:
Private mItem As String
Private mDetail As String
Estas deben ser declaradas en la sección de Declaraciones en la parte superior del código del módulo de la clase para que puedan ser utilizadas en todas las sub-rutinas a lo largo del módulo
Hay que darles nombres únicos para que sean diferentes de las propiedades que vamos a crear, por lo que se ha puesto una ‘m’ (de miembro) delante de cada nombre.
Las variables se declaran como Private para que no puedan ser vistas por nadie que utilice el objeto. Son variables de trabajo para usar dentro del código del objeto y no están ahí como parte del objeto final.
El siguiente paso es configurar el código para dar acceso a las dos propiedades. Esto se hace mediante una sentencia Property Let y una Property Get para cada propiedad. Estas deben ser Public, de lo contrario el objeto de nivel superior no tendrá ninguna propiedad visible
Public Property Let Item(vdata As String)
mItem = vdata
End Property
Public Property Get Item () As String
Item = mItem
End Property
Public Property Let Detail (vdata As String)
mDetail = vdata
End Property
Public Property Get Detail () As String
Detail = mDetail
End Property
Este código crea los medios para leer y escribir valores en las dos propiedades (Item y Detail) utilizando las dos variables privadas que se definieron en la sección de declaraciones del módulo.
El parámetro ‘vdata’ se utiliza para pasar los datos a la propiedad en cuestión.
Es importante que cada propiedad tenga una declaración ‘Let’ y ‘Get’ y que el nombre de la propiedad sea el mismo en cada caso. Podrías terminar con dos propiedades diferentes si estás mal escrito – ¡una de la que puedes leer y otra en la que puedes escribir!
Para ayudarte a crear este código, puedes usar Insertar | Procedimiento en el menú VBE para crear un esqueleto de código que creará el código inicial para las propiedades ‘Get’ y ‘Let’ para un nombre de propiedad dado
Esto mostrará una ventana emergente en la que puedes escribir el nombre de la propiedad y seleccionar ‘Property’ en los botones de opción:
Haz clic en ‘OK’ y el código del esqueleto se añadirá al módulo de la clase:
Public Property Get MyProperty() As Variant
End Property
Public Property Let MyProperty(ByVal vNewValue As Variant)
End Property
Esto evita cualquier error sobre los nombres de las propiedades. Simplemente añada su código entre las declaraciones ‘Public Property’ y ‘End Property’.
Ahora tiene un objeto llamado ‘MyItem’ que contendrá todos los datos para este ejercicio.
Creación de una Colección
La siguiente etapa consiste en crear un objeto de nivel superior como objeto Collection para dar acceso a las propiedades que has configurado en el objeto ‘MyItem’ De nuevo, necesitas definir un objeto de trabajo para que actúe como objeto de colección de la misma manera que definiste las dos variables de cadena en el objeto ‘MyItem’.
Private mItems As Collection
De nuevo, esto tiene que tener un nombre único, por lo que hay una ‘m’ (miembro del objeto) delante del nombre, y también se declara como ‘Private’ para que no aparezca cuando se utilice el nuevo objeto A continuación, tienes que rellenar el código Class_Initialize. Esto se ejecuta cuando se utiliza por primera vez el objeto dentro de su código, y determina qué valores se cargarán en el objeto Puedes acceder a esta sub-rutina seleccionando ‘Class’ en el primer desplegable y ‘Initialize’ en el segundo desplegable de la ventana del módulo
Private Sub Class_Initialize()
Dim objItem As MyItem
Set mItems = New Collection
For N = 1 To 3
Set objItem = New MyItem
objItem.Item = Worksheets("Hoja1").Range("a" & N).Value
objItem.Detail = Worksheets("Hoja1").Range("b" & N).Value
mItems.Add objItem
Next N
End Sub
El código crea un objeto llamado ‘objItem’ utilizando la definición de ‘MyItem’ que construimos como un módulo de clase anteriormente.
A continuación, crea una nueva colección basada en el objeto «mItems» definido anteriormente
Recorre los valores de la Hoja1 del libro de trabajo y los pone en las propiedades que hemos creado para el objeto «MyItem». Fíjate que cuando usas ‘objItem’, aparece un desplegable mostrando las dos propiedades, exactamente como si estuvieras usando un objeto de Excel incorporado.
El objeto ‘objItem’ se añade entonces al objeto ‘collection’ que ahora contiene todos los datos de los valores de las propiedades.
Los datos de entrada no tienen que ser tomados de una hoja de cálculo. Pueden ser valores estáticos, o pueden venir de una conexión a una base de datos como Microsoft Access o SQL Server, o pueden venir de otra hoja de cálculo.
A continuación, es necesario añadir una función pública llamada ‘Item’
Public Function Item(index As Integer) As MyItem
Set Item = mItems.Item(index)
End Function
Esto le permite referirse a objetos individuales dentro del objeto de la colección por su número de índice. Esta función proporciona un «espejo» de lo que está sucediendo en la colección ‘mItems’ en el fondo.
También tendrá que añadir una propiedad llamada ‘Count’ para que su código pueda establecer cuántos objetos ‘MyItem’ hay en la colección ‘mItems’, si desea iterar a través de ella.
Public Property Get Count() As Long
Count = mItems.Count
End Property
En este caso sólo necesita una propiedad ‘Get’ porque es de sólo lectura. Utiliza la colección mItems porque ésta ya tiene una propiedad count incorporada.
Ahora tienes un objeto (mItems) con una jerarquía completa definida por el objeto ‘MyItem’
Para que todo esto funcione, ahora necesitas rellenar una hoja de cálculo (Hoja1) con datos para que la rutina Class Initialize pueda recogerlos en el objeto This.
Tu hoja de cálculo debería tener este aspecto:
Utilización de su nuevo objeto
Ahora puede utilizar su objeto Collection (MyItems) dentro de un módulo VBA estándar de Excel. Introduzca el siguiente código:
Sub test_object()
Dim MyClass As New MyItems, n As Integer
MsgBox MyClass.Count
For n = 1 To MyClass.Count
MsgBox MyClass.Item(n).Item
MsgBox MyClass.Item(n).Detail
Next n
End Sub
Este código crea un objeto llamado ‘MyClass’ basado en el objeto de colección que creó llamado ‘MItems’. Esto dispara la rutina ‘Initialize’ que extrae todos los datos de la hoja de cálculo en el objeto.
Muestra el número de ítems en la colección y luego itera a través de la colección mostrando el texto ‘Item’ y el texto ‘Detail’. Notarás que cuando te refieras al objeto ‘MyClass’ en tu código, verás una lista de las dos propiedades miembro que ayuda a añadir la propiedad correcta.
Si cambias el valor de una celda en los datos de entrada de la hoja de cálculo, se actualizará automáticamente en la colección cuando vuelvas a ejecutar el código anterior, ya que cuando dimensionas el objeto, la rutina de inicialización se ejecuta y recoge todos los nuevos datos
Si utilizas la palabra ‘Static’ en lugar de ‘Dim’ la rutina de inicialización no se ejecuta y se mantienen los valores antiguos, mientras el código se ejecute continuamente. Si los datos de la hoja de cálculo cambian esto no se reflejará en el objeto
Sub Test_Static()
Static Myclass As New MyItems, n As Integer
For n = 1 To Myclass.Count
MsgBox Myclass.Item(n).Item
MsgBox Myclass.Item(n).Detail
Next n
End Sub
Resumen de la creación de un objeto utilizando un módulo de clase
Como ha visto, la creación de una jerarquía de módulos de clase para usar como objeto es un asunto bastante complicado, incluso para una estructura tan simple como el ejemplo proporcionado aquí. Las posibilidades de cometer errores son enormes
Sin embargo, tiene enormes ventajas al hacer su código más elegante y más fácil de leer. También es más fácil compartirlo con otras aplicaciones y desarrolladores de Excel al convertirlo en un Add-In.
En este ejemplo de cómo crear un objeto para contener datos, lo normal sería crear un array multidimensional para contener los datos de la hoja de cálculo de varias columnas, y escribir una línea de código para actualizar o leer cada elemento del array. Esto probablemente terminaría siendo bastante desordenado, y se podrían cometer errores fácilmente al abordar los distintos elementos.
Con tu nuevo objeto, puedes simplemente referirte a él y a los miembros que has creado debajo para mantener los datos.
Además, si los datos cambian en la hoja de cálculo (o en una base de datos vinculada si la has utilizado como fuente de datos dentro de tu módulo de clase) cada vez que utilices la sentencia ‘Dim’ se llamará a la rutina de inicialización y los datos se actualizarán instantáneamente. No es necesario escribir código para repoblar el array.
Uso de un Módulo de Clase para Crear un Repositorio de Variables
Cuando escribes código VBA utilizas variables por todas partes, todas con diferentes alcances. Algunas pueden estar definidas sólo para un procedimiento en particular, otras para un módulo en particular, y otras pueden ser variables globales que pueden ser utilizadas en toda la aplicación
Puedes crear un módulo de clase que contenga un gran número de variables, y como es un objeto, puede ser utilizado en cualquier parte de tu código, incluso en un formulario de usuario o en un control Active X que hayas colocado en una hoja de cálculo.
La ventaja añadida es que cuando te refieras a tu objeto variable, verás una lista de todos los nombres de las variables que contiene el objeto ordenados de forma ascendente.
Para crear un repositorio, necesita insertar un nuevo módulo de clase. Esto se hace usando Insertar | Módulo de clase en el menú del Editor VB
Cambia el nombre a ‘MyVariables’ utilizando la misma metodología que se ha comentado anteriormente en este artículo.
Introduce el siguiente código:
Private mV As Variant
Public Property Get Variable1() As Variant
Variable1 = mV
End Property
Public Property Let Variable1(ByVal vNewValue As Variant)
mV = vNewValue
End Property
Public Property Get Variable2() As Variant
Variable1 = mV
End Property
Public Property Let Variable2(ByVal vNewValue As Variant)
mV = vNewValue
End Property
Este código establece las propiedades ‘Let’ y ‘Get’ para dos variables (‘Variable1’ y ‘Variable2’). Las propiedades Let y Get son necesarias para cada una de tus variables para que sean de lectura/escritura
Puedes usar tus propios nombres para las variables en lugar de los de ejemplo en este código, y puedes añadir más variables, asegurándote de que cada nueva variable tiene una declaración ‘Let’ y ‘Get’.
La declaración privada de la variable ‘mV’ es para crear una variable de trabajo que sólo se utiliza dentro del módulo de la clase para transferir valores.
Para utilizar el repositorio de variables, introduzca el siguiente código en un módulo estándar:
Global VarRepo As New MyVariables
Sub TestVariableRepository()
MsgBox VarRepo.Variable1
VarRepo.Variable1 = 10
MsgBox VarRepo.Variable1
End Sub
Este código crea una instancia global de su objeto ‘MyVariables’ que ha creado. Sólo necesita hacer esta declaración una vez desde cualquier lugar de su código.
El código primero muestra el valor de ‘Variable1’ para mostrar que está vacío.
Se asigna un valor de 10 a ‘Variable1’ y se muestra el nuevo valor dentro del objeto para mostrar que esta propiedad tiene ahora este valor.
Como la instancia del objeto ‘MyVariables’ ha sido definida globalmente, puedes referirte a cualquiera de las variables definidas dentro del objeto desde cualquier lugar de tu código.
Esto tiene una gran ventaja, ya que si quieres usar tus variables en cualquier parte de tu código, sólo necesitas definir una variable global, y desde esa instancia, todas las variables pueden ser accedidas y modificadas libremente en todo tu código.
Convirtiendo su Objeto en un Add-In
Hasta ahora, el código para la creación de objetos está dentro de la aplicación del libro de trabajo. Sin embargo, si quieres poder compartir tu objeto con otros desarrolladores o en otras aplicaciones de Excel propias, puedes convertirlo en un Add-In
Para ello, lo único que hay que hacer es guardar el archivo como un Add-In. Seleccione Archivo | Guardar como y aparecerá una ventana del navegador
Seleccione el tipo de archivo como Add-In (.xlam) en el menú desplegable de tipo de archivo y haga clic en Aceptar. El archivo se guardará en la carpeta del complemento por defecto, pero puede cambiar la ubicación.
A continuación, podrá incorporar el archivo del complemento a sus aplicaciones de Excel, lo que le proporcionará la flexibilidad necesaria para hacer uso de su nuevo objeto
Para incluir su nuevo complemento en Excel, haga clic en Archivo en la cinta de Excel y, a continuación, en Opciones en la parte inferior del panel izquierdo
Haga clic en «Complementos» en el panel de la izquierda en la ventana emergente que aparece. En la parte inferior de la ventana hay un botón marcado como «Ir»
Haga clic en él y aparecerá una ventana emergente de «Complementos». Haga clic en «Examinar» y localice el archivo del complemento. Entonces podrá referirse a su objeto en su código.