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

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

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

No.22887 の関連記事表示

<< 0 >>
■22887  エクセルのプロセスが残る環境と残らない環境
□投稿者/ ぐっちょん -(2008/08/05(Tue) 12:31:46)

    分類:[.NET 全般] 

    ※実行環境(開発環境)
    OS:WINDOWSXP(SP2)
    Excelバージョン:Excel2000(9.0.3821 SR-1)

    ※(現地環境)
    OS:WINDOWSXP(SP2)
    Excelバージョン:Excel2000(9.0.3821 SR-1?)(同一だったと記憶していますが、確証無)
    ※現地ではネットワークに接続されていない為、WINDOWSの更新は行われていない

    ※開発言語
    VB.NET2005

    開発したアプリケーションでExcelを参照した後に、端末ごとにエクセルのプロセスが残る環境と残らない環境が存在します。
    開発している環境では、どの端末を使用してもエクセルのプロセスが残らないのですが、
    実際に現地で使用すると、端末にエクセルのプロセスが残ってしまいます。

    Web等でエクセルのプロセスが残る現象を調べてソースを見直してみたりしましたが、特にソースに問題点は見受けられません。
    (開発環境ではプロセスが残らない点からみて、ソースに問題はないかな?とは考えていますが)

    エクセルのプロセスが残る問題として何があるのか検討がつかず、手詰まり状態となっています。
    何か情報がありましたら、教えて頂けますでしょうか?
    (WINDOWSの更新が行われていないとかが問題かなと考えてますが、関係ないかな?)

    よろしくお願い致します。

    ※以下に念の為、ソースコード記載します。
    ================== 起動時の処理 ==================
    Dim xlApp As New Excel.Application
    Dim xlBooks As Excel.Workbooks = xlApp.Workbooks
    Dim xlBook As Excel.Workbook = xlBooks.Add
    Dim xlSheets As Excel.Sheets = xlBook.Worksheets
    Dim xlSheet As Excel.Worksheet = CType(xlSheets.Item(1), Excel.Worksheet)

    '================== データ入力 ==================
    xlSheet.Cells.NumberFormatLocal = "@" '全体を文字列に
    xlSheet.Range("A1").Resize(1, 10).Value = dataArray '範囲指定貼付(これをループで行ってます)

    '================== ファイルの保存処理 ==================
    xlApp.DisplayAlerts = False
    xlSheet.SaveAs(SaveFileDialog1.FileName)

    '================== 終了処理 =====================
    MRComObject(xlSheet) 'xlSheet の解放
    MRComObject(xlSheets) 'xlSheets の解放
    xlBook.Close(False) 'xlBook を閉じる
    MRComObject(xlBook) 'xlBook の解放
    MRComObject(xlBooks) 'xlBooks の解放
    xlApp.Quit() 'Excelを閉じる
    MRComObject(xlApp) 'xlApp を解放

    'オブジェクトの解放
    Private Sub MRComObject(Of T As Class)(ByRef objCom As T)
    If objCom Is Nothing Then
    Return
    End If
    Try
    If System.Runtime.InteropServices.Marshal.IsComObject(objCom) Then
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom)
    End If
親記事 /過去ログ43より / 関連記事表示
削除チェック/

■22895  Re[1]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ THREE-ONE -(2008/08/05(Tue) 13:13:58)
>
    こんにちは、THREE-ONEです。

    > xlSheet.Range("A1").Resize(1, 10).Value = dataArray '範囲指定貼付(これをループで行ってます)
    Range も COM オブジェクトだったと思います。
    環境で異なる理由はわかりませんが、こいつが残っているのかも。
記事No.22887 のレス /過去ログ43より / 関連記事表示
削除チェック/

■22894  Re[1]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ オガシン -(2008/08/05(Tue) 13:12:46)
    > '==================  データ入力  ==================  
    > xlSheet.Cells.NumberFormatLocal = "@"	'全体を文字列に
    > xlSheet.Range("A1").Resize(1, 10).Value = dataArray	'範囲指定貼付(これをループで行ってます)
    
    Dim xlRange As Excel.Range
    xlRange = xlSheet.Range("A1")
    xlRange.Resize(1, 10).Value = dataArray
    xlRangeの開放
    
    上記のようにセルに関わるものは一回づつ変数に代入してから
    使用したほうがいいかと思います。
    
    > 'オブジェクトの解放
    > Private Sub MRComObject(Of T As Class)(ByRef objCom As T)
    > If objCom Is Nothing Then
    >    Return
    > End If
    > Try
    > If System.Runtime.InteropServices.Marshal.IsComObject(objCom) Then
    >    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom)
    > End If
    
    途中で切れていますが例外が発生しても
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom)
    この行は実行されますよね?
記事No.22887 のレス /過去ログ43より / 関連記事表示
削除チェック/

■22896  Re[2]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ THREE-ONE -(2008/08/05(Tue) 13:15:17)
>
    うへ、タッチの差でかぶった。
記事No.22887 のレス /過去ログ43より / 関連記事表示
削除チェック/

