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

时间:2016-05-03 14:28:26

标签: c# excel vba excel-vba com

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

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

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

错误是:

  

' AsynchronousClient.GetAutomationObject()':找不到合适的覆盖方法。

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

有关如何修改代码的任何帮助或其他指导将不胜感激。

2 个答案:

答案 0 :(得分:0)

您的AsynchronousClient类正在实现IAsynchronousClient接口,我认为这个接口如下:

public interface IAsynchronousClient
{
    object GetAutomationObject();
}

你会像这样实现它:

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

错误消息确切地说明了问题所在:那里没有override。在实施overrideabstract方法时使用virtual方法,而不是接口成员。

删除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文章说“覆盖项目中主机项类的GetAutomationObject方法” - 这意味着您的类型应该来自定义虚拟或抽象的基类派生 GetAutomationObject方法。

答案 1 :(得分:0)

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

从Class项目开始。你需要GUID。您需要一个您的类需要实现的接口。您需要指定类应如何与Interface一起使用。它需要设置为“无”类型,以便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.aspxhttps://msdn.microsoft.com/en-us/library/ms973802.aspx