t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

VBA オートシェイプで作った桜のアイコンでユーザーフォームを可愛くデコレーションする

普段からこのブログを読んでくれてる方は、今回のタイトルを見て「ついにthomもVBAのやり過ぎで頭がおかしくなってしまったか」と思われた方もいるかもしれない。

可愛くだなんて。30超えたオッサンが何言うとんねん。
さてさて、今回作ったのはこれ。

でん!
f:id:t-hom:20170212001539p:plain

きゃーカワイイー!

…まじめな話、最初からコレをねらった訳ではなく、こんなふうになってしまったのは偶然の産物である。

きっかけはイラストの重要性に気付いたこと

マクロの機能的にはアイコンなんて何の意味もないと思う方も居るかもしれないけど、ユーザーがそのマクロの使用感に満足を覚えるかどうかという点でデザインは超重要な要素だ。

繰り返す。

デザインは超重要な要素だ。

さて、具体的にアイコンを付けようなどという発想に行き着いたきっかけはこちらのサイト。
ateitexe.com

アイコンの話が出てくるわけではないのだけど、説明にいろいろと可愛らしいイラストが添えてあり、読んでいて楽しい。
これまで私は説明のための図解をすることはあっても、ユーザーを楽しませるためという観点でイラストを書いたことは無かった。

そうだ!イラストだ!

と思い立ったとき、たまたまユーザーフォームのデザインを考えていたのでその2つが結びついた感じ。
それで、「よし、アイコンを付けよう。」となった。

なんでまた桜なのかというと、アイコンを作るにあたってとりあえず適当な画像が手元にないので、オートシェイプで済ませようと書き始めたところ、昼間ジュンク堂でたまたま立ち読みした本に、オートシェイプで桜の花びらを描く方法が載っていたので。

絵心がなくてもできる Wordで素敵なお絵描き

絵心がなくてもできる Wordで素敵なお絵描き

花びらの特徴的な形は一見難しそうに見えるけど、実はハートを挿入して頂点を上にずらすだけのもの。超簡単!たーのしー!
f:id:t-hom:20170212013144p:plain

それで桜を描いてそれに合うようにラベルでヘッダーに色をつけて、それに合う色は、、とやってるうちに気づいたら完全に女子だった。不覚。。

実際にアイコンを付ける方法

さて、アイコンを付けようと思ったはいいが、ひとつ困ったことがある。

基本的にはUserFormにImageコントロールを置いてLoadPictureする感じなんだけど、その画像は外部から持ってこなきゃいけない。するとExcelファイル単体で動作しなくなるので配布に難がある。

そこで、隠しシートに張り付けた画像を読み込むことを思いついた。ただ直接シートからLoadPictureはできないらしく、どうしても一回保存する必要がある。

Excelには幸い環境変数を取得するEnviron関数があるので、Temporaryフォルダを取得してそこに保存するようにしよう。

ここでまた技術的な課題があって、シェイプって直接保存できないんだ。
まぁ、いろいろ調べてたら、ChartObject(つまりグラフ)はExport命令でビットマップに書き出せるらしい。

何もデータを指定せずにグラフを挿入すると空の枠だけできるので、
f:id:t-hom:20170212013841p:plain

縦横比をそろえてからシェイプを張り付ける。
f:id:t-hom:20170212014142p:plain

グラフは標準で枠のサイズにあわせて中身が伸び縮みするので、最初に比率を合わせておかないとぐちゃっとなる。

それからグラフツールのレイアウトタブからグラフ名を「SakuraIcon」としておこう。
f:id:t-hom:20170212014704p:plain

最後にシート名を「Images」として準備完了。
最終的にシートは非表示にすれば良いけど、検証段階では表示させておく。

次にフォームをデザインしていく。

基本形はこちらで紹介したので説明を割愛。
thom.hateblo.jp

今回重要なのはImageコントロール

まずはフォームのアイコン表示位置に配置する。
今回説明用にイメージコントロールの背景色は黒にしたが、どのみち画像が入るので何色でも良い。
f:id:t-hom:20170212015438p:plain

それから今回イメージコントロールに設定するプロパティは以下の2つ。
f:id:t-hom:20170212015923p:plain

アイコンに枠線が入らないようにBorderStyleを0-fmBorderStyleNoneに設定し、画像が切れずにイメージコントロールに収まるようにPictureStyleModeを1-fmPictureStyleModeStretchに設定しておく。

最後にフォームにコードを書く。

Private Sub UserForm_Initialize()
    Dim chartObj As ChartObject
    Set chartObj = Sheets("Images").ChartObjects("SakuraIcon")
    chartObj.ShapeRange.Fill.ForeColor.RGB = Label1.BackColor
    chartObj.Chart.Export Environ("temp") & "\SakuraIcon.bmp"
    Image1.Picture = LoadPicture(Environ("temp") & "\SakuraIcon.bmp")
End Sub

まずImagesシートからSakuraIconグラフオブジェクトをchartObj変数に代入し、背景色をラベル1(今回はヘッダーのラベルがlabel1)と同じに設定している。こうするとヘッダーラベルの色を変更しても自動で画像の背景色が合うので桜の背景が透過的に見える。

次にグラフオブジェクトをテンポラリーフォルダーに保存し、それを読み込んでいるだけ。

bmpファイルを作る際にはグラフのサイズで出力されるため、実際に利用する際はImagesシートに置くグラフはアイコンと同じくらいのサイズまで縮小しておくと良い。ディスク容量の消費が減るというメリットもあるが、サイズが小さいほうが読み込み書き込み共に高速に行える。

Officeに用意されたImageMSOを利用する手も

さて、アイコンを利用したいだけなら自分で作らなくともImageMSOを利用する手もある。

コードを以下のように書き換えると、

Private Sub UserForm_Initialize()
    Image1.Picture = Application.CommandBars.GetImageMso("HappyFace", 80, 80)
End Sub

こんな感じで殺センセスマイリーが表示される。
f:id:t-hom:20170212022027p:plain

参考にしたのは以下のサイト。
www.ka-net.org

紹介されているのはボタンに表示させるコードだけどオブジェクトブラウザで調べたところボタンのPictureとイメージコントロールのPictureはどちらも同じ型だったのでそのまま流用できた。

ただこの方法だとOffice2010とOffice2013では見え方が違ってくる。
それによく見ると四隅に白色の背景が見える。つまりImageコントロールに読み込むと透過処理が出来ないってことかな。
手軽にアイコンを利用できる点はよさげなので、適宜活用していきたい。

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。