ワークシート上に画像を挿入するには、次のようにします。
Sub Macro1() ActiveSheet.Pictures.Insert "C:\Work\Sample1.jpg" End Sub
画像を、アクティブシートに挿入するときは、必ずアクティブセルに挿入されます。正確に言うと、アクティブセルの左上に画像の左上がくるように挿入されます。
次のように、シートを指定すれば、アクティブシートではない(表示されていない)シートに画像を挿入することもできます。
Sub Macro2() Sheets("Sheet1").Pictures.Insert "C:\Work\Sample1.jpg" End Sub
このように、挿入するシートがアクティブシートではなかった場合、画像は常にセルA1に挿入されます。そりゃそうですね。だって、アクティブシートではないシートに、アクティブセルはありませんから。
上述のように、挿入される画像は、基本的に「アクティブセルを左上」とした位置に挿入されます。もし、任意のセルに画像を挿入するのなら、まず挿入したい位置にアクティブセルを移動して・・・なんてことはしません。発想を変えます。挿入した画像を、指定した位置に移動すればいいんです。ちなみに、挿入した画像を、手動で移動する操作をマクロ記録すると、次のようなコードが記録されます。
Sub Macro3() ActiveSheet.Shapes.Range(Array("Picture 1")).Select Selection.ShapeRange.IncrementLeft 74.25 Selection.ShapeRange.IncrementTop 35.25 End Sub
ほとんどの人は、このコードを見て絶句するでしょう。「なんじゃ、これは・・・」って。1行目からツッコミどころ満載です。しかも、移動に関するコードには、74.25とか訳の分からない数値が出てくるし。よしんば、このコードを理解したところで、これを応用して"指定したセルに画像を移動する"なんてのは、相当に難しいです。
簡単です。画像を表すPictureオブジェクトには、その左位置を表すLeftプロパティと、上位置を表すTopプロパティが用意されています。それを指定すればいいんです。次のコードは、すでに挿入されている画像を、セルB3の位置に移動します。
Sub Macro4() ActiveSheet.Pictures("Picture 1").Top = Range("B3").Top ActiveSheet.Pictures("Picture 1").Left = Range("B3").Left End Sub
もし、挿入している画像が1枚しかないのでしたら、次のようにインデックスで指定した方が簡単です。
Sub Macro5() ActiveSheet.Pictures(1).Top = Range("B3").Top ActiveSheet.Pictures(1).Left = Range("B3").Left End Sub
なんか、同じようなコードが2行並んで美しくないですから、Withでくくりましょうか。
Sub Macro6() With ActiveSheet.Pictures(1) .Top = Range("B3").Top .Left = Range("B3").Left End With End Sub
挿入すると同時に、指定した位置に移動するのでしたら、次のようにします。
Sub Macro7() With ActiveSheet.Pictures.Insert("C:\Work\Sample1.jpg") .Top = Range("B3").Top .Left = Range("B3").Left End With End Sub
Insertの後ろに括弧を付けました。意味が分からない人は「括弧はどんなときに使うの?」をご覧ください。
挿入する画像ファイルを、毎回ユーザーに指定させるには、たとえば次のような感じですかね。
Sub Macro8() Dim A As String A = Application.GetOpenFilename("画像,*.jpg", , "画像ファイルの選択") If A = "False" Then Exit Sub With ActiveSheet.Pictures.Insert(A) .Top = Range("B3").Top .Left = Range("B3").Left End With End Sub
画像の横幅や高さは、WidthプロパティやHeightプロパティを使います。ここでも、数値で指定するというよりも、セルを基準にするのが簡単です。次のコードは、挿入した画像の横幅をセル範囲B3:C3に合わせます。
Sub Macro9() With ActiveSheet.Pictures.Insert("C:\Work\Sample1.jpg") .Top = Range("B3").Top .Left = Range("B3").Left .Width = Range("B3:C3").Width End With End Sub
高さもやってみましょう。
Sub Macro10() With ActiveSheet.Pictures.Insert("C:\Work\Sample1.jpg") .Top = Range("B3").Top .Left = Range("B3").Left .Height = Range("B3:B12").Height End With End Sub
上記の結果を見て、気づきましたか?画像の横幅(Width)や高さ(Height)を指定しても、元画像の"縦横比"は変わりません。じゃ、両方指定したらどうなるんでしょう?
Sub Macro11() With ActiveSheet.Pictures.Insert("C:\Work\Sample1.jpg") .Top = Range("B3").Top .Left = Range("B3").Left .Width = Range("B3:C3").Width .Height = Range("B3:B12").Height End With End Sub
後から指定した方が優先されます。いずれにしても、元画像の"縦横比"は維持したままです。これを強引に、縦横比を無視して、指定した大きさにしたいときは、LockAspectRatioプロパティにmsoFalseを指定します。標準では、縦横比が維持されますので、LockAspectRatioプロパティはmsoTrueです。ちなみに、msoFalseやmsoTrueの実体は、FalseやTrueと同じですから、Falseを指定しても同じ結果になります。
Sub Macro12() With ActiveSheet.Pictures.Insert("C:\Work\Sample1.jpg") .Top = Range("B3").Top .Left = Range("B3").Left .LockAspectRatio = msoFalse .Width = Range("B3:C3").Width .Height = Range("B3:B12").Height End With End Sub
考え方は正しいのですが、これ実行するとエラーになります。
LockAspectRatioプロパティは、Pictureオブジェクトではなく、Shapeオブジェクトのプロパティだからです。
いや、実を言うと、今のVBAにはPictureオブジェクトがありません。ちょっと記憶が不確かなのですが、確かPictureオブジェクトって、Excel 95までの仕組みだったはず。それが、VBAのバージョンが上がったExcel 97から「新しくShapeオブジェクト作ったから、これからはShapeオブジェクト使ってね~」みたくなったはずです。ただ、いきなり従来のPictureオブジェクトを使えなくしたら、それまでのマクロが動作しなくなりますから、下位互換性を保つために、いわば"裏ルート"として残してあると。そんな状況ではなかったかと。いや、いかんせん、かれこれ四半世紀近くも前の話ですからw さすがに正確なところは覚えていません。私の事務所には、Excel 95もありますから、そのうち確認してみます。
いずれにしても、LockAspectRatioプロパティはShapeオブジェトのプロパティです。ですから、次のようにしなければなりません。
Sub Macro13() With ActiveSheet.Pictures.Insert("C:\Work\Sample1.jpg") .Top = Range("B3").Top .Left = Range("B3").Left ActiveSheet.Shapes(1).LockAspectRatio = msoFalse .Width = Range("B3:C3").Width .Height = Range("B3:B12").Height End With End Sub
もちろん上記のコードは、アクティブシート上に画像が1つしか挿入されていないという前提です。もし、複数の画像がすでに挿入されていて、そこに新しい画像を挿入するのでしたら、次のように工夫しなければなりませんね。
Sub Macro14() With ActiveSheet.Pictures.Insert("C:\Work\Sample1.jpg") .Top = Range("B3").Top .Left = Range("B3").Left With ActiveSheet.Shapes .Item(.Count).LockAspectRatio = msoFalse End With .Width = Range("B3:C3").Width .Height = Range("B3:B12").Height End With End Sub
あるいは、名前で特定するのでしたら、次のような感じでしょうか。
Sub Macro15() With ActiveSheet.Pictures.Insert("C:\Work\Sample1.jpg") .Top = Range("B3").Top .Left = Range("B3").Left ActiveSheet.Shapes(.Name).LockAspectRatio = msoFalse .Width = Range("B3:C3").Width .Height = Range("B3:B12").Height End With End Sub
幸いなことに、挿入したPictureオブジェクトの名前(Nameプロパティ)と、指定するShapeオブジェクトの名前(Nameプロパティ)は、同じ文字列が設定されますので、その名前を流用しています。
ちなみに、今回写真でご登場いただいたのは、私の行きつけの店「地酒遊楽 裏や」の店長です。いつも、お世話になっています。裏やは、あの野崎酒店の系列で、全国の美酒を常時160種類取り揃えた地酒専門居酒屋です。旬のお料理と絶品の日本酒をご用意して、皆様のご来店を心よりお待ちしております。池袋東口から徒歩5分。お近くにお越しの際には、ぜひお気軽にお立ち寄りください。