Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将用户定义的函数添加到Visual Studio Excel加载项_C#_Excel_User Defined Functions_Excel Addins - Fatal编程技术网

C# 将用户定义的函数添加到Visual Studio Excel加载项

C# 将用户定义的函数添加到Visual Studio Excel加载项,c#,excel,user-defined-functions,excel-addins,C#,Excel,User Defined Functions,Excel Addins,在VisualStudio中,我有一个Excel 2010加载项项目。如何让该项目创建以下模块: 我知道我可以将工作簿与该模块一起保存,然后将其与外接程序一起使用。如果我可以让我的外接程序创建该模块,那就太好了。我认为VSTO不支持Excel UDF,一般建议使用自动化外接程序(如Sid的链接所示) 另一个选项是从VBA调用托管VSTO函数。同样,不建议这样做,但这是可能的 (链接中的教程摘要) 下面是从VBA调用托管函数的简单方法 使用VSTO中的函数创建一个类 <System.Run

在VisualStudio中,我有一个Excel 2010加载项项目。如何让该项目创建以下模块:


我知道我可以将工作簿与该模块一起保存,然后将其与外接程序一起使用。如果我可以让我的外接程序创建该模块,那就太好了。

我认为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
为托管代码创建钩子,并为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


可以创建模块。但是,要使其工作,必须在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加载项无法创建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;
    }
}

如果您真正想做的是编写.NET UDF,或者将.NET应用程序级命令和UDF加载项组合在一起,那么使用VSTO目前不是一个好的解决方案:
我建议使用(成本)或(免费)。
这两种方法都允许您创建.NET XLL UDF加载项和自动化UDF加载项(XLL UDF加载项提供了显著的性能优势,但对Excel对象模型的访问稍微受限)

也许会有所帮助。不!在走这条路之前要三思而后行。我敦促您使用UDF方法,以便您的代码逻辑是正确的)防止Excel用户更改很难检测到的关键逻辑b)在一个加载项中且不在多个工作簿中复制c)不需要受信任的权限d)单元可测试e)使用最新语言编写等,这就是我现在拥有的。如果我可以发布插件而不必发布启用宏的工作簿(book1.xlsx),那就太好了,所以我想这是不可能的,对吧?
[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;
    }
}