
MSDN フォーラムの質問に対応していて気付いた。
Word で For Each shp In ActiveDocuments.Shapes を行うと、期待どおりの動作をしない。
Excel では問題なし。
正確には For Each ループ内でのシェイプの削除。
以下ではコード付きで不可思議現象をご紹介。
本題に入る前に質問を要約しておこう。
Word で 500 個のテキストボックスを追加するコードを書いた。
Word 2007 で実行すると1秒で終わるのに、2010 では数分かかる。
なんで?
次のコードが書かれていた。
------------------------------
For i = 1 To 500
ActiveDocument.Shapes.AddTextbox msoTextOrientationHorizontal, 5, 5, 100, 72
Next
------------------------------
さて、本題はバージョンの違いによる所要時間の違いではない。
また、テキストボックスを追加する処理でもない。
不可思議現象が発生するのは、テキストボックスを削除する処理だ。
何度かテストをするために、テキストボックスを削除する処理を作った。
削除しないと、テストするたびに 500, 1000, 1500 ... とどんどん増えてしまう。
テキストボックスを削除するコードは次のとおり・・・
------------------------------
Dim shp As Shape
For Each shp In ActiveDocument.Shapes
If (shp.Type = msoTextBox) Then
shp.Delete
End If
Next
------------------------------
# 実際にはシェイプの数を数えたり所要時間を測ったりするコードがあるが
記事の趣旨に沿った部分のみとした。
で、何が不可思議なのか・・・
500 個のテキストボックスがある。
上の処理を実行すると、500 個が 250 個になる。
もう一度実行すると、250 個が 125 個になる。
つまり、For Each で全テキストボックスを一気に削除したいのだが
1回実行するごとに削除されるのは半分だけ。
全体が半分になり、それがさらに半分になり・・・ガマの油売りの逆である。
なので、Word 2016 では 500 個のテキストボックスを削除するのに
9回も繰り返して実行しなければならない。
オカシイなと思って、Excel で同じ処理を作ってみた。
テキストボックスを追加するコード・・・
------------------------------
dim i as Integer
For i = 1 To 500
ActiveSheet.Shapes.AddTextbox msoTextOrientationHorizontal, 5, 5, 100, 72
Next
------------------------------
削除するコード・・・
------------------------------
Dim shp As Shape
For Each shp In ActiveSheet.Shapes
If (shp.Type = msoTextBox) Then
shp.Delete
End If
Next
------------------------------
Word が Excel になったので、ActiveDocument が ActiveSheet になっている。
違いはそれだけ。
で、Excel での実行結果は?
期待どおり、1回実行するだけで 500 個のテキストボックスが全部削除できる。
なぜ Word では一気に削除できないのだろう?
オヤヂには謎である。
---------------------------------------------------------
ブログ記事についてのお問い合わせは「質疑応答 掲示板」で・・・
# ご質問にはできる限りお答えしています。
ただし、お名前(本名)を書いていただいた場合に限らせていただきます。

ここをクリックして、北窓舎のサイトにもお立ち寄りください・・・
Word で For Each shp In ActiveDocuments.Shapes を行うと、期待どおりの動作をしない。
Excel では問題なし。
正確には For Each ループ内でのシェイプの削除。
以下ではコード付きで不可思議現象をご紹介。
本題に入る前に質問を要約しておこう。
Word で 500 個のテキストボックスを追加するコードを書いた。
Word 2007 で実行すると1秒で終わるのに、2010 では数分かかる。
なんで?
次のコードが書かれていた。
------------------------------
For i = 1 To 500
ActiveDocument.Shapes.AddTextbox msoTextOrientationHorizontal, 5, 5, 100, 72
Next
------------------------------
さて、本題はバージョンの違いによる所要時間の違いではない。
また、テキストボックスを追加する処理でもない。
不可思議現象が発生するのは、テキストボックスを削除する処理だ。
何度かテストをするために、テキストボックスを削除する処理を作った。
削除しないと、テストするたびに 500, 1000, 1500 ... とどんどん増えてしまう。
テキストボックスを削除するコードは次のとおり・・・
------------------------------
Dim shp As Shape
For Each shp In ActiveDocument.Shapes
If (shp.Type = msoTextBox) Then
shp.Delete
End If
Next
------------------------------
# 実際にはシェイプの数を数えたり所要時間を測ったりするコードがあるが
記事の趣旨に沿った部分のみとした。
で、何が不可思議なのか・・・
500 個のテキストボックスがある。
上の処理を実行すると、500 個が 250 個になる。
もう一度実行すると、250 個が 125 個になる。
つまり、For Each で全テキストボックスを一気に削除したいのだが
1回実行するごとに削除されるのは半分だけ。
全体が半分になり、それがさらに半分になり・・・ガマの油売りの逆である。
なので、Word 2016 では 500 個のテキストボックスを削除するのに
9回も繰り返して実行しなければならない。
オカシイなと思って、Excel で同じ処理を作ってみた。
テキストボックスを追加するコード・・・
------------------------------
dim i as Integer
For i = 1 To 500
ActiveSheet.Shapes.AddTextbox msoTextOrientationHorizontal, 5, 5, 100, 72
Next
------------------------------
削除するコード・・・
------------------------------
Dim shp As Shape
For Each shp In ActiveSheet.Shapes
If (shp.Type = msoTextBox) Then
shp.Delete
End If
Next
------------------------------
Word が Excel になったので、ActiveDocument が ActiveSheet になっている。
違いはそれだけ。
で、Excel での実行結果は?
期待どおり、1回実行するだけで 500 個のテキストボックスが全部削除できる。
なぜ Word では一気に削除できないのだろう?
オヤヂには謎である。
---------------------------------------------------------
ブログ記事についてのお問い合わせは「質疑応答 掲示板」で・・・
# ご質問にはできる限りお答えしています。
ただし、お名前(本名)を書いていただいた場合に限らせていただきます。

ここをクリックして、北窓舎のサイトにもお立ち寄りください・・・