VBA
Eine benutzerdefinierte Klasse erstellen
Suche…
Bemerkungen
Dieser Artikel zeigt, wie Sie eine vollständige benutzerdefinierte Klasse in VBA erstellen. Es verwendet das Beispiel eines DateRange Objekts, da Start- und Enddatum häufig gemeinsam an Funktionen übergeben werden.
Hinzufügen einer Eigenschaft zu einer Klasse
Eine Property Prozedur ist eine Reihe von Anweisungen, mit denen eine benutzerdefinierte Eigenschaft eines Moduls abgerufen oder geändert wird.
Es gibt drei Arten von Eigenschaftszugängen:
- Eine
GetProzedur, die den Wert einer Eigenschaft zurückgibt. - Eine
LetProzedur, die einemObjecteinen (Nicht-Object) Wert zuweist. - Eine
SetProzedur, die eineObjectzuweist.
Eigenschafts-Accessoren werden häufig paarweise definiert, wobei für jede Eigenschaft sowohl Get als auch Let / Set werden. Eine Eigenschaft mit nur einer Get Prozedur wäre schreibgeschützt, während eine Eigenschaft mit nur einer Let / Set Prozedur nur schreibgeschützt wäre.
Im folgenden Beispiel sind vier Eigenschaftszugriffe für die DateRange Klasse definiert:
-
StartDate( Lesen / Schreiben ). Datumswert, der das frühere Datum in einem Bereich darstellt. Jede Prozedur verwendet den Wert dermStartDate. -
EndDate( Lesen / Schreiben ). Datumswert, der das spätere Datum in einem Bereich darstellt. Jede Prozedur verwendet den Wert dermEndDate. -
DaysBetween( schreibgeschützt ). Berechneter Integer-Wert, der die Anzahl der Tage zwischen den beiden Daten angibt. Da es nur eineGetProzedur gibt, kann diese Eigenschaft nicht direkt geändert werden. -
RangeToCopy(RangeToCopySchreiben ). EineSetProzedur, die zum Kopieren der Werte eines vorhandenenDateRangeObjekts verwendet wird.
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
Funktionalität zu einer Klasse hinzufügen
Jede öffentliche Sub , Function oder Property innerhalb eines Klassenmoduls kann aufgerufen werden, indem dem Aufruf eine Objektreferenz vorangestellt wird:
Object.Procedure
In einer DateRange Klasse kann ein Sub verwendet werden, um dem Enddatum eine Anzahl von Tagen hinzuzufügen:
Public Sub AddDays(ByVal NoDays As Integer)
mEndDate = mEndDate + NoDays
End Sub
Eine Function könnte den letzten Tag des nächsten Monatsendes zurückgeben (beachten Sie, dass GetFirstDayOfMonth außerhalb der Klasse nicht sichtbar ist, da es privat ist):
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
Prozeduren können Argumente eines beliebigen Typs akzeptieren, einschließlich Referenzen auf Objekte der definierten Klasse.
Im folgenden Beispiel wird getestet, ob das aktuelle DateRange Objekt ein Start- und Enddatum hat, das das Start- und Enddatum eines anderen DateRange Objekts enthält.
Public Function ContainsRange(ByRef TheRange As DateRange) As Boolean
ContainsRange = TheRange.StartDate >= Me.StartDate And TheRange.EndDate <= Me.EndDate
End Function
Beachten Sie die Verwendung der Me Notation, um auf den Wert des Objekts zuzugreifen, das den Code ausführt.
Klassenmodulumfang, Instanziierung und Wiederverwendung
Standardmäßig ist ein neues Klassenmodul eine Private-Klasse. Daher ist es nur für die Instantiierung und Verwendung innerhalb des VBProject verfügbar, in dem es definiert ist. Sie können die Klasse überall im selben Projekt deklarieren, instanziieren und verwenden:
'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
Oft schreiben Sie Klassen, die Sie in anderen Projekten verwenden möchten, ohne das Modul zwischen den Projekten zu kopieren. Wenn Sie in ProjectA eine Klasse mit dem Namen List definieren und diese Klasse in ProjectB möchten, müssen Sie 4 Aktionen ausführen:
Ändern Sie die instancing-Eigenschaft der
ListKlasse inProjectAim Eigenschaftenfenster vonPrivateinPublicNotCreatableErstellen Sie eine öffentliche "Factory" -Funktion in
ProjectA, die eine Instanz einerListKlasse erstellt und zurückgibt. Normalerweise enthält die Factory-Funktion Argumente für die Initialisierung der Klasseninstanz. Die Fabrik - Funktion ist erforderlich , da die Klasse kann verwendet werdenProjectBaberProjectBkann nicht direkt eine Instanz erstellenProjectA‚s - Klasse.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 FunctionTools..References...inProjectBüber das MenüTools..References...einen Verweis aufProjectATools..References....ProjectBinProjectBeine Variable, und weisen Sie ihr mithilfe der Factory-Funktion vonProjectAeine Instanz vonListDim 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