我是一个相对较新的编码员,以前从未使用过C#或VBA。我目前正在尝试将我的C#代码暴露给VBA。我一直关注MSDN guide如何做到这一点。
在覆盖我的方法时遇到错误:
public class AsynchronousClient : IAsynchronousClient {
protected override object GetAutomationObject(){
return this;
}
}
错误是:
' AsynchronousClient.GetAutomationObject()':找不到合适的覆盖方法。
我已经能够提取界面并将COMVisibleAttributes
添加到我的界面。
有关如何修改代码的任何帮助或其他指导将不胜感激。
答案 0 :(得分:0)
您的AsynchronousClient
类正在实现IAsynchronousClient
接口,我认为这个接口如下:
public interface IAsynchronousClient
{
object GetAutomationObject();
}
你会像这样实现它:
public class AsynchronousClient : IAsynchronousClient
{
public object GetAutomationObject()
{
return this;
}
}
错误消息确切地说明了问题所在:那里没有override
。在实施override
或abstract
方法时使用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.aspx和https://msdn.microsoft.com/en-us/library/ms973802.aspx