質問者
ExcelのワークシートににBV2005でデータの書き込みをする方法

質問
-
Excelの既存のワークシートにVB2005からデータを転送する方法ですが、次のような2とおりのほうう法でためしてみましたが満足できる方法が見つかりません。
dim cn As System.Data.OleDb.OleDbConnection
dim ad As System.Data.OleDb.OleDbDataAdapter
dim ds As New System.Data.DataSet()
dim cBuild As OleDb.OleDbCommandBuilder
cn = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;data source="c:_book1.xls;Extended Properties=Excel 8.0;")
ad = New System.Data.OleDb.OleDbDataAdapter("select * from [sheet1$]", cn)
cBuild = New OleDb.OleDbCommandBuilder(ad)cn.Open()
ad.Fill(ds, "sheet1")Messagebox.show(ds.Tables("sheet1").Rows(1)(2) )
ds.Tables("sheet1").Rows(1)(2) = 30
ad.Update(ds, "sheet1") <==== ここがエラーになるこのやり方ではMessagebox.show(ds.Tables("sheet1").Rows(1)(2) )のようなExcelからデータを読み込むことはできるのですが、ad.Update(ds, "sheet1")のように書きもみをしようとすると、 「UpdateCommand の動的 SQL 生成は、キーである列情報を返さない SelectCommand に対してはサポートされていません。」とエラーメッセージが出て、コマンドビルダーがあってもエラーを回避することができません。これが、Accessのファイルならデータフィールドの一つに主キーを設定すればこのエラーは出ません。ただ、エクセルでは一つの列を主キーとする方法がわからないので、このエラーを回避できません。うまくエクセルにデータを送る方法はないでしょうか?
もう一つの方法はエクセルをオートメーション化する方法で
'Dim oExcel As Object
'Dim oBook As Object
'Dim oSheet As Object''Start a new workbook in Excel.
'oExcel = CreateObject("Excel.Application")
'oBook = oExcel.Workbooks.Add''Add data to cells of the first worksheet in the new workbook.
'oSheet = oBook.Worksheets(1)
'oSheet.Range("A1").Value = "Last Name"ですが、これだとCreateObject("Excel.Application")で新しいワークシートを作って書き込むので、既存のエクセルのワークシートに書き込む方法がわかりません。
すでにあるワークシートに書き込む方法をご存知の方教えてください。
すべての返信
-
ADO.NET版に関しては以下を参考にして下さい。OleDbCommandBuilderが不完全なSQL文を生成しているんだと思います。手動でDataAdapterのUpdateCommandを構成して下さい。OleDbCommandBuilderは元々効率的ではありませんし、無理に使う必要は全くありません。
Excel ブックを変更するために、 ADO.NET OLEDbDataAdapter を使用しようとすると、エラー メッセージを表示します。
http://support.microsoft.com/kb/316756/ja
オートメーション版は以下を参考にしてみて下さい。http://7ujm.net/VB/VBEXCEL.html
Shigemin さんからの引用
ですが、これだとCreateObject("Excel.Application")で新しいワークシートを作って書き込むので、既存のエクセルのワークシートに書き込む方法がわかりません。
CreateObject("Excel.Application")は新しいワークシートを作っているわけではありません。Excelという名前空間にあるApplicationオブジェクトをインスタンス化しているだけです。 -
trapemiya さんからの引用 CreateObject("Excel.Application")は新しいワークシートを作っているわけではありません。Excelという名前空間にあるApplicationオブジェクトをインスタンス化しているだけです。
大事な部分が抜けていますね。Excel アプリケーションのプロセスはこの時点で起動しています。
Worksheet がいつ作成されるかですが、この後に Workbooks に対して Add するなり Open するなりすれば、Workbook が作成されます。Workbook が作成されるということは即ち、デフォルトの数で Worksheet が作成されるということになります。Worksheet が作成されるタイミングはここですね。 -
コメントありがとうございます。
OleDbCommandBuilderはだめだということですが、手動での定義のしかたがよくわかりません。
たとえば adをデータアダプターとして
ad.UpdateCommand = New OleDb.OleDbCommand("UPDATE [sheet1$]" SET A1=? B1=?")
なとど定義するのでしょうか? とくにエクセルでは上のコマンドでA1と書いた列名なども、どう書いていいのかわかりません。
先ほど本屋にいって見つけた方法では立ち上がっているエクセルに対してつかえる方法で
XLSApp = GetObject(, "Excel.AppLication")
XLSsheet = XLSApp.sheets("sheet1")XLSsheet.cells(1, 1) = 7 '書き込み
などとして書き込みは可能になりました。ただこれはエクセルのファイルbook.xlsを立ち上げておかないといけないという欠点があります。できればExcelを起動させないで書き込みがしたいのですが。
-
OleDbCommandBuilderはselect文を元にUpdate文などを生成するので、効率はあまりよくないのですが、使ってはダメということではありません。今回の場合は、OleDbDataAdapterのFillSchemaメソッドを実行してあげればうまくいきそうです。(以下を参照のこと)
You receive error messages when you try to use ADO.NET OLEDbDataAdapter to modify an Excel workbook
http://www.kbalertz.com/316756/Error.Occurs.OLEDbDataAdapter.Modify.Excel.Workbook.aspx
ただ、上で述べた理由によりOleDbCommandBuilderはやはりお勧めしません。OleDbCommandBuilderのGetUpdateCommand().CommandTextを使えば、どのようなSQL文が生成されているのかを見ることができますので、できれば以下の最後の発言を参照して、OleDbCommandBuilderを使わずにOLEDbDataAdapter だけで処理をするようにする方が良いです。
DataAdapter.Update() problems
https://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1431007&SiteID=1