将 VSTO 功能公开给 VBA,无需本地管理

发布于 2024-07-06 02:55:49 字数 252 浏览 9 评论 0原文

将 Dotnet VSTO Excel 加载项中的某些功能公开到 VBA 的最佳方法是什么,而不要求用户成为本地管理员(即无需 COM 注册,没有 HttpListener)? 是否可以通过 VBA 使用 Microsoft 消息队列?

What would be the best way to expose certain functionality in a Dotnet VSTO Excel add-in to VBA, without requiring the user to be a local administrator (i.e. no COM registration, no HttpListener)? Would it be possible to use Microsoft Message Queues from VBA?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

つ低調成傷 2024-07-13 02:55:49

如果我可以将您的问题解释为“如何在不注册 COM 的情况下将 .Net 程序集中的功能公开给 Excel”,那么一个很好的解决方案是使用 Excel 的 XLL 接口。
基本上,部署一个 xll shim 和一个关联的 .Net dll。 加载 xll 时,它会反映 dll 并将其中的函数公开给 Excel。

可以在此处找到开源实现 http://exceldna.typepad.com/ blog/2006/01/introducing_exc.html

这是一个商业的、封闭源代码的,但功能更丰富的一个
http://www.managementxll.com/

If I may interpret your question as broadly as "How do I expose functionality in a .Net assembly to Excel without COM registration" then an excellent solution is to use Excel's XLL interface.
Basically one deploys an xll shim and an associated .Net dll. When the xll is loaded it reflects over the dll and exposes the functions therein to Excel.

An open source implementation can be found here http://exceldna.typepad.com/blog/2006/01/introducing_exc.html

A commercial, closed source, but more feature rich one here
http://www.managedxll.com/

离不开的别离 2024-07-13 02:55:49

您不能简单地将它们实例化为 COM 对象,因为 VSTO 将不会在默认应用程序域中运行。

这是我的做法,诚然有点复杂。 这是将 VSTO 工作簿另存为 XLA 文件,在某些方面比纯 VSTO 外接程序更灵活。

  • 您需要使用 regasm.exe 生成将由您的 VBA 代码引用的类型库。

  • 在 .NET 对象模型中创建一个根工厂类,它能够实例化您想要在 VBA 中使用的任何类(类似于 Office 对象模型中的“Application”类)。

  • 然后您需要找到一种方法将此工厂类实例的引用传递给 VBA。 一旦 VBA 拥有对此工厂类实例的引用,它就可以调用其方法来实例化 .NET 对象模型中的任何其他对象。

  • 要将实例传递给 VBA,请在 VBA 代码中定义一个宏,如下所示

示例代码:

Private m_objMyFactory As Object

Public Sub RegisterFactory(MyFactory As Object)

    On Error GoTo ErrHandler
    Set m_objMyFactory = MyFactory
    Exit Sub
ErrHandler:
    MsgBox "An unexpected error occurred when registering the Factory component: " & Err.Description
    Exit Sub
End Sub
  • 现在将代码添加到 VSTO ThisWorkbook_Open 事件handler,它实例化您的工厂对象并调用上面的宏,传递对工厂对象的引用。

示例代码:

void ThisWorkbook_Open()
{
     try
     {
         ThisApplication.Run("RegisterFactory",
             new MyNamespace.MyFactory(),
             Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
             Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
             Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
             Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
             Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
             Type.Missing, Type.Missing, Type.Missing, Type.Missing);
     }
     catch (Exception ex)
     {
         MessageBox.Show("Load error: " + ex.ToString());
     }
}

为了使其稳健地工作,还有一些问题需要考虑 - 如果您有兴趣跟进此问题,请告诉我,我将发布更多详细信息。

You can't simply instantiate them as COM objects, as VSTO will not be running in the default application domain.

Here is how I've done it, which is admittedly a bit convoluted. This was with a VSTO workbook saved as an XLA file, which in some ways is more flexible than a pure VSTO add-in.

  • You need to generate a type library using regasm.exe that will be referenced by your VBA code.

  • Create a root factory class in your .NET object model, which is capable of instantiating any of the classes you want to consume in VBA (something like the "Application" class in the Office object models).

  • You then need to find a way to pass a reference to an instance of this factory class to VBA. Once VBA has a reference to an instance of this factory class, it can call its methods to instantiate any other objects in your .NET object model.

  • To pass an instance to VBA, define a macro in your VBA code as follows

Example code:

Private m_objMyFactory As Object

Public Sub RegisterFactory(MyFactory As Object)

    On Error GoTo ErrHandler
    Set m_objMyFactory = MyFactory
    Exit Sub
ErrHandler:
    MsgBox "An unexpected error occurred when registering the Factory component: " & Err.Description
    Exit Sub
End Sub
  • Now add code to the VSTO ThisWorkbook_Open event handler, which instantiates your factory object and calls the above macro passing a reference to the factory object.

Example code:

void ThisWorkbook_Open()
{
     try
     {
         ThisApplication.Run("RegisterFactory",
             new MyNamespace.MyFactory(),
             Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
             Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
             Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
             Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
             Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
             Type.Missing, Type.Missing, Type.Missing, Type.Missing);
     }
     catch (Exception ex)
     {
         MessageBox.Show("Load error: " + ex.ToString());
     }
}

There are a few more issues to consider to get this working robustly - if you're interested in following this up let me know and I'll post more details.

舟遥客 2024-07-13 02:55:49

您可能对 Excel4Net 感兴趣(它类似于 ExcelDNA 和 ManagedXll,但更易于使用):

网站:
http://www.excel4net.com

博客:
http://excel4net.blogspot.com

You may be interested in Excel4Net (it is similar to ExcelDNA and ManagedXll, but easier to use):

website:
http://www.excel4net.com

blog:
http://excel4net.blogspot.com

陈独秀 2024-07-13 02:55:49

仅供未来读者参考:您可能还想看看这个问题:

从 VBA (Excel) 访问 VSTO 应用程序插件类型

,特别是访问其中引用的博客:

VSTO 加载项、COMAddIns 和 RequestComAddInAutomationService

通过重写 RequestComAddInAutomationService () 您可以通过定义一个为所有这些功能提供入口点的 Facade 类并将该类公开给 VBA 来公开您想要的任何功能。

Just for reference for future readers: You might also want to have a look to this question:

Accessing a VSTO application-addin types from VBA (Excel)

and, in particular, to the blog that is referenced there:

VSTO Add-ins, COMAddIns and RequestComAddInAutomationService

By overriding RequestComAddInAutomationService() you can expose whatever functionality you want, by defining a Facade class that provides entry points for all those features, and exposing that class to VBA.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文