如何从VBA和Excel调用C#函数

如何从VBA和Excel调用C#函数,c#,excel,vba,vsto,C#,Excel,Vba,Vsto,我在Visual Studio 2019上安装了VSTO,并开始编写如下简单脚本: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; using Excel = Microsoft.Office.Interop.Excel; using Office = Microsoft.Office.Core; using Microsoft

我在Visual Studio 2019上安装了VSTO,并开始编写如下简单脚本:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Excel;

namespace ExcelAddIn1
{
    public partial class ThisAddIn
    {
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        private double ReturnMagicNumber()
        {
            return 123;
        }


        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }
        
        #endregion
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml.Linq;
使用Excel=Microsoft.Office.Interop.Excel;
使用Office=Microsoft.Office.Core;
使用Microsoft.Office.Tools.Excel;
命名空间ExcelAddIn1
{
公共部分类ThisAddIn
{
私有void ThisAddIn_启动(对象发送方,System.EventArgs e)
{
}
私有void ThisAddIn_关闭(对象发送方,System.EventArgs e)
{
}
私有双返回magicnumber()
{
返回123;
}
#区域VSTO生成的代码
/// 
///设计器支持所需的方法-不修改
///此方法的内容与代码编辑器一起使用。
/// 
私有void InternalStartup()
{
this.Startup+=new System.EventHandler(ThisAddIn\u启动);
this.Shutdown+=new System.EventHandler(ThisAddIn\u Shutdown);
}
#端区
}
}
我想知道如何在Excel中使用
ReturnMagicNumber()
函数作为用户函数,以及如何从VBA宏调用它


谢谢

VSTO不提供任何用于为Excel开发用户定义函数的功能。您需要自己创建这样的项目-它可以是自动化插件或XLL插件。这两种方法在本文中都有很好的描述


如果你选择的是XLL插件,你可以考虑使用它来简化开发很多。

< P> OK,我在不需要Excel DNA的情况下工作。

对于解决方案,我阅读了这篇文章,代码如下:

using System;
using System.Data;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;


namespace MagicNumberAddIn
{

    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface INumberGetter
    {
        double ExcelReturnNumber();
    }

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class NumberGetter : INumberGetter
    {
        public double ExcelReturnNumber()
        {
            return 123.0;
        }
    }


    public partial class MagicNumber
    {

        private NumberGetter myAddIn;

        protected override object RequestComAddInAutomationService()
        {
            if (myAddIn == null)
                myAddIn = new NumberGetter();

            return myAddIn;
        }


        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }
        
        #endregion
    }
}
VS 2019的C#代码如下:

using System;
using System.Data;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;


namespace MagicNumberAddIn
{

    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface INumberGetter
    {
        double ExcelReturnNumber();
    }

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class NumberGetter : INumberGetter
    {
        public double ExcelReturnNumber()
        {
            return 123.0;
        }
    }


    public partial class MagicNumber
    {

        private NumberGetter myAddIn;

        protected override object RequestComAddInAutomationService()
        {
            if (myAddIn == null)
                myAddIn = new NumberGetter();

            return myAddIn;
        }


        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }
        
        #endregion
    }
}

这对我来说很有用,因为我想要的是能够在VBA中使用C#插件,以便在VBA中获得多任务和异步功能。

是一个选项吗?这是否回答了您的问题?这是一件非常简单的事情,我正试图在这里完成。如果VSTO本身不能做到这一点,我甚至不明白为什么会存在……我看不到任何地方可以从Excel DNA C#中编写的VBA调用函数。很多关于VSTO的书都是从2007年开始的,之后就没有了,所以我开始猜测VSTO并不像VisualStudio中的其他东西那样被开发出来。问题是关于用VSTO开发用户定义的Excel函数。你可以直接问Excel DNA开发者这是否是你的选择。嗨,我已经找到了解决方案并发布在这里。但是我有一个问题,这个
[ComVisible(true)]
叫什么?我在任何一本书中都找不到这种代码,你知道这行代码在C#语法中是什么吗?