tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルExcelのプロセスが正常に終了しない
記事No4349
投稿日: 2006/09/28(Thu) 22:15
投稿者oka
初めて投稿させていただきます。

また、プロセスの正常終了についてですが、「Excelのプロセスが正常に終了しない理由」等を
参考させていただいたのですが、プロセスが残ってしまいます。

プロセスが残る原因となる部分については把握できたのですが、
その部分について「Marshal.ReleaseComObject() 」を実行して(いるつもり)
なのですが、どうしてもプロセスが残ってしまいます。

申し訳ありませんが、ご教授いただけないでしょうか。

(Marshal.ReleaseComObject()の実行の仕方についてはこのサイトで紹介されている物を
 使用させていただいております。)
(原因となる部分については↓ソースの"%"で囲っている部分です。)

環境は
OS XP
VB.net
です。

宜しくお願い致します。

#Region "*********"
    Public Sub ******()
        Dim xlFilePath As String = "C:\*******\*****.xls"

        '*********************  起動時の処理  ************************
        'Dim myWebPage As New System.Web.UI.Page
        'Dim xlApp As New Object
        Dim xlApp As New Excel.Application
        Dim xlBooks As Excel.Workbooks = xlApp.Workbooks
        '既存のファイルを開く
        Dim xlBook As Excel.Workbook = xlBooks.Open(xlFilePath)
        Dim xlSheets As Excel.Sheets = xlBook.Worksheets
        Dim xlSheet As Excel.Worksheet = xlSheets.Item("***")
        Dim i As Integer
        Dim intxlShapseCount As Integer = xlSheet.Shapes.Count

        'シート上に作成されるスタンプのグループ名の初期化
        Call SetStampGroupName()

        'シートの初期化
        Call ExcelSheetInitialize(xlSheet)

        Dim intSheetShapeCount As Integer
        'Dim i As Integer
        Dim j As Integer
        Dim k As Integer = 0
        Dim strStampName() As String

        'エクセルシート内から対象のシェイプを取得する。
        '*******************************************************
        intSheetShapeCount = xlSheet.Shapes.Count
        For i = 1 To intSheetShapeCount
            For j = 1 To xlSheet.Shapes.Item(i).GroupItems.Count
              
              '↓このif文のところが原因と思われます。
              '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
              If xlSheet.Shapes.Item(i).GroupItems.Item(j).Name = "テキスト Name1" Then
              '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       'また、MRComObject(xlSheet.Shapes.Item(i).GroupItems.Item("テキスト Name1")) という文をこの場所に追加しても、プロセスが残ります。

                    GoTo NSyori
                End If
            Next
        Next
        '********************************************************
NSyori:

      
            xlSheet.Shapes.Item(i).Select()
            'コピー&(ペースト)
            xlApp.Selection.Copy()
            xlSheet.Paste()
            xlSheet.Paste()
            xlSheet.Paste()



        '==================  終了処理  =====================


        'ShapesとShapesを構成しているグループの解放
        intxlShapseCount = xlSheet.Shapes.Count
        For i = 1 To intxlShapseCount
            MRComObject(xlSheet.Shapes.Item(i))
            Dim intShapesGroupsCount As Integer = xlSheet.Shapes.Item(i).GroupItems.Count
            For j = 1 To intShapesGroupsCount
                MRComObject(xlSheet.Shapes.Item(i).GroupItems.Item(j))
            Next
        Next


        MRComObject(xlSheet.Shapes)     'xlShapesの開放
        MRComObject(xlSheet)            'xlSheet の解放
        MRComObject(xlSheets)           'xlSheets の解放

        xlBook.Close(False)              'xlBook を閉じる

        MRComObject(xlBook)             'xlBook の解放
        MRComObject(xlBooks)            'xlBooks の解放
        xlApp.Quit()                    'Excelを閉じる

        MRComObject(xlApp)              'xlApp を解放
        '-------------------------------------------------------------------------
        '強制的にガベージ コレクションの実行。
        'GC.Collect()
        System.Threading.Thread.Sleep(1000)
        Dim localByName As Process() = Process.GetProcessesByName("Excel")
        If localByName.Length > 0 Then
            MessageBox.Show("まだ Excel.EXE が " & localByName.Length & " 個 起動しています。")
        End If
        '--------------------------------------------------------------------------

    End Sub

