Функция, возвращающая класс, содержащий функцию, возвращающую класс - PullRequest
4 голосов
/ 27 марта 2010

Я работаю над объектно-ориентированной надстройкой Excel для извлечения информации из базы данных нашей системы ERP.Вот пример вызова функции:

itemDescription = Macola.Item("12345").Description

Macola - это экземпляр класса, который заботится о доступе к базе данных.Item () - это функция класса Macola, которая возвращает экземпляр класса ItemMaster.Описание () является функцией класса ItemMaster.Это все работает правильно.

Элементы могут храниться более чем в одном месте, поэтому мой следующий шаг должен сделать это:

quantityOnHand = Macola.Item("12345").Location("A1").QuantityOnHand

Location ()является функцией класса ItemMaster, которая возвращает экземпляр класса ItemLocation (ну, в принципе, в любом случае).КоличествоOnHand () является функцией класса ItemLocation.Но по какой-то причине класс ItemLocation даже не инициализируется.

Public Function Location(inventoryLocation As String) As ItemLocation
    Set Location = New ItemLocation
    Location.Item = item_no
    Location.Code = inventoryLocation
End Function

В приведенном выше примере переменная item_no является переменной-членом класса ItemMaster.

Как ни странно, яможет успешно создать экземпляр класса ItemLocation вне класса ItemMaster в модуле, не относящемся к классу.

Dim test As New ItemLocation
test.Item = "12345"
test.Code = "A1"
quantityOnHand = test.QuantityOnHand

Есть ли способ заставить эту работу работать так, как я хочу?Я пытаюсь сделать API максимально простым.Так что для получения значения требуется всего одна строка кода.

Ответы [ 3 ]

1 голос
/ 28 марта 2010

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

Вот код для Class1:

Public Function f() As Class2
    Set f = New Class2
    f.p = 42
End Function

и вот код для Class2:

Private p_

Public Property Let p(value)
    p_ = value
End Property

Public Property Get p()
    p = p_
End Property

Private Sub Class_Initialize()
    Debug.Print "Class 2 init"
End Sub

Private Sub Class_Terminate()
    Debug.Print "Class 2 term"
End Sub

Если я зайду в ближайшее окно и введу:

set c1=new Class1

, а затем

?c1.f().p

Я вернусь:

Class 2 init
 42 
Class 2 term

Таким образом, создается экземпляр Class2, его свойство 'p' записывается и читается, но затем VBA убивает его после выполнения этой строки, поскольку ни одна переменная не имеет ссылки на этот экземпляр.

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

EDIT:

Чтобы пояснить, я имею в виду, что мой более простой пример вызова 'c1.f (). P' соответствует вашему

quantityOnHand = Macola.Item("12345").Location("A1").QuantityOnHand

но мой простой пример работает просто отлично. Итак, теперь у вас есть три ответа, которые составляют «нужно больше информации», но это интересная маленькая головоломка.

Если вы вообще не видите, что экземпляр ItemLocation создается, означает ли это, что вы также не видите вызов вашего метода Location из класса ItemMaster? Так что, возможно, проблема связана с размещенным кодом местоположения.

1 голос
/ 28 марта 2010

Каждый раз, когда ваша функция ссылается на Location, она создает New ItemLocation (потому что она вызывает функцию, похожую на рекурсивную), или так кажется. Может быть, вам нужно изолировать ItemMaster внутри функции, как это

Public Property Get Location(inventoryLocation As String) As ItemLocation

    Dim clsReturn As ItemLocation

    Set clsReturn = New ItemLocation

    clsReturn.Item = "item_no"
    clsReturn.Code = inventoryLocation

    Set Location = clsReturn

End Property

Я не уверен, почему вы используете функцию вместо свойства, но если у вас есть веская причина, я уверен, что вы можете это изменить. Я также не мог понять, откуда пришло item_no, поэтому я сделал это строкой.

1 голос
/ 27 марта 2010

Вы можете попытаться отделить объявление и создание экземпляров объектов в вашем коде VBA. Я также хотел бы создать переменную объекта, локальную для функции, и вернуть ее в конце. Попробуйте это:

Public Function Location(inventoryLocation As String) As ItemLocation
    Dim il As ItemLocation        'Declare the local object '
    Set il = New ItemLocation     'Instantiate the object on a separate line '
    il.Item = item_no
    il.Code = inventoryLocation
    Set Location = il             'Return the local object at the end '
End Function

Я не уверен, что это вызвало проблему, но я помню, что читал, что VB6 / VBA имеет проблему с объявлением и созданием экземпляра объекта в той же строке кода. Я всегда отделяю свой Dim от моего Set в VBA на две строки.

...