[教えて!VBA] 第4回 シート上の図形をコピーして他のセル上に貼り付けするにはどうすればいいの??

概要

この記事について

かんたんな概要と結論

コピー元の図形を参照するためには少々下準備が必要となります。
ペーストには二種類の方法がありますが、どちらを使用しても目的を果たすことができます。

こんにちは、dedeです。

この記事では、
VBAマクロに関する質問のうち、
皆が疑問に思っているトピックについて解説いたします。

今回は、 シート上の図形をコピーして他のセル上に貼り付けする方法
を解説いたします。

※この記事は、Office VBAマクロのうち
Excel VBAマクロに関するトピックです。

レベル:中級者向け

やりたいこと

次のように、すでに存在する図形を使って、
オレンジ色セルの位置に図形をコピーしたい、
しかも「正確な位置」にコピーしたいというケースを考えます。

■■ 正確な位置に処理を行う、というのは典型的なVBAマクロの出番です ■■

図形をコピーしたい

実装の方法としてはいくつか種類があるので、
それぞれの方法と利点について記していきたいと思います。

コード

図形の選択

コピー元の図形の選択方法は、
あらかじめ名前を名付けたうえで選択する方法と、
図形の置かれた位置のセル座標から選択する方法があります。

方法① 名前を名付けて選択

新しく図形を作成すると、
それぞれの図形には図形種類ごとに自動的に名前が割り振られます。

次の図のように笑顔マークを作成すると、
リボンの左下にある「名前ボックス」に「スマイル1」と名前がつけられています。

名前ボックスのデフォルト名

しかし、この名前のままVBAで図形を参照することはできません。

理由は、名前ボックスで表示される名前はローカライズされています(日本語)が、
一方でVBAで使用される名前は英語であるためです。

1Set myShape = ActiveSheet.Shapes("スマイル1")'//not working!

VBAで図形を参照するためには、
作成した図形の一つ一つに新しく名前を名付ける必要があります。

名前の付け方は、
図形を選択し、
リボンの左下にある「名前ボックス」で名前を編集します。

名前ボックスにおける名前の編集後

笑顔マーク、星マーク、禁止記号をそれぞれ次のように変更します。

図形種類 図形デフォルト名 図形変更後名前
笑顔マーク スマイル 1 笑顔
星マーク 星: 5 pt 2
禁止記号 "禁止"マーク 3 禁止

最後に、
VBA上では次のように図形を参照できます。

 1Sub 名前を名付けて図形を選択()
 2    Dim shapeSmile As Shape
 3    Dim shapeStar As Shape
 4    Dim shapeNG As Shape
 5    
 6    Set shapeSmile = ActiveSheet.Shapes("笑顔")
 7    Set shapeStar = ActiveSheet.Shapes("星")
 8    Set shapeNG = ActiveSheet.Shapes("禁止")
 9    
10    Debug.Print shapeSmile.TopLeftCell.Address '//笑顔マーク図形の座標位置
11    Debug.Print shapeStar.TopLeftCell.Address '//星マーク図形の座標位置
12    Debug.Print shapeNG.TopLeftCell.Address '//禁止マーク図形の座標位置
13End Sub
14

方法② 図形の置かれた位置のセル座標から選択

次のコードのように、
あらかじめ対象となる図形の置かれたセル座標を把握した上で、
現在のシートのすべての図形をループ処理で探索し、
目的の座標に一致したものを変数に格納していきます。

 1Sub 図形の置かれた位置のセル座標から選択()
 2    Dim shapeSmile As shape
 3    Dim shapeStar As shape
 4    Dim shapeNG As shape
 5    
 6    Dim myShape As Object
 7    
 8    For Each myShape In ActiveSheet.Shapes
 9        Select Case myShape.TopLeftCell.Address
10        '//笑顔マーク図形の座標に一致する場合
11        Case "$G$4"
12            Set shapeSmile = myShape
13        '//星マーク図形の座標に一致する場合
14        Case "$I$4"
15            Set shapeStar = myShape
16        '//禁止マーク図形の座標に一致する場合
17        Case "$K$4"
18            Set shapeNG = myShape
19        End Select
20        
21    Next
22    
23    Debug.Print shapeSmile.TopLeftCell.Address '//笑顔マーク図形の座標位置
24    Debug.Print shapeStar.TopLeftCell.Address '//星マーク図形の座標位置
25    Debug.Print shapeNG.TopLeftCell.Address '//禁止マーク図形の座標位置
26    
27End Sub

どちらが良いのか??

結論から言うと、
処理速度重視なら方法①、動的に図形を生成するコードを書くのならば方法②に軍配が上がるのかなと思います。

②の方法ではループ処理でシート上のすべての図形を調べるため、
どうしても時間はかかります(それでも図形の数が少なければ微々たるものですが)。

