C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: プロセス上の EXCEL.EXEが残ってしまいます。


(過去ログ 35 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■17422 / inTopicNo.1)  プロセス上の EXCEL.EXEが残ってしまいます。
  
□投稿者/ neko (3回)-(2008/04/23(Wed) 21:15:27)

分類:[.NET 全般] 

VisualBasic.netで 
[ 二つのエクセルファイルの情報を読み込んだ後に エクセルファイルを終了させる ] という処理を行いました。
ですが、
画面上ではエクセルが閉じるのを確認出来たのですが、プロセス上では EXCEL.EXEが残ってしまいます。
(エクセルの、アプリケーション、ブック、シート の開放も行ったのですが、プロセス上で残っていました。)
以下がそのソースなのですが、どうすれば、EXCEL.EXEを消すことができるのでしょうか。

たいへん初歩的な質問かとは思いますが、よろしくお願いいたします。



'------エクセルファイルを開く&表示-------

        'エクセルアプリケーションの定義
        Dim app1 = CreateObject("Excel.Application")
        Dim app2 = CreateObject("Excel.Application")

        app1.displayalerts = False
        app2.DisplayAlerts = False

        'ブックの定義
        Dim bk1 = app1.Workbooks
        Dim bk2 = app2.Workbooks

        Dim book1 = bk1.Open(myData.road_path1)
        Dim book2 = bk2.Open(myData.road_path2)

        'シートの定義
        Dim sheet1 = book1.Worksheets(1)
        Dim sheet2 = book2.Worksheets(1)

        '使用されている列数を取得する
        Dim Row1 = sheet1.UsedRange.Rows.Count() - 1
        Dim Row2 = sheet2.UsedRange.Rows.Count() - 1

        '使用されている行数を取得する
        Dim Col1 = sheet1.UsedRange.Columns.Count() - 1
        Dim Col2 = sheet2.UsedRange.Columns.Count() - 1

        '数値が大きい方を設定する
        myData.Max_Row = dif_suu(Row1, Row2)
        myData.Max_Col = dif_suu(Col1, Col2)

        'バッファ
        myData.File1_buf = New String(myData.Max_Row, myData.Max_Col) {}
        myData.File1_s_buf = New String(myData.Max_Row, myData.Max_Col) {}
        myData.File2_buf = New String(myData.Max_Row, myData.Max_Col) {}
        myData.File2_s_buf = New String(myData.Max_Row, myData.Max_Col) {}
        myData.File1_out_s_buf = New String(myData.Max_Row, myData.Max_Col) {}
        myData.File2_out_s_buf = New String(myData.Max_Row, myData.Max_Col) {}

        'ファイル1、2読込
        Try
            For i = 0 To myData.Max_Row
                For j = 0 To myData.Max_Col
                    '表示用バッファ、出力用バッファ登録
                    If sheet1.cells(i + 1, j + 1).value = Nothing Then
                        myData.File1_buf(i, j) = ""
                        myData.File1_s_buf(i, j) = ""
                        myData.File1_out_s_buf(i, j) = ""
                    Else
                        myData.File1_buf(i, j) = sheet1.cells(i + 1, j + 1).value
                        myData.File1_s_buf(i, j) = sheet1.cells(i + 1, j + 1).value
                        myData.File1_out_s_buf(i, j) = sheet1.cells(i + 1, j + 1).value
                    End If
                    If sheet2.cells(i + 1, j + 1).value = Nothing Then
                        myData.File2_buf(i, j) = ""
                        myData.File2_s_buf(i, j) = ""
                        myData.File2_out_s_buf(i, j) = ""
                    Else
                        myData.File2_buf(i, j) = sheet2.cells(i + 1, j + 1).value
                        myData.File2_s_buf(i, j) = sheet2.cells(i + 1, j + 1).value
                        myData.File2_out_s_buf(i, j) = sheet2.cells(i + 1, j + 1).value
                    End If
                Next
            Next
        Catch ex As Exception
            MsgBox("ファイルリードエラー")
            logfile.log_out("ERR", "ファイルリードエラー", Err.Description, "")
            Return conf.D_NG
        End Try

       '終了処理
        app1.Workbooks.close()
        app1.quit()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(sheet1)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(book1)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(bk1)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(app1)

        app2.Workbooks.close()
        app2.quit()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(sheet2)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(book2)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(bk2)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(app2)

