VBA. Можно ли передать свойство объекта в качестве аргумента метода?

Я довольно привык к VBA, не очень к объектам, и сейчас я упираюсь в стену...

Мой класс конфигурации имеет почти 100 свойств, поэтому я не буду спамить их здесь, поскольку подробности не имеют большого значения для моего вопроса.

Я надеялся запрограммировать дублирующую функцию, чтобы создавать несколько объектов из одного, а затем присваивать разные значения определенному свойству каждого нового объекта (добавлять новые элементы в конфигурации, поэтому он генерирует новые конфиги), которые будут выглядеть так:

Public Function Duplicate(SrcCfg As Config, PropertyName As String, Properties As String) As Collection
Dim Cc As Collection, _
    Cfg As Config, _
    TotalNumber As Integer, _
    A() As String

Set Cc = New Collection
A = Split(Properties, "/")
TotalNumber = UBound(A)

For i = 0 To TotalNumber
    'Create a copy of the source object
    Set Cfg = SrcCfg.Copy
    'Set the property for that particular copy
    Cfg.PropertyName = A(i)
    'Add that copy to the collection
    Cc.Add ByVal Cfg
Next i

    Duplicate = Cc
End Function

Но я не уверен, что коллекция — лучший результат (поскольку я возьму результаты и включу их в другую основную коллекцию), поэтому я открыт для предложений.

И я почти уверен, что мы не можем передать свойство в качестве аргумента (я потратил довольно много времени на поиск решения для этого...), и я не знаю, что с этим делать это было бы очень практично для меня. Так что если есть решение или обходной путь, с удовольствием попробую!

Вот остальные мои методы:

Friend Sub SetConfig(SrcConfig As Config)
    Config = SrcConfig
End Sub

Public Function Copy() As Config
    Dim Result As Config
    Set Result = New Config
    Call Result.SetConfig(Config)
    Set Copy = Result
End Function


Окончательный код для дублирования объекта:


Безотказно работает:

Private Cfg As Config

Friend Sub SetConfig(SrcConfig As Config)
    Set Cfg = SrcConfig
End Sub

Public Function Copy() As Config
    Dim Result As Config
    Set Result = New Config
    Call Result.SetConfig(Cfg)
    Set Copy = Result
End Function

Public Function Duplicate(PropertyName As String, Properties As String) As Collection
Dim Cc As Collection, _
    Cfg As Config, _
    TotalNumber As Integer, _
    A() As String

Set Cc = New Collection
A = Split(Properties, "/")
TotalNumber = UBound(A)

For i = 0 To TotalNumber
    'Create a copy of the source object
    Set Cfg = Me.Copy
    'Set the property for that particular copy
    CallByName Cfg, PropertyName, VbLet, A(i)
    'Add that copy to the collection
    Cc.Add Cfg
Next i

    Set Duplicate = Cc
End Function

person R3uK    schedule 17.07.2015    source источник
comment
Возможно, см. ответ Скотта здесь: /вопросы/4805475/   -  person Tim Williams    schedule 17.07.2015
comment
@TimWilliams: Спасибо, я начал с этого ответа, чтобы создать метод .copy, и это действительно было очень полезно!   -  person R3uK    schedule 17.07.2015


Ответы (1)


Вы действительно поняли это правильно, включая типы (String).

Просто замените свой

Cfg.PropertyName = A(i)

с участием

CallByName Cfg, PropertyName, vbLet, A(i)

Имя свойства должно быть передано в виде строки, а не ссылки или лямбда-выражения или чего-то еще, поэтому здесь нет безопасности типов или помощи компилятора. У вас будет ошибка времени выполнения, если вы ошибетесь в имени.

Что касается типа возвращаемого значения, то в VBA нет списков, поэтому с коллекцией, как правило, все в порядке, но поскольку в вашем конкретном случае вы заранее знаете, сколько объектов вы будете возвращать, вы можете объявить массив:

Dim Cc() As Config
ReDim Cc(1 to TotalNumber)

Вы могли бы объявить массив в любом случае, но если бы вы не знали общего числа, вы бы перераспределяли его на каждой итерации.

person GSerg    schedule 17.07.2015
comment
Спасибо за быстрый ответ, мне нравится читать, что это ВОЗМОЖНО! ‹3 Мои выходные будут намного приятнее! :) Я попробую это в ближайшее время и подтвержу ответ, если это не проблема для вас! - person R3uK; 17.07.2015
comment
Я протестировал его, и он работал потрясающе! :) Спасибо за ввод, и я опубликую свой обновленный код, чтобы людям было понятнее, когда они придут. - person R3uK; 20.07.2015
comment
Просто небольшой вопрос, так как я не уверен в этом, но я использую пользовательский объект в качестве аргумента, и все же это объектный метод, поэтому я могу изменить Set Cfg = SrcCfg.Copy на Set Cfg = Me.Copy и избавиться от аргумента? Это кажется довольно логичным, но я впервые действительно работаю с объектами VBA. - person R3uK; 21.07.2015