ExcelマクロVBA技術解説
ShapesとDrawingObjectsの相違点と使い方

ExcelマクロVBAの問題点と解決策、エクセルVBAの技術的解説
最終更新日:2019-09-24

ShapesとDrawingObjectsの相違点と使い方


VBA マクロ shapes DrawingObjects


マクロVBAで図(オートシェイプ等)を扱う時にいろいろ調べていくと、
図(オブジェクト)のコレクションが二つあることに気づきます。
Shapes コレクション
DrawingObjects コレクション
WEBのサンプルや書籍では多くはShapesが使われているはずですが、時々DrawingObjectsを見かけることもあります。
VBAではShapesとDrawingObjectsのどちらを使っても、目的の図(オートシェイプ等)を扱う事が出来ます。
本サイト内でも、基本的にはShapesですが、DrawingObjectsを紹介しているページもあります。
オートシェイプを他ブックの同じ位置に貼り付ける(Shapes,DrawingObjects)

コメントでリクエストを頂きました。「1つのシートにバラバラにあるオートシェープを一度に選択して、コピーし、ほかのブックのあるシートの同じ位置にペーストしたい」というもの。これには色々な問題が含まれています。

DrawingObjectsは古いVBAにあったもので、互換性のために残されているものになります。
従って現在では、非表示メンバになっています。

本来はShapesだけを使えば良いのですが、DrawingObjectsを使ったほうが便利な場合も存在します。
この二つのコレクションの相違点を確認し、どのような場合にDrawingObjectsを使うと便利かを考えてみます。

Shapes コレクション

Shapesは、Shapeオブジェクトのコレクションです。
Shapeオブジェクトの詳細については、
第97回.図形オートシェイプ(Shape)
マクロVBAで、オートシェイプ(図形)を扱う場合の解説です。オートシェイプ(図形)はShapeオブジェクトであり、ShapeオブジェクトのコレクションがShapesコレクションになります。Shapeオブジェクトは、多くのオブジェクトをメンバーに持った複雑なオブジェクトとなっています。
こちらを参照してください。

Shapesコレクションのメンバー
詳細は上記ページを見てもらうとして、
DrawingObjectsとの比較のためにメンバーの一覧を見てみます。

プロパティ Application
Count
Creator
Parent
Range
メソッド AddCallout
AddChart2
AddConnector
AddCurve
AddFormControl
AddLabel
AddLine
AddOLEObject
AddPicture
AddPicture2
AddPolyline
AddShape
AddSmartArt
AddTextbox
AddTextEffect
Add3DModel
BuildFreeform
Item
SelectAll

そんなに数は多くありません。
VBAのコレクションの多くは、プロパティ・メソッドは少なめになっています。

DrawingObjects コレクション

DrawingObjectsは、DrawingObjectオブジェクトのコレクションです・・・
と言いたいところですが、この表現はあまり正確とは言えません。
DrawingObjectというデータ型は存在していません。

DrawingObjects(インデックスor名前)で取得されるオブジェクトは、Object型になります。
DrawingObjectという特定のデータ型は存在していないので、Object型のコレクションとなっています。

DrawingObjectsは非表示メンバになっていますので、
オブジェクトブラウザで確認する場合は、右クリックから「非表示メンバを表示」で表示させてください。
VBA マクロ Shapes DrawingObjects


DrawingObjects コレクションのメンバー


プロパティ _Default
Accelerator
AddIndent
Application
ArrowHeadLength
ArrowHeadStyle
ArrowHeadWidth
AutoSize
Border
CancelButton
Caption
Characters
Count
Creator
DefaultButton
DismissButton
Display3DShading
DisplayVerticalScrollBar
DropDownLines
Enabled
Font
Height
HelpButton
HorizontalAlignment
InputType
Interior
LargeChange
Left
LinkedCell
ListFillRange
ListIndex
Locked
LockedText
Max
Min
MultiLine
MultiSelect
OnAction
Orientation
Parent
PhoneticAccelerator
Placement
PrintObject
ReadingOrder
RoundedCorners
Shadow
ShapeRange
SmallChange
Text
Top
Value
VerticalAlignment
Visible
Width
ZOrder
メソッド _Dummy12
_Dummy15
_Dummy22
_Dummy28
_Dummy3
_Dummy47
_Dummy54
_Dummy56
AddItem
BringToFront
CheckSpelling
Copy
CopyPicture
Cut
Delete
Duplicate
GetEnumerator
Group
Item
LinkCombo
List
RemoveAllItems
RemoveItem
Reshape
Select
Selected
SendToBack
Ungroup
Vertices

