OutputShapeToPicture|ワークシート上の図形を画像ファイルとして出力する
- yuji fukami
- 2 日前
- 読了時間: 6分

この部品でできること
OutputShapeToPicture は、ワークシート上に作図した図形(シェイプ)を、そのまま画像ファイルとして保存するExcel VBAの汎用プロシージャです。
対象のシェイプと保存先を渡すだけで、画像ファイルとして書き出す
拡張子は jpg / png / gif / bmp / tif から選べる
出力する画像の横幅をピクセル数で指定できる(省略時は2倍の解像度で出力)
背景色と余白(マージン)も指定できる
グループ化した図形や、貼り付けた画像(Picture型)にも対応
下の図は、ワークシート上に作図した図形を、ボタン1つで画像ファイルとして出力している様子です。

使いどころ
VBAで計算して作図したグラフや図形を、画像として保存・共有したいとき
Excelで作った図表を、資料や報告書に貼り付ける画像として書き出したいとき
複数のパラメータで作図した結果を、連続で画像ファイルとして出力したいとき
印刷やPDF化ではなく、画像ファイルとして扱いたいとき
コード
宣言セクションの Enum はモジュールの先頭に配置してください。本体に加え、依存する ClipText / GetClipText / CopySelection も含めています。下記をそのまま標準モジュールに貼り付ければ動作します。
なお GetClipText は「Microsoft Forms 2.0 Object Library」の参照設定が必要です。参照設定をしていない場合は、ユーザーフォームを1つ作成してから削除すると自動的に参照が追加されます。
使い方・引数
引数は7つです。後半の3つは省略可能です。
TargetShape(Object)・・・画像として出力する対象のシェイプ
folderPath(String)・・・出力先のフォルダパス
PictureName(String)・・・出力する画像のファイル名(拡張子は不要)
PictureExtension(Enum_PictureExtension)・・・出力する拡張子。vb_png / vb_jpg / vb_gif / vb_bmp / vb_tif から選ぶ
[Pixcel](Long)・・・出力する画像の横幅ピクセル数。省略時は元のサイズの2倍で出力
[Color](Long)・・・背景色。省略時は白(rgbWhite)
[Margin](Long)・・・上下左右の余白
呼び出し例は次のとおりです。シート上のグループ化した図形を、ブックと同じフォルダにjpgとして出力します。
実際に使用すると、下記の様にワークシート上の図形がそのまま画像ファイルとして出力されます。

