タイトル | : Re^6: VB2008で、単一のExcel.Shapesオブジェクトの取得方法 |
記事No | : 9363 |
投稿日 | : 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 で呼び出しています といった知識をもっと増やさなくてはいけませんね。。。
このような意味の分からない現象に沢山のアドバイスをどうもありがとうございます。 あの魔界の仮面弁士様からこんなにご意見をいただけると思っておりませんでした。 どうもありがとうございます!!
|