将 C# 代码暴露给 VBA GetAutomationMethod 错误

Exposing C# Code to VBA GetAutomationMethod Error

我是一个相对较新的编码员,之前从未使用过 C# 或 VBA。我目前正在尝试将我的 C# 代码公开给 VBA。我一直在关注 MSDN guide 如何做到这一点。

我 运行 在覆盖我的方法时遇到错误:

public class AsynchronousClient : IAsynchronousClient {
    protected override object GetAutomationObject(){
        return this;
    }
}

错误是:

'AsynchronousClient.GetAutomationObject()': no suitable method found to override.

我已经能够提取界面并将 COMVisibleAttributes 添加到我的界面中。

任何关于如何修改代码的帮助或额外指导将不胜感激。

您的 AsynchronousClient class 正在实现 IAsynchronousClient 接口,我认为它看起来像这样:

public interface IAsynchronousClient
{
    object GetAutomationObject();
}

你可以这样实现它:

public class AsynchronousClient : IAsynchronousClient
{
    public object GetAutomationObject()
    {
        return this;
    }
}

错误消息准确说明了问题所在:override 没有任何内容。在实现 abstractvirtual 方法时使用 override 方法,而不是接口成员。

删除 override 关键字,一切都会好起来的。下面的片段显示了 override 适用的情况:

public abstract class AsynchronousClientBase
{
    public abstract object GetAutomationObject();

    public virtual object GetFoo()
    {
        return null;
    }
}


public class AsynchronousClient : AsynchronousClientBase
{
    public override object GetAutomationObject()
    {
        return this;
    }

    public override object GetFoo()
    {
        return new Foo();
    }
}

您链接到的 MSDN 文章说 "Override the GetAutomationObject method of a host item class in your project" - 这意味着您的类型应该 derived 来自定义虚拟或抽象的基础 class GetAutomationObject 方法。

正如其他人所提到的,您执行的步骤是特定于 VSTO 技术的,而不是用于创建要与 VBA 一起使用的 DLL。老实说,如果您以前从未用任何一种语言编写过代码,那么这可能不是最好的开始...

从 Class 项目开始。您需要 GUID。您需要一个接口,您的 class 需要实现该接口。并且您需要指定 class 应如何与界面一起使用。需要将其设置为 Type "None" 才能使 Intellisense 等工作。 DLL 也需要进行 COM 注册。

这是我使用的一些测试代码,让您了解代码部分的外观

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using vbForm = Microsoft.Vbe.Interop.Forms;
using office = Microsoft.Office.Core;

//[assembly: Guid("B5C4D7F5-C9B2-491e-91BA-63C208959190")]

namespace COM_ClassLib_CS
{

    [Guid("BF78EB64-F59B-4086-9FC5-B87AA2002F4F")]
    [ComVisible(true)]
    public interface IVBAExtensions
    {
        string getTest(object app);
        void formData(object formControl);
        void passWordDoc(object doc);
        object[,] returnArray();
        string returnString();
    }

    [Guid("EC0B623E-E8A0-4564-84FB-2D8D149C8BA7")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComVisible(true)]
    public class VBAExtensions : IVBAExtensions
    {
        public VBAExtensions()
        {
        }

        //test using late-binding
        public string getTest(object app)
        {
            object xlApp = app.GetType().InvokeMember("Application", System.Reflection.BindingFlags.GetProperty, null,
                app, null);
            object nm = xlApp.GetType().InvokeMember("Name", System.Reflection.BindingFlags.GetProperty, null,
                xlApp, null);
            string appName = nm.ToString();
            object isReady = xlApp.GetType().InvokeMember("Ready", System.Reflection.BindingFlags.GetProperty, null,
                xlApp, null);
            string sReady = isReady.ToString();
            return sReady;
        }

        //test calling from a UserForm, passing control as argument
        public void formData(object formControl)
        {
            //string data = "";
            vbForm.TextBox t = formControl as vbForm.TextBox;
            t.Text = "test";
            //return data;
        }

        //test passing doc object and accessing its Window
        public void passWordDoc(object doc)
        {
            Microsoft.Office.Interop.Word.Document WordDoc = doc as Microsoft.Office.Interop.Word.Document;
            WordDoc.ActiveWindow.Caption = "Tested!";
        }

        //test returning an array to VBA calling procedure
        public object[,] returnArray()
        {

            //object[] array = new object[2] {"a", "b"};
            object[,] array = new object[2, 2];
            array[0, 0] = "a";
            array[0, 1] = "1";
            array[1, 0] = "b";
            array[1, 1] = "2";
            return array;
        }

        //test returning a string to VBA calling procedure
        public string returnString()
        {
            return "AbC";
        }

    }
}

更多信息可以参考https://msdn.microsoft.com/en-us/library/c3fd4a20.aspx and https://msdn.microsoft.com/en-us/library/ms973802.aspx