Excelでダイアログから画像を取得するサンプルコードを紹介します。
写真や画像の取得をする場合、通常は挿入メニューの画像取得を使いますが、VBAから取得することもできます。
なお、ExcelのVBAで画像を取得する方法は主に2種類あり、ひとつはPictures.Insertメソッドを使う方法、もうひとつはShapes.AddPictureメソッドを使う方法です。
両方を紹介しますので比較参考いただければと思います。
なお、この件については基礎編と実用編にページを分けています。
そして、このページの基礎編では画像の取得だけを行うシンプルなコードを紹介します。
リンクで画像を表示する
こちらは、画像データそのものを取り込むのではなく、画像のリンクを取得してExcelファイル内に画像を表示する方法です。
2つのメソッドについて、それぞれコードを記載します。
Pictures.Insertメソッドを使う方法
まずはこちらを見てください。
Sub 画像取得_PI()
ActiveSheet.Pictures.Insert ("画像ファイルのフルパス")
End Sub
画像のフルパス(画像の置いていあるフォルダやファイル名のアドレス)を指定して取得するならこれだけです。取得するシートがActiveSheetでなければSheet1のように指定する必要はありますが。
しかし、実際に画像を取得するときはタイトルにもあるようにファイル選択ダイアログから選択するほうが便利だと思うので、以降はすべてダイアログからの取得を前提に記載していきます。
Sub 画像リンク取得_PI()
'画像取得ダイアログを開く
Dim PictName As String
PictName = Application.GetOpenFilename _
("画像(*.png; *.jpg; *.jpeg; *.gif),*.png; *.jpg; *.jpeg; *.gif", , "画像ファイルの選択")
'ダイアログでキャンセルした場合は終了
If PictName = "False" Then Exit Sub
'画像の取得
ActiveSheet.Pictures.Insert (PictName)
End Sub
一気に長くなりましたが、画像の取得をするのは1行だけで、他の部分はファイル選択ダイアログからファイルを選択し、フルパスを取得するためのものです。
このコードでは、そのフルパスを「PictName」という名前の変数に格納し、Pictures.Insertメソッドに渡して画像を取得させています。
ちなみに画像の貼付場所を指定していない場合、アクティブセルの位置(左上を起点)に画像が取得されます。
ただし、先に記載したようにこのコードでは画像リンクの取得しかできません。
画像リンクの取得というのは、選択した画像のフルパスを取得し、Excelファイルを開くたびにそのフルパスの場所に画像を読みに行って表示する取得方法のことです。
そのため、画像のファイル名や置き場所が少しでも変わってしまうと、次回開いたときには画像を表示できなくなる点に注意が必要です。
なお、リンク先が見つからなかったときはこんな感じで表示されます。
この方法は、画像の保存場所を変えず、Excelファイルからもその画像ファイルをいつも読みに行ける環境下での運用、または取得した画像を保存する必要がない場合に適しています。
例えば、画像取得後に印刷だけして保存せずに終了するような使い方などにはいいんじゃないでしょうか。
やや特殊な状況下での使用が前提となりますが、画像データをExcelファイル内に保存しないぶん、ファイルサイズは大きくならないというメリットがあります。
Shapes.AddPictureメソッドを使う方法
Sub 画像リンク取得_AP()
'画像取得ダイアログを開く
Dim PictName As String
PictName = Application.GetOpenFilename _
("画像(*.png; *.jpg; *.jpeg; *.gif),*.png; *.jpg; *.jpeg; *.gif", , "画像ファイルの選択")
'ダイアログでキャンセルした場合は終了
If PictName = "False" Then Exit Sub
'画像の取得
With ActiveSheet
Set GetPic = .Shapes.AddPicture( _
Filename:=PictName, _
LinkToFile:=True, _
SaveWithDocument:=False, _
Left:=Selection.Cells.Left, _
Top:=Selection.Cells.Top, _
Width:=-1, _
Height:=-1)
End With
End Sub
こちらのコードでもPictures.Insertメソッドと同じように画像リンクが取得できます。
Shapes.AddPictureメソッドは引数が多く、省略もできないため、少しコードは長くなりますが、使うならこちらのほうをおすすめします。
その理由は、次で紹介する画像データそのものを取得するコードでも同じフォーマットで使用できることと、画像データを取得する際にPictures.Insertメソッドより優れている点があるからです。
詳しくは後ほど説明します。
画像をデータごと取得する
さて、前段では画像のリンクを取得して画像を表示する方法でしたが、こちらはリンク切れの心配がない画像データの取得方法です。
前段同様に2種類のメソッドを紹介します。
Pictures.Insertメソッドを使う方法
まずはPictures.Insertメソッドからです。
Sub 画像取得_PI()
'画像取得ダイアログを開く
Dim PictName As String
PictName = Application.GetOpenFilename _
("画像(*.png; *.jpg; *.jpeg; *.gif),*.png; *.jpg; *.jpeg; *.gif", , "画像ファイルの選択")
'ダイアログでキャンセルした場合
If PictName = "False" Then Exit Sub
'画像の取得
With ActiveSheet.Pictures.Insert(PictName)
.CopyPicture 'クリップボードにコピー(リンク切れなしの画像とするためのコピー)
.Delete 'リンク画像を削除
End With
'上記でコピーした画像を貼り付け(これでリンク切れなしの画像になる)
ActiveSheet.Paste
End Sub
このコードでは、前段と同じ手順で取得したリンク付き画像を.CopyPictureで一旦クリップボードにコピーして、取得したリンク付き画像は.Deleteで削除してしまいます。
そしてクリップボードに格納された画像を、ActiveSheet.Pasteで貼り付けます。
こうすることでリンクのない画像にすることができます。
少しめんどくさいというか、ダサい処理のように見えますが、過去の仕様変更によってPictures.Insertメソッドでリンクのない画像データを取得するには、こういった手順を踏む必要ができてしまいました。
また、紹介しておいて何ですが、この方法には少し欠点もあります。
クリップボードを経由させることで、画像はビットマップ形式に変換されてしまいます。
これの困ったところは、仮に取得画像がjpg圧縮でサイズを小さくしていたとしても、ビットマップ形式に変換されることでサイズが何倍にも膨れ上がってしまう可能性があります。
これではたくさんの画像を取り込むと動作が重くなりすぎて現実的には使えない場合があるでしょう。
Shapes.AddPictureメソッドを使う方法
では次にShapes.AddPictureメソッドのコードを紹介します。
Sub 画像取得_AP()
'画像取得ダイアログを開く
Dim PictName As String
PictName = Application.GetOpenFilename _
("画像(*.png; *.jpg; *.jpeg; *.gif),*.png; *.jpg; *.jpeg; *.gif", , "画像ファイルの選択")
'ダイアログでキャンセルした場合は終了
If PictName = "False" Then Exit Sub
'画像の取得
With ActiveSheet
Set GetPic = .Shapes.AddPicture( _
Filename:=PictName, _
LinkToFile:=False, _
SaveWithDocument:=True, _
Left:=Selection.Cells.Left, _
Top:=Selection.Cells.Top, _
Width:=-1, _
Height:=-1)
End With
End Sub
前段のShapes.AddPictureメソッドでリンク付き画像の取得コードとほぼ同じです。
違うのは次の2行だけです。
リンク付き | リンクなし |
---|---|
LinkToFile:=True, _ SaveWithDocument:=False, _ | LinkToFile:=False, _ SaveWithDocument:=True, _ |
見てのとおりですが、Shapes.AddPictureメソッドでは2つの引数の値(True・False)を逆に指定するだけで、「リンク付き画像⇔リンクなし画像」の切り替えができます。
コードが長くなる点を差し引いても、Shapes.AddPictureメソッドのわかりやすさはメリットになるのではないでしょうか。
また、Shapes.AddPictureメソッドでの画像取得はクリップボードを経由させる必要がないため、こちらの方法で取得した画像データはサイズが大きくなる心配もありません。
前段で、Pictures.Insertメソッドではなく、Shapes.AddPictureメソッドを使うことをおすすめした理由は上記のとおりです。
基礎編まとめ
このページでは、画像の取得に係る心臓部分の処理に絞って2つのメソッドでサンプルコードを紹介しました。
ただ、結論は特殊な事情がない限り画像取得にはShapes.AddPictureメソッドを使えばいい、ということになります。
一応、それぞれの特徴を簡単にまとめると次のような感じです。
特徴 | Pictures.Insert | Shapes.AddPicture |
---|---|---|
コードの長さ | 処理内容によっては短い | やや長め |
取得データサイズ | クリップボード経由の際に肥大化の懸念あり | そのままのサイズで取得 |
実用編では、実際に使うにあたって必要となるオプション設定まで含めたコードをメソッドごとに1つずつ紹介します。
コメント