- らら
- 常連さん
- 会議室デビュー日: 2005/01/21
- 投稿数: 28
- お住まい・勤務地: 埼玉県
|
投稿日時: 2005-12-16 18:13
いつも参考にさせていただいています。
ASP.netのVBでExcelファイルを作るプログラムを作成しています。
過去ログを参考にして作成し、無事にファイルが作成されることは確認できました。
しかし、Release版で実行すると問題ないのですが、
Debug版で1ステップづつ進めていきプログラムを終了すると
Excel.EXEがタスクに残ってしまい作成したExcelファイルを開くことができません。
Debug版だと動作が変わるのでしょうか?
ご存知の方、是非ご教授お願いします。
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2005-12-16 18:29
引用: |
|
ららさんの書き込み (2005-12-16 18:13) より:
Debug版で1ステップづつ進めていきプログラムを終了すると
Excel.EXEがタスクに残ってしまい作成したExcelファイルを開くことができません。
|
ソースを出して頂けませんか?
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- らら
- 常連さん
- 会議室デビュー日: 2005/01/21
- 投稿数: 28
- お住まい・勤務地: 埼玉県
|
投稿日時: 2005-12-19 10:52
じゃんぬねっとさん
早速のご返信ありがとうございました。
ソースは以下となっております。
Public Class CMakeFile
Public Function NewEx(ByRef fileName As String)
Dim strNewFile As String
'================== 起動時の処理 ===================
Dim xlApp As New Excel.Application
Dim xlBooks As Excel.Workbooks = xlApp.Workbooks
Dim xlFilePath As String = "D:\test.xls"
Dim xlBook As Excel.Workbook = xlBooks.Open(xlFilePath)
Dim xlSheets As Excel.Sheets = xlBook.Worksheets
Dim xlSheet As Excel.Worksheet = xlSheets.Item(1)
xlApp.Visible = False
'================== データの入力処理 ==================
Dim xlCells As Excel.Range
Dim xlRange1 As Excel.Range
xlCells = xlSheet.Cells
xlRange1 = xlCells(1, 12)
xlRange1.Value = "テストデータ"
MRComObject(xlRange1)
MRComObject(xlCells)
'================== ファイルの保存処理 ==================
strNewFile = "D:\test_tmp.xls"
xlApp.DisplayAlerts = False
xlSheet.SaveAs(strNewFile)
xlApp.DisplayAlerts = True
'================== 終了処理 =====================
MRComObject(xlSheet) 'xlSheet の開放
MRComObject(xlSheets) 'xlSheets の開放
xlBook.Close(False) 'xlBook を閉じる
MRComObject(xlBook) 'xlBook の開放
MRComObject(xlBooks) 'xlBooks の開放
xlApp.Quit() 'Excelを閉じる
MRComObject(xlApp) 'xlApp を開放
fileName = strNewFile
End Function
Private Sub MRComObject(ByRef objCom As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom)
Catch
Finally
objCom = Nothing
End Try
End Sub
End Class
呼出し元では、CMakeFileをNewしてNewExメソッドを呼び出しています。
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2005-12-19 11:48
ソースを拝見しました。
正常動作時 "では" 問題なさそうですね。
引用: |
|
ららさんの書き込み (2005-12-16 18:13) より:
Debug版で1ステップづつ進めていきプログラムを終了すると
Excel.EXEがタスクに残ってしまい作成したExcelファイルを開くことができません。
|
自動式ウォッチが働いて参照カウントが増えているせいだと思います。
ステップ実行時の自動式ウォッチ絡みをすべて非表示にしてみてください。
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2005-12-19 12:02
現状のコードですと、途中で例外が発生した場合に解放できなくなります。
以下のように Try 〜 Finally による実装にすべきだと思います。
参照する必要がなくなった時点で参照を解放してください。
コード: |
|
Public Class Form1
_______________________
| Windows フォーム デザイナで生成されたコード |
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
Private Sub Button1_Click(...) Handles Button1.Click
Dim stReturn As String = CMakeFile.NewEx()
MessageBox.Show(stReturn)
End Sub
End Class
Public Class CMakeFile
Public Shared Function NewEx() As String
Dim xlApp As New Excel.Application()
Try
Dim xlBooks As Excel.Workbooks = xlApp.Workbooks
Try
Dim xlFilePath As String = "D:\\test.xls"
Dim xlBook As Excel.Workbook = xlBooks.Open(xlFilePath)
Try
Dim xlSheets As Excel.Sheets = xlBook.Worksheets
Try
Dim xlSheet As Excel.Worksheet = DirectCast(xlSheets(1), Excel.Worksheet)
Try
Dim xlCells As Excel.Range = xlSheet.Cells
Try
Dim xlRange1 As Excel.Range = DirectCast(xlCells(1, 12), Excel.Range)
Try
xlRange1.Value = "テストデータ"
Finally
If Not xlRange1 Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange1)
End If
End Try
Finally
If Not xlCells Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlCells)
End If
End Try
Dim strNewFile As String = "D:\\test_tmp.xls"
xlApp.DisplayAlerts = False
xlSheet.SaveAs(strNewFile)
xlApp.DisplayAlerts = True
Return strNewFile
Finally
If Not xlSheet Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)
End If
End Try
Finally
If Not xlSheets Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets)
End If
End Try
Finally
If Not xlBook Is Nothing Then
Try
xlBook.Close()
Finally
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
End Try
End If
End Try
Finally
If Not xlBooks Is Nothing Then
Try
xlBooks.Close()
Finally
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
End Try
End If
End Try
Finally
If Not xlApp Is Nothing Then
Try
xlApp.Quit()
Finally
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
End Try
End If
End Try
End Function
End Class
|
- Try 〜 Finally で実装することにより、確実に解放が行われます。
また、スコープが明確になるため、他のブロックで誤って参照してしまうことを防ぎます。
- CMakeFile の構成を存じないのですが、
この NewEx メソッドは、共有メソッドの方が良いと思います。
- Function の使い方に誤りがあります。
参照渡しを使って戻り値を返すのではありません。
- Function の戻り値の型が宣言されていません。
Option Strict を On にしておけば、戻り値の型宣言の忘れを防ぐことができます。
- せっかく Function にしているのですから、メソッドから戻り値を返しましょう。
- 変数は使う直前に宣言と初期化を同時に行いましょう。
# 長文すいません。
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- らら
- 常連さん
- 会議室デビュー日: 2005/01/21
- 投稿数: 28
- お住まい・勤務地: 埼玉県
|
投稿日時: 2005-12-19 12:14
じゃんぬねっとさん
ご丁寧に全てのご指摘ありがとうございます。
先ほどじゃんぬねっとさんのサイトを見させていただきました。
http://jeanne.wankuma.com/tips/programing/02-releasecom.html
とても参考になりました。今後も活用させていただきます。
1つ1つのご指摘事項を解消して、また結果を報告させていただきます。
ありがとうございます。
|
- らら
- 常連さん
- 会議室デビュー日: 2005/01/21
- 投稿数: 28
- お住まい・勤務地: 埼玉県
|
投稿日時: 2005-12-19 18:46
無事にDebugのときでもエクセルが終了することを確認することができました。
自動式ウォッチを全て閉じることで解決しました。
↑で解決できる理由は、
自動式ウォッチウィンドウが表示されている状態なので
オブジェクトへの参照が残ってしまっているという認識でエクセルが
終了できないでいるということなのでしょうか?
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2005-12-19 18:58
引用: |
|
ららさんの書き込み (2005-12-19 18:46) より:
自動式ウォッチウィンドウが表示されている状態なので
オブジェクトへの参照が残ってしまっているという認識でエクセルが
終了できないでいるということなのでしょうか?
|
「参照カウントが増えますのでプロセスに居座る」ということです。
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|