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
Get
Prozedur, die den Wert einer Eigenschaft zurückgibt. - Eine
Let
Prozedur, die einemObject
einen (Nicht-Object
) Wert zuweist. - Eine
Set
Prozedur, die eineObject
zuweist.
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 eineGet
Prozedur gibt, kann diese Eigenschaft nicht direkt geändert werden. -
RangeToCopy
(RangeToCopy
Schreiben ). EineSet
Prozedur, die zum Kopieren der Werte eines vorhandenenDateRange
Objekts 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
List
Klasse inProjectA
im Eigenschaftenfenster vonPrivate
inPublicNotCreatable
Erstellen Sie eine öffentliche "Factory" -Funktion in
ProjectA
, die eine Instanz einerList
Klasse 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 werdenProjectB
aberProjectB
kann 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 Function
Tools..References...
inProjectB
über das MenüTools..References...
einen Verweis aufProjectA
Tools..References...
.ProjectB
inProjectB
eine Variable, und weisen Sie ihr mithilfe der Factory-Funktion vonProjectA
eine Instanz vonList
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