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

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

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

Re[3]: エクセルのプロセスが残る環境と残らない環境


(過去ログ 43 を表示中)

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

■22887 / inTopicNo.1)  エクセルのプロセスが残る環境と残らない環境
  
□投稿者/ ぐっちょん (14回)-(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
引用返信 編集キー/
■22894 / inTopicNo.2)  Re[1]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ オガシン (32回)-(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)
この行は実行されますよね?

引用返信 編集キー/
■22895 / inTopicNo.3)  Re[1]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ THREE-ONE (4回)-(2008/08/05(Tue) 13:13:58)
THREE-ONE さんの Web サイト
こんにちは、THREE-ONEです。

> xlSheet.Range("A1").Resize(1, 10).Value = dataArray '範囲指定貼付(これをループで行ってます)
Range も COM オブジェクトだったと思います。
環境で異なる理由はわかりませんが、こいつが残っているのかも。
引用返信 編集キー/
■22896 / inTopicNo.4)  Re[2]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ THREE-ONE (5回)-(2008/08/05(Tue) 13:15:17)
THREE-ONE さんの Web サイト
うへ、タッチの差でかぶった。
引用返信 編集キー/
■22901 / inTopicNo.5)  Re[1]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ 魔界の仮面弁士 (799回)-(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
引用返信 編集キー/
■22902 / inTopicNo.6)  Re[3]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ ぐっちょん (15回)-(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)
例外が発生したなら、この行は実行されてないですね^^;
この書き方だと問題ありそうでしょうか?
引用返信 編集キー/
■22907 / inTopicNo.7)  Re[2]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ オガシン (33回)-(2008/08/05(Tue) 16:56:03)
.NETのメモリ管理とCOMのメモリ管理は違ったいます。
.NETではGCによって参照されなくなったオブジェクトが破棄されますが
COMは参照カウント法で参照回数が0になったタイミングで破棄がされます。
なので

>>objCom = Nothing

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

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

開放には下記のメソッドを使っていました。
System.Runtime.InteropServices.Marshal.ReleaseComObject
引用返信 編集キー/
■22947 / inTopicNo.8)  Re[3]: エクセルのプロセスが残る環境と残らない環境
□投稿者/ ぐっちょん (17回)-(2008/08/06(Wed) 10:22:10)
魔界の仮面弁士さん、オガシンさん詳しい説明ありがとうございます。

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

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

(再現できる環境が何故か現地だけなので、確認できませんが解決済にしておきます)
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -