Để thêm vào các câu trả lời đã có sẵn:
với
.NET 4.0
, nó thực sự khá đơn giản để tiêu thụ một C# dll trong dự án VBA của bạn mà không cần đăng ký COM.
EDIT: Tôi chỉ cố gắng này với mscorlib.tlb
và mscoree.tlb
có trong C:\windows\Microsoft.NET\Framework\v2.0.50727
- tải một hội đồng biên soạn trong 3.5-- và nó chỉ làm việc tốt. Vì vậy, rõ ràng bạn không cần .NET 4.0.
Dưới đây là ví dụ về cách sử dụng C# dll trong dự án VBA của bạn. Nó được sửa đổi một chút từ câu trả lời this.
1) Thêm tài liệu tham khảo để libs loại vật liệu làm dự án VBA của bạn (Tools-> Tài liệu tham khảo):
C:\windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb
C:\windows\Microsoft.NET\Framework\v4.0.30319\mscoree.tlb
(sử dụng thư mục Framework64 nếu bạn đang chạy phiên bản 64-bit Office)
2) Trong dự án # C của bạn, hãy chắc chắn bạn thêm thuộc tính [ComVisible(true)]
đến lớp học của bạn:
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace VB6FuncLib
{
[ComVisible(true)]
public class VB6FuncLib
{
public VB6FuncLib()
{ }
public void test()
{
MessageBox.Show("Test Successful");
}
}
}
bạn không cần phải chec k tùy chọn "Đăng ký COM Interop". Đó là chỉ để xây dựng một đối tượng COM tiêu chuẩn. Bạn không cần phải kiểm tra "Make Assembly COM Visible" hoặc là, trừ khi bạn muốn toàn bộ assembly được hiển thị (điều đó cũng sẽ loại bỏ sự cần thiết cho thuộc tính COMVisible
).
3) Trong mã VBA của bạn, thêm một module mới với mã này:
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) Sao chép DLL vào thư mục tương tự như dự án văn phòng của bạn và chạy thử nghiệm() phụ trong VBA.
Ghi chú:
Cần lưu ý rằng một trong những hạn chế của phương pháp này là nó sẽ không hoạt động nếu DLL được lưu trữ trên một mạng chia sẻ từ xa. Một giải pháp đơn giản là sao chép nó vào cùng một thư mục cục bộ trên mỗi máy tính mà nó đang được sử dụng. Một giải pháp khác là bao gồm các tệp nhị phân trong dự án ứng dụng Access/VBA của bạn và có MS-Access xuất chúng. Một cách có thể được thực hiện bằng cách lưu trữ chúng trong Base64 trong một bảng hoặc bảng tính, sau đó chuyển đổi chúng và xuất chúng dưới dạng nhị phân.
Tôi đã có thể nhận được ràng buộc sớm (và do đó Microsoft IntelliSense) để làm việc bằng cách tạo một thư viện kiểu để đi với DLL (bằng cách sử dụng tlbexp), và thêm một tham chiếu đến TLB trong dự án VBA của tôi, nhưng nó phức tạp vấn đề một chút bởi vì nó đòi hỏi ứng dụng VBA của bạn để biết nơi cả DLL và các tập tin TLB (và cũng đòi hỏi một ai đó để đảm bảo rằng họ đang có).
Tôi đã xem xét sử dụng API đó. Trớ trêu thay, Microsoft đã tạo ra một gói để tránh đăng ký yêu cầu đăng ký và để lại cùng một câu hỏi mà tôi đã có trước đây - làm thế nào để có được nó trên máy khách của tôi? Mặc dù Microsoft.Windows.Actctx có sẵn cho Windows 2K3 + nhưng nó chỉ được bao gồm trong cài đặt Máy chủ. Có một câu hỏi SO khác phàn nàn về điều đó ở đây: http://stackoverflow.com/questions/979567/microsoft-windows-actctx-on-windows-xp. Và MSDN sao lưu nó lên đây: http://msdn.microsoft.com/en-us/library/aa375644(VS.85).aspx. – Jelly
Từ những gì tôi biết API ngữ cảnh kích hoạt là một phần của Kernel32.lib, có nghĩa là bạn không cần phải cài đặt bất kỳ thứ gì, và nó được bao gồm trong bất kỳ hệ điều hành nào có hỗ trợ cho SxS là WinXP SP2 và cao hơn. Tôi đã tự thực hiện trên WinXP SP3 và nó hoạt động mà không cần cài đặt đặc biệt. Tôi không biết về Microsoft.Windows.Actctx, nhưng tôi chắc chắn 100% bạn có thể gọi trực tiếp API bằng cách nhập các hàm có liên quan từ Kernel32.lib và gọi chúng trực tiếp. Giống như nó được trình bày tại mã mẫu này http://www.mazecomputer.com/sxs/help/sxsapi3.htm –
Tôi hiểu rồi. Tất cả các ví dụ trên web tôi đã thấy làm điều này trong VBA sử dụng các đối tượng Actctx thay vì API đó là lý do duy nhất tôi ban đầu kết luận rằng nó không thể được thực hiện trong mã. Rõ ràng, nó được thực hiện cả hai cách (và được gọi là điều tương tự) chỉ để gây nhầm lẫn cho tôi. Tôi không nên có quá nhiều rắc rối khi làm việc này và chạy - và nó phải là một giải pháp ổn định hơn là hack IL - vì vậy tôi sẽ di chuyển cờ giải pháp được chấp nhận khi tôi đến đó. Cảm ơn đã giúp đỡ! – Jelly