在 Visual Studio 中,我有一个 Excel 2010 插件项目。我怎样才能让该项目创建以下模块:
我知道我可以使用该模块保存该工作簿,然后将其与我的插件一起使用。如果我可以让我的插件创建该模块,那就太好了...
在 Visual Studio 中,我有一个 Excel 2010 插件项目。我怎样才能让该项目创建以下模块:
我知道我可以使用该模块保存该工作簿,然后将其与我的插件一起使用。如果我可以让我的插件创建该模块,那就太好了...
可以创建模块。但是,要使其正常工作,必须在 Excel 中选择“信任对 VB 项目模型的访问”的设置。如果未选择信任设置,则会引发拒绝访问的错误。
using Excel = Microsoft.Office.Interop.Excel;
using VB = Microsoft.Vbe.Interop;
Excel.Application eApp = new Excel.Application();
eApp.Visible = true;
Excel.Workbook eBook = eApp.Workbooks.Add();
VB.VBProject eVBProj = (VB.VBProject)eBook.VBProject;
VB._VBComponent vbModule = eVBProj.VBE.ActiveVBProject.VBComponents.Add(VB.vbext_ComponentType.vbext_ct_StdModule);
String functionText = "Function MyTest()\n";
functionText += "MsgBox \"Hello World\"\n";
functionText += "End Function";
vbModule.CodeModule.AddFromString(functionText);
我不认为 VSTO 支持 Excel UDF,一般建议是使用自动化插件(如 Sid 的链接所示)。
另一种选择是从 VBA 调用托管 VSTO 函数。再一次,这是不推荐的,但可能的。
(链接中的教程回顾)这是从 VBA 调用托管函数的任何简单方法。
在 VSTO 中使用您的函数创建一个类
<System.Runtime.InteropServices.ComVisible(True)> _
Public Class MyManagedFunctions
Public Function GetNumber() As Integer
Return 42
End Function
End Class
在 VSTO 中将您的课程连接到 VBA
Private Sub ThisWorkbook_Open() Handles Me.Open
Me.Application.Run("RegisterCallback", New MyManagedFunctions)
End Sub
为托管代码创建 Hook 并为 VBA 中的函数创建一个包装器
在电子表格或文档的 VBA 模块中
Dim managedObject As Object
Public Sub RegisterCallback(callback As Object)
Set managedObject = callback
End Sub
Public Function GetNumberFromVSTO() As Integer
GetNumberFromVSTO = managedObject.GetNumber()
End Function
现在您可以在单元格中输入 =GetNumberFromVSTO(),当 excel 启动时,单元格的值应该是 42。
http://blogs.msdn.com/b/pstubbs/archive/2004/12/31/344964.aspx
如果您真正想做的是编写 .NET UDF,或组合 .NET 应用程序级命令和 UDF 插件,那么使用 VSTO 目前不是一个好的解决方案:
我建议使用Addin Express(成本)或Excel DNA(免费)。
这两者都允许您创建 .NET XLL UDF 插件和自动化 UDF 插件(XLL UDF 插件提供显着的性能优势,但对 Excel 对象模型的访问稍有限制)
VSTO 插件无法创建 UDF,因此您需要为函数创建单独的插件。尽管此插件可以与 VSTO 插件在同一个 DLL 中,但如果没有特殊技巧,您无法在 VSTO 和 UDF 之间进行通信。
我有一篇关于这个的博客文章。它为您提供了一个完整的示例项目,其中包括 VSTO 和 UDF。
这是UDF本身的基本结构。
[Guid("3B81B6B7-3AF9-454F-AADF-FAF06E5A98F2")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[ComVisible(true)]
public interface IFunctions
{
int MYINT();
}
[Guid("F58C591D-A22F-49AD-BC21-A086097DC26B")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class Functions : IFunctions
{
public int MYINT()
{
return 42;
}
}