Excel VBA(マクロ)で図形を取得、選択する方法/Shapes、ShapeRange、Rangeプロパティの使い方

problem IT

VBAで図形に干渉したい場合は、ワークシートなどのオブジェクトにShapesプロパティを付けて、「シートの中のオブジェクト群」であるShapesコレクションを取得して使います。
Shapesコレクションに引数を付けることで、個別の図形=Shapeオブジェクトが取得できます。

スポンサーリンク

Shapesコレクション(すべての図形)

すべての図形の選択
オブジェクト.Shapes.SelectAll
vba 図形 shapes1
と言われてもなんのこっちゃかもしれませんので、実演します。
まず3つ図形を用意しておきます。
vba 図形 shapes2
マクロを開き、ActiveSheet.Shapesと記述します。
この時点で、「アクティブシートの図形全て」が選択されている状態です。「アクティブシートの図形全て」に対して命令を実行できるので、これを対象としてShapesコレクションと呼びます。
' vba
ActiveSheet.Shapes.SelectAll
コレクションの要素を全て選択するには、SelectAllメソッドを使います。
Selectメソッドは個別のオブジェクトを選択する命令で、この場合使えません。
vba 図形 shapes3
実行結果です。アクティブシートの図形が全て選択されています。

Shapeオブジェクト(個別の図形)

図形の選択
オブジェクト.Shapes(図形の名称または番号).Select
' vba
ActiveSheet.Shapes(1).Select
このコレクションからさらに個別のShapeオブジェクトを選択したい場合はどうするかというと、Shapesの後ろに()を付けて、その中に引数を指定します。
引数はインデックス番号でも図形を選択できますし、図形の名前などでも指定できます。
vba 図形 shapes4
実行すると、コレクション全体の中からインデックス番号「1」の図形が選択されていることが確認できます。
shapes range3
なお、複数指定(Shapes(1, 2).Selectなど)はエラーになります。
複数図形を選択したい場合は、Shapesコレクションに対して後述するRangeを使いActiveSheet.Shapes.Range(Array(1, 2)).Selectのように記述します。

図形のインデックス番号

図形 インデックス番号1
図形のインデックス番号は作った順ではなく、重なり順が一番下のものが「1」になります。下から二番目が番号2、三番目が番号3です。
同じコード(ActiveSheet.Shapes(1).Select)でもこの状態なら〇が選択され、
図形 インデックス番号2
この状態なら△が選択されます。

図形の名前

図形 名前で選択 shapes1
図形にはそれぞれ自動的に割り振られる名前があり、
図形 名前で選択 shapes3
名前ボックスをクリックして自由に変更することができます。
' vba
ActiveSheet.Shapes("maru").Select
""で囲って名前を指定することでも、図形の取得が可能です。

ShapeRangeコレクション(複数図形)

Shapesコレクションはシート上の図形全て、Shapeオブジェクトは単一の図形を意味し、これとは別に「複数の図形の範囲」を意味するShapeRangeコレクションというのもあります。
ShapeRangeコレクションは①図形みっつのうちふたつを選択したいとか、②図形全体のプロパティを変更する場合などに使用します。Shapesコレクションからはプロパティを変更できないので、一度ShapeRangeコレクションにする必要があります。

ShapeRangeプロパティ

shaperange1
とりあえず一回やってみます。Fill.ForeColorは図形の色を変える命令で、Shapesコレクションからは行えません。一回ShapeRangeにアクセスする必要があります。
失敗例①Shapesコレクションに対してShapeRangeプロパティを直接付けると、
shaperange2
エラーになります。ShapesコレクションはShapeRangeプロパティを持たない仕様だからです。
shaperange3
Selection(選択済の範囲)プロパティはShapeRangeを持つので、Shapes.SelectAllで図形全体を選択して一度命令を閉じ、次の行でSelectionから命令することで対応します。
②ShapeRangeを付けてない(ShapesコレクションからFill.ForeColorを実行しようとしている)のでこれもエラーになります。
' vba
' 図形全体を選択
ActiveSheet.Shapes.SelectAll
' 選択済の図形の色を変更
Selection.ShapeRange.Fill.ForeColor.RGB = RGB(100, 100, 100)

一回全体選択して、選択範囲にShapeRangeプロパティを付ける=ShapeRangeコレクションを取得し、Fill.ForeColorを実行すると、
shaperange4
こうなります。

Rangeプロパティ

' vba
' インデクス番号2、3の図形の色を変える
ActiveSheet.Shapes.Range(Array(2, 3)).Fill.ForeColor.RGB = RGB(0, 0, 255)
Rangeプロパティを付けた場合もShapeRangeコレクションを取得できます。選択したものをそのままコレクションにするShapeRangeとちがい、全体の中の任意の図形に干渉できます。Array=配列。
Shapesコレクションに対してRangeプロパティを付け、Array()の中で図形のインデクス番号や名称を指定することで取得します。
shapes range1
実行結果です。プロパティも変更できるし、複数範囲の選択も自在にできる重宝なプロパティです。

取得した図形に対してできること

ShapesコレクションやShapeオブジェクトに対して、たとえば以下のようなことができます。基本プロパティはShapesコレクションからは行えないので、適宜ShapeRangeコレクションから操作します。

他にも色々な命令があるので、より詳しく知りたい方は下記をご参照ください。

Excel(エクセル):図形
Excelでは、図形という機能を使うことで四角形や丸、矢印などのオブジェクトをシート状に配置することができます。セルの形状を無視して配置できるので、フローチャートや装飾、注釈などアイデア次第でさまざまな用途に利用できます。 図形作成・操作...
やりたいことから方法を探すエクセル(Excel)操作・関数・VBA(マクロ)逆引きまとめ
逆引き(やりたいことから探す)Excel記事まとめ
関数・演算子・メソッド・プロパティ名から探すExcel/VBA(マクロ)使い方・組み合わせ方まとめ
こちらはExcelやメソッドの諸機能を、機能の名称から探せるまとめ記事です。

コメント

  1. 宮腰 弘司 より:

    こんにちは、すなぎつ様

    私は宮腰と申します。

    アリーナ照明の保守用にエクセル図面で水銀灯の不良箇所チェック表を作りました。

    下記、構文でいろんな色の「○」図形が多数有ります。

    この色及び透明度の図形をマクロで選択し個数をカウント出来るのでしょうか。

    ヒントを頂ければ幸いです。

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

    Sub 選択図形の塗りつぶし黒色() ‘黒色

    On Error GoTo ErrHandl

    With Selection.ShapeRange.Fill
    .Visible = msoTrue
    .ForeColor.RGB = RGB(0, 0, 0)
    .Transparency = 0.6
    .Solid
    End With

    Exit Sub
    ErrHandl:
    MsgBox “外したい電球を選択してから実行してください。”
    Err.Clear

    End Sub

    • すなぎつ より:

      宮腰様

      コメントありがとうございます。たとえば下記のようなコードで該当図形の数は数えられると思いますが、いかがでしょうか。

      Sub 電球カウント()
      Dim 図形の数
      Dim count: count = 0
      図形の数 = ActiveSheet.Shapes.count
      For i = 1 To 図形の数
      If ActiveSheet.Shapes.Range(Array(i)).Fill.Visible = msoTrue And _
      ActiveSheet.Shapes.Range(Array(i)).Fill.ForeColor.RGB = RGB(0, 0, 0) And _
      ActiveSheet.Shapes.Range(Array(i)).Fill.Transparency = 0.6 Then
      count = count + 1
      End If
      Next
      MsgBox count

      End Sub