VBA
Создание пользовательского класса
Поиск…
замечания
В этой статье будет показано, как создать полный пользовательский класс в VBA. Он использует пример объекта DateRange
, потому что начальная и конечная дата часто передаются вместе с функциями.
Добавление свойства в класс
Процедура Property
представляет собой серию операторов, которые извлекают или изменяют настраиваемое свойство в модуле.
Существует три типа аксессуаров свойств:
- A
Get
процедуру, возвращающую значение свойства. - A
Let
процедура, которая присваиваетObject
значение (nonObject
). - Процедура
Set
, которая назначает ссылкуObject
.
Атрибуты доступа к ресурсам часто определяются парами, используя как Get
и Let
/ Set
для каждого свойства. Свойство только с процедурой Get
будет доступно только для чтения, а свойство с процедурой Let
/ Set
будет только для записи.
В следующем примере для класса DateRange
определены четыре свойства accessors:
-
StartDate
( чтение / запись ). Значение даты, представляющее более раннюю дату в диапазоне. Каждая процедура использует значение переменной модуляmStartDate
. -
EndDate
( чтение / запись ). Значение даты, представляющее более позднюю дату в диапазоне. Каждая процедура использует значение переменной модуляmEndDate
. -
DaysBetween
( только для чтения ). Вычисленное целочисленное значение, представляющее количество дней между двумя датами. Поскольку существует только процедураGet
, это свойство не может быть изменено напрямую. -
RangeToCopy
( только для записи ). ПроцедураSet
, используемая для копирования значений существующего объектаDateRange
.
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
Добавление функциональности в класс
Любые общедоступные Sub
, Function
или Property
внутри модуля класса можно вызывать, предшествуя вызову с помощью ссылки на объект:
Object.Procedure
В классе DateRange
Sub
может использоваться для добавления количества дней до даты окончания:
Public Sub AddDays(ByVal NoDays As Integer)
mEndDate = mEndDate + NoDays
End Sub
Function
может вернуть последний день следующего месяца (обратите внимание, что GetFirstDayOfMonth
не будет виден вне класса, поскольку он является закрытым):
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
Процедуры могут принимать аргументы любого типа, включая ссылки на объекты определяемого класса.
В следующем примере проверяется, имеет ли текущий объект DateRange
дату начала и дату окончания, которая включает дату начала и окончания другого объекта DateRange
.
Public Function ContainsRange(ByRef TheRange As DateRange) As Boolean
ContainsRange = TheRange.StartDate >= Me.StartDate And TheRange.EndDate <= Me.EndDate
End Function
Обратите внимание на использование нотации Me
как способ доступа к значению объекта, выполняющего код.
Класс модуля, возможности и повторное использование
По умолчанию новый класс-класс является частным, поэтому он доступен только для экземпляра и использования в VBProject, в котором он определен. Вы можете объявлять, создавать экземпляры и использовать класс в любом месте одного и того же проекта:
'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
Но часто вы будете писать классы, которые вы хотели бы использовать в других проектах, не копируя модуль между проектами. Если вы определяете класс List
в ProjectA
и хотите использовать этот класс в ProjectB
, вам необходимо выполнить 4 действия:
Измените свойство
ProjectA
классаList
вProjectA
в окне свойств, отPrivate
доPublicNotCreatable
Создайте публичную «фабричную» функцию в
ProjectA
которая создает и возвращает экземпляр классаList
. Обычно заводская функция включает аргументы для инициализации экземпляра класса. Функция фабрики требуется, потому что класс может использоватьсяProjectB
ноProjectB
не может напрямую создать экземпляр класса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
В
ProjectB
добавьте ссылку наProjectA
используя менюTools..References...
В
ProjectB
объявите переменную и присвойте ей экземплярList
используя заводскую функцию из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