ショートプログラム

パズル  Visio2019に対応していますVisio2016に対応していますVisio2013に対応しています

VisioとVBAで作った初歩的なパズルを題材に、オブジェクト情報と画像の扱い方を紹介します。(2017.7.4更新)

まずはサンプルのテンプレートをダウンロードして下さい。ファイルはZIP形式で23kb程です。
ダウンロードした圧縮ファイルは解凍し、適当なフォルダへ入れて下さい。

※1)ファイルをご利用いただく際は、開発者モードとしてください。
    開発者モードの設定:「オプション」「詳細設定」「開発モードで実行する」にチェック

※2)ファイルを起動するとセキュリティに関する通知が表示されますので、「マクロを有効にする」を指定してください。

ダウンロードしたテンプレートを使って図面を開きます。図面が開いたら、メニューの「開発タブ内のマクロ」を選び、ダイアログで「パズル.VisioJP.NewGame」を選択して実行しファイル選択の画面でパズルに使用する画像を選択して下さい。



ファイルの選択後、変換アプリケーションが実行されます。
インポートが正常に終わるとパズルのピース数を入力するダイアログが表示されます。



ピース数が多いとVisioの動きが鈍くなるので、気をつけてください。

実行ボタンを押すとインポートした画像をピースに分解、適当な保護とグリッドの設定を行った後マクロは終了します。
用紙の左側にピース、右にインポートした元の画像です。元の画像を消したい場合はレイヤ設定で消して下さい。



本題

さて、Visioに取り込んだ画像の一部だけを表示したい場合、皆さんはどういう作業をしますか?
ペイントブラシで予め必要な部分を切り取っておくのも良いですが、修正のたびにペイントブラシに戻るのは辛いです。
今回の御題のパズルのように元画像は一つで必要に応じて部分的に表示したい場合もあるでしょう。
そんな場合にはVisioのトリミングツールを使います。

トリミングツールを使うと、画像の大きさを維持したままシェイプの大きさ(表示部分)を変更できたり、表示位置に合わせて画像を動かすことが出来ます。ではプログラムで制御するにはどうしたら良いのでしょう?

実はクリッピングの結果は、主にシェイプシートの図形セクションとオブジェクトセクションに反映されます。



ImgWidthとImgHeightは画像の大きさ、ImgOffsetXとImgOffsetYは表示画像がそれぞれPinX、PinYからどれくらい離れているかを現しています。

ちょっと値を変更してみましょう。


イメージの大きさをシェイプの25%、イメージの位置を右中央にしてみました

こんどは画像の大きさをそのままにして、表示位置だけを動かしてみました。



さぁ、これでパズルのピースを作る基本は理解できたと思います。
後は、元画像を必要なだけコピーしてオブジェクトセクションを編集すると、インポートした画像を単にコピーしただけでは、コピーした分の情報がファイルに残ってしまいます。
100kの画像をVisio上で10枚コピーしたら100k×10枚で1000kの図面ファイルになります。
では、どうしたら良いのでしょう?もう気が付いた方も居るでしょうけど、ピースの各シェイプは表示位置ImgOffsetX(Y)だけが異なるだけなのでマスタシェイプにしてしまえば良いのです。

マスタシェイプから派生した(つまりコピー)したシェイプは、マスターシェイプと異なる部分の情報だけを持ちます。大雑把に言えばマスタシェイプから100個のシェイプを図面上にドロップしても各シェイプはPinX(Y)の情報だけを保持しているだけで済むのです。



VBAマクロの簡単な説明

ImportImage()でパズルの元画像をVisioに読み込んでマスタシェイプ化します。
次にReSizeDocument()で元画像とVisioの図面用紙サイズを一致させます。
SetGameForm1でピースの数を決定したら、グリッドをピース数に合わせます。
実行ボタンを押すとピースをランダムに配置しながら各種保護を掛けます。
以下ポイントの説明です。

DoCmdメソッド

ImportImage()のVisio.Application.DoCmd (visCmdFileImport)ですが、これはDoCmdメソッドを使って元画像を読み込むダイアログを表示しています。
Visioのプルダウンから「挿入/図」と操作したのと同じ結果が得られます。
DoCmdはVBA以外にもシェイプシートでも使うことが出来ます。例えばカスタムプロパティ画面を呼び出すにはDoCmd(1312)を使います。

マスタシェイプ化

ImportImage()で読み込んだ直後の画像(WMFに変換されている)はマスタシェイプ化されていないので、自図面にドロップし直してマスタシェイプ化します。図面上に残った残骸は消します。

シェイプの複写を抑制

ピースが複写されたら困ります。
SetGameForm1のCommandButton1_Clickでピースに対して各種保護を掛けていますが、複写を禁止するプロパティが有りません。
で、私の場合はDropイベントが発生した時に自分自身を削除する命令DoCmd(1023)を付け加えました。ただ削除自体を禁止しているので自分を削除する前にLockDeleteプロパティを無効にしています。

wmfObj.Cells("EventDrop").Formula = "SETF(" & """" &"LockDelete" & """" &",0)+DoCmd(1023)"

シェイプシートのセルでは命令と命令の間に+を入れることで複数の命令が記述できます。限度は有りますが・・・

このページの先頭へ