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:

  1. Una Get procedimiento que devuelve el valor de una propiedad.
  2. Un procedimiento Let que asigna un valor (no de Object ) a un objeto.
  3. Un procedimiento Set que asigna una referencia de Object .

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 :

  1. 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 .
  2. 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 .
  3. DaysBetween ( solo lectura ). Valor entero calculado que representa el número de días entre las dos fechas. Como solo hay un procedimiento de Get , esta propiedad no se puede modificar directamente.
  4. RangeToCopy ( solo escritura ). Un procedimiento de Set utilizado para copiar los valores de un objeto DateRange existente.
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:

  1. Cambie la propiedad de PublicNotCreatable instancias de la clase List en ProjectA en la ventana Propiedades, de Private a PublicNotCreatable

  2. Cree una función pública de "fábrica" ​​en ProjectA que cree y devuelva una instancia de una clase de List . 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 porque ProjectB puede usar la clase, pero ProjectB no puede crear directamente una instancia de la clase de ProjectA .

     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 Function
    
  3. En ProjectB agregue una referencia a ProjectA usando el menú Tools..References...

  4. En ProjectB , declare una variable y asígnele una instancia de List usando la función de fábrica de ProjectA

     Dim 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
    


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow