Сборка надстройки для VBA IDE с помощью VB.NET

Я спросил об этом в другом месте, но никогда не находил, что кто-то знает, как создать надстройку для VBA IDE с помощью VB.NET - ... Это вообще возможно? Кто - нибудь может привести мне пример?

5 ответов


возможно, вам нужно написать com addin с помощью интерфейса IDTExtensibility2, выберите общий шаблон проекта addin из нового проекта.

редактировать

В противном случае для создания этого дополнения с нуля вам нужно будет сделать следующее:

  1. создать новую библиотеку классов проекта
  2. добавить ссылки на "расширяемость", она должна быть в списке. Возможно, Вам потребуется загрузить PIAs для вашей версии office. (и возможно, VSTO, но я не уверен в этом пункте)
  3. добавить ссылки на " Microsoft.Vbe.Interop " снова должен быть с PIAs.
  4. установите флажок "регистрация для COM-взаимодействия" на вкладке "свойства".
  5. дополнительно на вкладке настройки отладки измените запуск на внешнюю программу и введите путь к Excel exe в папке programfiles (если это предназначено для excel), это позволит проекту быть отлаживаемый.
  6. дополнительно в параметрах команды добавьте запись на рабочий лист или документ word, который покажет диалоговое окно добавления с помощью макроса при запуске, для разработки это имеет смысл, чтобы упростить отладку. например, "C:\vbe.файл xlsm"
  7. дополнительно также установите путь запуска в каталог листа, например " C:\"
  8. реализуйте интерфейс "IDTExtensibility2", найденный в сборке" расширяемость".
  9. называем это класс "Connect" (это просто предпочтение)
  10. атрибут class с следующим

[равен comvisible(правда), Идентификатор GUID("YourGeneratedGuid"), Идентификатор Progid("YourAddinName.Connect")]

вот реализация, чтобы вы начали, сначала замените " YourAddinName "на ваше AppName и создайте Guid для"YourGeneratedGuid". Вам нужно будет зарегистрировать 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

вот реестр .ключевой скрипт для регистрации Аддина, обратите внимание, что вам нужно будет изменить некоторые настройки, чтобы зарегистрировать его правильно.

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\VBA\VBE.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"

Примечание маркеры "YourGeneratedGuid" должны иметь фигурные скобки {} и быть такими же, как Guid в attrib выше, маркер "YourAssemblyNameFullTypeName" должен быть полным именем сборки, маркер "YourAddinName.Соединять" должен быть тот же ProgId, установленный в attrib выше.

ПРИМЕЧАНИЕ

также нашел это полезным, может сэкономить вам пару часов гуглить.

'HKEY_CURRENT_USER\Software\Microsoft\VBA.0\Common
'FontFace=Courier New (STRING - Default if missing)
'FontHeight=10 (DWORD - Default if missing)                

к сожалению almog.шаги ори мне не помогли. Вот моя версия, чтобы помочь людям в будущем:

  1. создать C# или VB.NET проект библиотеки классов с именем "VBEAddIn"

    добавьте следующие сборки взаимодействия в качестве ссылок на проект, используя "Project", " Add Reference..."меню", вкладка "Обзор".

  2. расширяемость (C:\Program файлы\Microsoft Visual Studio 10.0\средства Visual Studio для Office\PIA\Common\расширяемость.dll файлы) - если его нет там попробуйте C:\Program файлы (x86)\ если вы используете x64 PC.

  3. Microsoft.Офис.Взаимодействие.В формате Excel (файлы C:\Program \Майкрософт Visual студии 10.0\в Visual Studio для Office\Пиа\Валюты14\Майкрософт.Офис.Взаимодействие.Превосходить.dll файлы)

  4. Microsoft.Vbe.Interop (C:\Program файлы\Microsoft Visual Studio 10.0\средства Visual Studio для Office\PIA\Office14\Microsoft.Vbe.Взаимодействие.dll файлы)

  5. (необязательно) Microsoft.Vbe.Взаимодействие.Форм (файлы C:\Program \Майкрософт Visual студии 10.0\в Visual Studio для Office\Пиа\Валюты14\Майкрософт.Vbe.Взаимодействие.Формы.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

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
    }
}

