none
C#のDLLをExcel VBAからコールすると実行時エラー'429' RRS feed

  • 質問

  • C# や VB で作成した DLLをExcel VBAからコールすると

    実行時エラー'429'

    ActiveXコンポーネントはオブジェクトを作成できません。

    となり、どうしてもExcel VBA からDLLがコールできません。

    いろんなサイトを参考に同じようにソースを作りテストしてみたのですが

    同じ結果にしかならず何が悪いのかが、どうしてもわかりません。

    このエラーだけだと、何が悪いのかがわからずとても困っております。

    なんとなくExcelVBAでオブジェクトを見つけられていない気がしているのですが

    どうやったら、Excel VBAでオブジェクトを作成してくれるのかが

    見当がつきません。

    原因の特定方法、または対策をご教授いただけないでしょうか?

    環境・ソースは以下です。

    Windows7 64Bit SP1 .NET4.0 Visual C# 2010 Express

    OFFICE 64Bit SP2

    C#ソース

    using System.Runtime.InteropServices;

    namespace ClassLibrary1

    {

        [ClassInterfaceAttribute(ClassInterfaceType.AutoDual)]

        public class Class1

        {

            public int add(int x, int y)

            {

                return x + y;

            }

        }

    }

    C#設定

    ・構成 AnyCPU Debug

    ・アセンブリをCOM参照可能にする

    ・COM相互運用機能の登録

    ・アセンブリの署名 キーファイル追加

    Excel VBAソース

    Sub CallDll()

        Dim d As New ClassLibrary1.Class1

        MsgBox (d.Add(1, 2))

    End Sub

    実行方法 エクセルファイルをdllと同じフォルダに置き、

    参照設定後、実行

    d.Add(1, 2)実行時に実行時エラー'429'

    以上、なにかヒントになることでもあれば、お願いします。

    2013年8月4日 12:17

回答

  • regasm の 64bit 版は以下にありますので、そちらを試してみるところから始めてください。
    C:\windows\Microsoft.NET\Framework64\v4.0.30319

    • 回答としてマーク ExcelVBA 2013年8月4日 22:30
    2013年8月4日 22:14
    モデレータ
  • モデレータさん

    ありがとうございます!!!

    C#のCOM相互運用の登録が.NETの32Bitで動作しているようで

    C:\windows\Microsoft.NET\Framework64\v4.0.30319

    にパスを通し下記にて登録すると

    regasm /codebase /tlb ClassLibrary1.dll

    うまく動きました。

    なぜかC#の参照している .NETのパスがおかしい? ということのようです。


    • 編集済み ExcelVBA 2013年8月4日 22:31
    • 回答としてマーク ExcelVBA 2013年8月4日 22:36
    2013年8月4日 22:29