#End Region


#Region "COM オブジェクトへの参照を開放"
    'COM オブジェクトへの参照を解放するプロシージャ(既存のファイルを開く場合も共用)
    Private Sub MRComObject(ByRef objCom As Object)
        'COM オブジェクトの使用後、明示的に COM オブジェクトへの参照を解放する
        Try
            '提供されたランタイム呼び出し可能ラッパーの参照カウントをデクリメントします
            If Not objCom Is Nothing AndAlso System.Runtime.InteropServices. _
                                                      Marshal.IsComObject(objCom) Then
                Dim I As Integer
                Do
                    I = System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom)
                Loop Until I <= 0
            End If
        Catch
        Finally
            '参照を解除する
            objCom = Nothing
        End Try
    End Sub
#End Region

[ツリー表示へ]
タイトルRe: Excelのプロセスが正常に終了しない
記事No4350
投稿日: 2006/09/28(Thu) 22:36
投稿者花ちゃん
> また、プロセスの正常終了についてですが、「Excelのプロセスが正常に終了しない理由」等を
> 参考させていただいたのですが、プロセスが残ってしまいます。

だったら、
1.基本的に、下記のように、[.]が2つ連続で使用されたら解放できません。

 Cells プロパティ・Rows プロパティ・Columns プロパティ・Borders プロパティ 等のように
 最後に s が付く プロパティ 等

と書いてありませんでしたか?

xlSheet.Shapes.Item(i).GroupItems.Item(j).Name

個々に変数に受けて下さい。

'また、MRComObject(xlSheet.Shapes.Item(i).GroupItems.Item("テキスト Name1")) という文をこの場所に追加しても、プロセスが残ります。

これは、ちょっとむちゃです。 

今一度、ここのサンプルや「Excelのプロセスが正常に終了しない理由」を良く見て下さい
自分で理解しないと、次もキット躓くでしょう、せめて「Excelのプロセスが正常に
終了しない理由」に書いてある事位は、自分で色々、試して見て下さい。
(私のコード以外の部分は、VB6.0 のコードをそのまま貼り付けただけでは。)

[ツリー表示へ]
タイトルRe^2: Excelのプロセスが正常に終了しない
記事No4351
投稿日: 2006/09/28(Thu) 23:09
投稿者oka
申し訳ありません。
以後、もっと良く読んでから質問させていただきます。

また、再度「Excelのプロセスが正常に終了しない理由」等を参考させていただき、理解を深めていきたいと思いますので、宜しくお願い致します。


ご指摘いただいた部分を修正した後、追って結果の方連絡させていただきます。

[ツリー表示へ]
タイトルRe^3: Excelのプロセスが正常に終了しない
記事No4352
投稿日: 2006/09/29(Fri) 01:19
投稿者oka
結果の方ご報告させていただきます。

最初に書かせていただきました

'エクセルシート内から対象のシェイプを取得する。
'*******************************************************
intSheetShapeCount = xlSheet.Shapes.Count
For i = 1 To intSheetShapeCount
  For j = 1 To xlSheet.Shapes.Item(i).GroupItems.Count
   '↓このif文のところが原因と思われます。
   '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   If xlSheet.Shapes.Item(i).GroupItems.Item(j).Name = "テキスト Name1" Then
   '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
NSyori
    End If
    Next
Next
'********************************************************

の部分ですが、ご指摘いただいたように↓のように修正し、

'**********************
        intSheetShapeCount = xlShapes.Count
        For i = 1 To intSheetShapeCount
            xlShape = xlShapes.Item(i)
            xlGroupItems = xlShape.GroupItems
            For j = 1 To xlGroupItems.Count
                xlGroupItem = xlGroupItems.Item(j)
                If xlGroupItem.Name = "テキスト Name1" Then
                    GoTo NSyori
                End If
            Next
        Next
'**********************

それらに対して「Marshal.ReleaseComObject() 」を実行する事によって、Excelのプロセスを
終了させる事ができました。

今回、私の参考不足のせいで、煩わしい思いをさせてしまい申し訳ありませんでした。
この先質問させていただく事もあるかと思いますが、今後気をつけますので宜しくお願い致します。

[ツリー表示へ]