Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

ИЗМЕНИТЬ

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

  • Создайте новую библиотеку классов проекта
  • Добавьте ссылки на "Расширяемость", он должен быть в списке. Вам может потребоваться загрузить PIA для вашей версии офиса. (и, возможно, VSTO, но я не уверен в этом)
  • Добавить ссылки на "Microsoft.Vbe.Interop" снова должен быть с PIA.
  • В закладке свойств установите флажок "Регистрация для Com-взаимодействия".
  • ДОПОЛНИТЕЛЬНО На вкладке настроек отладки измените запуск на внешнюю программу и введите путь к excel exe в папке программных файлов (если это предназначено для excel), это позволит проекту отладка.
  • ДОПОЛНИТЕЛЬНО. В параметрах команды добавить запись на рабочий лист или слово doc, которое будет отображать диалог добавления с помощью макроса при запуске, для разработки имеет смысл оптимизировать работу отладки. например, "C:\vbe.xlsm"
  • ДОПОЛНИТЕЛЬНО Также задайте путь запуска к каталогу рабочих листов, например "C: \"
  • Внедрите интерфейс "IDTExtensibility2", найденный в сборке "Расширяемость".
  • Вызов этого класса "Подключиться" (это только предпочтение)
  • Атрибут класса со следующим

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

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

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

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)                

Ответ 2

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

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

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

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

  • Microsoft.Office.Interop.Excel(C:\Program Files\Microsoft Visual Studio 10.0\Visual Studio Tools для Office\PIA\Office14\Microsoft.Office.Interop.Excel.dll)

  • Microsoft.Vbe.Interop(C:\Program Files\Microsoft Visual Studio 10.0\Visual Studio Tools для Office\PIA\Office14\Microsoft.Vbe.Interop.dll)

  • (необязательно) Microsoft.Vbe.Interop.Forms(C:\Program Files\Microsoft Visual Studio 10.0\Visual Studio Tools для 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

С#

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

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

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

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

  • На вкладке "Скомпилировать", "Параметры расширенного компиляции" убедитесь, что для поля "Целевой ЦП" установлено значение "AnyCPU", что означает, что сборка может быть выполнена как 64-разрядная или 32- бит, в зависимости от выполняемой .NET Framework, которая загружает его.

  • На вкладке "Подписание" убедитесь, что "Подписать сборку" не указано.

Затем добавьте ключи реестра, сохраните приведенный ниже фрагмент как файл 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"
  • Создайте надстройку VBE в Visual Studio и откройте Excel.
  • Откройте редактор VBA (Alt + F11).
  • Перейдите в меню "Add-Ins", "Add-In Manager...", чтобы проверить, что надстройка зарегистрирована правильно.
  • Загрузите надстройку. Вы должны увидеть окно сообщения "VBEAddIn.Connect, загруженное в редактор VBA"

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

введите описание изображения здесь

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

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

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

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

введите описание изображения здесь

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

Final Trick для решения этой проблемы:

Если это все еще не удается, закройте приложение Office, перейдите в Visual Studio, Project Properties > Build Tab > Tick Register для COM Interop > Build Solution и откройте Office Add In > Alt + F11 > AddIns Menu > AddIn Manager и нажмите Loaded/выгружен.


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

Ответ 3

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

  • Создайте новый проект С# (или 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;
            }
        }
    }
    
  • Настройте свойства проекта, чтобы сделать его COM видимым.

  • Зарегистрируйтесь для COM-взаимодействия.
  • Скомпилировать проект.
  • Скопируйте файл библиотеки типов в системную папку Windows.
  • Ссылка на библиотеку типов из редактора Access VBA.
  • Используйте 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

Ответ 4

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

После быстрого google похоже, что вам нужно будет установить "Register for Com Interop" = True в разделе "Свойства проекта" → "Сборка", но, как я уже сказал, я никогда раньше не пробовал это.

Ответ 5

Также учтите, что руководство проекта (в случае С# в assamblyInfo.cs) отличается от руководства класса "Подключиться".

При выполнении тех же рекомендаций в "невозможно преобразовать в библиотеку типов" -error при проверке: "Свойства проекта"> вкладка "Строка"> "Регистрация для COM-взаимодействия"