ワークシートに挿入した画像はPictureオブジェクトで表されます。まぁ、正確にはPictureオブジェクトではないんですけど、そのへんは「画像を挿入する」をご覧ください。で、そのPictureオブジェクトには、上位置を表すTopプロパティと、左位置を表すLeftプロパティがあります。両者を指定することで、挿入した画像の位置を指定できます。ちょっと、やってみましょうか。次のコードは、セルB3に画像を挿入します。
Sub Macro1() With ActiveSheet.Pictures.Insert("C:\Work\Sample2.jpg") .Top = Range("B3").Top .Left = Range("B3").Left End With End Sub
写真は、みなさんお馴染み、青森の「田酒」です。しかも!ただの田酒ではありません!弁慶米100%という、まさに幻の逸品。通称"田酒の赤ラベル"です。ほとんど流通しない貴重なお酒です。いやぁ~美味かったぁ~(^▽^)
え~と、何でしたっけ?あ、そっか画像ね。このように、TopプロパティとLeftプロパティで位置を指定できるんですが、問題は2枚目です。次の画像を、この1枚目の画像と揃えて表示したいと。実務では"あるある"ですね。
もし、次の画像を、すでに挿入している画像に、ピタリとくっつけて挿入したいのでしたら、次のように考えます。
まずは、既存画像の「真下」に挿入してみます。であれば、画像の左位置は、既存画像と同じです。
Sub Macro2() With ActiveSheet.Pictures.Insert("C:\Work\Sample3.jpg") .Top = 既存画像の真下 .Left = ActiveSheet.Pictures(1).Left End With End Sub
「Pictures(1)」というのは、位置の基準としている既存画像が、アクティブシートに1枚だけ存在しているという意味です。もし、複数の画像がアクティブシート上に挿入されていたら、この基準となる既存画像を"何とかして"特定します。さて、問題は「真下」の位置です。これは、次のようにすれば計算できます。
既存画像の「真下」ということは、既存画像のTop(上位置)と、既存画像のHeight(高さ)を足したところです。
Sub Macro2() With ActiveSheet.Pictures.Insert("C:\Work\Sample3.jpg") .Top = ActiveSheet.Pictures(1).Top + ActiveSheet.Pictures(1).Height .Left = ActiveSheet.Pictures(1).Left End With End Sub
でました!作です!しかもクラウン!その名も「筰(ザク クラウン)」三重県鈴鹿は清水清三郎商店の内山杜氏が、その持てる力を惜しみなく注ぎ込んだという、渾身の自信作。贅沢な原料をふんだんに使い、仕込みに必要なすべての工程で手間暇を惜しまず、一滴一滴、丁寧に搾った最高品質のお酒です。一口含んだ途端に口いっぱいに広がる華やかで奥深い香りは、まさに"芸術品"。ラベルは三重の伝統工芸「伊勢和紙」を「鈴鹿墨」で染めた「染め和紙」です。「伊勢和紙」とは、神宮御用紙として伊勢神宮の神札などに使われている清浄な和紙。その和紙を、平安時代から続くと言われる高品質の墨「鈴鹿墨」で、一枚一枚丁寧に染め上げられています。伝統の和紙と繊細なグラデーションが、これ以上ない気品を漂わせます。750mlで35,000円近い金額もさることながら、全国で限定120本という超貴重酒。これ、次回はない、もう一生飲めない銘酒です。ちなみに、あまりに美味しいので調子に乗って何杯も飲んだら、とんでもない金額になりましたっけww(^▽^)
え~と、何でしたっけ?あ、そっか画像ね。はいはい...
既存画像の右に挿入するのも考え方は同じです。今度は、Topは既存画像と同じです。で、左位置(Left)は、既存画像の「Left + Width」です。
Sub Macro3() With ActiveSheet.Pictures.Insert("C:\Work\Sample3.jpg") .Top = ActiveSheet.Pictures(1).Top .Left = ActiveSheet.Pictures(1).Left + ActiveSheet.Pictures(1).Width End With End Sub
ちなみに、見てお分かりのように、2枚の画像は元のサイズが同じです。一般的に、同じデジカメやスマホなどで撮影した画像は、同じサイズで保存されます。ですから、こうして並べたときにも違和感はありません。もし、挿入する画像のサイズが異なっていたら、並べるとピッタリ揃いません。当たり前です。そうした"画像の元サイズ"を、VBAで何とか調整したり変更したりしようと試みる人がいますが、やめた方がいいです。理由は明白です。VBAは「何でもできる魔法の道具」ではなく、表計算ソフトであるExcelを操作するための"マクロ言語"に過ぎないからです。何でもできるわけじゃありません。そこを勘違いしている人が、実に多いです。複数の画像ファイルを、すべて同じ大きさに変更するような操作は、VBAではなく、フリーのオンラインソフトなどを使った方がはるかに簡単です。そうして、サイズを揃えた上で読み込みます。何でもかんでも、VBAだけでやろうとしないでください。
画像をピタリとくっつけて表示すると、逆に見にくくなるかもしれません。画像の間隔を、少し開けるというのも、よくある話ですね。上記の考え方で、少しだけ余裕を加えてあげてもいいのですけど、もうひとつ"あるある"のやり方として、セルに合わせるというのも多いことでしょう。たとえば、次のような感じです。
上図では、2枚目の画像が挿入されているセルB16を特定できれば、いいわけです。しかし、1枚目の画像の大きさは分かりません。画像ですから。セルに値が入力されているのではありません。Endモードなどは使えません。さあ、どうしましょう。
画像などのShapeオブジェクトには、そのShapeオブジェクトの左上が乗っているセルを表すTopLeftCellプロパティと、右下が乗っているセルを表すBottomRightCellプロパティがあります。
Sub Macro4() With ActiveSheet.Pictures(1) MsgBox "左上:" & .TopLeftCell.Address MsgBox "右下:" & .BottomRightCell.Address End With End Sub
つまり「左上」セルと「右下」セルから、画像の下のセル(ここではセルB16)を導き出すには、どうしたらいいかということです。
ここでは、2つの方法をご紹介します。
まずは簡単な方法から。
今回、新しい画像を挿入するセルは、セルB16です。これ、Cellsで表すと「Cells(16, 2)」です。このうち、列の「2」は左上セル「Cells(3, 2)」の列と同じです。
さらに「Cells(16, 2)」で行を表す「16」は、右下セル「Cells(15, 4)」の行「15」に1を加えた数値です。以上のことから、新しい画像を挿入するセルは
Cells(右下セルの行+1, 左上セルの列)
だと分かります。
右下セルの行 → 画像.BottomRightCellの行 → 画像.BottomRightCell.Row
左上セルの列 → 画像.TopLeftCellの列 → 画像.TopLeftCell.Column
なのですから、まとめると、次のようになります。
Sub Macro5() Dim R As Long, C As Long R = ActiveSheet.Pictures(1).BottomRightCell.Row C = ActiveSheet.Pictures(1).TopLeftCell.Column With ActiveSheet.Pictures.Insert("C:\Work\Sample3.jpg") .Top = Cells(R + 1, C).Top .Left = Cells(R + 1, C).Left End With End Sub
まぁ、普通にやるなら、この方法でしょうね。
ApplicationオブジェクトのIntersectメソッドは、複数のセル範囲の共有セルを返します。
ここでは、「左上」セルを含む列全体と「右下」セルを含む行全体の中で共有しているセルを求めます。
目指すセルは、この共有セルの1つ下のセルです。
Sub Macro6() Dim Target As Range With ActiveSheet.Pictures(1) Set Target = Application.Intersect(.TopLeftCell.EntireColumn, .BottomRightCell.EntireRow).Offset(1, 0) End With With ActiveSheet.Pictures.Insert("C:\Work\Sample3.jpg") .Top = Target.Top .Left = Target.Left End With End Sub
意味が分からない人は、無理をしないで最初の"一般的な方法"で、やってください。