函数返回一个包含返回类的函数的类
我正在研究面向对象的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。所以它只需要一行代码来检索一个值。
每次你的函数引用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是从哪里来的,所以我把它做成了一个字符串。
我认为你的解决方案几乎和我的完全一样。我认识到同样的问题,但显然它没有帮助: -/ – 2010-03-28 15:57:48
我认为你的意思是“创建一个新的ItemLocation”,而不是“ItemMaster”... – jtolle 2010-03-28 17:11:37
右本。我发誓我在发布之前阅读了所有其他答案,但显然我没有。 正确jtolle。 – 2010-03-28 17:35:52
您可以尝试分离出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
分离出两行。
感谢您的建议。然而,它没有任何区别。 – Scott 2010-03-27 22:38:19
我似乎无法重现这一点,但让我报告我做了什么,也许这将帮助您找到您的问题。
下面是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'方法的调用?所以可能的问题是上传'位置'代码。
我知道这是用来展示问题的示例代码,所以你可能已经意识到了这一点,但那些不应该谷歌的“得墨忒耳定律”... – jtolle 2010-03-27 21:29:33
你怎么知道“..出于某种原因,ItemLocation类甚至没有被初始化。“ ?? – RBarryYoung 2010-03-27 21:44:17
@jtolle - 我没有在这里遮住任何东西。我搜索了“德米特法”,但不知道你认为我的代码有什么问题? @RBarryYoung - 我在ItemLocation类的Class_Iizeize中有一些代码来打印调试消息。没有消息=没有初始化。 – Scott 2010-03-27 23:07:10