QA@IT
この質問・回答は、@ITの旧掲示板からインポートされたものです。

VB からのExcel参照

こんにちは
VB .NET2003 + Excel2000 環境です

VB(WindowsApplication)からExcelを読み込んでDB出力する
プログラムを開発しています
セル内容の取得方法がよくわかりません
----------------------------------------------------
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
Dim xlProc As Excel.Worksheet
Dim s1 As String
Dim w1 As Excel.Range
xlApp = CType(CreateObject("Excel.Application"), Excel.Application)
xlApp.Workbooks().Open("c:\tmp\test.xls")
xlBook = CType(xlApp.Workbooks("test.xls"), Excel.Workbook)
xlProc = CType(xlBook.Worksheets("sheet1"), Excel.Worksheet)

----------------------------------------------------
[1] s1 = xlProc.Range(xlProc.Cells(2, 1),
       xlProc.Cells(2, 1)).Value.ToString
OKでした
----------------------------------------------------
[2] s1 = xlProc.Cells(2, 1).ToString
NGでした s1の内容は "System.__ComObject" となります
----------------------------------------------------
[3] w1 = xlProc.Range(xlProc.Cells(2, 1), xlProc.Cells(2, 3))
s1 = CType(w1.Value, Object)(1, 1)

ビルド時「CType(w1.Value, Object)(1, 1)」の箇所が
Option Strict On では、遅延バインディングを使用できません。
となってしまいます
  (開発の規則上Option Strict Onなのです)
この場合の型はなんなのかよくわかりません

----------------------------------------------------
Excelを参照してセル内容を取得する場合
上記[1]以外はできないのでしょうか
教えて下さい
よろしくお願い致します

質問者:Posh

回答

Poshさんの書き込み (2004-01-24 18:15) より:


[2] s1 = xlProc.Cells(2, 1).ToString

NGでした s1の内容は "System.__ComObject" となります


[1]ではちゃんとValueプロパティを使っているのに、
[2]では何故Valueプロパティを使われていないのでしょう?
(Rangeプロパティが返すのも、Cellsプロパティが返すのもどちらもExcel.Rangeです)

s1 = xlProc.Cells(2, 1).Value.ToString
が一番シンプルでは?

投稿者:よねKEN

編集 履歴 (0)

よねKENさんコメントありがとうございます
ご指摘のように
[2-1] s1 = xlProc.Cells(2, 1).value.ToString
とした場合
ビルドエラーになってしまうのです
「Option Strict On では、
  遅延バインディングを使用できません。」

型変換すればと思ったのですが
[2-2] s1 = CType(xlProc.Cells(2, 1).value, Excel.Range).ToString
上記の場合「xlProc.Cells(2, 1).value」の箇所が
遅延バインディングを使用できません。になってしまいます

[2-3]s1 = CType(xlProc.Cells(2, 1), Excel.Range)(1, 1).ToString
上記2-3の場合ビルドでエラーにはなりませんが
s1の中身は"System.__ComObject"になってしまいます

[2-4]s1 = CType(xlProc.Cells(2, 1), Excel.Range)(1, 1).Value.ToString
2-4は遅延バインディングを使用できません。になってしまいます

前のVBであれば
Dim Wk_Dtl As Variant
Wk_Dtl = SH.Range(SH.Cells(1, 1), SH.Cells(1,10))
s1 = Wk_Dtl(1, 1)
上記のようにVariant型に転記して、配列で処理できたのですが
.NETはできないのでしょうか

何かいい方法がありましたら
ご教授下さい。

投稿者:Posh

編集 履歴 (0)

Poshさんの書き込み (2004-01-25 18:48) より:

よねKENさんコメントありがとうございます

ご指摘のように

[2-1] s1 = xlProc.Cells(2, 1).value.ToString

とした場合

ビルドエラーになってしまうのです

「Option Strict On では、

  遅延バインディングを使用できません。」

申し訳ありません。実験してたプロジェクトでは設定を
Option Strict Onにするのを忘れてました。

で、Option Strict On環境では、下記のようにします。

s1 = CType(xlSheet.Cells(2, 1), Excel.Range).Value.ToString()

先の投稿にも書きましたが、Cellsプロパティで返されるものは、Range型なので、
型変換をきちんと行えばOKです。

型変換すればと思ったのですが

[2-2] s1 = CType(xlProc.Cells(2, 1).value, Excel.Range).ToString

上記の場合「xlProc.Cells(2, 1).value」の箇所が

遅延バインディングを使用できません。になってしまいます

ValueプロパティではなくCells(2,1)の返すものを型変換して下さい。

[2-3]s1 = CType(xlProc.Cells(2, 1), Excel.Range)(1, 1).ToString

上記2-3の場合ビルドでエラーにはなりませんが

s1の中身は"System.__ComObject"になってしまいます

そのコードは、
s1 = CType(xlProc.Cells(2, 1), Excel.Range).Item(1, 1).ToString

と同じ意味になり、Item(1,1)に対するExcel.Rangeへの型変換処理がありません。
また、セルの値を取得するにはそのValueプロパティにアクセスしないといけませんが、
これも記述されていません。

正しく書き直すと下記のようになります。

s1 = CType(CType(xlProc.Cells(2, 1), Excel.Range)(1, 1), Excel.Range).Value.ToString
'またはs1 = CType(CType(xlProc.Cells(2, 1), Excel.Range).Item(1, 1), Excel.Range).Value.ToString

Excelマクロで、

xlSheet.Cells(2,1) = "適当な値"

のようなコードが書けますが、これは、

xlSheet.Cells.Item(2,1).Value = "適当な値"

と書くことと同じ意味で、これが省略なしの正式な書き方です。
CellsプロパティはRangeオブジェクトを返します。Rangeオブジェクトの
既定のプロパティはItemプロパティのため、省略して、Cells(2,1)とかけます。
さらにValueプロパティも省略できますが、VB.NETではValueプロパティを略すことはできません。

#あれ?Cellsの返すのがRangeオブジェクトで、Itemの返すのもRangeオブジェクトで、
#Rangeオブジェクトの既定のプロパティはItemプロパティなのにValueプロパティを
#略せてしまうのは何故だろう??

投稿者:よねKEN

編集 履歴 (0)

よねKENさん 回答ありがとうございます

ご指摘の通り
s1 = CType(xlSheet.Cells(2, 1), Excel.Range).Value.ToString()
でうまくいきました

s1 = CType(CType(xlProc.Cells(2, 1), Excel.Range)(1, 1),
Excel.Range).Value.ToString
に関しても納得致しました

ご回答頂き誠に感謝しております
ありがとうございました。

投稿者:Posh

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。