出力する横幅を指定したい場合は、第5引数に希望のピクセル数を渡します。
仕組み(シェイプを画像にする流れ)
Excelには「シェイプを直接画像ファイルとして保存する」という機能がありません。そこでこの部品では、グラフ(ChartObject)を経由して書き出すという定番の手法を使っています。Chart.Export メソッドは、グラフを画像ファイルとして保存できるためです。
処理の流れは次のようになっています。
対象のシェイプをクリップボードにコピーする
新しいシート(画像出力用)を作り、そこに出力サイズのグラフ(ChartObject)を追加する
グラフの中にシェイプを貼り付け、サイズと余白を調整する
Chart.Export で画像ファイルとして書き出す
グラフと作業用シートを削除して、元のシートに戻る
作業用のシートを新規作成して、そこで処理してから消しているのは、元のシート上で処理すると「書き込みができません」というエラー(Err.Number = 70)が出ることがあるためです。処理が終われば跡形もなく片付くので、使う側は意識する必要がありません。
クリップボードのコピー完了を待つ工夫
このコードで特徴的なのが、シェイプをコピーする部分のループ処理です。
VBAの Copy メソッドは、実行してもクリップボードへの格納が完了するまでに少し時間がかかることがあります。格納が終わる前に次の貼り付け処理へ進んでしまうと、空のグラフが出力されたり、エラーで止まったりします。
そこで、あらかじめ ClipText("Dummy") でダミーの文字列をクリップボードに入れておき、コピー後に GetClipText で中身を確認しています。クリップボードに画像が入ると文字列は取得できなくなる(空文字が返る)ので、空文字が返ってきた=コピーが完了したと判断できます。完了するまでは DoEvents を挟みながらコピーを繰り返し、最大100回で打ち切ります。
「一定時間待つ」のではなく「完了を確認してから進む」形にすることで、環境や図形の大きさによる処理時間の差に左右されず、確実にコピーを終えてから次に進めます。
ピクセル数の指定と倍率の計算
Pixcel を指定した場合の倍率は、次の式で求めています。
シェイプの幅はポイント単位、出力したい画像の幅はピクセル単位なので、この2つの単位を変換する必要があります。1.463 はその変換のための係数で、実際に出力した画像のサイズを確認しながら調整した実測値です。コメントに「謎の係数」と残しているとおり理論値ではありませんが、この値で概ね指定どおりのピクセル数で出力できます。
Pixcel を省略した場合は倍率が 2 になります。等倍(1)ではなく2倍にしているのは、画面表示のサイズそのままだと画像が粗くなるためで、少し高解像度で出力する既定にしています。
依存プロシージャ
このコードは次の自作プロシージャに依存します。上の「コード」ブロックにすべて含めているので、そのまま貼り付ければ動作します。宣言セクションの Enum_PictureExtension はモジュールの先頭に置いてください。
ClipText:文字列をクリップボードに格納する部品です。詳しくは ClipText を参照してください。コピー完了を判定するためのダミー文字列を入れるのに使っています。
GetClipText:クリップボードの文字列を取得する部品です。詳しくは GetClipText を参照してください。コピーが完了したかの判定に使っています。
CopySelection:Selection.Copy を成功するまで繰り返す部品です。コピー時に稀に発生するエラーを回避するために使っています。
応用・注意点
TargetShape の型を Shape ではなく Object にしているのは、シェイプ(Shape型)だけでなく、シートに貼り付けた画像(Picture型)も同じように扱えるようにするためです。型を限定していないので、Shapes("名前") で取得したものをそのまま渡せます。
複数の図形をまとめて1枚の画像にしたい場合は、Shapes.Range(Array("図形1", "図形2")).Group でグループ化してから渡します。出力後に Ungroup で元に戻すのを忘れないようにしてください。
出力先がOneDrive配下のフォルダの場合、ThisWorkbook.Path がURL形式(https://d.docs.live.net/...)で返ることがあり、そのままではファイル出力に失敗します。OneDriveのパスをローカルパスに変換してから渡してください。
ピクセル数を大きく指定しすぎると、グラフの作成に失敗して出力エラーになることがあります。エラー処理を入れる場合は、作業用シート(画像出力用)が残ってしまわないよう、エラー時にシートを削除する処理も併せて用意しておくと安全です。
jpg は背景が白で塗りつぶされますが、png を指定しても背景色(Color 引数)は適用されます。背景を透明にしたい場合は、この方法では対応できません。
計算した座標から図形を作図して画像化する、という流れで使う場合は、DrawPolyLineAddPolyLine や ConvXYListForSheetCenter と組み合わせると、計算からファイル出力まで一連の処理を自動化できます。
サンプルブック(ダウンロードして試せます)
コードの詳しい動きは上のコードブロックと解説のとおりですが、まず動かして試したい場合は、下記のサンプルブックをダウンロードして、ボタンを押すだけで動作を確認できます。
まとめ
OutputShapeToPicture は、ワークシート上の図形を画像ファイルとして書き出す汎用プロシージャです。Excelには図形を直接画像化する機能がないため、内部ではグラフ(ChartObject)を経由する定番の手法を使い、作業用シートの作成から後片付けまでをすべて内部で完結させています。クリップボードのコピー完了を確認してから次に進む設計になっているので、環境による処理時間の差にも左右されにくく、計算して作図した図形をそのまま画像として保存したい場面で扱いやすい部品です。