в окне свойств проекта проект:

  1. на вкладке " приложение "убедитесь, что для имени сборки и корневого пространства имен установлено значение"VBEAddIn".

  2. на вкладке " компиляция "убедитесь, что установлен флажок" регистрация для COM-взаимодействия". Мы не заморачивались с регистрацией сборки для COM-взаимодействия вручную с правильной regasm.инструмент exe. Однако обратите внимание, что флажок "регистрация для COM-взаимодействия" зарегистрирует только надстройку dll как 32-разрядную библиотеку COM, а не как 64 - разрядную COM библиотека.

  3. на вкладке "компиляция", кнопка "Дополнительные параметры компиляции", убедитесь, что "целевой процессор" combobox установлен в "AnyCPU", что означает, что сборка может быть выполнена как 64-разрядная или 32-разрядная, в зависимости от выполнения .NET Framework, который загружает его.

  4. на вкладке " подписание "убедитесь, что" подписать сборку " не помечено.

Далее добавьте разделы реестра, сохраните приведенный ниже фрагмент как файл ASCI с reg расширение и дважды щелкните его, чтобы добавить значения в реестр.

Важное Замечание: перед запуском reg-файла, поменяйте путь: "кода"="файл:///с:\Дев\VBEAddIn\VBEAddIn\бин\отладки\VBEAddIn.DLL-файл"

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\VBA\VBE.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"
  1. создайте надстройку VBE в Visual Studio и откройте Excel.
  2. откройте редактор VBA (Alt + F11).
  3. перейдите в "надстройки", " менеджер надстроек..."меню для проверки правильности надстройки зарегистрированный.
  4. загрузить надстройку. Вы должны увидеть окно сообщения " VBEAddIn.Подключение загружено в Редакторе VBA"

Если вы получите эту ошибку:

enter image description here

'VBEAddIn' не может быть загружен.

удалить его из списка доступных надстроек?

вероятно, вы не изменили путь "CodeBase"="file:///C:\Dev\VBEAddIn\VBEAddIn\bin\Debug\VBEAddIn.файл DLL"

и проверьте, что ключ кодовой базы находится в реестре (добавьте строку regkey с кодовой базой, если она не существует):

enter image description here

затем закройте приложение Office, снова создайте VBE AddIn из Visual Studio, откройте Office (Excel, Outlook, Word и т. д.) и Alt + F11, меню AddIns > AddIn Manager и выберите AddIn и отметьте загружено/выгружено.

финальный трюк, чтобы преодолеть эту проблему:

Если это все еще не удается, закройте приложение Office, goto Visual Studio, свойства проекта > вкладка "сборка" > отметьте регистр для COM-взаимодействия > решение для сборки и откройте Office Add In > Alt + F11 > AddIns Menu > AddIn Manager и нажмите "загружено/выгружено".


этот ответ использует некоторую информацию из Quintero Карло (MZTools), которую я изменил, Ref:http://www.mztools.com/articles/2012/MZ2012013.aspx


Я также нашел эту ссылку полезной для создания DLL VBA из C# или VB.NET:

  1. создать новый C# (или VB.Net) проект и выберите библиотеку классов в качестве типа шаблона.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace SimpleCalc
    {
        public class Calc
        {
            private int numberOne = 0;
            private int numberTwo = 0;
    
            public void SetNumberOne(int number)
            {
                numberOne = number;
            }
    
            public void SetNumberTwo(int number)
            {
                numberTwo = number;
            }
    
            // Add two integers
            public int Add()
            {
                return numberOne + numberTwo;
            }
        }
    }
    
  2. настроить свойства проекта, чтобы сделать его видимым для COM.

  3. регистрация для COM-взаимодействия.
  4. скомпилировать проект.
  5. скопируйте файл библиотеки типов в системную папку Windows.
  6. ссылка типа библиотека из редактора Access VBA.
  7. используйте DLL в коде VBA.

    Public Function test()
        Dim lngResult As Long
    
        Dim objCalc As SimpleCalc.Calc
        Set objCalc = New SimpleCalc.Calc
    
        objCalc.SetNumberOne (3)
        objCalc.SetNumberTwo (6)
    
        lngResult = objCalc.Add()
    
    End Function
    

предоставлены GeeksEngine.com


Я бы предположил, что вы можете вызвать .NET DLL из своего кода VBA (никогда не делал этого сам). Просто создайте проект библиотеки классов VB и создайте DLL для использования в VBA.

после быстрого google, похоже, вам нужно будет установить "регистрация для COM-взаимодействия" = True в свойствах проекта - >Build, но, как я уже сказал, Я никогда не пробовал это раньше.


также позаботьтесь о том, чтобы Guid проекта (в случае c# в assamblyInfo.cs) отличается от Guid класса "Connect".

наличие того же идентификатора Guid приводит к "не удалось преобразовать в библиотеку типов" - ошибка при проверке: свойства проекта > вкладка сборки > регистрация для COM-взаимодействия