プロが教えるわが家の防犯対策術!

PowerPoint VBAでFor Eachを使ったとき、おかしな挙動をします。

例えば、スライド上に適当に図形を3つ挿入します。
そして、それらすべての図形を消去する以下のマクロを書きました。

Sub test()

Dim shp As Shape

For Each shp In ActiveWindow.Selection.SlideRange.Shapes
shp.Delete
Next shp

End Sub

このマクロを実行すると、
本来は1回の操作で全図形が削除されるはずですが、
なぜか図形が1つだけ残ってしまい、2回目のマクロ実行でようやく全図形が消去できます。

症状としては、(Wordの例ですが)以下の記事とまったく同じです。
https://blog.goo.ne.jp/ashm314/e/ce8e78058c256f9 …

なお、消去ではなく、全図形を選択するマクロ(以下)は正常に動作します。

Sub test2()

Dim shp As Shape

For Each shp In ActiveWindow.Selection.SlideRange.Shapes
shp.Select msoFalse
Next shp

End Sub

原因は一体何なのでしょうか?
また、回避策はありますか?

よろしくお願いいたします。

A 回答 (4件)

Excelの場合は、For Each ~ Next でもSelectionの処理で順番に


Deleteできますが、WordやPowerPointは最初のループしたときに
Deleteされた時点で順番が狂います。
https://www.relief.jp/docs/powerpoint-vba-select …

回避策として、For ~ Nextで逆順に処理することで対応します。
(逆順でないと、エラーになるので間違えないように)
https://www.relief.jp/docs/powerpoint-vba-delete …

Sub アクティブスライドの図形をすべて削除する()
 Dim i As Long
 With ActiveWindow.Selection.SlideRange
  For i = .Shapes.Count To 1 Step -1
With .Shapes(i)
'    If _
'   .Type = msoAutoShape Or _
'   .Type = msoLine Or _
'   .Type = msoGroup Then
    .Delete
'   End If
  End With
  Next i
 End With
End Sub


Wordの場合

Sub アクティブドキュメントの図形をすべて削除する()
 Dim i As Long

 With ActiveDocument
  For i = 1 To .Shapes.Count
  With .Shapes(i)
'   If _
'   .Type = msoAutoShape Or _
'   .Type = msoLine Or _
'   .Type = msoGroup Then
    .Delete
'   End If
  End With
  Next i
 End With
End Sub
    • good
    • 2
この回答へのお礼

ExcelとPowerPointでは、同じコードでも実行結果が異なるのですね。
疑問に思っていたことが解決でき、良かったです。
回避策も示していただき、どうもありがとうございました。

お礼日時:2019/06/07 21:37

No.3の回答者です。


Wordのマクロの一部に書き間違いがありました。
間違っている部分
  For i = 1 To .Shapes.Count
正しくは
For i = .Shapes.Count To 1 Step -1
です。
Wordでの処理を再確認しているときに、書き換えてしまったままで
コピーして回答欄に記載してしまいました。
    • good
    • 0

こんにちは



直接の回答ではありませんが、対応法としての別案です。
不定数のオブジェクト等を消去する際などに、よく用いられる方法。

以下をループする。(試してはいませんので、未確認です)
 『shapeが存在する間、最初のshapeを削除する』
    • good
    • 0
この回答へのお礼

ありがとうございました。

お礼日時:2019/06/07 21:37

For Eachの中で、コレクション自体を変化させて大丈夫でしたっけ?


おそらく、コレクションが変化してしまったことで、「次」や「終了判定」が誤動作しているのだと思われます。

VB.Netだとエラーになる操作です。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!