以下の条件でVB.NET内でExcelを操作したいと思っております。
■条件■
1.参照設定(Microsoft Excel XX.X Object Library)を設定しない
2.Option Strict Off には設定しない。
■やりたいこと■
クラス内にて、以下のように記述しております。
Public Function SetRange(strCell as String) as object
objxlsApp = CreateObject("Excel.Application")
objxlsWorkBooks = objxlsApp.Workbooks
objxlsSheets = objxlsWorkBook.Worksheets
objxlsSheet = objxlsSheets("Sheet1")
objxlsRange = objxlsSheet.Range(strCell )
Return objxlsRange
End Function
上記の関数を
クラス名.SetRange("A1").Value = "テスト"
というように使用したいのですが、 「遅延バインディングを使用できません」と表示されます。
■条件■を満たしながらの回避方法をご存じであれば、ご教授ください。
※参照設定を行った場合は、Public Function SetRange(strCell as String) as Excel.Range
と記述できるので問題はありませんでした。
CallByName を利用してみてください。
回答ありがとうございます。
クラス名.SetRange("A1").Value = "テスト"
というように使用したいのも前提です。
objextの引き渡し方に何か対策がないでしょうか?
> クラス名.SetRange("A1").Value = "テスト"
> というように使用したいのも前提です。
Option Strict はファイル単位に設定できますが、
一部のみ On/Off を切り替える訳にはいかないのでしょうか?
それが駄目なら、やはり CallByName (またはリフレクション)が必要かと。
CallByName(クラス名.SetRange("A1"), "Value", vbLet, "テスト")
もし On のまま、かつ、CallByName やリフレクション無しでという条件なら、
クラス名.SetRange("A1").Value = "テスト"
の SetRange メソッドの戻り値を、「Value プロパティを持った自作クラス」に
差し替えて対応するか、もしくはSetRange メソッドの代わりに、
クラス名.SetValue("A1", "テスト")
の構文に改造する必要があるかと思います。
(相手が Object 型でなければ、拡張メソッドという手が使えますが…)
説明が不十分で申し訳ございません。
クラス名.SetRange("A1").Value = "テスト"
と使用したいのは一部です。
クラス名.SetRange("A1").XXXX = ○○○○○○
といった具合に、"A1"をRange化したものを扱いたいと思っております。
objectという受け渡しの形にはこだわっておりませんので、
>(相手が Object 型でなければ、拡張メソッドという手が使えますが…)
上記の例をご教授願えませんでしょうか?
> クラス名.SetRange("A1").Value = "テスト"
まず、Excel.Range オブジェクトの解放処理(Marshal.ReleaseComObject)を
どのタイミングで行う予定でしょうか?
通常通り、利用側に処理させる仕様にするのであれば、
x = クラス名.SetRange("A1")
x.Value = "テスト"
Marshal.ReleaseComObject(x)
となるでしょう(あるいは、IDisposable にして Using させるか…)。
一方、解放の責務を(利用側では無く)クラス側に負わせるなら、先の回答のように
(案1)
クラス名.SetValue("A1", "テスト") の構文にして、
解放処理をこのメソッド内に収める。
(案2)
クラス名.SetRange("A1").Value = "テスト" の構文で SetRange が返すオブジェクトを、
Excel の Range クラスではなく、COM オブジェクトを含まないマネージクラスにする。
(そしてこれが先の、「Value プロパティを持った自作クラス」の話に繋がってきます。)
などが考えられます。案2の実装は大変そうですけれども。
(他にも手はあるでしょうが、どの方法が良いのかはケースバイケースかと)
> と使用したいのは一部です。
もちろん、Value 以外のメンバも実装しなければなりませんね。
その場合、どの範囲までを対象としますか?
単に Excel の Range オブジェクトを扱うだけでも、200 以上のメンバ定義が
ありますし、Excel のバージョンによっても定義に差があるのが現状です。
結果、参照設定無しで運用する場合、
(a) 一部のメンバーのみをカプセル化する。
(b) すべてのメンバーをカプセル化する。
(c) レイトバインドで運用する。
の選択が必要になってきます。b 案は理想ですが、現実的では無いでしょうね。
>> (相手が Object 型でなければ、拡張メソッドという手が使えますが…)
> 上記の例をご教授願えませんでしょうか?
下記の拡張メソッドの解説記事を参照してみてください。
http://msdn.microsoft.com/ja-jp/magazine/cc163317.aspx
こちらの件、案2で解決させていただきました。
大変参考になり、助かりました。
本当にありがとうございました。
(案2)
クラス名.SetRange("A1").Value = "テスト" の構文で SetRange が返すオブジェクトを、
Excel の Range クラスではなく、COM オブジェクトを含まないマネージクラスにする。
(そしてこれが先の、「Value プロパティを持った自作クラス」の話に繋がってきます。)
ツイート | ![]() |