Ricerca…


Osservazioni

Questo articolo mostrerà come creare una classe personalizzata completa in VBA. Utilizza l'esempio di un oggetto DateRange , perché una data di inizio e di fine viene spesso passata insieme alle funzioni.

Aggiunta di una proprietà a una classe

Una procedura Property è una serie di istruzioni che recupera o modifica una proprietà personalizzata su un modulo.

Esistono tre tipi di accessori di proprietà:

  1. Una procedura Get che restituisce il valore di una proprietà.
  2. Un Let procedura che assegna un (non Object value) per un oggetto.
  3. Una procedura Set che assegna un riferimento Object .

Gli accessor di proprietà sono spesso definiti in coppia, utilizzando sia un Get e Let / Set per ogni proprietà. Una proprietà con solo una procedura Get sarebbe di sola lettura, mentre una proprietà con solo una procedura Let / Set sarebbe di sola scrittura.

Nell'esempio seguente, vengono definiti quattro accessor di proprietà per la classe DateRange :

  1. StartDate ( lettura / scrittura ). Valore data che rappresenta la data precedente in un intervallo. Ogni procedura utilizza il valore della variabile del modulo, mStartDate .
  2. EndDate ( lettura / scrittura ). Valore data che rappresenta la data successiva in un intervallo. Ogni procedura utilizza il valore della variabile del modulo, mEndDate .
  3. DaysBetween ( DaysBetween lettura ). Valore intero calcolato che rappresenta il numero di giorni tra le due date. Poiché esiste solo una procedura Get , questa proprietà non può essere modificata direttamente.
  4. RangeToCopy ( solo scrittura ). Una procedura Set utilizzata per copiare i valori di un oggetto DateRange esistente.
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

Aggiunta di funzionalità a una classe

Qualsiasi Sub , Function o Property all'interno di un modulo di classe può essere richiamata precedendo la chiamata con un riferimento a un oggetto:

Object.Procedure

In una classe DateRange , è possibile utilizzare una Sub per aggiungere un numero di giorni alla data di fine:

Public Sub AddDays(ByVal NoDays As Integer)
    mEndDate = mEndDate + NoDays
End Sub

Una Function potrebbe restituire l'ultimo giorno del prossimo mese (nota che GetFirstDayOfMonth non sarebbe visibile al di fuori della classe perché è privato):

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

Le procedure possono accettare argomenti di qualsiasi tipo, compresi i riferimenti agli oggetti della classe in fase di definizione.

L'esempio seguente verifica se l'oggetto DateRange corrente ha una data di inizio e una data di fine che include la data di inizio e di fine di un altro oggetto DateRange .

Public Function ContainsRange(ByRef TheRange As DateRange) As Boolean
    ContainsRange = TheRange.StartDate >= Me.StartDate And TheRange.EndDate <= Me.EndDate
End Function

Notare l'uso della notazione Me come modo per accedere al valore dell'oggetto che esegue il codice.

Scopo del modulo di classe, istanziazione e riutilizzo

Per impostazione predefinita, un nuovo modulo di classe è una classe privata, quindi è disponibile solo per l'istanziazione e l'utilizzo all'interno del VBProject in cui è definito. Puoi dichiarare, creare un'istanza e utilizzare la classe ovunque nello stesso progetto:

'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

Ma spesso scrivi classi che ti piacerebbe usare in altri progetti senza copiare il modulo tra i progetti. Se si definisce una classe denominata List in ProjectA e si desidera utilizzare tale classe in ProjectB , sarà necessario eseguire 4 azioni:

  1. Modificare la proprietà di PublicNotCreatable della classe List in ProjectA nella finestra Proprietà, da Private a PublicNotCreatable

  2. Creare una funzione "factory" pubblica in ProjectA che crea e restituisce un'istanza di una classe List . In genere, la funzione factory include argomenti per l'inizializzazione dell'istanza di classe. La funzione factory è necessaria perché la classe può essere utilizzata da ProjectB ma ProjectB non può creare direttamente un'istanza della classe 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. In ProjectB aggiungi un riferimento a ProjectA usando il menu Tools..References... .

  4. In ProjectB , dichiarare una variabile e assegnargli un'istanza di List utilizzando la funzione factory di 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow