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

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

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.17422 の関連記事表示

<< 0 >>
■17422  プロセス上の EXCEL.EXEが残ってしまいます。
□投稿者/ neko -(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)
親記事 /過去ログ35より / 関連記事表示
削除チェック/

■17423  Re[1]: プロセス上の EXCEL.EXEが残ってしまい
□投稿者/ ネタ好き -(2008/04/23(Wed) 21:18:08)
記事No.17422 のレス /過去ログ35より / 関連記事表示
削除チェック/

■17424  Re[1]: プロセス上の EXCEL.EXEが残ってしまいます。
□投稿者/ 魔界の仮面弁士 -(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()
    こちらも同様。
記事No.17422 のレス /過去ログ35より / 関連記事表示
削除チェック/

■17699  Re[2]: プロセス上の EXCEL.EXEが残ってしまいます。
□投稿者/ neko -(2008/04/30(Wed) 13:12:01)
    ネタ好きさん、魔界の仮面弁士さん、ありがとうございます。
    こうやって、返信させてもらったら良いのかどうかもわからない初心者で、回答していただいたのにお礼がいえなくてすみませんでした。
    このやり方でいいのかもわからないのですが、とにかくお礼をお伝えしたくて、書き込ませていただきました。
    間違った書き方だったら、お許しください。
    これからもいろいろご迷惑をお掛けすると思いますが、どうぞよろしくお願いいたします。
記事No.17422 のレス /過去ログ35より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -