VBA技術解説
ShapesとDrawingObjectsの相違点と使い方

ExcelマクロVBAの問題点と解決策、VBAの技術的解説
公開日:2019-09-24 最終更新日: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)
・図形オートシェイプ(Shape)関連のオブジェクト群 ・図形オートシェイプ(Shape)の追加 ・図形オートシェイプ(Shape)の削除 ・図形オートシェイプ(Shape)の編集 ・図形オートシェイプ(Shape)の全選択 ・図形オートシェイプ(Shape)の扱い方を工夫する ・オートシェイプ(Shape)を扱う実践例 ・図形オートシェイプ(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)
・図形オートシェイプ(Shape)関連のオブジェクト群 ・図形オートシェイプ(Shape)の追加 ・図形オートシェイプ(Shape)の削除 ・図形オートシェイプ(Shape)の編集 ・図形オートシェイプ(Shape)の全選択 ・図形オートシェイプ(Shape)の扱い方を工夫する ・オートシェイプ(Shape)を扱う実践例 ・図形オートシェイプ(Shape)に関連する記事
オートシェイプを他ブックの同じ位置に貼り付ける
コメントでリクエストを頂きました。「1つのシートにバラバラにあるオートシェープを一度に選択して、コピーし、ほかのブックのあるシートの同じ位置にペーストしたい」というもの。これには色々な問題が含まれています。
図をセル内に強制的に収める(Shape)
図(画像等)をエクセルに貼り付けた後、セルの移動と一緒に動かない場合があります。もちろん、図の書式のプロパティでは、「セルに合わせて移動」にしてある場合の話です。図がセルを大きくはみ出しているいる場合(隣のセルよりさらにはみだしている場合)は、セルのコピー、移動にくっていてきません。
図を確認しながら消していく(Shape)
行削除や、列削除等により、図が見えなくなってしまう事があります。しかも、セルのコピーで沢山出来てしまい、困った事ありませんか。「ジャンプ」→「セル選択」で、オブジェクトで一括選択して削除する事は出来ます。
写真の取込方法について(Pictures.Insert,Shapes.AddPicture)
・Pictures.Insertメソッド ・Shapes.AddPictureメソッド ・Shapesに関連する記事
入力規則のドロップダウンが消えてしまうマクロ(Shapes内のDrop Down)
シートのShapeを全削除すると、入力規則のリストのドロップダウンが消えてしまいます。入力規則のリストのドロップダウンの設定については、エクセル入門.入力規則.リスト こちらを参照して下さい。入力規則のリストのドロップダウンが消えてしまう具体的なマクロは、以下のようなVBAコードになります。
オブジェクトの探索方法
・オブジェクト探索の説明で使う例題 ・自動記録を使ってオートシェイプの概要を知る ・ローカルウィンドウでオートシェイプのテキストを調べる ・オートシェイプの位置移動について ・VBAを完成させる ・オブジェクトブラウザーを使いさらにオブジェクトを調べる ・ウォッチウィンドウについて



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

Byte配列と文字コード関数について

・文字列をByte配列に入れる ・文字コードについて ・文字列をByte配列に入れて、文字列に戻す ・文字列をByte配列に入れて、自力で文字列に戻す ・文字列をSJISに変換してからByte配列にいれて、自力で文字列に戻す ・最後に
Applicationを省略できるApplicationのメソッド・プロパティ一覧
・Applicationを省略できるかどうかの確認 ・Applicationを省略できるApplicationのメソッド一覧 ・Applicationを省略できるApplicationのプロパティ一覧 ・最後に一言
PowerQueryの強力な機能をVBAから利用する方法
・説明に使用するデータ ・PowerQueryの操作方法 ・PowerQueryのマクロの記録 ・PowerQueryのVBA文法 ・PowerQueryの機能を利用したマクロVBA ・PowerQueryについて
ShapesとDrawingObjectsの相違点と使い方
新規挿入可能なシート名の判定
・シート名として使える文字列か判定 ・シートの存在確認:存在すればシートのオブジェクトを返す ・シートの挿入:存在すればシートのオブジェクトを返す
VBAにおける配列やコレクションの起点について
・配列の起点について ・コレクション ・Collectionオブジェクト ・その他:文字列関数 ・配列の起点の原則
VBAのマルチステートメント(複数のステートメントを同じ行に)
・VBAでのステートメントという用語について ・行継続(1ステートメントを複数の行に) ・VBAマルチステートメントの基本 ・VBAマルチステートメントの応用 ・マルチステートメントの最後に
クリップボードに2次元配列を作成してシートに貼り付ける
・クリップボードのデータ取得/クリップボードへデータ送信 ・エクセルの行・列のデータ ・クリップボードに2次元配列を作成してシートに貼り付けるVBA ・クリップボードに2次元配列の最後に
ユーザー定義型の制限とクラスとの使い分け
・ユーザー定義型 ・クラスについて ・ユーザー定義型とクラスの速度比較 ・ユーザー定義型の制限 ・ユーザー定義型の制限とクラスとの使い分け
シングルクォートの削除とコピー(PrefixCharacter)
・シングルクォーテーション意味 ・VBAでシングルクォーテーションがコピーされる場合と消える場合 ・VBAでのシングルクォーテーションの取得方法 ・VBAでシングルクォーテーションを取り除くVBA ・VBAでシングルクォーテーションを含めて値コピーするVBA
空文字列の扱い方と処理速度について(""とvbNullString)
・String型変数のメモリ配置と取得する関数 ・空文字列について ・String変数に空文字列を入れる ・セルに空文字列を入れる ・Stringが空文字列か判定 ・InputBox関数の戻り値が空文字列判定 ・空文字列の処理方法による速度比較


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

VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
累計を求める数式あれこれ|エクセル関数応用(2024-01-22)
複数の文字列を検索して置換するSUBSTITUTE|エクセル入門(2024-01-03)
いくつかの数式の計算中にリソース不足になりました。|エクセル雑感(2023-12-28)
VBAでクリップボードへ文字列を送信・取得する3つの方法|VBA技術解説(2023-12-07)
難しい数式とは何か?|エクセル雑感(2023-12-07)
スピらない スピル数式 スピらせる|エクセル雑感(2023-12-06)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.変数宣言のDimとデータ型|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.並べ替え(Sort)|VBA入門
8.条件分岐(IF)|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門




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


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



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