【问题标题】:Create UDF using VSTO and no VBA使用 VSTO 而非 VBA 创建 UDF
【发布时间】:2009-02-12 09:42:44
【问题描述】:

类似于question(但在我的情况下不是 VSTO SE),但是,我只想确认在 Visual Studio 2005 和 Excel 2003 中使用纯 VSTO 创建 UDF 是不可能的 - 所以,绝对很清楚,我的问题是:

是否可以在不使用任何 VBA 或其他技巧的情况下使用 Visual Studio 2005 和 VSTO 解决方案创建 Excel 2003 UDF?

我知道 ManagedXLL、ExcelDNA、Excel4Net 等,但暂时不想考虑这些。

谢谢

【问题讨论】:

    标签: c# vsto excel-interop


    【解决方案1】:

    关于是否有办法绕过 COM 或 VBA,我认为这是不可能的(至少在没有任何非常肮脏的技巧的情况下是不可能的)。原因是 Office 可以执行外部代码(即您的加载项)的唯一方法是通过 COM。甚至 VSTO 在下面仍然使用旧的 IDTExtensibility2 COM 接口。 IDTExtensibility2 是 Microsoft Office 应用程序的所有加载项都必须实现的 COM 接口。

    在 VSTO 之前,Office 加载项必须自己实现此 IDTExtensibility2 接口。在这种基于 COM 的加载项(或 COM 可见的托管加载项)中,您可以按照here 的描述简单地添加您的 UDF。

    然而,现在有了 VSTO,多了一层抽象:VSTO 使用所谓的Solution Loader 实现 IDTExtensibility2,这是 VSTO 运行时提供的一个 dll。这意味着您的加载项不再是 COM 可见的。因此,如果您将 UDF 添加到 VSTO 加载项,Office 将看不到它。

    Paul Stubbs 在他的博客中解释了如何使用 VSTO 和 VBA:How to create Excel UDFs in VSTO managed code

    1. 用你在 VSTO 中的函数创建一个类

      <System.Runtime.InteropServices.ComVisible(True)>
      Public Class MyManagedFunctions
          Public Function GetNumber() As Integer
              Return 42
          End Function 
      End Class
      
    2. 在 VSTO 中将您的课程连接到 VBA

      Private Sub ThisWorkbook_Open() Handles Me.Open
          Me.Application.Run("RegisterCallback", New MyManagedFunctions)
      End Sub
      
    3. 为托管代码创建 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。

    【讨论】:

    • 嗨 - 谢谢。是的,我知道通过使用一些 VBA 和 COM 来装饰我的班级,我可以做到这一点,但鉴于问题的警告,这并不能回答问题。
    • 我编辑了我的答案以解释为什么我认为没有办法绕过 COM 或 VBA。
    【解决方案2】:

    我不明白你为什么要这样做?

    VSTO 和通过 COM 互操作(来自 .NET)公开 UDF 是两个不同的任务。 为什么要在 VSTO 项目中托管 UDF 方法?

    注册 .net UDF 程序集的方式意味着它必须位于与 VSTO 项目不同的项目中。但是,如果您想在两个应用程序之间共享数据,那么您可以使用各种本机 .net 方法,或者只是从您的 VSTO 项目中的适当范围对象中“调用”UDF 函数。

    您认为有必要在 VSTO 中使用 UDF 吗?

    【讨论】:

      【解决方案3】:

      this 文章中,Eric Carter 继续解释如何按照您的要求进行操作。在顶部,他甚至链接到上述博客文章的更新。

      【讨论】:

      • 谢谢,但该链接解决方案不使用 VSTO,它只是将 .Net 程序集的类型公开给 COM。
      • 您仍在谈论两个功能上不同的概念,并且没有修改您的问题来说明为什么将 UDF 与 VSTO 项目放在同一个项目中如此重要。
      【解决方案4】:

      按照 Eric Carter 的说明创建 UDF,并将 Excel 范围作为参数传递给您的 UDF。您可以使用给定的范围通过 VSTO 访问 Excel 的对象模型: Excel.Range rg = param1 as Excel.Range; Excel.Workbook wb = rg1.Worksheet.Application.ActiveWorkbook;

      【讨论】:

        【解决方案5】:

        我不熟悉使用 VS2005 和 VSTO 在 Excel 2003 中创建 UDF 的方法,而无需至少一点 VBA。这里有 2 个链接可以进一步讨论这个问题:

        http://geekswithblogs.net/Denis/archive/2007/01/03/102623.aspx

        http://blogs.msdn.com/pstubbs/archive/2004/12/31/344964.aspx

        【讨论】:

        • 谢谢,但根据问题,有没有办法在没有任何 VBA 的情况下做到这一点?似乎可以使用 VSTO SE 完成,但仅使用 pure VSTO 可以完成吗?
        • 对不起,我不知道任何纯 VSTO 方式,只是 VBA/VSTO 组合。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-12
        • 2019-07-07
        • 2016-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多