Shapesに比べて非常に多くのメンバーがあることがお分かりいただけると思います。

DrawingObjectsは、Microsoft/Docsの通常のページには載っていません。
DrawingObjectsメンバ
このページは、「以前のバージョンのドキュメント」として残されているページになります。

ShapesとDrawingObjectsの相違点

上で見たように、ShapesとDrawingObjectsのプロパティ・メソッドは大きく違っています。
DrawingObjectsは古いVBAで、互換性のために残されている非表示メンバです。
互換性としで残されている非表示オブジェクトやコレクションは、
他の新しいオブジェクトやコレクションに引き継がれるのが通常ではありますが、
必ずしも、全てが引き継がれているとは限りません。
中には引き継がれずに、他のオブジェクトやコレクションメンでは扱えなくなっているものも存在します。
少なくとも、DrawingObjectsの代替えとしてShapesが存在していると単純に考えることはできません。

Countプロパティの違い
私が最も大きな違いと考えるのは、コレクションに含まれるオブジェクトに違いがあるという事です。
ActiveSheet.DrawingObjects.Count
ActiveSheet.Shapes.Count
これら二つは同じなのでしょうか。(同じとして紹介しているページもあると思います。)
シートに「入力規則」の「リスト」を設定して、
イミディエイトウインドウで、
?ActiveSheet.DrawingObjects.Count
?ActiveSheet.Shapes.Count
上記二つの値を確認してください、違ったはずです。
Shapes.Countの方が1多くなったはずです。
Shapesには、入力規則のドロップダウンが含まれてしまいます。
これにより、以下のようなトラブルが発生します。
入力規則のドロップダウンが消えてしまうマクロ(Shapes内のDrop Down)
シートのShapeを全削除すると、入力規則のリストのドロップダウンが消えてしまいます。入力規則のリストのドロップダウンの設定については、エクセル入門.入力規則.リスト こちらを参照して下さい。入力規則のリストのドロップダウンが消えてしまう具体的なマクロは、以下のようなVBAコードになります。

Shapeオブジェクトに入っているプロパティ・メソッド
DrawingObjectsにあった多くのプロパティ・メソッドの中には、
Shapesコレクションではなく、中のShapeオブジェクトに入っているものがあります。
ほんの一部、良く使いそうなものを例に説明すると、
例えばプロパティでは、
PrintObject
これは、Shapeオブジェクト.ControlFormat.PrintObjectとして存在します。
メソッドでは、
Copy
Cut
Delete
Duplicate
これらは、Shapeオブジェクトに存在します。

しかし、ここで考えたいのは、
コレクションにあるプロパティ・メソッドは、コレクション内のすべてのオブジェクトに対して一括で作用します。
オブジェクトのプロパティ・メソッドは、そのオブジェクトのみにしか作用しません。
つまりDrawingObjectsでは、全ての図(オブジェクト)に対して一括で操作できるプロパティ・メソッドが多数存在したが、
Shapesでは、個別のオブジェクトに対して操作しなければならないという事です。

コレクションの要素を指定して取得されるオブジェクトの違い
Shapesは、Shapeオブジェクトのコレクションです。
つまり、Shapes(インデックス)はShapeオブジェクトです。
対して。
DrawingObjectというデータ型は存在していません。
DrawingObjects(インデックス)は、汎用のobject型になります。

イミディエイトで以下を確認してみましょう。
?typename(ActiveSheet.DrawingObjects(1))
Rectangle ← この結果はあくまで例として
図(オブジェクト)によって結果はまちまちになります。
TextBox、Picture、・・・
対して、
?typename(ActiveSheet.shapes(1))
Shape
これはShapeオブジェクトなので納得できると思いますが、図の種類がこれでは判別できません。
Shapeの場合は、Typeプロパティで判別します。
?ActiveSheet.Shapes(1).Type
1
この結果は、MsoShapeType列挙の数値になります。

DrawingObjectsの便利な使い道

前述したように、
DrawingObjectsでは、全ての図(オブジェクト)に対して一括で操作できるプロパティ・メソッドが多数存在するので、
そのような場合は、DrawingObjectsが便利に使えるという事になります。

