tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re^6: VB2008で、単一のExcel.Shapesオブジェクトの取得方法
投稿日: 2009/09/08(Tue) 12:40
投稿者camputer
 魔界の仮面弁士 様

 どうもありがとうございます!!

 PCのスペックは関係なさそうでございました。
が、一個だけ分かりました!下のようにFor〜NextでObjectを色々扱っているのですが、
(簡単のため、宣言式や解放コードを省いて書かせていただきます)
    FName = Dir(Mypath & "*.xls", vbNormal)
        Do While FName <> ""
            Dim iSheetMax As Integer = xlSheets.Count
            For iSheet = 1 To iSheetMax
        xlSheet = xlSheets(iSheet)
                Dim iShapeMax As Integer = myShapes.Count
        For iShape = 1 To iShapeMax
                    myShape = myShapes.Item(iShape)

        Next
                Dim iChartMax As Integer = MyChartObjects.Count
                For iChart = 1 To iChartMax
             MyChartObject = MyChartObjects.Item(iChart)

                Next
       Next
        Next
    Loop

以前解放のテストをした時に上のコードで、
    For iChart = 1 To iChartMax
の部分を
    For Each MyChartObject in MyChartObjects

    Next
としておいても解放にひっかからなかったので、そのままにしておいた事が一因のようです。
 IntegerとStringでひっかかったコードを下のように2種類、再現してみましたが、
For Each MyChartObject in MyChartObjects の状態だと、
  test1-a:解放不可
  test1-b:解放可
  test2-a:解放不可
  test2-b:解放可
となるのが、
For iChart = 1 To iChartMaxだと、
  test1-a:解放可
  test1-b:解放可
  test2-a:解放可
  test2-b:解放可
になりました。

↓テスト内容でございます。普通は解放に影響しないコードだと思われるのですが。。
test1-a
                myShapes = xlSheet.Shapes
                myShapes.SelectAll()
                Dim iShapeMax As Integer = myShapes.Count 
                For i = 1 To iShapeMax
                    myShape = myShapes.Item(i)
                    
                    MRComObject(myShape)
                Next

                MRComObject(myShapes) : myShapes = Nothing

test1-b
                myShapes = xlSheet.Shapes
                myShapes.SelectAll()
                Dim iShapeMax As Object = myShapes.Count '←As Objectにして解放しました。
                For i = 1 To iShapeMax
                    myShape = myShapes.Item(i)

                    MRComObject(myShape)
                Next
                MRComObject(iShapeMax)
                MRComObject(myShapes) : myShapes = Nothing

test2-a
                If Len(tbox.AlternativeText) > 0 Then 〜

test2-b
                Dim tboxAlternativeText As String = tbox.AlternativeText
                If Len(tboxAlternativeText) > 0 Then 〜




>アプリを終了させていない状態で確認してみてください。
 終了直前にメッセージボックス起動状態で確認しております。どうもありがとうございます。
下のようなコードになります。

    Private Sub Excel業務効率化(ByRef Integer1 As Integer, ByVal String1 As String, ByRef Integer2 As Integer)
        Dim myApp As Excel.Application
        myApp = CreateObject("Excel.Application")
        Dim myBook As Excel.Workbook
        Dim myBooks As Excel.Workbooks = myApp.Workbooks
        Dim xlSheet As Excel.Worksheet
        Dim xlSheets As Excel.Sheets
      
        Dim tbox As Excel.Shape
        Dim myShape As Excel.Shape
        Dim myShapes As Excel.Shapes
        Dim myShapeUng As Excel.ShapeRange
        Dim FName As String


        FName = Dir(Mypath & "*.xls", vbNormal)
        Do While FName <> ""

     '<中略>(本案件はすべて、ここの解放中に起こっている現象でございます。。)

        Loop
        Me.Activate()

        MRComObject(myBooks) : myBooks = Nothing
        myApp.Quit() : MRComObject(myApp) : myApp = Nothing


    '↓VB花ちゃんのコード(http://hanatyan.sakura.ne.jp/dotnet/Excel01.htm)でも
       '確認させていただきました。
      
        '★☆★☆★☆★☆★☆ Debug 中は下記を実行して確認しながら進めて下さい
        Dim st As Integer = System.Environment.TickCount
        Do While System.Environment.TickCount - st < 5000
            Application.DoEvents()
            System.Threading.Thread.Sleep(500)
            If Process.GetProcessesByName("Excel").Length = 0 Then
                MessageBox.Show("Excel.EXE は解放されました。")
                Exit Do
            End If
        Loop
        If Process.GetProcessesByName("Excel").Length >= 1 Then
            MessageBox.Show("まだ Excel.EXE が起動しています。")
            '一度メッセージボックスを表示すると解放されるようなので再度確認
            If Process.GetProcessesByName("Excel").Length = 0 Then
                MessageBox.Show("Excel.EXE は解放されました。")
            End If
        End If

        MsgBox("完了", , "完了") '←花ちゃんのコードを入れさせていただく前は、
               'ここのメッセージを表示したままで確認しておりました。
    End Sub


 リンク先、どうもありがとうございました。まだ閲覧した事が無かったです。
今から勉強させていただきます。

 いまいち納得がいかない現象なのですが、
「For Each O in Os という因子を含んでいるにも関わらず偶然うまく解放できている
コード」に対して、Excelオブジェクトのプロパティから作られているStringやIntegerの
参照か何かがそれを邪魔する(?)ということでしょうか。。。??

 今後コーディングする上で、Com参照しているオブジェクトがいくつか
残っているかどうか確認する手段があればいいのですが。。
それと何より、魔界の仮面弁士様から以前「PowerPointのオブジェクト開放ができません」で
アドバイスいただいたような
>ゆえに私は、For Each ではなく For で呼び出しています
といった知識をもっと増やさなくてはいけませんね。。。

 このような意味の分からない現象に沢山のアドバイスをどうもありがとうございます。
あの魔界の仮面弁士様からこんなにご意見をいただけると思っておりませんでした。
どうもありがとうございます!! 

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。