8

VBAでCOM公開メソッドにアクセスしようとしています。

問題: VBAにすべてのデフォルトメソッド(GetHashCode、、GetTypeなど)が表示されていますが、COMインターフェイスの一部であり、COMが表示されるように特別に記述されたメソッド(以下のように)は表示されませんToStringgetStringValue()

セットアップの詳細:

  • Visual Studio 2008
  • Windows 7 x64
  • Office 2007
  • .NET 3.5

インターフェイス'IGetMyString.cs'

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

namespace SimpleCOMAssembly
{
    [ComVisible(true), GuidAttribute("4153A1AC-ECE9-4f66-B56C-1DDEB6514D5D")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    interface IGetMyString
    {
        [DispId(1)]
        string getStringValue();
    }
}

実装'GetMyString.cs'

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

namespace SimpleCOMAssembly
{
    [ComVisible(true), GuidAttribute("0A3D4D65-CF50-4020-BF13-77001F8AAABE")]
    [ProgId("SimpleCOMAssembly.GetMyString")]
    [ClassInterface(ClassInterfaceType.None)]
    public class GetMyString : IGetMyString
    {
        public GetMyString() { }

        [ComVisible(true), Description("Get my string")]
        public string getStringValue()
        {
            return "hello";
        }
    }
}

[ビルドプロパティ]で、[アセンブリCOMを表示する]をオンにしました(以下のスナップショットを参照)

ここに画像の説明を入力してください

また、Visual Studio 2005に「COM相互運用機能の登録」を作成するように依頼しました(以下のスナップショットを参照)

ここに画像の説明を入力してください

そして最後に、ビルド後のイベントとして、regasm.exeを実行して、次のように.DLLと.TLBをレジストリに登録します。

%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\regasm /codebase "$(TargetPath)" /tlb:"$(TargetDir)$(TargetName).lib"

Excel Object Explorerビューで、COMサーバー(上記のSimpleCOMAssembly)を有効にしましたが、Object Explorerでは、COMインターフェイスメソッドが一覧表示されません(以下を参照)。 ここに画像の説明を入力してください

誰かが私が欠けているものを知るのを手伝ってくれますか?それはCOMインターフェースメソッドがVBAに表示されない原因になっていますか?

生成されたTLBのITypeLibビューを添付して 編集ここに画像の説明を入力してください

4

4 に答える 4

6

Excelオブジェクトブラウザのスクリーンショットは、問題を明確に示しています。GetHashcode、GetType、およびToStringメソッドがどのように表示されるかに注意してください。これらは、System.Objectから継承されたメソッドです。ただし、スニペットは明示的に(そして正しく)[ClassInterface(ClassInterfaceType.None)]を使用するため、クラスの実装は非表示になります。

隠されていません。それがどのように起こったかはよくわかりませんが、以前の試みの古いタイプライブラリがそれを説明している可能性があります。しかし、ビルド手順は非常に疑わしいものであり、支援しすぎています。「アセンブリタイプをCOM表示にする」オプションは、ビルドシステムに.NETタイプを公開させるためのかなり大雑把な方法です。しかし、あなたのコードは、洗練された右上のピンキーアップのお茶を飲む方法を使用して、型をCOMに公開しています。これには、[ComVisible(true)]属性、チェックボックスの機能、および[ClassInterface]属性(チェックボックスの機能ではない)が含まれます。

したがって、問題は、ビルドシステムに2つのインターフェイスを実装するように依頼したことです。基本クラスから継承したもの(この場合は_Object)と、宣言から継承したもの(この場合はIMyGetString)。これは問題なく、すべてCOM互換ですが、VBAはあまり優れたCOMコンシューマーではありません。それは[デフォルト]インターフェースだけが好きで、それはあなたの場合は_Objectです。スクリーンショットからはっきりと見えます。

したがって、[アセンブリCOMを表示する]オプションをオフにします。

そして、Regasmを呼び出すビルド後のイベントまたは「COM相互運用機能に登録」チェックボックスのいずれかを選択します。両方の方法でそれを行うと、なぜそれが機能しないのかわからない確率が2倍になります。ポストビルドが必要になるのは、64ビットバージョンのOfficeのアセンブリを登録する必要がある場合のみです。

于 2012-05-13T20:39:46.403 に答える
3

私は同じ問題を抱えていました。このリンクを見つけました。

Excelから.netライブラリを呼び出すためのガイド パブリックメンバーを持つ「FooClass」というクラスを持つ「Foo.tlb」というTLBファイルを参照している場合。これらのメンバーはデフォルトで遅延バインディング(ランタイムバインディング)インターフェイスのみで構築されているため、これらのメンバーを表示することはできません。

クラスを変更してアーリーバインディングを設定できます。これにより、インテリセンスとクラスのメンバーをオブジェクトブラウザーで公開できるようになります。

C#:

[ClassInterface(ClassInterfaceType.AutoDual)]
public class FooClass
{
    public FooClass()
    {
    }
    public string DoSomething()
    {
        return "I am printing....";
    }
}

この変更を実装すると、オブジェクトブラウザにDoSomethingメソッドが表示されるはずです。注:最初にdllを尊重する必要があります。

于 2013-01-17T20:34:17.177 に答える
2

記録のために-他の誰かがこの答えを必要とする場合に備えて-私はこれとまったく同じ問題(OLEViewとすべて)を抱えていました、そしてそれは私を狂わせていました。以前にいくつかのC#COMを作成したことがあるため、何が間違っているのか理解できませんでした。IGetMyStringインターフェイス(この投稿では)をとして宣言するのを忘れましたpublic

これが誰かの時間を節約することを願っています。

于 2012-11-12T14:57:30.867 に答える
0

さらに、現在のソリューションを検討している他の人のために、VisualStudioでこれを実行する方法は他にもいくつかあります。

まず、[アセンブリCOMを表示する]と[COM相互運用機能に登録する](ビルドオプションの下)をオンにしました。

次に、 PUBLICインターフェイスに追加しました。

[Guid("[some guid]")]

そしてちょうど私の公開クラスに行き、これを追加しました:

[Guid("[some other unique guid]")]
[ClassInterface(ClassInterfaceType.None)]

そしてそれはうまくいきます。すべてが正しく行われた場合は、コンパイルにdllとtlbが含まれている必要があります。そこから、作業中のプロジェクトにそれらをインポートすると、VB6はすべてのオブジェクトのメソッドと、その他の公開された値/セッター/ゲッターを表示および表示します。列挙型もこのメソッドを使用して正常に機能するようです。

環境:

  • .NETFrameworkバージョン4.7.2の使用
  • ウインドウズ10
于 2021-02-22T21:16:07.580 に答える