是否可以让 .NET 列表<T>显示在 VBA 中?



Nutshell:

是否可以让 VBA 与在 .NET (C#) 类库中创建的列表进行交互?我看到List<T>属于System.Collections.Generic所以我不能以某种方式轻松让 VBA 使用它吗?

背景:

我有一个 C# 构建的接口,用于在 VBA 中创建智能感知选项的类:

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("47BC2BB4-B7AA-427E-9971-4EA996412D709813")]
public interface IMyClass
{
bool Test1 { get; set; }
List<NameSpacer.CustomClass> MyListOfCustoms { get; }
}

MyClass是从界面派生的,我使用 progID 和 blahblah 正确设置了所有内容,因此在 Access 或 Excel 中的 VBA 中使用此类时,基本上我的所有字段和属性都显示得很好......

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("JamHeadArt.MyClass")]
[Guid("60437B5C-5AFE-491C-9264-7475A96AE321")]
public class MyClass : IMyClass
{
public bool Test1 { get; set; }
public List <NameSpacer.CustomClass> MyListOfCustoms { get; private set; }
}

除了名单!我想知道是否可以让 VBA 查看列表?由于 VBA 不处理列表...

这不是我的命名空间,因为 CustomClass 属于子命名空间 - 我尝试更改为全局命名空间,但没有效果。

这不是因为它是CustomClass列表并且它可以很好地处理字符串吗? 我已经为我的自定义类设置了接口,也可以在 VBA 中使用它。我尝试了一个简单的字符串List,但也没有用。

所以我想我可能必须编写一个自定义的列表包装类才能让 VBA 能够使用列表,但希望有人能阐明为什么它不可见以及最简单的方法是什么。

我正在与您分享一些代码示例,这些示例用于将某些对象的集合传递给vba:

接口:

[DispId(17)]
int GetCustomerDetails(long custId, out ArrayList customerDetails);

实现:

public int GetCustomerDetails(long custId, out ArrayList details)
{
// . . . getting data from provider or something
details = provider.GetDetails(custId);
// other stuff    
// return code.
}

成功注册对象后,您可以通过以下方式从 vba 获取该数据:

Dim oDetails As Object
Dim obj
Private Sub SomeCommand_Click()
Dim ret As Integer
Set obj = CreateObject("YourObject") 'The requirement was to create object without referencing actual library
ret = obj.GetCustomerDetails(custId.Text, oDetails)
Dim str As String
str = oDetails(0).YourPropertyName
'. . .
End Sub

这些属性应该以类似的方式工作(我实际上还没有测试过这部分,如果有什么不工作,请告诉我):

C#:

public ArrayList MyListOfCustoms { get; set; }

VBA:

Dim obj
Private Sub SomeCommand_Click()
Set obj = CreateObject("YourObject")
Dim str As String
str = obj.MyListOfCustoms(0).YourPropertyName
'. . .
End Sub

您可以通过 system.collections 访问 SortedList 和 ArrayList

Set sortedList = CreateObject( "System.Collections.Sortedlist" )
Set arrayList = CreateObject( "System.Collections.Arraylist" )

它们必须与后期绑定或添加引用一起使用,但没有智能意义。

例如,使用 ArrayList

ThisWorkbook.VBProject.References.AddFromguid "{BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}", 2, 4

还有.AddFromFile方法。

虽然我将接受 SeM 的答案,但根据最初提供的评论,我也用我自己的问题回答我是如何做到的:

在我的界面中,我添加了 ArrayList:

ArrayList Attributes { get; }

对我的班级也:

public ArrayList Attributes { get; private set; }

ArrayList不采用类型,因为它们是异构的。

使用最少的代码,我能够在以下过程中将所有List传递给数组列表 我的类结构是这样的:

Atts = new List<MyCustomClass>();
Atts.Add(a)
...
Atts.Add(z);
Attributes = new ArrayList(Atts); // This was the only new line I had to write.

对于初始化后列表会增长和缩小的所有情况,这并不理想,但对我来说它是完美的。

如果我想从两个列表中添加和删除内容,我必须构建几个方法。

最新更新