使用VB.NET为VBA IDE构建加载项

Oor*_*ang 12 vb.net vba add-in vbe

我在其他地方问了这个问题,但是从来没有发现任何人知道如何使用VB.NET为VBA IDE构建一个加载项.它甚至可能吗?有人能给我一个例子吗?

alm*_*ori 16

您可能需要使用IDTExtensibility2接口编写com插件,从新项目中选择共享插件项目模板.

编辑

否则,要从头开始创建此插件,您需要执行以下操作:

  1. 创建一个新的项目类库
  2. 添加对"可扩展性"的引用,它应该在列表中.您可能需要为您的办公室版本下载PIA.(也许是VSTO,但我不确定这一点)
  3. 再次添加对"Microsoft.Vbe.Interop"的引用应该与PIA一起使用.
  4. 选中属性选项卡中的"注册Com Interop"框.
  5. 可选在调试设置选项卡中,将启动更改为外部程序,并在programfiles文件夹中输入excel exe的路径(如果这是针对excel的),这是为了允许项目可调试.
  6. 可选在命令选项中,在工作表中添加一个条目,或者在启动时使用宏显示addin对话框的word文档,以便进行开发,这样可以简化调试体验.例如"C:\ vbe.xlsm"
  7. 可选还设置工作表目录的启动路径,例如"C:\"
  8. 实现"可扩展性"程序集中的"IDTExtensibility2"接口.
  9. 将此类命名为"Connect"(这只是一个偏好)
  10. 使用以下内容对类进行属性

[ComVisible(true),Guid("YourGeneratedGuid"),ProgId("YourAddinName.Connect")]

下面是一个让你入门的实现,首先用你的AppName替换"YourAddinName"并为"YourGeneratedGuid"创建一个Guid.您需要将Addin注册到正确的注册表位置,查看后面的注册表项以获取想法,还要替换注册表项中的一些vars.

Imports System
Imports System.Drawing
Imports System.Linq
Imports System.Runtime.InteropServices
Imports Extensibility
Imports Microsoft.Vbe.Interop

Namespace VBEAddin


