2

vba を vb6 に変換して .dll を作成する - ハウツー - ヒント、ヒント、およびリスク」では、VBA コードを VB.NET コードに変換し、Excel で COM として VB.NET の関数にアクセスする方法について説明しました。

Excel では、関数は VBA 経由で次のようにアクセスする必要があります。

Public Function getParameterNumberOfMaterial() As Integer
    Dim myclass as New ExcelExample.ExcelVB
    getParameterNumberOfMaterial = myclass.getParameterNumberOfMaterial()
End Function

これは、ユーザーに公開されるすべての VBA 関数に対して、VB.NET に変換するときに上記のようにラッパーを作成する必要があることを意味します。

VBA ラッパーを記述せずに関数を直接使用する方法はありますか? つまり、Excel では、getParameterNumberOfMaterial()VBA ラッパーを作成しなくても、ユーザーは元の VBA 関数と同じように を直接使用できます。

4

2 に答える 2

2

COM 可視の .DLL 内の .NET 関数を Excel から直接呼び出すことはできますが、COM および Excel と互換性を持たせるには、それらを少し変更する必要があります。この例は、私がよく知っている C# で記述しますが、概念は VB.Net でも同じである必要があります。

新しいクラス プロジェクトを開き、InteropServices ライブラリをインポートする行を追加します。

using System.Runtime.InteropServices;

呼び出したい関数を含むインターフェイスを宣言します。

public interface ISample
{
      object func1(int p1);
      object func2(string p1);
}

インターフェイスにリストされている関数のみが Excel で使用できます。関数の戻り値の型が「オブジェクト」であることに注意してください。これは、Excel が結果をシートに正しく表示するために必要です。

インターフェイスを実装するクラスを宣言し、COM 経由で公開します。

[ClassInterface(ClassInterfaceType.None)]  // the proper way to declare COM-visible classes
public class Sample : ISample
{
    public object func1(int p1)
    { 
        // sample implementation
        object[,] retval = new object[1,1]
        retval[0,0] = "a";
        return retval;
    }

    public object func2(string p1)
    {
           // ....
    }

Excel では、すべての戻り値の型がオブジェクトの 2 次元配列であると想定されるため、関数の戻り値をこの方法で変換する必要があります。

また、DLL の登録と登録解除を支援するいくつかの関数を追加する必要があります。

    // helper function to get Registry key of given type
    private static string GetSubKeyName(Type type)
    {
        return "CLSID\\{" + type.GUID.ToString().ToUpper() + "}\\Programmable";
    }

    // called when class is being registered
    [ComRegisterFunctionAttribute]
    public static void RegisterFunction(Type type)
    {
        // register the automation DLL function will be visible to Excel
        RegistryKey key = Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type));
        if (key != null)
        {
            key.SetValue(string.Empty, Environment.SystemDirectory + @"\mscoree.dll");
        }
    }
    

    // called when class is being unregistered
    [ComUnregisterFunctionAttribute]
    public static void UnregisterFunction(Type type)
    {
        try
        {
            // remove automation DLL from registry
            Registry.ClassesRoot.DeleteSubKeyTree(GetSubKeyName(type));
        }
        catch (Exception ex)
        {
            Debug.Print(ex.Message + ex.StackTrace);
        }
    }
  • プロジェクトのプロパティ画面の「アプリケーション」タブで、「アセンブリ情報」をクリックし、「アセンブリを COM 可視にする」にチェックを入れます。[OK] をクリックします。
  • [ビルド] タブで、下部にある [COM 相互運用に登録] をクリックします。
  • プロジェクトをビルドします。

Excel で [開発] リボンをクリックし、[アドイン]、[自動化] の順にクリックして、プロジェクトまでスクロールします。[namespace].[classname] の形式でリストされます。

Excel ワークシートで関数を直接呼び出すことができるようになりました。

=func1(12)

これに関する MSDN ブロガーからの投稿もありますが、かなり古いものです。

PS VB.Net への変換に関してサポートが必要な部分がありましたら、お知らせください。サポートさせていただきます。

于 2013-01-25T15:46:02.947 に答える
0

以前は Excel 97 までの方法がありましたが、セキュリティ リスクとして削除されました。call 関数は、COM dll から関数を呼び出すことができました。http://www.cpearson.com/excel/Call.htm

于 2013-01-13T13:29:11.783 に答える