Присвоение свойств объекту с помощью цикла - PullRequest
0 голосов
/ 08 июня 2018

Я новичок в объектах и ​​Excel VBA, поэтому извиняюсь, если это избыточный вопрос, но я провел последние 2 дня, пытаясь загрузить новый объект со свойствами, которые хранятся в листе Excel.

У меня есть около 60 свойств, которые нужно загрузить.Моя основная подпрограмма загружает каждый новый экземпляр, используя подпрограмму Load в классе.

Sub Main()
Dim loadedCompound As Compound    'my class

Set loadedCompound = New Compound  

loadedCompound.Load Selection      'a sub in Compound class

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

Sub Main()
Dim loadedCompound As Compound    'my class
Dim arrayProperties() As String   'Array of the class property names

Set loadedCompound = New Compound  
arrayProperties = 
Split(",CDKFingerprint,SMILES,NumBatches,CompType,MolForm",",")

For i = 1 To UBound(arrayProperties)
    loadedCompound.arrayProperties(i) = Selction.Offset(0, i)
Next i

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

Sub Load(ARID As Range)

pCDKFingerprint = ARID.Offset(0, 1)
pSMILES = ARID.Offset(0, 2)
pNumBatches = ARID.Offset(0, 3)
pCompType = ARID.Offset(0, 4)
pMolForm = ARID.Offset(0, 5)
pMW = ARID.Offset(0, 6)
pChemName = ARID.Offset(0, 7)
pDrugName = ARID.Offset(0, 8)
pNickName = ARID.Offset(0, 9)
pNotes = ARID.Offset(0, 10)
pSource = ARID.Offset(0, 11)
pPurpose = ARID.Offset(0, 12)
pRegDate = ARID.Offset(0, 13)
pCLOGP = ARID.Offset(0, 14)
pCLOGS = ARID.Offset(0, 15)

Данные для переменных хранятся на листев формате строки.

Есть ли простой лаконичный способ кодировать это?

1 Ответ

0 голосов
/ 09 июня 2018

вы можете использовать CallByName () function:

arrayProperties = Split(",CDKFingerprint,SMILES,NumBatches,CompType,MolForm", ",")
For i = 1 To UBound(arrayProperties)
    CallByName loadedCompound, "p" & arrayProperties(i), VbLet, Selection.Offset(0, i).Value
Next i

Я бы добавил, что более надежный подход к обработке объекта потребовал бы некоторой инкапсуляции, чтобы предотвратить случайную запись свойств.выставив Public property, вы оставите его Private и предоставите некоторый Public Let метод для его установки:

так что вашCompound класс будет:

Private pCDKFingerprint As Variant
Private pSMILES As Variant
....

Public Property Let CDKFingerprint(val As Variant)
    pCDKFingerprint = val
End Property

Public Property Let SMILES(val As Variant)
    SMILES = val
End Property

....

и, следовательно, ваш код будет использовать его следующим образом:

Sub Main()
    Dim loadedCompound As Compound    'my class
    Dim arrayProperties() As String   'Array of the class property names
    Dim i As Long

    Set loadedCompound = New Compound
    arrayProperties = Split(",CDKFingerprint,SMILES,NumBatches,CompType,MolForm", ",")

    For i = 1 To UBound(arrayProperties)
        CallByName loadedCompound, arrayProperties(i), VbLet, Selection.Offset(0, i).Value
    Next i
End Sub
...