我有一个对象列表,它们是表中的“键” - 键只是第一列中的项。它们可以是整数或字符串,具体取决于我们从中读取的数据库表。由于我们经常使用它们,我们将该列缓存在名为“Keys”的ArrayList中。
我们编写了返回Row的封面方法,一个使用字符串和其他整数的方法。如果调用整数版本,它只是按索引返回该行。如果你调用字符串,它会向下查找匹配键,并使用该索引来拉出该行。
好的,现在我将密钥传递给Excel,在循环中拉出其中一个,并询问它是什么......
TypeName(DB.Keys(i))
对象返回......
Long
很好,键必须是整数!所以现在我将通过调用存取方法Row ...
来尝试获取该键的行DB.Row(DB.Keys(i))
它调用带有String的版本。
哇!
任何人都可以想到VBA回调我们的VB.net DLL最终会调用错误的访问者的原因吗?
ADDED CODE:我无法弄清楚如何将代码作为回复,所以我正在编辑它。这是VB.net类中的代码:
Public Function Row(ByVal K As String) As DataRow
Dim R As DtaRow = DB.Tables(0).Rows(K)
Return New DataRow(R)
End Function
Public Function Accounts(ByVal K As Integer) As DataRow
Dim R As DtaRow = DB.Tables(0).Rows(K)
Return New DataRow(R)
End Function
如果您想知道,有两个版本的行,它们采用字符串或整数。
此代码在VB.net中运行良好。您可以通过键字符串或行号询问一行,该行调用正确的行,调用正确的行,然后输出正确的答案。
但是在VBA中,它总是使用字符串输入调用该方法。如果我将它重命名为RowIHATEYOUALL,那么我可以调用Integer版本。但是当他们有两个时,只有签名不同,没有这样的运气。
A和我(见评论)是我的错字。
答案 0 :(得分:1)
互操作层不支持重载方法。每当您致电Row
时,都会使用带有该名称的首次声明的方法。 .NET重载解析算法不适用于此。
其他重载以Row_2
,Row_3
等方式向VBA公开。因此,以下代码应该按预期执行:
DB.Row_2(DB.Keys(i))
这种对声明顺序的隐含依赖具有很高的错误可能性。因此,我建议
或者,如果您想保留.NET的“漂亮”重载版本,请为VBA添加兼容性方法:
<Obsolete("Compatibility method for VBA, use Row instead.")>
Public Function RowByKeyVBA(ByVal K As String) As DataRow
Return Row(K)
End Function
<Obsolete("Compatibility method for VBA, use Row instead.")>
Public Function RowByNumberVBA(ByVal K As Integer) As DataRow
Return Row(K)
End Function
更多信息可在以下问题中找到:
答案 1 :(得分:0)
按照Heinzi的注释(上图),我通过为每个调用制作三个方法签名来修复此问题,一个采用一个Object,然后尝试弄清楚它是什么,其他人采用字符串和整数。在VB / C#/ etc中,正如所期望的那样调用正确的String或Integer方法,从VBA调用Object版本,Heinzi指出
这会导致非常小的问题,即用户可能具有“数字值”,实际上是一个字符串。例如,数组键可能是“User3232”或“3232”,两者都是表中的String对象。所以你必须要小心,只是询问Object是否可以转换为Int32是不够的。这不太可能影响大多数用户。