2009-08-05 8 views
3

おはようは、開発者がフェロー:私の共有アドインコンストラクタで何が問題になっていますか?

私は現在、いくつかのパフォーマンスの問題を解決しようとしている

エクセル共有アドイン以前の開発者から継承され、基本的に私は、アドインのものが内部どのように機能するかを見つけようとしていますExcelで、私は情報のためのネットを検索していた意味、私の理解では、次のとおりです。LoadBehaviourがオープンイベント中にExcelワークブック3

  • に設定する必要があり、レジストリで

    1. 以前に参照されているすべてのアドインをロードする必要がありますVBAプロジェクトで
    2. ドキュメントが開いている私のアドインは、VBAコードで使用できるようにする必要があります。

    このようにグローバル変数

    Public myAddin As Object 
    
    Set myAddin = New TradingAddin.TradingAddin 
    

    がある今、私は、アドインにlog4netのを追加して、不思議に十分な私は、Excelワークブックで開くイベント中に、次の行動

    を見ていましたC#クラスのコンストラクタが呼び出されます。

    コンストラクタがもう1回呼び出され、すべてのIDTExtensibility2メソッドOnConnection、OnDisconnectionなどが期待通りに呼び出されます。

    私はExcelがロードされたら、アドイン、それはVBEコードに利用可能であるべきと私は

    Set myAddin = Application.COMAddins.Item("Trading").Object 
    

    のようなものを書くことができると思った。しかし、それは何もないとクラスのコンストラクタを呼び出すことが二度すべての状態を破棄返しますExcelワークブックの使用中にメモリ内で使用できるはずのC#オブジェクト内に保存されます。

    更新:

    プラットフォームは、Visual Studio 2005チームエディションとターゲット・アプリケーションは、Excel 2003ので、アドインが共有アドインです。私はVSTOを使用していません。

    私はVBAで起動しようとしていた実際のコードが

    Set addIn = Application.COMAddIns.Item("K2Trading.K2Trading").Connect 
    
    Set managedObject3 = addIn.Object <--- This value that I thought was an Instance of the Add-in is equal to Nothing (NULL) 
    
    Set addIn = Application.COMAddIns("K2Trading.K2Trading").Connect 
    

    また2つの負荷アドインを正しくすべての拡張イベントOnConnectionに焼成初めてから3にレジストリにLoadBehaviourを変更され、OnDisconecctionとObject Class Constructor、Add-inのインスタンスをVBAの参照に接続し、そこからInterfaceを介して公開されるすべてのメソッドを呼び出す方法を意味する、Add-inのVBAから呼び出し部のための方法を見つける必要がありますCOMオブジェクト????

    また、ProcMonを使用して、このリンク(非常に便利)のアドインが見つかって読み込まれたことを再度確認しました。http://blogs.msdn.com/dvespa/archive/2008/10/15/troubleshooting-outlook-com-addins-using-procmon.aspx

    私たちはおそらく正しい方向を指していますか?

    COMオブジェクトのインスタンス数は、どのようにして読み込まれますか?または別の言葉に入れて、COMオブジェクトの単一のインスタンスを持つことは可能でしょうか?

    TIA、 ペドロ

    マイクへ:

    私はあなたのソリューションを試みたが、I'vは(HRESULTからの例外:0x80004005の(E_FAIL))予期しないエラーに直面して、このコード

    を実行するとき
    public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, 
        object addInInst, ref System.Array custom) 
    { 
        object missing = System.Reflection.Missing.Value; 
    
        try 
        { 
         if (debug) 
         { 
          log.Debug("Connection Mode :" + connectMode); 
         } 
    
         this.excelApp = (Excel.Application)application; 
         this.addInInstance = addInInst; 
    
         Office.COMAddIn addIn = this.excelApp.COMAddIns.Item(ref addInInst); 
    
         //addIn.Object = this; 
    
         // We connect our Instance of the Add-in to the Arrya of COMAddins of Excel 
         VBA.Interaction.CallByName(addIn, "Object", VBA.CallType.Let, this); 
    
         ^
         | 
         The Exception occurs here. 
    

    あなたと少し違って見えることに気づくでしょう。少し前に投稿しました

    public void OnConnection(
        object application, 
        Extensibility.ext_ConnectMode connectMode, 
        object addInInst, 
        ref System.Array custom) 
    { 
        // Direct call fails b/c ".Object" is a late-bound call: 
        // 
        // addInInst.Object = this; 
    
    
        // Reflection fails I believe b/c .Object is a 'let' assigned 
        // property for reference type, which is very unusual even for 
        // COM (although legal) and is a foreign concept to .NET. Use 
        // of the right BindingFlags here *might* work, but I'm not sure: 
        // 
        // PropertyInfo propInfo; 
        // propInfo = addInInst.GetType().GetProperty("Object"); 
        // propInfo.SetValue(addInInst, this, null); 
    
    
        // This works!: 
        VBA.Interaction.CallByName(addInInst, "Object", VBA.CallType.Let, this); 
    } 
    

    addInInstはOffice.COMAddinが、私のクラスのインスタンスとして渡されていないので、それはそのクラスに存在していないので、そう は、オブジェクトのプロパティに代入しようとすることは間違ってい

    また、私は好奇心が強いですExcelがアドインをロードする方法については、Excelをロードした直後の私の所見に基づいていますが、OnConnectionメソッドはすぐに実行されませんでしたが、= AvgCost()関数がヒットするまでは??

    アイデア?

  • +0

    、これはペドロに役立ちます願っていますか?あなたは何を求めているのですか? – shahkalpesh

    答えて

    2

    のCOMオブジェクトのインスタンス数が であることがわかりましたか?別の言葉を言えば、 は、単一の COMオブジェクトのインスタンスを持つことができますか?

    ここでCOMアドインを意味しますか? Excelに同じCOMアドインを複数回ロードすることはできません。

    今私は はVBA で参照する場合には、追加し、あちこちにあり、すべてのメソッドを呼び出す接続する方法を意味し、 のVBAから 呼び出し部分は、アドインのための方法を見つける必要があります COMオブジェクトのインターフェイスに公開されていますか?

    VBAはすべてバインドされていますが、VB6 DLLや.NETアセンブリのようなDLLにはあらかじめコンパイルされていません。したがって、あなたのVBAコールのすべてが遅れている必要があります。最も簡単なのはExcel.Appliction.Run("NameOfYourVbaMacro")に電話して、ワークブック内の標準モジュール内に格納されているマクロを呼び出すことです。 (ワークブックには、Excel.Application.Workbooks["NameOfYourAddin.xla"]を使用して名前でアクセスできます。強制的にロードするとき以外は、特にアドインとして扱う必要はありません)リフレクションコードを使用して、ワークブックやワークシートのメンバー、 ThisWorkbookクラスモジュールまたはWorksheetクラスモジュールのいずれかの背後にコードがある場合は、

    私はExcelがロードされると アドインで VBEコードに利用可能であるべきと私は

    ように設定MyAddinの= Application.COMAddins.Item(「取引」何かを書くことができると考えました).Object

    私が正しく理解していれば、あなたはC#で管理されているCOMアドインをVBAコード(前述)のように呼び出すだけでなく、VBAコードでもC#で管理されたCOMアドインを呼び出すには?これは多分複雑なものだと思いますが、おそらく考え直す必要があるかもしれませんが、それはできます。

    ComAddin.Objectプロパティを使用してCOM呼び出し元に管理対象COMアドインを公開するのは、C#から実行されたときには難しいですが、実行可能です。以下の説明を参照してください。

    Calling Managed Add-In method from Automation client

    私は

    マイク

    編集...これはあなたが軌道に乗るのに役立ちます願ってい

    :あなたは、これはalittleが に見える気づいただろうペドロの返信への対応

    ペドロ、

    あなたとは異なる投稿を投稿しました 前...

    はい、あなたのコードは違うので、うまくいきません!最低で

    、あなたの最後の行が正しくないになります。

    代わり
    VBA.Interaction.CallByName(addIn, "Object", VBA.CallType.Let, this); 
    

    、あなたのコードは、「addInInst」にあなたのクラスに渡すべきである:

    VBA.Interaction.CallByName(addInInst, "Object", VBA.CallType.Let, this); 
    

    そして、私はわからないんだけどこの行で何をしようとしているか:

    Office.COMAddIn addIn = this.excelApp.COMAddIns.Item(ref addInInst); 
    

    この行は例外をスローするように見えます。私はそれがしないことに非常に驚いています。しかし、アクセスするCOMアドインのprogIdを渡す場所に似たコードは、通常、.Objectプロパティを使用してCOMアドインにアクセスする外部呼び出し元によって使用されます。これは、から以内に使用する必要のあるコードではありません。それは、そのクラスに存在していないので、

    addInInstはそう Objectプロパティに代入しようと、 Office.COMAddin私 クラスのインスタンスとして渡されていないためには、間違ってい

    ここで何をしようとしているのか分かりません。 IDTExtensibility2を実装するクラスのインスタンス以外のオブジェクトを渡すことができるかどうかはわかりません。最低でも、返すクラスはでなければなりません。正しいクラスとインターフェイスの属性を使用してCOM可視クラスにする必要があります。しかし、私は、OnConnectionメソッド内からIDTExtensibility2を実装するクラスを渡すという標準的な方法に固執するほうがはるかに簡単だと思います。つまり、 'this'オブジェクト参照を渡します。

    標準的なアプローチを超えた魅力的なものを試してみたいと思うなら、それは大丈夫ですが、まずは簡単な例を取り上げます。例題Calling Managed Add-In method from Automation clientに示すコードを複製してみてください。作業が完了したら、より洗練された操作に移行することができます。しかし、一度あなたが単純なバージョンの作業をしたら、これがあなたが必要とするすべてであることがわかります。

    私はあなたが直面している問題が何であるかを

    マイク

    +0

    マイクは天から来ました。私が持っていた問題の1つは、私のOnConnectionメソッドでの後半のbindig問題でした。なぜなら、VBAサイドで見たのは、set managedObject =新しいK2Trading.K2Tradingの集まりだったからです。Add-変数を数回初期化することで大きな問題を作り出しますが、検出されない変数があります。私の上司が問題を見つけて見つけて最適化を行うとき、なぜ私のコードはComAddin.Object経由で機能していなかったのですか?私は月曜日にお会いしましょうが、これが解決策であると確信しています。 –

    +0

    良いペドロ、それがどうなるか教えてください。 –

    関連する問題