シートの全ての図の「オブジェクトを印刷する」を設定する
アクティブシートの全ての図の「オブジェクトを印刷する」のチェックを外します。

ActiveSheet.DrawingObjects.PrintObject = False

※DrawingObjects(インデックス)にもPrintObjectは存在します。

Shapesを使った場合は、

Dim sp As Shape
For Each sp In ActiveSheet.Shapes
  sp.ControlFormat.PrintObject = False
Next

このように一つずつ設定する必要があります。

シートの全ての図を削除する
アクティブシートの全ての図を削除します。



ActiveSheet.DrawingObjects.Delete

※DrawingObjectsには入力規則のドロップダウンは含まれていません。

Shapesを使った場合は、

Dim sp As Shape
For Each sp In ActiveSheet.Shapes
If Not sp.Name Like "Drop Down*" Then
  sp.Delete
End If
Next

このように、入力規則のドロップダウンかを判定して削除しないようにする必要があります。

シートの全ての図を別シートへコピーする
Worksheets(1)の全ての図をコピーし、
Worksheets(2)のA1セルに貼り付けします。

Worksheets(1).DrawingObjects.Copy
With Worksheets(2)
  .Select
  .Range("A1").Select
  .Paste
End With

Shapesを使った場合
オートシェイプを他ブックの同じ位置に貼り付ける
コメントでリクエストを頂きました。「1つのシートにバラバラにあるオートシェープを一度に選択して、コピーし、ほかのブックのあるシートの同じ位置にペーストしたい」というもの。これには色々な問題が含まれています。
.SelectAll
Selection.Copy
このようなVBA記述をするか、もしくはShape一つずつCopyすることになります。

シートの全ての図を複製して別シートへ移動
Worksheets(1)の全ての図を複製&切り取りし、
Worksheets(2)のA1セルに貼り付けします。

Dim objs As Object
Set objs = Worksheets(1).DrawingObjects.Duplicate
objs.Cut
With Worksheets(2)
  .Select
  .Range("A1").Select
  .Paste
End With

Shapesを使った場合は、
Shapeオブジェクト一つずつに対してDuplicateを実行しなければならず、
この場合なら、Duplicateを使うメリットがないと思います。


図(オブジェクト)のコピーを行うと、その図(オブジェクト)が選択状態になります。
図の選択状態を解除するには、以下のどちらかのVBAで行ってください。

With シート
  .Protect
  .Unprotect
End With
With シート
  .Select
  .Range("A1").Select
End With

一般的な方法として、ActiveCell.Activateを使う方法も考えられますが、
DrawingObjectsで複数の図をコピーした時には、ActiveCellが取得できない状態になってしまう為、
ActiveCellでエラーとなってしまいます。

最後に

ShapesとDrawingObjectsの違いを見てきましたが、
そもそも図オブジェクトは、多くのオブジェクトをメンバーに持った複雑なオブジェクトとなっていて、全てを把握するのはとても困難なオブジェクトになります。
必要に応じて、都度プロパティ・メソッドを調べられるようにしておけば良いと思います。

最初に書いた通り、DrawingObjectsは古いVBAですので通常は使うべきではないでしょう。
このような古いオブジェクト・コレクションは、今後のバージョンアップに際し動作保証されない可能性もありますし、
なにより、信頼すべきドキュメントが見つからない為にVBA記述に苦労することが多々あります。
従って、基本的にはShapesで書くようにしたほうが良いでしょう。
とはいえ、
一括でシートの全ての図に対して操作したい場合は、便利な方法として覚えておくと役に立つこともあると思います。

図形オートシェイプ(Shape)に関連する記事