すべての返信

  • 外池と申します。ご質問の文面に明示されていない以下の点はどうなってますでしょうか?

    ★エラーが出るのは、OfficeとVisual Studioが同居しているパソコンですか? それとも、Officeだけが入っているパソコンに、別のパソコンのVisual Studioで作ったDLLを移して動作させようとしていますか?

    ご質問の文面で、一点だけ「おや?」と思うのは、「エクセルファイルをdllを同じフォルダに置き」の下りです。dllをエクセルファイルと同じフォルダに置く必然性は無いと小生は理解しており、むしろ、dllを置いておくべき場所から移してしまっていないか? もっと言えば、dllを置いてある場所をOSに登録する操作が上手くいってないのではないか? と想像しています。

    2013年8月4日 12:56
  • 外池さん

    ご返信ありがとうございます。

    エラーが出るのは、OfficeとVisual Studioが同居しているパソコンです。

    私もdllをエクセルファイルと同じフォルダに置く必然性は感じていませんが

    パスが関係しているかも。と、同じところにおいてみました。

    異なる場所においても同じ結果です。。。

    念のため、.NET4.0にパスを通し、C:\DLLにおいて下記コマンドを実行してみましたが

    やはり、実行時エラー429です。

      C:\DLL>regasm /codebase /tlb ClassLibrary1.dll

    なにかヒントになることがあれば助かります。

    2013年8月4日 13:38
  • 外池です。小生の手元の環境では実行できましたが、環境の相違と、アクセス権管理の問題でつまづいたりしましたので、あくまで「参考まで」ということで、ご理解下さい。

    ---------------------------------------

    1) OSは、Windows 7 pro. 64bitです。

    2) 開発環境は、Visual Studio 2008で、ご質問と同等のプロジェクトを作成してdllをビルドしたところ、追加のregasm等の必要はありませんでした。dllは、レジストリの

    HKEY_CLASSES_ROOT\Wow6432Node\CLSID\

    及び

    HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID\

    の配下に登録されました。

    3) ただし、「COM相互運用機能の登録」について、Administratorsグループのアカウントで作業しているにもかかわらずエラーとなり、UACをOFFにしなければなりませんでした。

    4) 小生のOfficeは2010(誤2013)の32bit版ですが、このExcelで、VBAのエディタに入り参照のダイアログを開けると、ちゃんと、登録したdllのプロジェクト名が見えてました。

    ---------------------------------------

    既にお気づきと思いますが、ExcelVBAさんと環境の最大の相違は、Officeのバージョンです。64bit版で使うことを意図した場合、dllの登録は、64bit版のregasmを使うべきのようです。

    ダメもとで、Visual Studioでプロジェクトをx64にターゲットを絞ってビルドしようとしたところ、dllの生成には成功するのですが、COM相互運用機能の登録の段階(regasmに相当)で、エラーで止まりました。

    手動で、64bit版のregasmをつかって登録(/codebase と、/tlbオプションつきで)してみると、regeditで、64bit版用に登録されたようです。ただ、こいつを呼び出すExcelの64bit版を持っていないので、ここから先がテストできません。

    • 編集済み 外池 2013年8月4日 22:17 Officeのバージョン誤り
    2013年8月4日 17:05
  • regasm の 64bit 版は以下にありますので、そちらを試してみるところから始めてください。
    C:\windows\Microsoft.NET\Framework64\v4.0.30319

    • 回答としてマーク ExcelVBA 2013年8月4日 22:30
    2013年8月4日 22:14
    モデレータ
  • 外池さん

    情報ありがとうございます。

    恐縮ですがもう1点だけ教えていただければありがたいです。

    Officeは2013の32bit版とのことですので

    C#の構成マネージャーでプラットフォームをx86を選択していただくと

    32bit版のDLLが作成されますのでExcel VBAから呼び出すことができると思います。

    その場合、VBAのソースはC#のDLLを実行しMsgBoxに結果を表示するでしょうか?

    大変恐縮なのですが、外池さんの環境でDLLコールできるか教えていただければありがたいです。

    2013年8月4日 22:15
  • ご存知かもしれませんが、念のために書き込みます。

    「COM 相互運用機能の登録」は HKEY_LOCAL_MACHINE への書き込みアクセスが必要なので、「Administratorsグループのアカウントで作業しているにもかかわらずエラー」は正常です。
    機能させたいのであれば、「UAC を OFF にする」のではなく、「Visual Studio を”管理者として実行”」してください。
    (この機能のために、UAC を OFF にするのは過剰と考えられたために書き込みました。どちらにせよ、この機能は 32bit として登録されるので、今回のケースには適用できないとは思っています)

    2013年8月4日 22:18
    モデレータ
  • 外池です。

    失礼、小生のOfficeは2010です。2013はタイポ。

    さて、WOW64上では、Office 32bit版のExcelからは、ちゃんと呼び出せましたよ? ただし、32bit整数は、Excel VBA上では、Long型としてますが。

    で、エラーメッセージの意味からして・・・、「ActiveXコンポーネントはオブジェクトを作成できません」のときは、コンポーネントの登録はできているみたいですね。登録ができていないときは、「ユーザー型は定義されていません」のエラーになります。

    もしかすると、64bit Excel VBAでも、32bit整数はLong型にしないといけないのかも?

    2013年8月4日 22:20
  • モデレータさん

    ありがとうございます!!!

    C#のCOM相互運用の登録が.NETの32Bitで動作しているようで

    C:\windows\Microsoft.NET\Framework64\v4.0.30319

    にパスを通し下記にて登録すると

    regasm /codebase /tlb ClassLibrary1.dll

    うまく動きました。

    なぜかC#の参照している .NETのパスがおかしい? ということのようです。


    • 編集済み ExcelVBA 2013年8月4日 22:31
    • 回答としてマーク ExcelVBA 2013年8月4日 22:36
    2013年8月4日 22:29
  • 外池さん

    対応ありがとうございました!

    2013年8月4日 22:34
  • 外池です。

    上手くいって、よかったです。

    ただ・・・、「.NETのパスがおかしい?」ということは無いと思います。プロジェクトからCOM相互運用の面倒を見てもらう仕組みが、32bit版のCOMを作ることを前提としている、ということだと思います。

    Officeの側においても、基本的に、64bitではなく、32bit版が目下のところ推奨されている、こととも、相通じると思います。

    Azuleanさんから指摘があった、UACを切るのは過剰、という件、小生もそのハズと思いつつ、小生の環境でとりあえず動作させるために設定しました。Visual Studioを「管理者で実行」する件にすいては、小生自身、調べてみます。「管理者」の定義をよく承知してないゆえ。

    -------------------

    追記:UAC制御と管理者の意味、調べて納得です。しかし、面倒なもんですね。Visual Studioのスタートメニューのショートカットに、直にアクセスするのも、一苦労してます。

    -------------------

    追記2:Visual Studio 2008を、Windows 7上で、UACを変更せずに、「管理者として実行」することができました。この開発環境で、32bit版用のCOM dllのビルドと登録、Excel VBAからの呼び出し、ひととおりできました。小生も勉強になりました。
    • 編集済み 外池 2013年8月5日 0:55 作業進捗
    2013年8月5日 0:21