![](/img/trans.png)
[英]VBA Macro no longer works when used as a COM Add-In (VB.NET) (Mail Merge function)
[英]Build add-in for VBA IDE using VB.NET
我在其他地方問了這個問題,但是從來沒有發現任何人知道如何使用VB.NET為VBA IDE構建一個加載項。 它甚至可能嗎? 有人能給我一個例子嗎?
您可能需要使用IDTExtensibility2接口編寫com插件,從新項目中選擇共享插件項目模板。
編輯
否則,要從頭開始創建此插件,您需要執行以下操作:
[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
這是注冊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"
注意標記“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)
不幸的是almog.ori的步驟對我不起作用。 這是我的版本,以幫助未來的人們:
創建名為“VBEAddIn”的C#或VB.NET類庫項目
使用“項目”,“添加引用...”菜單,“瀏覽”選項卡添加以下Interop程序集作為對項目的引用。
可擴展性(C:\\ Program Files \\ Microsoft Visual Studio 10.0 \\ Visual Studio工具用於Office \\ PIA \\ Common \\ Extensibility.dll) - 如果它不在那里嘗試C:\\ Program Files(x86)\\如果您使用的是x64 PC。
Microsoft.Office.Interop.Excel(C:\\ Program Files \\ Microsoft Visual Studio 10.0 \\ Visual Studio Tools for Office \\ PIA \\ Office14 \\ Microsoft.Office.Interop.Excel.dll)
Microsoft.Vbe.Interop(C:\\ Program Files \\ Microsoft Visual Studio 10.0 \\ Visual Studio Tools for Office \\ PIA \\ Office14 \\ Microsoft.Vbe.Interop.dll)
(可選)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
}
}
在項目的“項目屬性”窗口中:
在“應用程序”選項卡中,確保程序集名稱和根命名空間都設置為“VBEAddIn”。
在“編譯”選項卡中,確保選中“注冊COM互操作”復選框。 我們不會為使用正確的regasm.exe工具手動注冊COM Interop程序集而煩惱。 但請注意,“注冊COM互操作”復選框只會將加載項dll注冊為32位COM庫,而不是64位COM庫。
在“編譯”選項卡的“高級編譯選項”按鈕中,確保“目標CPU”組合框設置為“AnyCPU”,這意味着程序集可以執行為64位或32位,具體取決於執行加載它的.NET Framework。
在“簽名”選項卡中,確保未簽名“簽署程序集”。
接下來添加注冊表項,將下面的代碼段保存為帶有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"
如果您收到此錯誤:
無法加載'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
我還發現這個引用有助於從C#或VB.NET制作VBA DLL:
創建一個新的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; } } }
配置項目屬性以使其可見。
在VBA代碼中使用DLL。
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
我想你可以從你的VBA代碼中調用一個.NET DLL(我自己從未真正做過)。 只需創建一個VB類庫項目並創建一個在VBA中使用的DLL。
快速谷歌之后看起來你需要在Project Properties-> Build下設置“Register for Com Interop”= True,但就像我說的那樣,我以前從未嘗試過這個。
還要注意項目的Guid(在assamblyInfo.cs中的c#的情況下)與類“Connect”的Guid不同。
在檢查時,具有相同的Guid導致“無法轉換為類型庫” - 錯誤:項目屬性>構建選項卡>注冊COM Interop
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.