簡體   English   中英

如何在 Microsoft Access 中使用 C# DLL

[英]How to use a C# DLL in Microsoft Access

我在 Visual Studio 2019 中創建了下面的 class,其中“使程序集 COM-Visible”設置為 true,並選中“注冊 COM 互操作”。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace SimpleCalc
{

    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [Guid("95F54E1A-826C-4766-9FE9-D32C47B07504")]
    public interface _Test
    {
        string HelloWorld { get; }
    }

    [ClassInterface(ClassInterfaceType.None)]
    [Guid("9F7248AF-4E59-4938-AECC-B938703F33BB")]
    [ProgId("SimpleCalc.Test")]
    public class Test : _Test
    {
        public string HelloWorld { get { return "Hello, World! "; } }
    }
}

代碼編譯良好,我可以在 VBA 中引用它,屬性“Hello World”顯示在 object 瀏覽器的 class“測試”中。

但是,當我嘗試使用代碼訪問 onClick 事件子例程時

Dim o As Test
Set o = New Test 
MsgBox o.HelloWorld

錯誤:'429'“ActiveX 組件無法創建對象”在 Set o = New Test 處生成。

我究竟做錯了什么?

嗯,首先? 您沒有將接口標記為公開

例如;

    public interface _Test

接下來,我將刪除 Prog_id - 你不需要它,我認為這也會搞砸。

而且,真的,我看不出有什么理由在這里建立一個接口? 我懷疑在 c# (或者肯定在 VBA 中),你不需要聲明從 class 派生的公共成員變量類型,而不必創建 class 的實例,然后我想你需要可以做一個接口的案例,但是其他的那么這個原因嗎?不需要)。

也不需要擔心代碼中的 GUIDS。 項目設置將解決這個問題。

而且您實際上並不需要命名空間 - 項目默認會再次處理這個問題。

所以,現在我們歸結為:

using System.Runtime.InteropServices;

[ClassInterface(ClassInterfaceType.AutoDual)]
public class COMTest1
    {
        public string HelloWorld
        {
            get
            {
                return "Hello, World! ";
            }
        }

    }

好的,現在好多了,當然:我們需要在這里選中“com visible”框:

在此處輸入圖像描述

或者您可以在 class 接口類型設置上方添加一個 COMvisible=true。

在開發過程中,您可以(應該)注冊 COM 程序集。 在目標機器上,您必須執行 regasm.exe,但在您的開發機器上,您可以讓 VS 為您執行此操作。 例如這里:

在此處輸入圖像描述

現在上面對項目做了零 - 它只為你做那個 regasm。

此時,則在VBA中,可以使用后期綁定,也可以提前綁定。 假設我們在 tools->reference from VBA 中設置了一個引用,如下所示:

在此處輸入圖像描述

現在我們的 VBA 代碼將如下所示:

Sub Test23434324()

  Dim cTest As New CShapeCOMTest.ComTest1
  
  Debug.Print c.HelloWorld
  
End Sub

所以,我不會打擾界面 - 但你的不是公開的。

以上就是您真正需要的所有內容。 代替交互,只需將成員標記為公共或私有。 這包括你傾倒getter/setter。

你可以在 class 級別有這個:

public class COMTest1
    {

public string CompanyName;
public string PhoneNumber;

        public string HelloWorld
        {
            get
            {
                return "Hello, World! ";
            }
        }

    }

而這些公共成員將出現在 VBA intel-sense 中。

所以,我什至不介意界面。

我通常不會為簡單的公共成員(比如字符串)而煩惱 get/sets

作為基本規則? 構建一個簡單干凈的 class - 您只添加接口標簽,沒有 GUIDS,沒有其他任何東西,也不需要接口。 我的大部分課程都是這樣寫的。 所以這里不需要太多的愛和關懷。

事實上,您甚至不需要 Classinterface 標記 - 您只需在上述程序集 window 中設置 make com 程序集為真復選框即可。 (但是,如果你這樣做,你會失去 VBA com 端的 intei-sense )。

代碼越少,我們就越將其與絕對最小值配對?

編寫的代碼越少,搞砸的問題就越少。

***編輯: ************************************

工作測試的例子是這樣的:

using System.Runtime.InteropServices;

[ClassInterface(ClassInterfaceType.AutoDual)]
public class COMTest1
    {

public string CompanyName;
public string PhoneNumber;

        public string HelloWorld
        {
            get
            {
                return "Hello, World! ";
            }
        }

    }

強制項目為 x86。 這將強制 regams.exe 更正注冊。 如果您一直在運行 Access + 測試 - 您必須退出訪問,否則 .dll 在運行該代碼時會被鎖定。

記得在組件下設置 MAKE 組件 COM 可見。

請記住檢查 com 互操作的寄存器(項目上的構建選項卡)。

有了上面,在 VBA 中,你甚至會看到這樣的 intel-sense:

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM