在Excel单元格中返回用户自定义数据类型

4

我已经在互联网上和stackoverflow上搜索了很久,但是我还没有找到解决方案。

这是我的需求:

假设我在一个名为“MyClass”的类模块中有以下代码:


Option Explicit
Dim var1 as integer

初始化(v为整数) var1 = v

函数 获取Var1() 获取Var1 = var1

Then I have a UDF in a separate module with the code

 
Function InitializeMyClass(v as integer) as MyClass
   Dim myvar as MyClass
   Set myvar = new MyClass
   Call myvar.Initialize(v)
   Set InitializeMyClass = myvar
End Function

函数 GetMyVar(m as MyClass) GetMyVar = m.GetVar1() End Function

现在我在单元格A1中有“=InitializeMyClass(3)”,在单元格A2中有“=GetMyVar(A1)”。“#VALUE”错误出现在两个单元格中。这当然是由于我试图将用户定义的数据类型返回到单元格A1中所致。我觉得这应该是可能的,但我不确定如何做到。

编辑:哦,是的,问题是,“是否有一种方法让我将用户定义的数据类型返回到单元格中,然后在上面给出的示例中从另一个UDF中调用它?我不知道这是否需要使用COM。如果是这样,有人知道我该如何开始吗?理想情况下,如果有人有一个关于这是如何工作的示例,那就太好了!”

另一个编辑:我们来看看,现在我知道它是可以完成的:阅读此描述,它不是定量的,但会让您了解它们的工作原理,http://www.quanttools.com/index.php?option=com_content&task=view&id=19


另外,我也无法嵌套这些函数。也就是说,我不能执行 "=GetMyVar(InitializeMyClass(3))" 这样的操作。有人有什么想法吗? - B Rivera
我认为 Range 对象的 Formula 或 Value 属性不能存储对象的引用。如果尝试将 Set myRange.Value = anObject,则会失败。Formula 也是如此。如果省略 Set,则似乎会选择对象的默认属性而不是对象本身。 - barrowc
GetMyVar(InitializeMyClass(3))在VBA中运行得非常好。它似乎应该能够在Excel单元格中工作。我可以理解在单元格中返回MyClass对象会有问题(这是主要问题),但至少,如果最终返回类型是Excel可以识别的类型,则“= GetMyVar(InitializeMyClass(3))”应该可以工作,因为单元格实际上不必存储MyClass。 InitializeMyClass的返回值只是传递给GetMyVar。此外,我以前见过这样做(童子军的荣誉)。但我不知道是否必须调整COM或类似内容。 - B Rivera
@BRivera,自从您发布了链接后,内容就不见了。我一直想做同样的事情!您能分享一下如何完成吗?您可以给我最简单的解释,我会自己弄明白的! - airstrike
3个回答

2
正如其他答案所建议的那样,您问题的字面回答是“不行”。您不能在单元格中存储除数字、字符串、布尔值、错误等简单值之外的任何内容。您不能从UDF返回任何除这些简单值、数组或范围引用之外的东西。
然而,您可以通过传递(并将其存储在单元格中)某种句柄来实现您想要的基本功能,该句柄是合法的单元格值(即“myclass:instance:42”)。这可能就是您在编辑中链接到的示例所做的。但是,您的代码必须能够解释句柄值的含义并自己维护内存中的对象。如果您关心不泄漏对象,这可能会变得棘手,因为如果使用VBA执行所有这些操作,则有很多方法可以擦除或覆盖句柄,而您无法检测到。
我现在没有它,但您可能需要查看Steve Dalton撰写的《使用C/C++开发Excel插件的金融应用程序》一书。

http://www.amazon.com/Financial-Applications-using-Development-Finance/dp/0470027975/ref=ntt_at_ep_dpt_1

他讨论了如何使用XLL插件更加稳健地处理这样的句柄。

+1,感谢提供书籍链接。我一定会查看的。很遗憾,在Excel单元格中不可能使用“=GetMyVar(InitializeMyClass(3))”,但在VBA中使用GetMyVar(InitializeMyClass(3))是合法的。 - B Rivera
2
我还应该提一下一个叫做Resolver One的产品。它是一个基于Python的电子表格,您可以在单元格中存储对象并像上面所述那样使用它。当然,如果您需要使用Excel,它不是Excel,但是如果您只是想为自己解决问题或者您可以选择用户将要使用的工具,那么您可能会想看看它。 - jtolle
天啊!令人惊讶的是,尽管 Excel 经过多年的开发,却无法做到 Resolver One 所能做的。我可能会下载免费试用版来自己使用。说服我的客户转向 Resolver One 可能会有些困难,因为他对 Excel 有一定的依赖。Resolver Systems 的产品演示相当不错。 - B Rivera

1

看起来这是个有难度的问题。虽然有些不太专业,但你可以在初始化函数中返回一个名称(字符串),然后将名称参数添加到 Get 函数中。基本上是通过操作名称字符串而不是直接操作对象。


是的,最好我想避免这种情况。我曾经见过一个软件应用程序完成我所描述的任务,但是1)我已经忘记了它的名称,2)我不知道在后台进行了什么操作才能实现这种行为。我不介意学习COM或类似的东西来实现这种额外的功能,但我不知道从哪里开始。能够在单元格中存储用户定义类型确实会极大地打开Excel的功能。 - B Rivera
我相信使用 Variant 数据类型一定有方法可以做到这一点,但我不知道答案。 - Lance Roberts
1
是的,我尝试了我能想到的一切。此外,我也无法在Excel单元格中嵌套这些函数(请参见我的问题评论)。我本以为这肯定是可能的,因为函数的最终输出是整数类型。但我猜测自定义函数不知道如何返回除内置类型之外的类型。 - B Rivera

0

嵌套不起作用,因为myvar在UDF执行完成后就超出了范围。实际上,尝试在工作表函数中返回对象可能会有其他问题(肯定会有),但即使没有这些问题,作用域问题仍然会导致失败。

您可以在单元格中存储对象的指针,并通过该指针获取对象,但是作用域问题仍然会导致失败。要从指针获取对象,它必须保持在作用域内,因此为什么要存储指针呢。

显然,您的实际情况比示例更复杂。因此,不能将对象存储在单元格中,但如果您解释一下您想要实现的目标,可能会有替代方案。


也许我对VBA / Excel中的UDF有些不理解,但为什么会失去范围呢?InitializeMyClass难道不是返回一个MyClass变量吗?如果我有一个返回double类型的UDF,那么我当然可以将其嵌套在另一个接受double类型输入变量的UDF中。我认为至少函数嵌套应该起作用。顺便问一下,如何在单元格中存储指向用户定义数据类型的指针? - B Rivera

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接