Сборка надстройки для VBA IDE с использованием VB.NET - PullRequest
12 голосов
/ 22 декабря 2009

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

Ответы [ 5 ]

16 голосов
/ 22 декабря 2009

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

EDIT

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

  1. Создать новую библиотеку классов проекта
  2. Добавьте ссылки на «Расширяемость», она должна быть в списке. Возможно, вам придется скачать PIA для вашей версии офиса. (и, возможно, VSTO, но я не уверен в этом)
  3. Добавить ссылки на «Microsoft.Vbe.Interop» снова следует с PIA.
  4. Установите флажок «Зарегистрироваться для Com Interop» на вкладке свойств.
  5. ДОПОЛНИТЕЛЬНО На вкладке параметров отладки измените запуск на внешнюю программу и введите путь к Excel exe в папке программных файлов (если это предназначено для Excel), чтобы проект можно было отлаживать. .
  6. ДОПОЛНИТЕЛЬНО В опциях команды добавьте запись на лист или слово doc, которое будет отображать диалоговое окно надстройки с использованием макроса при запуске, для разработки имеет смысл упростить процесс отладки. например, "C: \ vbe.xlsm"
  7. ДОПОЛНИТЕЛЬНО Также задайте путь запуска для каталога рабочей таблицы, например "C: \"
  8. Реализация интерфейса "IDTExtensibility2", найденного в сборке "Extensibility".
  9. Назовите этот класс "Connect" (это просто предпочтение)
  10. Приписать класс следующим

[ComVisible (истина), Guid ( "YourGeneratedGuid"), ProgId ( "YourAddinName.Connect")]

Вот реализация, с которой можно начать. Сначала замените «YourAddinName» на AppName и создайте Guid для «YourGeneratedGuid». Вам нужно зарегистрировать надстройку в нужном месте реестра, посмотреть разделы реестра, которые следуют, чтобы получить представление, а также заменить некоторые переменные в разделах реестра.

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

Вот скрипт реестра .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"

ПРИМЕЧАНИЕ токены "YourGeneratedGuid" должны содержать фигурные скобки {} и совпадать с Guid в указанном выше атрибуте; токен "YourAssemblyNameFullTypeName" должен быть полным именем сборки, токеном " YourAddinName.Connect "должен быть таким же ProgId, который указан в атрибуте выше.

Боковое примечание

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

'HKEY_CURRENT_USER\Software\Microsoft\VBA\6.0\Common
'FontFace=Courier New (STRING - Default if missing)
'FontHeight=10 (DWORD - Default if missing)                
11 голосов
/ 02 сентября 2013

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

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

    Добавьте следующие сборки Interop в качестве ссылок на проект, используя меню «Проект», «Добавить ссылку ...», вкладку «Обзор».

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

  3. Microsoft.Office.Interop.Excel (C: \ Program Files \ Microsoft Visual Studio 10.0 \ Инструменты Visual Studio для Office \ PIA \ Office14 \ Microsoft.Office.Interop.Excel.dll)

  4. Microsoft.Vbe.Interop (C: \ Program Files \ Microsoft Visual Studio 10.0 \ Инструменты Visual Studio для 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

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 Interop с помощью соответствующего инструмента regasm.exe. Однако обратите внимание, что флажок «Register for COM interop» регистрирует только dll надстройки как 32-битную библиотеку COM, а не как 64-битную библиотеку COM.

  3. На вкладке «Компиляция» кнопкой «Дополнительные параметры компиляции» убедитесь, что в поле со списком «Target CPU» установлено значение «AnyCPU», что означает, что сборка может выполняться как 64-разрядная или 32-разрядная. бит, в зависимости от исполняющей .NET Framework, которая его загружает.

  4. На вкладке «Подписывание» убедитесь, что флажок «Подписать сборку» снят.

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

Важное примечание: Перед запуском 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"
  1. Создайте надстройку VBE в Visual Studio и откройте Excel.
  2. Откройте редактор VBA (Alt + F11).
  3. Перейдите в меню «Надстройки», «Менеджер надстроек ...», чтобы проверить правильность регистрации надстройки.
  4. Загрузить надстройку. Вы должны увидеть окно сообщения «VBEAddIn.Connect загружен в VBA-редактор»

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

enter image description here

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

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

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

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

enter image description here

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

Последний трюк для преодоления этой проблемы:

Если это не помогло, закройте приложение Office, перейдите в Visual Studio, Свойства проекта> Вкладка «Сборка»> «Регистрация тиков» для COM-взаимодействия> Построение решения и откройте «Надстройка Office»> «Alt + F11»> «Меню надстроек»> «Менеджер надстроек» и нажмите «Загруженные». /Unloaded.


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

1 голос
/ 02 марта 2012

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

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

    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 Interop.
  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

0 голосов
/ 11 июля 2018

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

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

0 голосов
/ 22 декабря 2009

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

После быстрого поиска в Google вы должны установить «Зарегистрироваться для Com Interop» = «Истина» в «Свойствах проекта» -> «Сборка», но, как я уже сказал, я никогда раньше не пробовал.

...