一方、コピー元の図形が次々と動的に生成されるような場合や、
シートごとどこか他のブックからコピーして、その上の図形を操作したいような場合では、
いちいち名前を変更するのも大変だし、名前被りの問題も考慮しなければならないため、
方法②に優位性があるでしょう。

コピーとペースト

図形をコピーして指定した場所にペーストする方法は、
ペースト先のセルを選択した後にペーストを行う方法と、
シートの任意の場所にペーストしてから図形を移動する方法の二種類が存在します。

方法① ペースト先のセルを選択してペースト

次のようなコードです。

 1Sub ペースト先のセルを選択してペースト()
 2    Dim shapeSmile As shape
 3    Dim shapeStar As shape
 4    Dim shapeNG As shape
 5    
 6    Set shapeSmile = ActiveSheet.Shapes("笑顔")
 7    Set shapeStar = ActiveSheet.Shapes("星")
 8    Set shapeNG = ActiveSheet.Shapes("禁止")
 9    
10    '//笑顔マークをペースト
11    shapeSmile.Copy
12    
13    '////1. G5セル(ペーストしたいセルアドレス)を選択
14    ActiveSheet.Range("G5").Select
15    '////2. ペーストの実行
16    ActiveSheet.Paste
17    '////以下繰り返し
18    ActiveSheet.Range("G6").Select
19    ActiveSheet.Paste
20    
21    '//星マークをペースト
22    shapeStar.Copy
23    ActiveSheet.Range("I5").Select
24    ActiveSheet.Paste
25    ActiveSheet.Range("I6").Select
26    ActiveSheet.Paste
27    
28    '//禁止マークをペースト
29    shapeNG.Copy
30    ActiveSheet.Range("K5").Select
31    ActiveSheet.Paste
32    ActiveSheet.Range("K6").Select
33    ActiveSheet.Paste
34    
35End Sub

方法② シートにペーストしてから図形を移動

次のようなコードです。

 1Sub シートにペーストしてから図形を移動()
 2    Dim shapeSmile As shape
 3    Dim shapeStar As shape
 4    Dim shapeNG As shape
 5    
 6    Set shapeSmile = ActiveSheet.Shapes("笑顔")
 7    Set shapeStar = ActiveSheet.Shapes("星")
 8    Set shapeNG = ActiveSheet.Shapes("禁止")
 9    
10    '//笑顔マークをペースト
11    shapeSmile.Copy
12    '////1. ペーストの実行
13    ActiveSheet.Paste
14    '////2. ペーストした図形を指定位置(ペーストしたいセルアドレス位置)に移動
15    With Selection
16        .Top = ActiveSheet.Range("G5").Top
17        .Left = ActiveSheet.Range("G5").Left
18    End With
19    '////以下繰り返し
20    ActiveSheet.Paste
21    With Selection
22        .Top = ActiveSheet.Range("G6").Top
23        .Left = ActiveSheet.Range("G6").Left
24    End With
25    
26    '//星マークをペースト
27    shapeStar.Copy
28    ActiveSheet.Paste
29    With Selection
30        .Top = ActiveSheet.Range("I5").Top
31        .Left = ActiveSheet.Range("I5").Left
32    End With
33    ActiveSheet.Paste
34    With Selection
35        .Top = ActiveSheet.Range("I6").Top
36        .Left = ActiveSheet.Range("I6").Left
37    End With
38'
39    '//禁止マークをペースト
40    shapeNG.Copy
41    ActiveSheet.Paste
42    With Selection
43        .Top = ActiveSheet.Range("K5").Top
44        .Left = ActiveSheet.Range("K5").Left
45    End With
46    ActiveSheet.Paste
47    With Selection
48        .Top = ActiveSheet.Range("K6").Top
49        .Left = ActiveSheet.Range("K6").Left
50    End With
51    
52    
53End Sub
54
55

どちらが良いのか??

上のコードを見るとわかるように、
セル選択の後にペースト実行する方法①のほうが簡潔です。

しかし、方法②のほうが適している場合もあります。
それは、次のような場合です。

  • シートにセル選択時イベントが設定されており、図形ペースト時にイベントを発火させたくないとき
  • シート保護機能により、セルの選択が禁止されているとき

デモ

次のように、笑顔マーク、星マーク、禁止マークを
下に続く2行にコピペしたいとします。

マクロ実行前

上記で記載した「ペースト先のセルを選択してペースト」関数を実行すると、
各マークが規則正しくコピペされ配置されます。

マクロ実行後

終わりに

VBAマクロで図形をいじったりするのは、
マクロでしっかりしたツールを作るときよりも、
むしろ簡単な作業の自動化のために突発的に作成する場合が多いかと思います。

そのような場合でも、図形の取り扱いを慣れておけば
手作業よりもずっと効率よくマクロを組むことが可能となるでしょう。

関連記事

comments powered by Disqus