Para añadir a las respuestas ya existentes:
con
.NET 4.0
, de hecho es bastante fácil de consumir una DLL de C# en su proyecto de VBA sin registrar el COM.
EDITAR: Acabo de intentar esto con el mscorlib.tlb
y mscoree.tlb
que están en C:\windows\Microsoft.NET\Framework\v2.0.50727
- cargar un ensamblado compilado en 3.5-- y funcionó muy bien. Entonces aparentemente no necesitas .NET 4.0.
El siguiente es un ejemplo de cómo usar un dll C# en su proyecto de VBA. Se modifica ligeramente desde la respuesta this.
1) Añadir referencias a las siguientes bibliotecas de tipo de su proyecto de VBA (Herramientas> Referencias):
C:\windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb
C:\windows\Microsoft.NET\Framework\v4.0.30319\mscoree.tlb
(use carpeta Framework64 si está ejecutando 64 bits de Office)
2) En el proyecto de C#, asegúrese de añadir el atributo [ComVisible(true)]
a su clase:
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace VB6FuncLib
{
[ComVisible(true)]
public class VB6FuncLib
{
public VB6FuncLib()
{ }
public void test()
{
MessageBox.Show("Test Successful");
}
}
}
usted no necesidad de CHEC k la opción "Registrarse para la interoperabilidad COM". Eso es solo para construir un objeto COM estándar. No es necesario que marque "Hacer visible el ensamblaje COM", a menos que desee que todo el conjunto sea visible (lo que también eliminaría la necesidad del atributo COMVisible
).
3) En su código VBA, añadir un nuevo módulo con este código:
Sub Test()
Dim Host As mscoree.CorRuntimeHost
Set Host = New CorRuntimeHost
Host.Start
Dim Unk As IUnknown
Host.GetDefaultDomain Unk
Dim AppDomain As AppDomain
Set AppDomain = Unk
Dim ObjHandle As ObjectHandle
Set FS = CreateObject("Scripting.FileSystemObject")
Path = FS.GetParentFolderName(CurrentDb().Name)
Set ObjHandle = AppDomain.CreateInstanceFrom(Path & "\VB6 Function Library.dll", "VB6FuncLib.VB6FuncLib")
Dim ObjInstance As Object
Set ObjInstance = ObjHandle.Unwrap
ObjInstance.test
Host.Stop
End Sub
4) Copiar el archivo DLL en la misma carpeta que el proyecto de Office y ejecute la prueba() sub en VBA.
Notas:
Cabe señalar que una de las limitaciones de esta técnica es que no va a funcionar si el DLL se almacena en un recurso compartido de red remoto. Una solución simple sería copiarlo en la misma carpeta local en cada PC donde se usa. Otra solución sería incluir los archivos binarios en su aplicación de Access/proyecto de VBA y exportarlos a MS-Access. Una forma de lograrlo sería almacenarlos en Base64 en una tabla u hoja de cálculo, y luego convertirlos y exportarlos como binarios.
Pude conseguir el enlace anticipado (y, por lo tanto, Microsoft IntelliSense) para trabajar creando una biblioteca de tipos para ir con el DLL (usando tlbexp), y agregando una referencia al TLB en mi proyecto de VBA, pero lo hace complicar las cosas un poco porque requiere que su aplicación VBA sepa dónde están los archivos DLL y TLB (y también requiere que alguien se asegure de que estén allí).
Intenté usar esa API. Irónicamente, sin embargo, Microsoft creó un paquete para evitar el registro que requiere registro y deja la misma pregunta que tenía antes: ¿cómo obtenerla en la máquina de mi cliente? Aunque Microsoft.Windows.Actctx está disponible para Windows 2K3 +, solo se incluye en las instalaciones del servidor. Hay otra pregunta de SO quejándose de eso aquí: http://stackoverflow.com/questions/979567/microsoft-windows-actctx-on-windows-xp. Y MSDN lo respalda aquí: http://msdn.microsoft.com/en-us/library/aa375644(VS.85).aspx. – Jelly
Según lo que sé, la API de contexto de activación es parte de Kernel32.lib, lo que significa que no tiene que tener nada instalado, y está incluido en cualquier sistema operativo que tenga soporte para SxS, que es WinXP SP2 y superior. Lo he hecho solo en WinXP SP3 y funcionó sin instalaciones especiales. No sé sobre Microsoft.Windows.Actctx, pero estoy 100% seguro de que puede invocar la API directamente importando las funciones relevantes de Kernel32.lib e invocandolas directamente. Al igual que se presenta en este código de ejemplo http://www.mazecomputer.com/sxs/help/sxsapi3.htm –
Oh, ya veo. Todos los ejemplos en la web que había visto de hacer esto en VBA usan el objeto Actctx en lugar de la API, que es la única razón por la que originalmente concluí que no se podía hacer en código. Aparentemente, está implementado en ambos sentidos (y llamado lo mismo) solo para confundirme. No debería tener demasiados problemas para ponerlo en funcionamiento, y debería ser una solución más estable que piratear la IL, así que moveré la bandera de solución aceptada cuando llegue allí. ¡Gracias por la ayuda! – Jelly