■22902  Re[3]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ ぐっちょん -(2008/08/05(Tue) 15:48:06)
    オガシンさん、THREE-ONEさん有難うございます。

    >上記のようにセルに関わるものは一回づつ変数に代入してから
    >使用したほうがいいかと思います。

    >Range も COM オブジェクトだったと思います。
    >環境で異なる理由はわかりませんが、こいつが残っているのかも。

    おっと、という事は私がソース上で見落としてた部分がありましたか^^;
    1回ずつRangeオブジェクトを開放する処理に修正して、現地の環境で試してみたいと思います。

    >途中で切れていますが例外が発生しても
    >System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom)
    >この行は実行されますよね?

    すいません、切れていました
    Public Shared Sub MRComObject(Of T As Class)(ByRef objCom As T)
    If objCom Is Nothing Then
    Return
    End If
    Try
    If System.Runtime.InteropServices.Marshal.IsComObject(objCom) Then
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom)
    End If
    Finally
    objCom = Nothing
    End Try
    End Sub

    FinallyでNothingを格納しています。
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom)
    例外が発生したなら、この行は実行されてないですね^^;
    この書き方だと問題ありそうでしょうか?
記事No.22887 のレス /過去ログ43より / 関連記事表示
削除チェック/

■22901  Re[1]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ 魔界の仮面弁士 -(2008/08/05(Tue) 15:46:48)
    2008/08/05(Tue) 16:04:51 編集(投稿者)

    # 既に回答が付いていますが、補足の意味を込めて。

    No22887 (ぐっちょん さん) に返信
    > xlSheet.Cells.NumberFormatLocal = "@" '全体を文字列に
    ここで、Range オブジェクトの解放処理が漏れています。

    Dim xlRange As Excel.Range = xlSheet.Cells
    xlRange.NumberFormatLocal = "@"
    MRComObject(xlRange)

    > xlSheet.Range("A1").Resize(1, 10).Value = dataArray '範囲指定貼付(これをループで行ってます)
    ここで、Range オブジェクトがさらに 2 つ解放漏れ。

    xlRange = xlSheet.Range("A1")
    Dim xlResizedRange As Excel.Range = xlRange.Resize(1, 10)
    xlResizedRange.Value = dataArray
    MRComObject(xlResizedRange)
    MRComObject(xlRange)


    > '================== 終了処理 =====================
    処理中にエラーが発生した場合に備えるために、これらは本来、
    Finally ブロックなどに配置されるべきとされています。


    > オブジェクトの解放
    > Private Sub MRComObject(Of T As Class)(ByRef objCom As T)
    End Try がありませんが、実際にはどのような実装になっているのでしょうか?


    > If System.Runtime.InteropServices.Marshal.IsComObject(objCom) Then
    > System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom)
    > End If
    多くのケースでは、FinalReleaseComObject を使う必要は無く、
    ReleaseComObject をそれぞれ 1 回ずつ呼ぶだけで十分かと思います。

    ReleaseComObject ではなく、FinalReleaseComObject を使った実装にしてしまうと、
    下記のような場合に、★の行を実行できなくなってしまいますので、その点は注意してください。


     Sub Main()
        :
      xlSheet1 = xlSheets(1)
      xlSheet1.Name = "Template"
      Call Copy(xlSheets)
      xlSheet1.Select()  '★ Sub Copy 内で強制解放させてしまうと、この行の実行が失敗する
        :
     End Sub

     Sub Copy(ByVal xlSheets As Excel.Sheets)
        :
      Dim xlSheet As Excel.Worksheet = DirectCast(xlSheets.Item(n), Excel.Worksheet)
        :
      MRComObject(xlSheet)
        :
     End Sub
記事No.22887 のレス /過去ログ43より / 関連記事表示
削除チェック/

■22907  Re[2]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ オガシン -(2008/08/05(Tue) 16:56:03)
    .NETのメモリ管理とCOMのメモリ管理は違ったいます。
    .NETではGCによって参照されなくなったオブジェクトが破棄されますが
    COMは参照カウント法で参照回数が0になったタイミングで破棄がされます。
    なので

    >>objCom = Nothing

    上記のコードでobjComの参照値をNothingにしても
    参照カウントはデクリメントされないと思うので、開放メソッド実行時に
    例外が発生した場合プロセスが残る可能性があると思います。

    #自分も魔界の仮面弁士さんの書き込みを見ながら作ったクチなので
    #魔界の仮面弁士さんのほうが詳しいと思いますが

    開放には下記のメソッドを使っていました。
    System.Runtime.InteropServices.Marshal.ReleaseComObject
記事No.22887 のレス /過去ログ43より / 関連記事表示
削除チェック/

■22947  Re[3]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ ぐっちょん -(2008/08/06(Wed) 10:22:10)
    魔界の仮面弁士さん、オガシンさん詳しい説明ありがとうございます。

    ReleaseComObjectの変更、終了処理をFinallyブロックに配置、Rangeオブジェクトの開放等やってみます。

    お蔭様で、手詰まりとなっていた箇所が解決できそうです。
    また今後ともよろしくお願いします。

    (再現できる環境が何故か現地だけなので、確認できませんが解決済にしておきます)
記事No.22887 のレス / END /過去ログ43より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -