SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

EXCEL2007とEXCEL2016で画像のサイズ変更のVBA動作に非互換/EXCELの小ネタ

f:id:arakan_no_boku:20190307220715j:plain

EXCELのデフォルト設定が変わって、今まで動いていたVBAが動かなくなる。

よくある話なので驚きはしないですが、今回は、ちょっと慌てました。

意外に、情報がネットにあがってないように思えたので、備忘がてら書いておきます。 

 

現象

EXCEL2007で問題なく動作していたものが、EXCEL2016では動かなくなりました。

EXCEL2007とEXCEL2016の非互換です。

なお、今更、EXCEL2007かよ!というツッコミが聞こえてきそうではありますが、つい最近までプライベートではEXCEL2007しか持ってなかったのです(笑)

今回EXCEL2007とEXCEL2016の非互換で問題になったのは、以下の2か所です。

  • Pictures.Insertで画像ファイルを取り込んだShapeのTypeが「msoPicture」から「msoLinkedPicture」に変わっていた。
  • プロパティのデフォルトが「セルに合わせて移動するが、サイズ変更をしない」になっていた。 

個別にみていきます。

  

ShapeのTypeが「msoPicture」から「msoLinkedPicture」に変わっていた

何故、これが困るかというと、VBAで画像とかを扱う時、TypeでShapeの種類を確認して処理しなければいけないからです。

例えば、シートの画像を削除したいとき

For Each img In Sheets(mainSheetName).Shapes
        img.Delete
Next img

こうやってしまうと、指定シートの画像もフォームオブジェクト(ボタンとか)も全部消えていまいます。

だから、ボタンは消したくない場合とかは

For Each img In Sheets(mainSheetName).Shapes
    If img.Type <> msoFormControl Then
        img.Delete
    End If
Next img

 という風に、Typeで除外するものを指定する必要があります。

上記ならEXCEL2007でもEXCEL2016でも動きます。

でも「Pictures.Insert」で取り込んだ画像イメージだけを消したいと思って、今回は以下のようにしていたところ。

For Each img In Sheets(mainSheetName).Shapes
    If img.Type = msoPicture Then
        img.Delete
    End If
Next img

EXCEL2007では画像が削除されますが、EXCEL2016では削除されませんでした。

デフォルトのTypeが違っているのですから。

まあ、この2種類程度なら、msoPicture または msoLinkedPictureみたいに、ORで複数のTypeを指定する方法で何とかなるでしょうが・・なんだかなあ。

 下位互換で何とかならないんですかねえ。

 

プロパティのデフォルトが変更になっていた影響

VBAでサイズ変更するときは以下のようなコードでやってました。

Sheets(mainSheetName).Pictures.Insert imgFileName
For Each img2 In Sheets(mainSheetName).Shapes
    If img2.Type <> msoFormControl Then
        img2.LockAspectRatio = True
        img2.Width = 150
    End If
Next img2

サイズ変更する対象のTypeを指定する必要があるのは、前記の削除と同じです。

フォームのボタンまでサイズ変更するわけにはいきませんから。

それで「msoFormControl以外」という条件でサイズ変更してます。

削除はうまく言ったから大丈夫だろうと思うと、画像のサイズ変更ではまだ条件が足りませんでした。

この原因がプロパティでした。

EXCEL2007の時と異なり、EXCEL2016ではプロパティがデフォルトで「セルに合わせて移動するが、サイズ変更をしない」になっているからです。

だから、EXCEL2016の場合は「 XXX.Placement = xlMoveAndSize」のように、移動もサイズ変更も可能だよと、プロパティを変更してやらないといけません。

Sheets(mainSheetName).Pictures.Insert imgFileName
For Each img2 In Sheets(mainSheetName).Shapes
    img2.Placement = xlMoveAndSize
    If img2.Type <> msoFormControl Then
        img2.LockAspectRatio = True
        img2.Width = 150
    End If
Next img2

 後者のコードなら、EXCEL2007でも動きますから、ShapeのPlacementプロパティに「xlMoveAndSize」を設定するのは、サイズ変更等をするなら必須と思ったほうがよさそうです。 

これで動くようになりました。

やれやれ・・です。