Вопрос или проблема
Я отправлял ранее вопрос, касающийся функции-члена класса. Теперь я сталкиваюсь с новой проблемой: если возвращаемое значение функции-члена – это класс, в котором функция определена.
Функция-член fReadData
работает (я задавал ранее вопрос по этому поводу), функция-член fReadData2
не работает.
Или: проблема в тестовых функциях?
'ClassOne
Option Explicit
Private pOne As Double
Private Sub Class_Initialize()
End Sub
Private Sub Class_Terminate()
End Sub
Public Property Get One() As Double
One = pOne
End Property
Public Property Let One(lOne As Double)
pOne = lOne
End Property
' это работает, возвращаемое значение - double
Public Function fReadData(alue As Range) As Double
pOne = alue.Cells(1)
fReadData = pOne
End Function
' это не работает, возвращаемое значение - ClassOne
Public Function fReadData2(alue As Range) As ClassOne
pOne = alue.Cells(1)
fReadData2.One = pOne
End Function
Тест выглядит следующим образом: обе функции читают значение ячейки и должны поместить это значение на электронную таблицу
' основной модуль
Option Explicit
Dim oOne As New ClassOne
' это работает
Function Test(alue As Range) As Double
oOne.fReadData alue
Test = oOne.One
End Function
' это не работает
Function Test2(alue As Range) As Double
oOne.fReadData2 alue
Test2 = oOne.One
End Function
Функция Test2
должна поместить значение C1 в ячейку C3, как функция Test
это сделала с ячейкой B3
fReadData2.One = pOne
fReadData2
– это зарезервированное слово внутри функции fReadData2 для возвращения значения из функции путем присвоения ему значения: fReadData2 = pOne
. Таким образом, оператор доступа к членам (точка) не может быть применен к нему, так как fReadData2 пуст (не имеет присвоенного значения до этого).
Поэтому, если вы определили функцию fReadData2 как ClassOne, вам нужно присвоить ей соответствующее значение, затем вы можете присваивать значения публичным полям или свойствам:
Set fReadData2 = New ClassOne
fReadData2.One = pOne
Если вам нужно вернуть текущий объект, используйте идентификатор Me:
pOne = alue.Cells(1)
Set fReadData2 = Me
Ответ или решение
Вопрос, который вы подняли, касается работы с функциями-членами класса в VBA, особенно когда функции возвращают экземпляры класса. Давайте подробно рассмотрим проблему и решение.
Анализ проблемы
Вы определили два метода в классе ClassOne
— fReadData
и fReadData2
. Первый метод возвращает значение типа Double
, и его работа проходит успешно. Второй метод должен возвращать экземпляр самого класса ClassOne
, но не работает должным образом.
Вот ключевые моменты вашей проблемы:
- Определение функций: В обоих методах вы устанавливаете значение
pOne
из указанного диапазона, однако методfReadData2
не возвращает нужный экземпляр. - Необходимость использовать оператор
Set
: Когда вы работаете с объектами (например, экземплярами классов) в VBA, необходимо использовать операторSet
для назначения ссылок на объекты. - Использование
Me
для возврата текущего объекта: Для возврата текущего экземпляра класса внутри метода вы можете использоватьMe
.
Решение
Вам нужно изменить метод fReadData2
так, чтобы он корректно возвращал экземпляр ClassOne
. Ниже представлен исправленный код:
'ClassOne
Option Explicit
Private pOne As Double
Private Sub Class_Initialize()
End Sub
Private Sub Class_Terminate()
End Sub
Public Property Get One() As Double
One = pOne
End Property
Public Property Let One(lOne As Double)
pOne = lOne
End Property
' Этот метод работает, возвращая значение типа Double
Public Function fReadData(alue As Range) As Double
pOne = alue.Cells(1)
fReadData = pOne
End Function
' Этот метод должен возвращать экземпляр класса ClassOne
Public Function fReadData2(alue As Range) As ClassOne
pOne = alue.Cells(1)
Set fReadData2 = Me ' Возвращаем текущий экземпляр класса
End Function
Использование в главном модуле
Теперь ваш главный модуль должен работать следующим образом:
' main module
Option Explicit
Dim oOne As New ClassOne
' Этот метод работает
Function Test(alue As Range) As Double
oOne.fReadData alue
Test = oOne.One
End Function
' Теперь этот метод будет работать
Function Test2(alue As Range) As Double
oOne.fReadData2 alue
Test2 = oOne.One
End Function
Заключение
С исправлением это решение должно корректно работать. Метод fReadData2
теперь возвращает экземпляр текущего класса, который установлен с помощью Set fReadData2 = Me
. Позиционирование метода Set
имеет критическое значение при работе с объектами в VBA, и его необходимо учитывать.
Если у вас возникают дополнительные вопросы или трудности, пожалуйста, не стесняйтесь обращаться за дополнительной помощью!