3

私は Boo を調査しており、Excel (この例では 2007) を自動化するいくつかの由緒ある VB スクリプトを変換してみるのは有益な演習になると考えました。多くのことは非常に簡単に変換できるように見えますが、範囲を選択するのに非常に苦労しています。それらを取得または設定しようとすると、TargetInvocationException Member not found が発生します。

これは、私が booish で実行した (切り詰めた) 例です。

def CreateInstance(progid):
    type = System.Type.GetTypeFromProgID(progid)    
    return type()   

xl as duck = CreateInstance("Excel.Application")
xl.Visible = true
xl.Workbooks.Add

sht as duck = xl.ActiveSheet
#Next line throws exception
rng as duck = sht.Range("A1")

シートの Name プロパティの設定など、特定の機能は正常に機能しますが、範囲を操作するにはどうすればよいですか? 呼び出す必要がある VB が隠している特別なメソッドがいくつかあります。

乾杯、

レニー。

4

1 に答える 1

3

Range は実際にはプロパティであり、インデクサーとして機能するという点でやや特殊なプロパティです。つまり、配列または辞書のようなセマンティクスを備えています。ほとんどの言語では、これは にアクセスすることを意味しますsht.Range["A1"]。これはシンタックス シュガーであり、実際には他のメソッドと同じようにアクセスできます。

sht.get_Range("A1",System.Reflection.Missing.Method)

Boo、Ruby、IronRuby を使用して、構文シュガー スタイルと明示的なメソッド呼び出しの両方を使用して、コードを繰り返してみました。IronRuby では問題なく動作しますが、32 ビット インタープリターでのみ動作します。私の構成では 32 ビット アプリである通常の Ruby でも、問題なく動作しました。64 ビット インタープリターでは、Range プロパティが正しく解決されませんでした。

そのため、Boo Interactive Shell が 64 ビット モードで実行されており、それが原因で相互運用が失敗しているのではないかと思いました。残念ながら、CORFLAGS.exe を使用してローカルの Boo バイナリを 32 ビット モードで実行するように設定した後も同じ問題が再現されたので、それが本当の問題だとは思いません。

ただし、次のように、Excel ドットネット相互運用ライブラリと相互運用サービスの名前空間を明示的にインポートすることでうまくいきました。

import Microsoft.Office.Interop.Excel
import System.Runtime.InteropServices

xl_type=typeof(Application).GetCustomAttributes(typeof(CoClassAttribute),true)[0].CoClass
xl=xl_type()
xl.Visible=true
xl.Workbooks.Add

それで:

xl.Range["A1","A2"].Value=12
xl.Range["A1",System.Type.Missing].Value="Alpha"
(xl.ActiveSheet as Worksheet).Range["A1","A2"].Value2='Whatever'

これらはすべて機能しますが、本質的には、遅延バインディングに慣れている「Scriptiness」を放棄する必要があります (これは、ダックタイピングが行っていることです)。

ほとんどの言語 (C# 4.0 以外) に当てはまる VB/VBScript との違いの 1 つは、一般に、オプションのパラメーターは透過的に処理されないため、オプションをサポートするメソッドを扱うときは API をより注意深く調べる必要があることです。パラメータ (System.Type.Missing または System.Reflection に相当するものに置き換えます)。これは、Excel の相互運用ドキュメントで見つけることができますが、検索するよりも簡単な場合は、おそらくリフレクションを使用してオプションとしてマークされたパラメーターを識別することができます。

Ruby にはこれらのオブジェクトをレイト バインドするための合理的な解決策があるため、Boo の COM 相互運用シナリオに欠落している機能 (またはバグ) があるのではないかと思います。

追加するために編集: Sam Ng は、C# 4.0 でのインデックス付きプロパティのサポートについて書いています。彼の投稿で説明されている問題は、Boo にも当てはまる可能性があります。

于 2009-12-03T04:53:11.283 に答える