【问题标题】:How do I use a .NET class in VBA? Syntax help!如何在 VBA 中使用 .NET 类?语法帮助!
【发布时间】:2010-04-04 08:19:01
【问题描述】:

好的,我有几个要在 VBA 中使用的 .NET 类。所以我必须通过 COM 注册它们。我想我(终于)弄清楚了 COM 注册,但现在我需要有关如何创建对象的语法的帮助。这是一些伪代码,显示了我正在尝试做的事情。

编辑:将附加对象更改为返回 ArrayList 而不是 List

.NET 类看起来像这样...

public class ResourceManagment
{
    public ResourceManagment()
    {
        // Default Constructor
    }

    public static List<RandomObject> AttachedObjects()
    {
        ArrayList list = new ArrayList();
        return list;
    }
}

public class RandomObject
{
    // 
    public RandomObject(int someParam)
    {

    }

}

好的,这就是我想在 VBA 中做的事情(在 C# 中演示),但我不知道如何......

public class VBAClass
{
    public void main()
    {
        ArrayList myList = ResourceManagment.AttachedObjects();
        foreach(RandomObject x in myList)
        {
            // Do something with RandomObject x like list them in a Combobox
        }
    }
}

需要注意的一点是 RandomObject 没有公共的默认构造函数。所以我不能像Dim x As New RandomObject 这样创建它的实例。 MSDN 说你不能通过 COM 实例化一个没有默认构造函数的对象,但是如果它是由另一个方法返回的,你仍然可以使用该对象类型... Types must have a public default constructor to be instantiated through COM. Managed, public types are visible to COM. However, without a public default constructor (a constructor without arguments), COM clients cannot create an instance of the type. COM clients can still use the type if the type is instantiated in another way and the instance is returned to the COM client. You may include overloaded constructors that accept varying arguments for these types. However, constructors that accept arguments may only be called from managed (.NET) code.

补充:这是我在VB中的尝试:

Dim count As Integer
count = 0
Dim myObj As New ResourceManagment
For Each RandomObject In myObj.AttachedObjects
    count = count + 1
Next RandomObject

【问题讨论】:

    标签: .net vba com instantiation


    【解决方案1】:

    您的问题是 AttachedObjects() 方法是静态的。 COM 不能做静态方法。在 COM 中,唯一可以做的“静态”操作是“实例化一个类”。

    因此,为了从 VBA 调用 AttachedObjects 方法,只需将其设为非静态(即删除其定义中的 static 关键字)。除此之外,该方法可能与现在完全一样。而且你的 VBA 代码看起来也不错 - 一旦你修改了方法应该可以工作。

    以防万一它不起作用,这是下一个问题:你到底得到了什么错误,在什么时候?

    【讨论】:

      【解决方案2】:

      要解决这个问题,您需要在 .net 代码中创建一个 RandomObjectFactory 并让它创建 RandomObject 实例以在 VBA 中使用

      所以是这样的:

      public class RandomObjectFactory
      {
           public static Create(int someParam)
           {
                return new RandomObject(someParam);
           } 
      }
      

      你可以扩展这个类来拥有更多的 create 方法重载来创建不同的 RandomObjects 重载

      更新:

      基于对问题的正确理解this questionthis one可能会有用

      【讨论】:

      • 好吧,我并不是真的想从 VBA 中“创建”一个 RandomObject 实例。我只是想使用在 ResourceManagement 类(托管 .NET)中创建的 RandomObjects 列表。
      • 抱歉,我当时误读了这个问题。你想知道循环的 vba 语法吗?你的第一个问题是你已经向 com 端返回了一个泛型列表,但是 com 不支持泛型(你应该得到一个编译器警告,开始这是你想要做的。)你能做到吗?访问 VBA 中的 ResourceManagement 类?
      • 是的。在 VBA 项目中,我添加了对 .NET 程序集的引用。然后在 VBA 中我可以做到这一点“将 myObj 作为新的资源管理”,但是我该如何调用 AttachedObjects 方法。
      • 正如我所说,您看不到该方法,因为它是通用的并且 com 不支持该方法。您需要添加一个新方法,该方法返回 COM 可以理解的内容。我认为您可能会返回一个集合,但为了安全起见,我会返回 RandomObject[]。您可以将该功能委托给现有功能并返回 newList.ToArray();我没有使用 VBA 中的 .net com 做太多事情,所以我不确定您是否能够直接使用该数组,但在 C++ 中,我们可以使用 SafeArrays 来访问 com 数组。 VBA 对 com 的支持可能要好得多,所以这可能更容易
      • ArrayList 代替 List 怎么样?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-10
      • 2016-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多