2010-03-27 194 views
4

我正在研究面向对象的Excel加载项以从我们的ERP系统的数据库中检索信息。下面是一个函数调用的例子:函数返回一个包含返回类的函数的类

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

马科拉是一类需要的数据库访问护理的一个实例。 Item()是Macola类的一个函数,它返回一个ItemMaster类的实例。 Description()是ItemMaster类的一个函数。这一切都正常工作。

项目可以被存储在多个位置,所以我的下一步就是要做到这一点:

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

位置()是ItemMaster类返回ItemLocation的一个实例的功能类(理论上来说,无论如何)。 QuantityOnHand()是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类的成员变量。

奇怪的是,我可以在非类模块中成功实例化ItemMaster类之外的ItemLocation类。

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

有什么方法可以使我的工作方式符合我的要求吗?我试图尽可能简化API。所以它只需要一行代码来检索一个值。

+1

我知道这是用来展示问题的示例代码,所以你可能已经意识到了这一点,但那些不应该谷歌的“得墨忒耳定律”... – jtolle 2010-03-27 21:29:33

+0

你怎么知道“..出于某种原因,ItemLocation类甚至没有被初始化。“ ?? – RBarryYoung 2010-03-27 21:44:17

+0

@jtolle - 我没有在这里遮住任何东西。我搜索了“德米特法”,但不知道你认为我的代码有什么问题? @RBarryYoung - 我在ItemLocation类的Class_Iizeize中有一些代码来打印调试消息。没有消息=没有初始化。 – Scott 2010-03-27 23:07:10

回答

1

每次你的函数引用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是从哪里来的,所以我把它做成了一个字符串。

+0

我认为你的解决方案几乎和我的完全一样。我认识到同样的问题,但显然它没有帮助: -/ – 2010-03-28 15:57:48

+0

我认为你的意思是“创建一个新的ItemLocation”,而不是“ItemMaster”... – jtolle 2010-03-28 17:11:37

+0

右本。我发誓我在发布之前阅读了所有其他答案,但显然我没有。 正确jtolle。 – 2010-03-28 17:35:52

1

您可以尝试分离出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从VBA中的Set分离出两行。

+0

感谢您的建议。然而,它没有任何区别。 – Scott 2010-03-27 22:38:19

1

我似乎无法重现这一点,但让我报告我做了什么,也许这将帮助您找到您的问题。

下面是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杀死它后该行执行,因为没有变量有一个参考实例。

就像我说过的,这与您所描述的问题不符。我可能错过了一些细节,但我希望这有助于。

编辑:

为了澄清,我的意思是我叫的更简单的例子 'c1.f()P',以符合您的

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

但是我简单的例子只是罚款。所以你现在有三个答案,相当于“需要更多信息”,但这是一个有趣的小谜题。

如果你没有看到'ItemLocation'的实例被创建,那么这是否意味着你没有看到对类'ItemMaster'的'Location'方法的调用?所以可能的问题是上传'位置'代码。