以下も参考にして下さい。
第97回.図形オートシェイプ(Shape)
マクロVBAで、オートシェイプ(図形)を扱う場合の解説です。オートシェイプ(図形)はShapeオブジェクトであり、ShapeオブジェクトのコレクションがShapesコレクションになります。Shapeオブジェクトは、多くのオブジェクトをメンバーに持った複雑なオブジェクトとなっています。
オートシェイプを他ブックの同じ位置に貼り付ける
コメントでリクエストを頂きました。「1つのシートにバラバラにあるオートシェープを一度に選択して、コピーし、ほかのブックのあるシートの同じ位置にペーストしたい」というもの。これには色々な問題が含まれています。
図をセル内に強制的に収める(Shape)
図(画像等)をエクセルに貼り付けた後、セルの移動と一緒に動かない場合があります。もちろん、図の書式のプロパティでは、「セルに合わせて移動」にしてある場合の話です。図がセルを大きくはみ出しているいる場合(隣のセルよりさらにはみだしている場合)は、セルのコピー、移動にくっていてきません。
図を確認しながら消していく(Shape)
行削除や、列削除等により、図が見えなくなってしまう事があります。しかも、セルのコピーで沢山出来てしまい、困った事ありませんか。「ジャンプ」→「セル選択」で、オブジェクトで一括選択して削除する事は出来ます。
写真の取込方法について(Pictures.Insert,Shapes.AddPicture)
写真を取り込んでアルバムのようにしたり各種の資料を作ったりと写真をエクセルに取り込む機会は多いようです。しかし最近は写真のサイズも大きくなり手動で取り込んだままではスクロールもままならない状態となってしまいます。そこで写真ファイルを指定しA列に上から順番に貼り付けさらにセル内に収まるように縮小するマクロになります。
入力規則のドロップダウンが消えてしまうマクロ(Shapes内のDrop Down)
シートのShapeを全削除すると、入力規則のリストのドロップダウンが消えてしまいます。入力規則のリストのドロップダウンの設定については、エクセル入門.入力規則.リスト こちらを参照して下さい。入力規則のリストのドロップダウンが消えてしまう具体的なマクロは、以下のようなVBAコードになります。
オブジェクトの探索方法
VBAを書き進めて行くと、どうしてもオブジェクトの扱い時に分からないことがでてきます、何が分からないかというと、オブジェクトの中の目的の要素をどのように指定したら良いのかということです、オブジェクトの中を探索して、目的の要素にたどり着く方法を説明します。ローカルウィンドウを主体に説明します。



同じテーマ「マクロVBA技術解説」の記事

Excelアドインの作成と登録について
VBAでのタイマー処理(SetTimer,OnTime)
マクロでShift_JIS文字コードか判定する
Byte配列と文字コード関数について
VBA+SeleniumBasicで検索順位チェッカー(改)
Applicationを省略できるApplicationのメソッド・プロパティ一覧
PowerQueryの強力な機能をVBAから利用する方法
ShapesとDrawingObjectsの相違点と使い方
新規挿入可能なシート名の判定
VBAにおける配列やコレクションの起点について
VBAのマルチステートメント(複数のステートメントを同じ行に)


新着記事NEW ・・・新着記事一覧を見る

VBAクラスのAttributeについて(既定メンバーとFor…Each)|VBA技術解説(10月19日)
VBAの用語について:ステートメントとは|VBA技術解説(10月16日)
VBAのマルチステートメント(複数のステートメントを同じ行に)|VBA技術解説(10月14日)
VBAコードの全プロシージャー・プロパィ一覧を取得|VBAサンプル集(10月12日)
VBAでエラー行位置(行番号)を取得できるErl関数|VBA技術解説(10月11日)
手動計算時の注意点と再計算方法|ExcelマクロVBA技術解説(10月9日)
引数の数を可変にできるパラメーター配列(ParamArray)|VBA入門(10月7日)
VBEの使い方:デバッグ|ExcelマクロVBA入門(10月6日)
VBAにおける配列やコレクションの起点について|VBA技術解説(10月5日)
VBEの使い方:オブジェクト ブラウザー|VBA入門(10月5日)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.RangeとCellsの使い方|ExcelマクロVBA入門
4.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
5.変数とデータ型(Dim)|ExcelマクロVBA入門
6.繰り返し処理(For Next)|ExcelマクロVBA入門
7.マクロって何?VBAって何?|ExcelマクロVBA入門
8.ひらがな⇔カタカナの変換|エクセル基本操作
9.空白セルを正しく判定する方法(IsEmpty,IsError,HasFormula)|VBA技術解説
10.セルに文字を入れるとは(Range,Value)|VBA入門



  • >
  • >
  • >
  • ShapesとDrawingObjectsの相違点と使い方

  • このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


    記述には細心の注意をしたつもりですが、
    間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
    なお、掲載のVBAコードは自己責任で使ってください。万一データ破損等の損害が発生しても責任は負いません。




    このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
    本文下部へ