教えて下さい。
現在、データをEXCELに出力しようとプログラムを組んでいますが、キーが変わったら
シートを追加し、書き込むというような処理をしたいと考えております。
単純に1シートへの出力は問題なくできましたが、上記のようにキーが変わったらシートを増やす
というような動きに応用すると、どうしてもEXCELのプロセスが残ってしまいます。
そもそも基本的なEXCELへの出力、シートの追加等の仕方のサンプルプログラムはないで
しょうか。。。。
抽象的な質問で申し訳ありませんが、教えて頂きたいと思います。
開発環境 : VB2008
ReleaseComObject でWEB検索すればいくらでもありますよね?
編集 削除返答ありがとうございます。
私の作成しているプログラムは以下のような形となっていて(ある程度加工してありますが、、、)
どうしてもブレイクしたタイミングでシートを追加し、そこへ出力しようと思うとEXCELのプロセス
が残ったままとなってしまいます。。。
本当に困っています。
どうか助けて下さい。
よろしくお願いします。
【プログラム内容】
'既存のEXCELファイルを開く
Dim xlFilePath As String = "C:\TEST.xls"
'起動時の処理
Dim xlApp As New Excel.Application
Dim xlBooks As Excel.Workbooks = xlApp.Workbooks
Dim xlBook As Excel.Workbook = xlBooks.Open(xlFilePath)
xlApp.Visible = True ' 確認のためExcelのウィンドウを表示する
Dim xlSheets As Excel.Sheets = xlBook.Worksheets
Dim xlSheet As Excel.Worksheet = CType(xlSheets.Item(1), Excel.Worksheet)
xlSheet = xlSheets.Item(1) 'シートの選択
xlSheet.Copy(After:=xlBook.Worksheets(1)) 'シートのコピー
xlSheet = xlSheets.Item(2) '再度シートを選択
xlSheet.Name = "zz" 'シートに名前を付ける
Dim x, y As Integer
x = 0
y = 0
Dim fcount As Integer
Dim Aコード As String
Aコード = ZZZ(0).Bコード
Dim strDat(20, 20) As Object
For icount As Integer = 0 To count - 1
If Aコード <> ZZZ(icount).Bコード Then
'データをEXCELファイルに書き出し
Dim xlRange As Excel.Range
xlRange = xlSheet.Range("A1:O30") 'データの入力セル範囲
xlRange.Value = strDat 'セルへデータの入力
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)
Dim xlSheet2 As Excel.Worksheet = CType(xlSheets.Item(2), Excel.Worksheet)
xlSheet2 = xlSheets.Item(2) 'シートの選択
xlSheet2.Copy(After:=xlBook.Worksheets(2)) 'シートのコピー
xlSheet2 = xlSheets.Item(2) '再度シートを選択
xlSheet2.Name = "YY" 'シートに名前を付ける
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet2)
Aコード = ZZZ(icount).IN_Bコード
x = 0
strDat(x, 1) = ZZZ(icount).IN_XX
strDat(x, 2) = ZZZ(icount).IN_YY
fcount = 1
Else
strDat(x, 1) = ZZZ(icount).IN_XX
strDat(x, 2) = ZZZ(icount).IN_YY
End If
x = x + 1
Next
Dim xlRange3 As Excel.Range
'データの入力セル範囲
xlRange3 = xlSheet.Range("A1:O30")
'セルへデータの入力
xlRange3.Value = strDat
'COM オブジェクトの解放
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange3)
xlBooks.Close()
xlApp.DisplayAlerts = False
xlApp.Quit()
'COM オブジェクトの解放
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
'Excel のプロセス終了
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
> Dim xlSheet As Excel.Worksheet = CType(xlSheets.Item(1), Excel.Worksheet)
> xlSheet = xlSheets.Item(1) 'シートの選択
一つの変数に、連続して 2 回代入しているのは何故ですか?
Dim a As Integer = 1
a = 2
と書いたら、先に代入した方が使われることは無いですよね。
> xlSheet.Copy(After:=xlBook.Worksheets(1)) 'シートのコピー
After 引数に指定するオブジェクトも、変数にとって ReleaseComObject が必要です。
> xlSheet = xlSheets.Item(2) '再度シートを選択
変数 xlSheet によって参照されていた .Item(1) を ReleaseComObject することなしに、
新たに別のオブジェクト .Item(2) を代入しているため、解放漏れが発生しています。
> Dim xlSheet2 As Excel.Worksheet = CType(xlSheets.Item(2), Excel.Worksheet)
> xlSheet2 = xlSheets.Item(2) 'シートの選択
ここでも、無駄な代入処理が行われています。
> xlSheet2.Copy(After:=xlBook.Worksheets(2)) 'シートのコピー
解放漏れ。早期解放が必要な場合は、COM オブジェクトは逐一変数に受けましょう。
> xlSheet2 = xlSheets.Item(2) '再度シートを選択
解放漏れ。前のオブジェクトを解放せずに次のオブジェクトを代入してはいけません。
> 'COM オブジェクトの解放
解放順が危ういです。内側のオブジェクトから解放しましょう。
今回の場合で言えば、
Range → Sheet/Worksheet → Sheets
→ Workbook → Workbooks → Application
の順になります。(Close 処理は、適宜、これらの間に挟み込みます)
>> 'COM オブジェクトの解放
> 解放順が危ういです。内側のオブジェクトから解放しましょう。
> Close 処理は、適宜、これらの間に挟み込みます
具体例として
http://hanatyan.sakura.ne.jp/dotnet/Excel01.htm
もうこのコード見飽きた。
http://qanda.rakuten.ne.jp/qa7192595.html
平気で嘘ついて質問を切り上げて、ハンドル変えて掲示板変えて。