VBA
Creación de una clase personalizada
Buscar..
Observaciones
Este artículo mostrará cómo crear una clase personalizada completa en VBA. Utiliza el ejemplo de un objeto DateRange , porque las fechas de inicio y finalización a menudo se pasan juntas a las funciones.
Agregar una propiedad a una clase
Un procedimiento de Property es una serie de sentencias que recupera o modifica una propiedad personalizada en un módulo.
Hay tres tipos de accesores de propiedad:
- Una
Getprocedimiento que devuelve el valor de una propiedad. - Un procedimiento
Letque asigna un valor (no deObject) a un objeto. - Un procedimiento
Setque asigna una referencia deObject.
Los accesores de propiedades a menudo se definen en pares, utilizando tanto Get como Let / Set para cada propiedad. Una propiedad con sólo una Get procedimiento sería de sólo lectura, mientras que una propiedad con sólo una Let / Set procedimiento sería de sólo escritura.
En el siguiente ejemplo, se definen cuatro DateRange propiedades para la clase DateRange :
-
StartDate( lectura / escritura ). Valor de fecha que representa la fecha anterior en un rango. Cada procedimiento utiliza el valor de la variable del módulo,mStartDate. -
EndDate( lectura / escritura ). Valor de fecha que representa la fecha posterior en un rango. Cada procedimiento utiliza el valor de la variable del módulo,mEndDate. -
DaysBetween( solo lectura ). Valor entero calculado que representa el número de días entre las dos fechas. Como solo hay un procedimiento deGet, esta propiedad no se puede modificar directamente. -
RangeToCopy( solo escritura ). Un procedimiento deSetutilizado para copiar los valores de un objetoDateRangeexistente.
Private mStartDate As Date ' Module variable to hold the starting date
Private mEndDate As Date ' Module variable to hold the ending date
' Return the current value of the starting date
Public Property Get StartDate() As Date
StartDate = mStartDate
End Property
' Set the starting date value. Note that two methods have the name StartDate
Public Property Let StartDate(ByVal NewValue As Date)
mStartDate = NewValue
End Property
' Same thing, but for the ending date
Public Property Get EndDate() As Date
EndDate = mEndDate
End Property
Public Property Let EndDate(ByVal NewValue As Date)
mEndDate = NewValue
End Property
' Read-only property that returns the number of days between the two dates
Public Property Get DaysBetween() As Integer
DaysBetween = DateDiff("d", mStartDate, mEndDate)
End Function
' Write-only property that passes an object reference of a range to clone
Public Property Set RangeToCopy(ByRef ExistingRange As DateRange)
Me.StartDate = ExistingRange.StartDate
Me.EndDate = ExistingRange.EndDate
End Property
Agregando Funcionalidad a una Clase
Se puede llamar a cualquier Sub , Function , o Property pública dentro de un módulo de clase precediendo a la llamada con una referencia de objeto:
Object.Procedure
En una clase de DateRange , se puede usar un Sub para agregar un número de días a la fecha de finalización:
Public Sub AddDays(ByVal NoDays As Integer)
mEndDate = mEndDate + NoDays
End Sub
Una Function podría devolver el último día del próximo fin de mes (tenga en cuenta que GetFirstDayOfMonth no sería visible fuera de la clase porque es privada):
Public Function GetNextMonthEndDate() As Date
GetNextMonthEndDate = DateAdd("m", 1, GetFirstDayOfMonth())
End Function
Private Function GetFirstDayOfMonth() As Date
GetFirstDayOfMonth = DateAdd("d", -DatePart("d", mEndDate), mEndDate)
End Function
Los procedimientos pueden aceptar argumentos de cualquier tipo, incluidas las referencias a los objetos de la clase que se está definiendo.
El siguiente ejemplo prueba si el objeto DateRange actual tiene una fecha de inicio y una fecha de finalización que incluye la fecha de inicio y finalización de otro objeto DateRange .
Public Function ContainsRange(ByRef TheRange As DateRange) As Boolean
ContainsRange = TheRange.StartDate >= Me.StartDate And TheRange.EndDate <= Me.EndDate
End Function
Tenga en cuenta el uso de la notación Me como una forma de acceder al valor del objeto que ejecuta el código.
Ámbito del módulo de clase, creación de instancias y reutilización.
De forma predeterminada, un nuevo módulo de clase es una clase privada, por lo que solo está disponible para la creación de instancias y su uso dentro del VBProject en el que está definido. Puede declarar, crear instancias y usar la clase en cualquier lugar del mismo proyecto:
'Class List has Instancing set to Private
'In any other module in the SAME project, you can use:
Dim items As List
Set items = New List
Pero a menudo escribirá clases que le gustaría usar en otros proyectos sin copiar el módulo entre proyectos. Si define una clase llamada List en ProjectA , y desea usar esa clase en ProjectB , entonces deberá realizar 4 acciones:
Cambie la propiedad de
PublicNotCreatableinstancias de la claseListenProjectAen la ventana Propiedades, dePrivateaPublicNotCreatableCree una función pública de "fábrica" en
ProjectAque cree y devuelva una instancia de una clase deList. Normalmente, la función de fábrica incluiría argumentos para la inicialización de la instancia de clase. La función de fábrica es necesaria porqueProjectBpuede usar la clase, peroProjectBno puede crear directamente una instancia de la clase deProjectA.Public Function CreateList(ParamArray values() As Variant) As List Dim tempList As List Dim itemCounter As Long Set tempList = New List For itemCounter = LBound(values) to UBound(values) tempList.Add values(itemCounter) Next itemCounter Set CreateList = tempList End FunctionEn
ProjectBagregue una referencia aProjectAusando el menúTools..References...En
ProjectB, declare una variable y asígnele una instancia deListusando la función de fábrica deProjectADim items As ProjectA.List Set items = ProjectA.CreateList("foo","bar") 'Use the items list methods and properties items.Add "fizz" Debug.Print items.ToString() 'Destroy the items object Set items = Nothing