|
2013/05/20(Mon) 22:06:47 編集(投稿者)
■No66727 (きのこる さん) に返信 > 2.0だとget_Offset(1,0)と表記する必要がある(すべてのパラメータを省略せず記載する必要あり) > 4.0だとOffset[1,0]と表記(xを省略してOffset[1]と書く事もできる?(この場合意味不明だけど)) 「xを省略して」というのは、Offset(行, 列) プロパティの、第二引数(列)を省略する場合のことですね。 実際 VBA の世界では、.Offset(1) や .Offset(, 1) といった表現も見かけます。
> すこし勉強してみましたが、残念ながらイマイチ理解できていません。 省略可能な引数については理解頂いているように見えたので、『get_Offset』の件について。
今回の get_ 表記は、C# にて参照設定で呼び出す場合に限定した話です。 (とりあえずは「そういうものである」という程度の認識で OK かと思います)
そもそも、Excel の Offset プロパティは、引数が必要なプロパティであるにも関わらず、 肝心の C# が、『引数付きプロパティ』をサポートしていないという点から生じる問題です。
COM コンポーネント、あるいは VB 4 以降や VBA においては、 引数付きプロパティがサポートされており、たとえば VB.NET であれば Public Interface ISample ReadOnly Property Foo(ByVal a As Integer) As Integer ReadOnly Property Bar(ByVal a As Integer) As Integer End Interface という定義を持った DLL を容易に作成できます。
しかしながら、C# の言語仕様ではこのような定義を作成できません。 (一応、近い機能としてインデクサーが用意されてはいますが)
ただし作成できないだけで、利用することはできます。
上記をコンパイルすると、自動的に get_Foo/get_Bar という名のアクセサメソッドが 生成される仕様になっています。これにより、引数付きプロパティをサポートしてない言語や そもそもプロパティをサポートしていない言語などからも呼び出すことが出来る仕組みです。 (書き込み可能なプロパティの場合は、同様に set_系メソッドが用意されます)
その結果、上記の VB 製 DLL を C# から参照設定した場合、その定義が public interface ISample { int get_Bar(int a); int get_Foo(int a); } というメソッド表記であるかのように振る舞われることになります。 実際はプロパティなのに、メソッドが並んでいるように見えますね。
この点は C# 5.0 になった今でも変わりません。 これが、「.get_Offset メソッド」を使う事になる理由です。
Excel の PIA である Microsoft.Office.Interop.Excel の .NET ライブラリを、 Visual C# 2005 や 2008 から参照した場合、Excel.Range クラスの Offset プロパティは、 object x = rng.get_Offset(1, 0); // OK //object y = rng.Offset[1, 0]; // NG のような動作となります。
一方、C# 4.0 からは COM 対応が強化されており、C# 2010 や 2012 から参照した場合に、 object x = rng.get_Offset(1, 0); // OK object y = rng.Offset[1, 0]; // OK のように、元のプロパティのままでも扱えるように拡張されました。 (相手が COM オブジェクトでない場合は、プロパティとメソッドが区別されます)
ただし、C# から Type.InvokeMember で呼び出す場合や、dynamic から呼び出す場合、 あるいは VB から利用する場合には、get_Offset メソッドではなく、 Offset プロパティとして扱う必要があります。
長々書きましたが、要するに、get_Offset 形式での指定が必要になるのは、 VS200X 系の C# にて参照設定して開発している場合に限定されるということです。
>>> C#から遅延バインディングを用いてエクセルへのデータ入力を行いたいのですが、 遅延バインディングの場合、実行する Excel バージョンによって書き方が変わったり、 同じコードが別のメソッド呼び出しになる可能性を秘めているため、ご注意ください。
たとえば、Range.Value プロパティも、先の getter/setter の問題を抱えています。 しかも Offset プロパティとは異なり、Excel バージョンによって動作が異なります。
Range オブジェクトの Value プロパティは、 Excel 2000 以下では引数の無いプロパティでしたが、 Excel 2002 以上では、省略可能な引数として XlRangeValueDataType を 受け取るようになっているためです。
バージョンによる違いが大きいところでは、Range.Insert メソッド。 今回は使用されていないので関係ありませんが、 Excel 2002 が『Function Insert(Optional Shift, Optional CopyOrigin)』 Excel 2000 が『Function Insert(Optional Shift)』 Excel 97 が、『Sub Insert(optional Shift)』 という、バージョンごとに異なる実装を持っている為、要件次第では バージョンチェックのコードも必要になる可能性があります。
まぁ、2010 以降では dynamic が使えるようになったため、 この手の問題に対処しやすくなってはいるのですけれども。
|