''' <summary>
''' The object for implementing an Add-in.
''' </summary>
''' <seealso class='IDTExtensibility2' />
<Guid("YourGeneratedGuid"), ProgId("YourAddinName.Connect")> _ 
Public Class Connect
    Implements IDTExtensibility2
    Private _application As VBE 'Interop VBE application object


    #Region "IDTExtensibility2 Members"

    ''' <summary>
    ''' Implements the OnConnection method of the IDTExtensibility2 interface.
    ''' Receives notification that the Add-in is being loaded.
    ''' </summary>
    ''' <param term='application'>
    ''' Root object of the host application.
    ''' </param>
    ''' <param term='connectMode'>
    ''' Describes how the Add-in is being loaded.
    ''' </param>
    ''' <param term='addInInst'>
    ''' Object representing this Add-in.
    ''' </param>
    ''' <seealso class='IDTExtensibility2' />
    Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, ByVal addInInst As Object, ByRef [custom] As Array)
    _application = CType(Application,VBE)
    End Sub

    Private Sub onReferenceItemAdded(ByVal reference As Reference)
        'TODO: Map types found in assembly using reference.
    End Sub

    Private Sub onReferenceItemRemoved(ByVal reference As Reference)
        'TODO: Remove types found in assembly using reference.
    End Sub


    Private Sub BootAddin()
        'Detect change in active window. 
    End Sub

    ''' <summary>
    ''' Implements the OnDisconnection method of the IDTExtensibility2 interface.
    ''' Receives notification that the Add-in is being unloaded.
    ''' </summary>
    ''' <param term='disconnectMode'>
    ''' Describes how the Add-in is being unloaded.
    ''' </param>
    ''' <param term='custom'>
    ''' Array of parameters that are host application specific.
    ''' </param>
    ''' <seealso class='IDTExtensibility2' />
    Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef [custom] As Array)
    End Sub

    ''' <summary>
    ''' Implements the OnAddInsUpdate method of the IDTExtensibility2 interface.
    ''' Receives notification that the collection of Add-ins has changed.
    ''' </summary>
    ''' <param term='custom'>
    ''' Array of parameters that are host application specific.
    ''' </param>
    ''' <seealso class='IDTExtensibility2' />
    Public Sub OnAddInsUpdate(ByRef [custom] As Array)
    End Sub

    ''' <summary>
    ''' Implements the OnStartupComplete method of the IDTExtensibility2 interface.
    ''' Receives notification that the host application has completed loading.
    ''' </summary>
    ''' <param term='custom'>
    ''' Array of parameters that are host application specific.
    ''' </param>
    ''' <seealso class='IDTExtensibility2' />
    Public Sub OnStartupComplete(ByRef [custom] As Array)
        'Boot dispatcher

    End Sub


    ''' <summary>
    ''' Implements the OnBeginShutdown method of the IDTExtensibility2 interface.
    ''' Receives notification that the host application is being unloaded.
    ''' </summary>
    ''' <param term='custom'>
    ''' Array of parameters that are host application specific.
    ''' </param>
    ''' <seealso class='IDTExtensibility2' />
    Public Sub OnBeginShutdown(ByRef [custom] As Array)
    End Sub

    #End Region
End Class
End Namespace
Run Code Online (Sandbox Code Playgroud)

这是注册Addin的注册表.key脚本,请注意您需要更改一些设置才能正确注册.

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\VBA\VBE\6.0\Addins\YourAddinName.Connect]
"CommandLineSafe"=dword:00000000
"Description"="Description for your new addin"
"LoadBehavior"=dword:00000000
"FriendlyName"="YourAddinName"


[HKEY_CLASSES_ROOT\CLSID\{YourGeneratedGuid}]
@="YourAddinName.Connect"

[HKEY_CLASSES_ROOT\CLSID\{YourGeneratedGuid}\Implemented Categories]

[HKEY_CLASSES_ROOT\CLSID\{YourGeneratedGuid}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="YourAddinName.Connect"
"Assembly"="YourAssemblyNameFullTypeName"
"RuntimeVersion"="v2.0.50727"
"CodeBase"="file:///PathToAssembly"

[HKEY_CLASSES_ROOT\CLSID\{YourGeneratedGuid}\ProgId]
@="YourAddinName.Connect"
Run Code Online (Sandbox Code Playgroud)

注意标记"YourGeneratedGuid"必须包含大括号{}并且与上面attrib中的Guid相同,标记"YourAssemblyNameFullTypeName"必须是程序集全名,标记"YourAddinName.Connect"必须是相同的ProgId设置在上面的attrib.

边注

也发现这有用,可能会节省你几个小时的谷歌搜索.

'HKEY_CURRENT_USER\Software\Microsoft\VBA\6.0\Common
'FontFace=Courier New (STRING - Default if missing)
'FontHeight=10 (DWORD - Default if missing)                
Run Code Online (Sandbox Code Playgroud)


Jer*_*son 11

不幸的是almog.ori的步骤对我不起作用.这是我的版本,以帮助未来的人们:

  1. 创建名为"VBEAddIn"的C#或VB.NET类库项目

    使用"项目","添加引用..."菜单,"浏览"选项卡添加以下Interop程序集作为对项目的引用.

  2. 可扩展性(C:\ Program Files\Microsoft Visual Studio 10.0\Visual Studio工具用于Office\PIA\Common\Extensibility.dll)- 如果它不在那里尝试C:\ Program Files(x86)\如果您使用的是x64 PC.

  3. Microsoft.Office.Interop.Excel(C:\ Program Files\Microsoft Visual Studio 10.0\Visual Studio Tools for Office\PIA\Office14\Microsoft.Office.Interop.Excel.dll)

  4. Microsoft.Vbe.Interop(C:\ Program Files\Microsoft Visual Studio 10.0\Visual Studio Tools for Office\PIA\Office14\Microsoft.Vbe.Interop.dll)

  5. (可选)Microsoft.Vbe.Interop.Forms(C:\ Program Files\Microsoft Visual Studio 10.0\Visual Studio工具用于Office\PIA\Office14\Microsoft.Vbe.Interop.Forms.dll)

使用以下代码向项目添加类:

VB.Net:

Imports Microsoft.Office.Interop
Imports Extensibility
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports Microsoft.Vbe.Interop

<ComVisible(True), Guid("3599862B-FF92-42DF-BB55-DBD37CC13565"), ProgId("VBEAddInVB.Net.Connect")> _
Public Class Connect
    Implements Extensibility.IDTExtensibility2

    Private _VBE As VBE
    Private _AddIn As AddIn

    Private Sub OnConnection(Application As Object, ConnectMode As Extensibility.ext_ConnectMode, _
       AddInInst As Object, ByRef custom As System.Array) Implements IDTExtensibility2.OnConnection
        Try
            _VBE = DirectCast(Application, VBE)
            _AddIn = DirectCast(AddInInst, AddIn)
            Select Case ConnectMode
                Case Extensibility.ext_ConnectMode.ext_cm_Startup
                Case Extensibility.ext_ConnectMode.ext_cm_AfterStartup
                    InitializeAddIn()
            End Select
        Catch ex As Exception
            MessageBox.Show(ex.ToString())
        End Try
    End Sub

    Private Sub OnDisconnection(RemoveMode As Extensibility.ext_DisconnectMode, _
       ByRef custom As System.Array) Implements IDTExtensibility2.OnDisconnection

    End Sub

    Private Sub OnStartupComplete(ByRef custom As System.Array) _
       Implements IDTExtensibility2.OnStartupComplete
        InitializeAddIn()
    End Sub

    Private Sub OnAddInsUpdate(ByRef custom As System.Array) Implements IDTExtensibility2.OnAddInsUpdate

    End Sub

    Private Sub OnBeginShutdown(ByRef custom As System.Array) Implements IDTExtensibility2.OnBeginShutdown

    End Sub

    Private Sub InitializeAddIn()
        MessageBox.Show(_AddIn.ProgId & " loaded in VBA editor version " & _VBE.Version)
    End Sub

End Class
Run Code Online (Sandbox Code Playgroud)

C#:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using Extensibility;
using Microsoft.Vbe.Interop;
using System.Windows.Forms;

namespace VBEAddin
{
    [ComVisible(true), Guid("3599862B-FF92-42DF-BB55-DBD37CC13565"), ProgId("VBEAddIn.Connect")]
    public class Connect : IDTExtensibility2
    {
        private VBE _VBE;
        private AddIn _AddIn;

        #region "IDTExtensibility2 Members"

        public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
        {
            try 
            {
                _VBE = (VBE)application;
                _AddIn = (AddIn)addInInst;

                switch (connectMode) 
                {
                    case Extensibility.ext_ConnectMode.ext_cm_Startup:
                        break;
                    case Extensibility.ext_ConnectMode.ext_cm_AfterStartup:
                        InitializeAddIn();

                        break;
                }
            }
            catch (Exception ex) 
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void onReferenceItemAdded(Reference reference)
        {
            //TODO: Map types found in assembly using reference.
        }

        private void onReferenceItemRemoved(Reference reference)
        {
            //TODO: Remove types found in assembly using reference.
        }

        public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
        {
        }

        public void OnAddInsUpdate(ref Array custom)
        {
        }

        public void OnStartupComplete(ref Array custom)
        {
              InitializeAddIn();
        }

        private void InitializeAddIn()
        {
            MessageBox.Show(_AddIn.ProgId + " loaded in VBA editor version " + _VBE.Version);
        }

        public void OnBeginShutdown(ref Array custom)
        {
        }

        #endregion
    }
}
Run Code Online (Sandbox Code Playgroud)

在项目的"项目属性"窗口中:

  1. 在"应用程序"选项卡中,确保程序集名称和根命名空间都设置为"VBEAddIn".

  2. 在"编译"选项卡中,确保选中"注册COM互操作"复选框.我们不会为使用正确的regasm.exe工具手动注册COM Interop程序集而烦恼.但请注意,"注册COM互操作"复选框只会将加载项dll注册为32位COM库,而不是64位COM库.

  3. 在"编译"选项卡的"高级编译选项"按钮中,确保"目标CPU"组合框设置为"AnyCPU",这意味着程序集可以执行为64位或32位,具体取决于执行加载它的.NET Framework.

  4. 在"签名"选项卡中,确保未签名"签署程序集".

接下来添加注册表项,将下面的代码段保存为带有reg扩展名的ASCI文件,然后双击它将值添加到注册表中.

重要说明:在执行reg文件之前,请更改路径:"CodeBase"="file:/// C:\ Dev\VBEAddIn\VBEAddIn\bin\Debug\VBEAddIn.dll"

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\VBA\VBE\6.0\Addins\VBEAddIn.Connect]
"CommandLineSafe"=dword:00000000
"Description"="Description for your new addin"
"LoadBehavior"=dword:00000000
"FriendlyName"="VBEAddIn"


[HKEY_CLASSES_ROOT\CLSID\{3599862B-FF92-42DF-BB55-DBD37CC13565}]
@="VBEAddIn.Connect"

[HKEY_CLASSES_ROOT\CLSID\{3599862B-FF92-42DF-BB55-DBD37CC13565}\Implemented Categories]

[HKEY_CLASSES_ROOT\CLSID\{3599862B-FF92-42DF-BB55-DBD37CC13565}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="VBEAddIn.Connect"
"Assembly"="VBEAddIn"
"RuntimeVersion"="v2.0.50727"
"CodeBase"="file:///C:\Dev\VBEAddIn\VBEAddIn\bin\Debug\VBEAddIn.dll"

[HKEY_CLASSES_ROOT\CLSID\{3599862B-FF92-42DF-BB55-DBD37CC13565}\ProgId]
@="VBEAddIn.Connect"
Run Code Online (Sandbox Code Playgroud)
  1. 在Visual Studio中构建VBE加载项并打开Excel.
  2. 打开其VBA编辑器(Alt + F11).
  3. 转到"加载项","加载项管理器..."菜单以检查加载项是否已正确注册.
  4. 加载加载项.您应该看到消息框"在VBA编辑器中加载VBEAddIn.Connect"

如果您收到此错误:

在此输入图像描述

无法加载'VBEAddIn'.

从可用的加载项列表中删除它?

它可能你没有改变路径"CodeBase"="file:/// C:\ Dev\VBEAddIn\VBEAddIn\bin\Debug\VBEAddIn.dll"

并检查CodeBase密钥是否在注册表中(如果CodeBase不存在,则添加一个带有CodeBase的字符串regkey):

在此输入图像描述

然后关闭Office应用程序,再次从Visual Studio,Open Office(Excel,Outlook,Word等)和Alt + F11,AddIns菜单> AddIn Manager构建VBE AddIn,并选择AddIn和Tick Loaded/UnLoaded.

最后的伎俩克服这个问题:

如果仍然失败,请关闭Office应用程序,转到Visual Studio,项目属性>构建选项卡>勾选注册COM Interop>构建解决方案,然后打开Office添加> Alt + F11> AddIns菜单> AddIn Manager,然后单击已加载/已卸载.


这个答案使用了我修改过的Carlo's Quintero(MZTools)中的一些信息,参考:http://www.mztools.com/articles/2012/MZ2012013.aspx