Excel 2010中的VBA:函数的Scripting.Dictionary返回值不会作为parameter passing给包装函数调用

已经把我的头从桌子上撞了几个小时,而且已经search到了互联网的chuff,所以如果我错过了一个明显的解决scheme,我很抱歉…

我有两个function:

Public Function DictFromRanges(rKeys As Range, rValues As Range) As Scripting.Dictionary Debug.Assert (rKeys.Columns.Count = rValues.Columns.Count) Dim rRetDict As Scripting.Dictionary Set rRetDict = New Scripting.Dictionary ' loop through ranges adding values from rValues with keys from rKeys Dim iKey As Integer For iKey = 1 To rKeys.Columns.Count rRetDict(rKeys.Columns(iKey).Value) = rValues.Columns(iKey).Value Next iKey ' set return value Set DictFromRanges = rRetDict End Function Public Function MinTurnsToKill(dictAttack As Scripting.Dictionary, iHealth As Integer) As Integer MinTurnsToKill = iHealth End Function 

如果我在电子表格的单元格中执行以下操作:

 =MinTurnsToKill(DictFromRanges(F2:L2,F3:L3),100) 

DictFromRanges()似乎正常工作,当我单步在debugging器中。

MinTurnsToKill()是引起我脑海中的错误 – 显然它是空的,但它甚至没有被调用(我本来就有代码,但是我只是为了确认它是否被调用)。

为了进一步testing发生了什么,我写了2个代理函数:

 Public Function Proxy(rKeys As Range, rValues As Range) As Variant Dim dict As Scripting.Dictionary Set dict = DictFromRanges(rKeys, rValues) Proxy = MinTurnsToKill(dict, 42) End Function Public Function ProxyToo(rKeys As Range, rValues As Range) As Variant ProxyToo = MinTurnsToKill(DictFromRanges(rKeys, rValues), 42) End Function 

当从Excel电子表格中的单元格调用时,这些都工作正常(即都打印42):

 =Proxy(F2:L2,F4:L4) =ProxyToo(F2:L2,F4:L4) 

所以,看起来像excel只是拒绝将返回的字典从DictFromRanges()传递到MinTurnsToKill()中,如果它们被用在位于电子表格实际单元格内的评估引擎中的话。

事实上,当我在电子表格单元格中执行以下操作时,就好像拒绝承认MinTurnsToKill()甚至存在一样:

 =MinTurnsToKill(DictFromRanges(F2:L2,F3:L3),100) 

我认为必须有一种方法来使excel发挥很好,我非常感激,如果有人可以告诉我如何:)

干杯,

亚历克斯

这个问题来自于你将这两个函数用作用户定义函数(UDF),也就是直接从单元中调用它们。 Excel无法处理Scripting.Dictionarytypes的返回 – 因此也不会将此结果传递给MinTurnsToKill函数。

幸运的是,Excel可以处理Variant – 而且Scripting.Dictionary是从Variant “派生”的,如果你只是简单地改变这两行,整个事情就会起作用:

 Public Function DictFromRanges(...) As Variant Public Function MinTurnsToKill(dictAttack As Variant, ... 

希望能解决你的问题。

注意:没有看到真正的代码给你MinTurnsToKill ,它看起来非常像一个HLOOKUP (或者INDEX / MATCH对我来说,也许这里根本就不需要VBA,或者不用字典,你可以使用.WorksheetFunction.Hlookup(100, [F2:L3],2,0)

请记住,Excel期望每个函数返回“值”(这是基本的),而你的DictFromRanges返回对象。 你是对的,在VBA环境中,你的解决scheme工作的很好,但是在传递给Excel的时候会破坏函数规则。 build议非常简单 – 将两个function合并为一个将返回值的function。