4

これは長い質問ですが、コーディングとテストの部分は本当に簡単に再現できるはずです。

で2 つの別々Class Librariesのファイルを作成C#しましたが、以前のプロジェクトや試用版の既存のレジストリ キーが原因で、名前の衝突の問題が発生していると思います。

ここに私の2つのクラスがあります:

using System;
using System.Runtime.InteropServices;

namespace Test
{

    [InterfaceType(ComInterfaceType.InterfaceIsDual),
    Guid("ED5D264B-1D80-4A5D-9C14-8297D90B7037")]
    public interface ITest
    {
        // body
    }

    [ClassInterface(ClassInterfaceType.None)]
    [Guid("8B261B92-8EC5-4CDC-A551-67DEB42137FF")]
    [ProgId("Test.TestClass")]
    public class TestClass : ITest
    {
        // body
    }
} 

using System;
using System.Runtime.InteropServices;
using ADODB;

namespace Test
{

    [InterfaceType(ComInterfaceType.InterfaceIsDual),
    Guid("ED5D264B-1D80-4A5D-9C14-8297D90B7037")]
    public interface IConnection
    {
        // body
    }

    [ClassInterface(ClassInterfaceType.None)]
    [Guid("8B261B92-8EC5-4CDC-A551-67DEB42137FF")]
    [ProgId("Test.Connection")]
    public class Connection : IConnection
    {
        // body
    }
}

私は次のように .Net コンポーネントを COMに公開しました:
Excel からアセンブリにアクセスするために、ADODB 参照をアセンブリに追加し、アセンブリ COM を表示、com interop に登録することにチェックを入れました。*.tlbまた、各ファイル ( 2 つのプロジェクトに対して 2 つのファイル) への参照を追加したので、事前バインディングを使用してそれらにアクセスし、VBA Intellisenseを使用できます。

Connection別のマシンでも同じ手順を実行しましたが、 as クラスを使用して事前バインディングを使用できます。

Connection元のマシンで削除していない古いレジストリ キーがいくつかあり、VBE でクラス名として使用できないと考えています。手動でレジストリをスキャンし、プロジェクトに関連すると考えられるものをすべて削除しました。

また、プロジェクトを完全に削除し、サードパーティのソフトウェアを使用してレジストリをスキャンして不足しているdlls を探しましたが、役に立ちませんでした:/

以前に登録したすべての GUID を削除し、新しいプロジェクトを作成するたびに新しい GUID を適用しました (念のため)

異なる名前空間とクラス名を使用して新しいプロジェクトを作成しました ( using ADODB;) このように早期バインディングをまだ使用できていないため、名前の競合の問題Test.Connectionがあると想定しています。100% 確信はありませんが、名前クラスが原因ではないかと疑っています。Connection

Test.TestClassVBAの名前空間:

TestClass事前バインディングを使用すると、次の 2 つの方法で型のインスタンスを宣言して使用できます。

Dim x as Test.TestClass
Dim x as TestClass

VBE オブジェクト エクスプローラーF2TestClass移動すると、他のライブラリと比較して適切に表示され、COM を使用する一般的な考え方が表示されます。

TestClass オブジェクト エクスプローラー

Test.Connectionただし、ライブラリを使用したい場合TestClass、生成され*.tlbファイルが. そのため、代わりにこのようにバインドする必要がありますProgId's

Dim x As Test.Test_Connection
Dim x As Test_Connection

そして、 (ドット)ではなく(アンダースコア)Object Explorerを使用して名前を表示します。これは、なぜこれが起こるのかを簡単に説明できます-読み続けてください:)_.

事前バインディングを使用できない

現状では、衝突を避けるために名前を変更するのは VBE 環境ではないと確信しています。VSの*.tlbジェネレーターです。

*.tlbアセンブリ フォルダーに移動し、両方のファイルを で開きましたNotepad++。ライブラリのには*.tlb、が含まれるとは異なり、がTest.Connection含まれる名前がすでに含まれていることがはっきりとわかります。_Test.TestClass.

ファイルを手動で編集しようとし*.tlbましたが、混合バイナリ ファイルであるため、何らかの効果がありますが、Excel が奇妙な方法で応答しなくなるため、この方法を避ける必要があります。

問題が何であり、どこから来るのかをよく説明したと思います。私の質問は次のとおりです。私の s をオーバーライドしないようにジェネレーター
に指示するために、C# コードで使用する属性はありますか? ファイルを操作する別の方法はありますか? この問題はありますか? クラスの名前を変更せずに回避できますか?*.tlbProdId
*.tlb
name collisionConnection

こんなに長い質問で申し訳ありませんが、私はほぼ一週間掘り下げ続けてきましたが、まだこれを解決できません。

注: IntelliSense ctrl+を使用する VBA (または VBE オブジェクト エクスプローラー) では、またはが使用されspaceていないようです。それらはVBE環境でまだ予約されていないため、ライブラリ自体に関係していると考えています。ConnectionRecordset

この問題がここで取り上げられた理由の参考として、エイリアスを作成する C# に相当する VBA または VB.NET インポートを参照し
てください。

4

1 に答える 1