VBA
Tworzenie niestandardowej klasy
Szukaj…
Uwagi
W tym artykule pokażemy, jak utworzyć pełną niestandardową klasę w języku VBA. Wykorzystuje przykład obiektu DateRange
, ponieważ data początkowa i końcowa są często przekazywane razem do funkcji.
Dodawanie właściwości do klasy
Procedura Property
to seria instrukcji, które pobierają lub modyfikują właściwość niestandardową w module.
Istnieją trzy typy osób przystępujących do nieruchomości:
- Procedura
Get
, która zwraca wartość właściwości. - Procedura
Let
, która przypisuje wartość (nieObject
) do obiektu. - Procedura
Set
, która przypisuje odwołanie doObject
.
Akcesoria do właściwości są często definiowane parami, przy użyciu zarówno Get
i Let
/ Set
dla każdej właściwości. Właściwość tylko z procedurą Get
byłaby tylko do odczytu, a właściwość tylko z procedurą Let
/ Set
byłaby tylko do odczytu.
W poniższym przykładzie zdefiniowano cztery akcesoria do właściwości dla klasy DateRange
:
-
StartDate
( odczyt / zapis ). Wartość daty reprezentująca wcześniejszą datę w zakresie. Każda procedura wykorzystuje wartość zmiennej modułowejmStartDate
. -
EndDate
( odczyt / zapis ). Wartość daty reprezentująca późniejszą datę w zakresie. Każda procedura wykorzystuje wartość zmiennej modułowej,mEndDate
. -
DaysBetween
( tylko do odczytu ). Obliczona wartość całkowita reprezentująca liczbę dni między dwiema datami. Ponieważ istnieje tylko proceduraGet
, tej właściwości nie można modyfikować bezpośrednio. -
RangeToCopy
( tylko do zapisu ). ProceduraSet
używana do kopiowania wartości istniejącego obiektuDateRange
.
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
Dodanie funkcjonalności do klasy
Dowolną publiczną Sub
, Function
lub Property
w module klasy można wywołać, poprzedzając wywołanie odwołaniem do obiektu:
Object.Procedure
W klasie DateRange
można użyć Sub
do dodania liczby dni do daty końcowej:
Public Sub AddDays(ByVal NoDays As Integer)
mEndDate = mEndDate + NoDays
End Sub
Function
może zwrócić ostatni dzień następnego miesiąca (pamiętaj, że GetFirstDayOfMonth
nie będzie widoczny poza klasą, ponieważ jest prywatny):
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
Procedury mogą przyjmować argumenty dowolnego typu, w tym odwołania do obiektów definiowanej klasy.
Poniższy przykład sprawdza, czy bieżący obiekt DateRange
ma datę początkową i końcową, która obejmuje datę początkową i końcową innego obiektu DateRange
.
Public Function ContainsRange(ByRef TheRange As DateRange) As Boolean
ContainsRange = TheRange.StartDate >= Me.StartDate And TheRange.EndDate <= Me.EndDate
End Function
Zwróć uwagę na użycie notacji Me
jako sposobu na uzyskanie dostępu do wartości obiektu uruchamiającego kod.
Zakres modułu klasy, instancja i ponowne użycie
Domyślnie nowy moduł klasy jest klasą prywatną, więc jest dostępny tylko do tworzenia instancji i używania w ramach VBProject, w którym jest zdefiniowany. Możesz zadeklarować, utworzyć instancję i użyć klasy w dowolnym miejscu w tym samym projekcie:
'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
Ale często piszesz klasy, których chciałbyś użyć w innych projektach bez kopiowania modułu między projektami. Jeśli zdefiniujesz klasę o nazwie List
w ProjectA
i chcesz użyć tej klasy w ProjectB
, musisz wykonać 4 akcje:
Zmień właściwość instancji klasy
List
wProjectA
w oknie Properties, zPrivate
naPublicNotCreatable
Utwórz publiczną funkcję „fabryki” w
ProjectA
która tworzy i zwraca instancję klasyList
. Zwykle funkcja fabryki zawiera argumenty inicjujące instancję klasy. Funkcja fabryczna jest wymagana, ponieważ klasa może być używana przezProjectB
aleProjectB
nie może bezpośrednio utworzyć instancji klasyProjectA
.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
W
ProjectB
dodaj odwołanie doProjectA
za pomocą menuTools..References...
W
ProjectB
zadeklaruj zmienną i przypisz do niej instancjęList
za pomocą funkcji fabryki zProjectA
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