引用返信 編集キー/
■17423 / inTopicNo.2)  Re[1]: プロセス上の EXCEL.EXEが残ってしまい
□投稿者/ ネタ好き (146回)-(2008/04/23(Wed) 21:18:08)
2008/04/23(Wed) 21:18:45 編集(投稿者)

No17422 (neko さん) に返信
http://jeanne.wankuma.com/tips/programing/
http://jeanne.wankuma.com/tips/programing/dispose.html
http://jeanne.wankuma.com/tips/programing/releasecom.html
これが参考になると思います。
引用返信 編集キー/
■17424 / inTopicNo.3)  Re[1]: プロセス上の EXCEL.EXEが残ってしまいます。
□投稿者/ 魔界の仮面弁士 (691回)-(2008/04/23(Wed) 22:52:37)
2008/04/24(Thu) 03:17:08 編集(投稿者)
No17422 (neko さん) に返信
> 画面上ではエクセルが閉じるのを確認出来たのですが、プロセス上では EXCEL.EXEが残ってしまいます。
> (エクセルの、アプリケーション、ブック、シート の開放も行ったのですが、プロセス上で残っていました。)

可能であれば、タイプライブラリを利用したコードに差し替えた方が無難かと思います。

.NET でレイトバインドした場合、特定状況下において、型変換時に内部的に参照カウントが
増加してしまい、Marshal.ReleaseComObject を余計に呼び出さねばならない事がありますので。

# 複数バージョンの Excel に対応させたい場合は、レイトバインドになるのも仕方ないですけど。

> Dim sheet1 = book1.Worksheets(1)
> Dim sheet2 = book2.Worksheets(1)
ここが NG です。Sheets / Worksheets コレクションを変数に受けてください。

sheets = book1.Worksheets
sheet1 = sheets(1)
Marshal.ReleaseComObject(sheets)

という感じで。


> Dim Row1 = sheet1.UsedRange.Rows.Count() - 1
> Dim Row2 = sheet2.UsedRange.Rows.Count() - 1
ここも NG。4 つの Range オブジェクトを解放し忘れています。

.UsedRange から返される Range オブジェクトを変数に受け、
その .Rows から返される Range オブジェクトも変数に受け、
それぞれを解放する処理を加えてください。

> Dim Col1 = sheet1.UsedRange.Columns.Count() - 1
> Dim Col2 = sheet2.UsedRange.Columns.Count() - 1
同様。


> If sheet1.cells(i + 1, j + 1).value = Nothing Then
ここで NG。.Cells から返される Range オブジェクトと、
._Default から返される Range オブジェクトを明示的に解放してください。

aaa = sheet1.Cells
bbb = aaa(i + 1, j + 1)
ccc = bbb.Value
Marshal.ReleaseComObject(bbb)
Marshal.ReleaseComObject(aaa)


> Else
>    myData.File1_buf(i, j) = sheet1.cells(i + 1, j + 1).value
>    myData.File1_s_buf(i, j) = sheet1.cells(i + 1, j + 1).value
>    myData.File1_out_s_buf(i, j) = sheet1.cells(i + 1, j + 1).value
> End If
以下、.Cells 系はすべて同様に。


> '終了処理
> app1.Workbooks.close()
ここは、bk1.Close() にすべきかと。

> app2.Workbooks.close()
こちらも同様。

引用返信 編集キー/
■17699 / inTopicNo.4)  Re[2]: プロセス上の EXCEL.EXEが残ってしまいます。
□投稿者/ neko (4回)-(2008/04/30(Wed) 13:12:01)
ネタ好きさん、魔界の仮面弁士さん、ありがとうございます。
こうやって、返信させてもらったら良いのかどうかもわからない初心者で、回答していただいたのにお礼がいえなくてすみませんでした。
このやり方でいいのかもわからないのですが、とにかくお礼をお伝えしたくて、書き込ませていただきました。
間違った書き方だったら、お許しください。
これからもいろいろご迷惑をお掛けすると思いますが、どうぞよろしくお願いいたします。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -