学生でも社会人でも分かる!!初めてのプログラミング入門 第6回 分岐
2017/02/15
目次
↑ ↑ ↑
画像を半分の大きさにリサイズするプログラムの更なる改造 #1
今回は前回改造した画像を半分の大きさにリサイズするプログラムを更に改造することを考えてみたいと思います。
このプログラムは現状でも動くものにはなっていますが、まだ改良すべき点は残っているのです。
それはどこかと申しますと、このプログラムは画像ファイル以外に対しても操作が可能になっているという点です。
このプログラムは画像を半分の大きさにリサイズするものですが、それにも拘らず、画像以外のファイルを「エクスプローラ」で選択した状態で動かすことが可能であり、もしそうした場合には、画像ではないファイルに対して画像のリサイズの場合と全く同じ操作を行おうとしてしまいます。
たとえば、画像ファイルではなくテキストファイルを選択してこのプログラムを動かした場合にどのようなことが起こるかを実際に試してみましょう。
HiMacroExの画面で前回改造した画像を半分の大きさにリサイズするプログラムを開き、「エクスプローラ」で適当なテキストファイルを選択し、HiMacroExの「再生」ボタンを押します。
すると、私の環境では「メモ帳」が起動し、「エクスプローラ」で選択していたテキストファイルが開かれました。そして、それ以外のことは何も起こっていないように思えます。起動した「メモ帳」が閉じられることもありません。
勿論皆さんのパソコンではもっと別のことが起こったかもしれません。
しかし、意味のないことが起こったということには変わりありません。
そもそもこのプログラムは画像の大きさを半分にするプログラムなのですから、テキストファイルに対して何か意味のあることを行えるはずがないのは当然と言えば当然です。
しかし、それならせめて、画像ファイル以外が選択された状態でプログラムが実行された際には、ユーザに対して「画像ファイルを選択してください」というようなメッセージを表示した方が良いのではないでしょうか?
あるいは、最低でも、何もしない(意味のない余計なことは何もしない)ようにすべきです。つまり、意味もなく「メモ帳」の画面を開いたりなどはするべきではありません。
今回は前回のプログラムを更に改造してユーザが画像ファイル以外に対してリサイズを行おうとした場合にはエラーメッセージを表示するようにしたいと思います。
しかし、一体、どのような命令があれば所望の動作を実現できるのでしょうか?
今やりたいのは、
- 選択されているのが画像ファイルなら画像のリサイズを行う。
- 選択されているのが画像ファイル以外なら適切なエラーメッセージを表示する。
ということです。
結局のところ、これは、選択されているファイルの種類に応じてパソコンに対する操作を変えるということです。
そして、パソコンに対する操作というのはHiMacroExの場合命令として記述するのですから、これはつまり、選択されているファイルの種類に応じて実行する命令を変えるということです。
要は、ある場合はこの命令を実行して、別の場合は別の命令を実行するというようなことがやりたい訳です。
実は、HiMacroExにはこのようなことを実現するための命令がちゃんと用意されています。
分岐命令
プログラムを実行した際に状況に応じて実行する命令を変えるには分岐命令というものを使用します。
何故分岐命令と言うのかというと、状況に応じて実行する命令を変えるということは、予めプログラム中には様々な状況に対する命令を書いておき、プログラムを実行した際にはプログラム中に書かれている様々な状況で実行する命令の中からどれか1つ実際に実行する命令を選び出すことになるからです。
それはある意味、分岐命令があるところまではプログラムに書かれている命令を上から下に順番に実行してきたのが、正に分岐命令のところでその時の状況に応じて命令の実行の流れが幾つかに分かれるということです。
そのため、分岐という言葉を使ってそれを表している訳です。
さて、またちょっと別の観点からの話になりますが、HiMacroExは分岐命令を使って分岐を行う際にクリップボードの中身に基づいて分岐を行います。
皆さんはクリップボードという言葉をご存知でしょうか?
もしかしたら、初めて聞く方が多いかもしれません。しかし、皆さんはパソコン上での様々な作業でクリップボードを日常的に使用しています。
パソコンにはコピーとか切り取りとか貼り付けという機能がありますが、実は、これは正にクリップボードを使って実現されています。
クリップボードというのは、実は、パソコンでコピーや切り取りを行った際にコピー、あるいは、切り取りされたデータ(内容)が記憶される場所のことなのです。
なので、パソコンでコピーや切り取りを行った際には、コピーや切り取りされたデータというのはまずクリップボードに記憶されます。
そして、クリップボードに何かデータが記憶されている状態で今度は貼り付けを行えば、その記憶されているデータが実際に貼り付けられるということになります。
このように、クリップボードというものを介して、パソコンのコピーや切り取りや貼り付けの機能は動いているのです。
そして、HiMacroExはこのクリップボードに記憶されているデータを使って分岐を行います。
ただし、分岐を行う前にはHiMacroExに対してクリップボードに記憶されているデータを取り出すように命令しなければなりません。
そして、実際に分岐を行う際には、HiMacroExはクリップボードから取り出したデータがプログラム中の専用の命令に記載されているデータと一致するかを調べていき、もし一致する場合はその専用の命令の直後に書かれている命令のみを実行します。逆に、一致しない場合はその命令の直後に書かれている命令は実行しません。
HiMacroExはこのような形でプログラム中で分岐を書くことを可能にしています。
それでは、より具体的な命令の書き方を見ていきましょう。前回の繰り返しの場合と同じく、HiMacroExでは分岐も複数の命令を組み合わせないと記述することができません。
まず、プログラムで分岐を行うにはHiMacroExに対してクリップボードに記憶されているデータを取り出すように命令しなければならないのでした。
これを行うにはGetClip
という命令を使用します。
命令
GetClip
- クリップボードに記憶されているデータを分岐のために取り出す。
この命令を分岐命令の前に書いておけばクリップボードに記憶されているデータが取り出され、そのデータをその後の分岐で使用することができるようになります。
ということは、そもそもこのGetClip
命令を実行する前にクリップボードに何か分岐の基準となるデータが記憶されていなければならないということになります。
ですから、順番としては、最初にクリップボードに分岐の基準となるデータを記憶させて、次にGetClip
命令を使ってHiMacroExにクリップボードに記憶されているデータを取り出させ、最後に分岐命令を使って取り出したデータを基に実際に分岐を行うという流れになります。
なお、クリップボードに分岐の基準となるデータを記憶させるのはどのように行えば良いのかと疑問に思われるかもしれませんが、その部分は皆さんが常日頃コピーや切り取りを行っているのと同じ操作をプログラム外でするか、それをそのままプログラム化すれば良いだけです(実を言うと、HiMacroExにはクリップボードを直接操作するための命令も用意されているのですが、それらの命令については別の機会に書くことにします)。
ですから、何らかのデータに基づいて分岐を行う際のデータの流れは下のようになります。
ちょっと煩雑ですが、このような手順を踏むことで分岐を行うための準備を整えることができます。
そして、実際にプログラムで分岐を行うにはプログラム中の分岐を行いたい場所で<Switch>
という命令を記述します。
これにより、HiMacroExはこの命令から分岐が始まることを理解することができます。
そして、次に、クリップボードから取り出したデータとの比較を行うデータを記載するための命令を記述します。
この命令は<Case データ>
という風に記述します。このデータ
というのが正にクリップボードから取り出したデータとの比較を行うデータを表しています。なので、データ
の部分にはデータ
とそのまま入力するのではなく、具体的なデータの内容を書かなければなりません。
たとえば、クリップボードから取り出したデータの内容がkuma
である場合に実行する命令を記述したい場合には<Case kuma>
という命令をまず記述します。
そして、この命令を記述した直後に実際に実行する命令を記述します。
実行する命令は複数でも構いません。すなわち、プログラムの中で複数行に亘っても構いません。
そして、実行する命令を書き終わった場合にはまた別の<Case データ>
命令を記述していくことができます。つまり、クリップボードから取り出したデータが別のデータであった場合のための命令を書くこともできます。
そして、最後に、クリップボードから取り出したデータがどの<Case データ>
命令のデータにも当て嵌まらないということも考えられます。
HiMacroExにはそのような場合のみに実行する命令を記述するための命令も用意されており、これには<Default>
という命令を使用します。そして、<Default>
命令を記述した後にクリップボードから取り出したデータがどの<Case データ>
命令のデータにも当て嵌まらない場合に実行したい命令を記述します。
このようにして<Case データ>
命令や<Default>
命令を使うことにより、HiMacroExはどのような場合にどの命令を実行しなければならないかを理解することができます。
そして、分岐に関する全ての命令を書き終わったら最後に</Switch>
という命令を記述します。
これにより、HiMacroExはこの命令までで分岐が終わることを理解することができます。
プログラム中で分岐を行うのは前回の繰り返しよりも更に複雑になってきますが、ここまでの説明で分岐を行うための命令の書き方が概ね分かっていただけたかと思います。
以後、<Switch>
命令を分岐開始命令、</Switch>
命令を分岐終了命令、<Case データ>
命令を場合分け命令、<Default>
命令をデフォルト命令と呼ぶことにしたいと思います。
命令
<Switch>
- 分岐を開始する。
命令
</Switch>
- 分岐を終了する。
命令
<Case データ>
データ
がクリップボードから取り出したデータと一致する場合に次の命令から次の場合分け命令やデフォルト命令や分岐終了命令の前までの命令を順番に実行する。
命令
<Default>
- どの場合分け命令の次の命令も実行されなかった場合に次の命令から分岐終了命令の前までの命令を順番に実行する。
分岐を含む典型的なプログラムは下のようになります。
プログラムの一部
-
・・・
GetClip
- クリップボードに記憶されているデータを分岐のために取り出す。
<Switch>
- 分岐を開始する。
<Case foo>
- クリップボードから取り出したデータが
foo
である場合に次の命令から次の場合分け命令の前までの命令を順番に実行する。 <Case bar>
- クリップボードから取り出したデータが
bar
である場合に次の命令から次のデフォルト命令の前までの命令を順番に実行する。 <Default>
- クリップボードから取り出したデータが
foo
でもbar
でもない場合に次の命令から分岐終了命令の前までの命令を順番に実行する。 </Switch>
- 分岐を終了する。
・・・
・・・
・・・
・・・
・・・
上のプログラムのfoo
やbar
というのは適当なデータの代わりに使っているだけの文字列であり特に意味はありません。プログラミングでは適当なデータや名前を表すためにfoo
やbar
のような文字列をよく使います。
最後に、分岐命令について1つ補足しておかなければならないことがあります。
それはHiMacroExでは分岐の中で更に分岐を行うことはできないということです。
つまり、HiMacroExでは<Switch>
命令と</Switch>
命令の間に別の<Switch>
命令を入れることはできません。
ちなみに、これはHiMacroExのプログラミング言語に特有の特徴であって、他の一般的なプログラミング言語については、分岐の中で更に分岐を行うことも可能となっているものが殆どです。
実を言うと、HiMacroExでも、分岐の中で分岐を行うことは完全に不可能という訳ではありません。ただし、HiMacroExでそのような分岐を行うにはやや込み入った迂遠なテクニックを用いる必要がありますので、それはこの連載記事のもう少し後の方で紹介することにしたいと思います。
メッセージ表示命令
分岐の行い方については分かりましたが、それでは、メッセージはどのように表示すれば良いのでしょうか?
実に用意周到なことに、HiMacroExにはメッセージを表示するための命令も最初から用意されています。
それはMsgBox メッセージ
という命令です。ここでメッセージ
というのは実際に表示するメッセージの文章を表しています。なので、メッセージ
の部分にはメッセージ
とそのまま入力するのではなく、具体的なメッセージを記入しなければなりません。
命令
MsgBox メッセージ
- メッセージボックスを表示する。
たとえば、MsgBox これはメッセージです。
という命令をプログラムに記述し、実行すると、下のようなメッセージボックスが表示されます。
そして、このメッセージボックスが表示されている間はプログラムの実行は止まり続けます。つまり、メッセージボックスが表示されている間はメッセージを表示する命令の次以降の命令が実行されることはありません。
そして、逆に、このメッセージボックスの「OK」ボタンをクリックすれば、このメッセージボックスは閉じられ、プログラムの実行が再開されることになります。その場合、メッセージを表示する命令の次以降の命令が順番に実行されていくことになります。
このように、ユーザに対して何かメッセージを出したい場合には、このメッセージボックスを表示する命令を使用すると便利です。
画像を半分の大きさにリサイズするプログラムの更なる改造 #2
さて、分岐命令とメッセージ表示命令について解説して、ようやっと画像を半分の大きさにリサイズするプログラムを更に改造するための準備が整いました。
まず、前回改造したプログラムを再掲しておきます。
プログラム3(プログラム1の改造)
- 1
Application
Application
キーを押したことにする。- 2
H
H
キーを押したことにする。- 3
<r 5>
- 繰り返しを開始する。5回繰り返す。
- 4
↓
↓
キーを押したことにする。- 5
</r>
- 繰り返しが完了していない場合には繰り返しの最初の命令に戻る。完了した場合には次の命令に進む。
- 6
Enter
Enter
キーを押したことにする。- 7
1000
1000
ミリ秒待機する。- 8
LCtrl Down
- 左
Ctrl
キーを押したままでいることにする。 - 9
W
W
キーを押したことにする。- 10
LCtrl Up
- 左
Ctrl
キーを離したことにする。 - 11
Tab
Tab
キーを押したことにする。- 12
5
5
キーを押したことにする。- 13
0
0
キーを押したことにする。- 14
Enter
Enter
キーを押したことにする。- 15
LCtrl Down
- 左
Ctrl
キーを押したままでいることにする。 - 16
S
S
キーを押したことにする。- 17
LCtrl Up
- 左
Ctrl
キーを離したことにする。 - 18
LAlt Down
- 左
Alt
キーを押したままでいることにする。 - 19
F4
F4
キーを押したことにする。- 20
LAlt Up
- 左
Alt
キーを離したことにする。
それから、今一度どのような改造を行いたかったかを書いておきましょう。
- 選択されているのが画像ファイルなら画像のリサイズを行う。
- 選択されているのが画像ファイル以外なら適切なエラーメッセージを表示する。
このようにして、画像ファイル以外が選択された状態でプログラムが実行された場合にもユーザにとって分かりやすい(ユーザフレンドリーな)動きをするようにしたかったのでした。
上の箇条書きから分かるように、今やらなければならないのは選択されているのが画像ファイルであるかどうかによってプログラム中で分岐を行うということです。
しかし、どうすれば選択されているファイルが画像ファイルなのかどうかを見分けることができるのでしょうか?
よく考えてください、パソコンにおいてファイルの種類というのは何で決まっていたでしょうか?
そうです、拡張子です(拡張子が何のことだか分からない方はごめんなさい。この連載記事はパソコンをある程度使いこなしている方を対象としていますので、拡張子については既に知っていることを前提にしています。拡張子について知らない方は、お手数ですが各自で調べてみてください)。
拡張子というのはファイル名の後ろの方に付いている.
から始まる3文字程度の文字列でした。
たとえば、「エクスプローラ」で適当なフォルダを開けば、どんなファイルにも拡張子が付いているのが見て取れます(稀に拡張子が付いていないファイルもありますが)。
ちなみに、「エクスプローラ」で拡張子が表示されていない場合には、「表示」メニューの「ファイル名拡張子」という項目をチェックすると表示されるようになります。
上の画像の場合、ファイルには.jpg
、.zip
、.txt
などの拡張子が付いています。
そして、この拡張子こそが正にファイルの種類を表しているのでした。
たとえば、.jpg
という拡張子はJPEGという形式で保存されている画像ファイルを表していますし、.zip
という拡張子は圧縮されたファイルを表していますし、.txt
という拡張子はテキストファイルを表しています。
ウィンドウズも基本的にはファイルの拡張子を見てファイルの種類を判断しています。
しかし、勿論、ファイルの拡張子とファイルの実際の中身の種類が合っていないという場合もなくはないです。
たとえば、ファイルの拡張子は.txt
になっているのに実際はテキストファイルではないというようなこともなくはないです。
実際、「エクスプローラ」で画像ファイルの拡張子を.txt
に変更するというようなことも簡単に出来てしまいます。
そして、実際に画像ファイルの拡張子を.txt
に変更してみると、ウィンドウズでさえも本当は画像ファイルであるはずのファイルをテキストファイルと判断してしまうことが分かります。
たとえば、上の画像の01.jpg
という名前のファイルを01.txt
という名前に、つまり、あたかもテキストファイルであるかのように変更してみると、実際に「エクスプローラ」でもそのファイルはテキストファイルであると見做されます。
勿論このファイルは本当は画像ファイルなのであってテキストファイルでは断じてありません。
結局、ファイルの本当の種類を知るにはファイルの中身を調べてみるしかないということです。
しかし、ウィンドウズでさえもファイルの種類を判断するのにファイルの中身までは見ずに拡張子だけを見ているのですから、今私たちが作っている画像を半分の大きさにリサイズするプログラムに関しても、ファイルの種類を判断するにはファイルの拡張子を見るだけで十分でしょう。
そうすると、ファイルの拡張子と実際のファイルの中身が合っていなかったらプログラムがエラーを起こす可能性があるということですが、それはもう仕方のないことです。
プログラムを作成する場合には、どのようなエラーの可能性があるのかを十分に把握することはとても重要ですが、全ての可能性に対処するのではなく時には割り切ることも重要なのです。
という訳で、選択されているファイルが画像ファイルかどうかを見分けるのはファイルの拡張子を見て行うことにしましょう。
それでは、次に、プログラムでファイルの拡張子を読み取るにはどうすれば良いのでしょうか?
色々な方法が考えられるかもしれませんが、単純な方法で良いのです。どんな方法でも、ファイルの拡張子の部分が取得できさえすれば良いのです。
まず、このプログラムを実行する時のことを思い出してください。このプログラムは「エクスプローラ」で操作の対象となるファイルが選択されていることを前提としているのでした。
ということは、プログラムの実行を開始した直後に、「エクスプローラ」でファイルの名前変更を行うための操作を行うようにプログラムを書いておけば下の画面のようにプログラムの実行の際に選択されていたファイルの名前が変更できる状態にすることができるはずです。
最初の状態ではファイル名の拡張子を除いた部分が選択されていますが、ここから更にキーボードのEnd
キーを押せばカーソルをファイル名の最後に持っていくことができます。
そして、ここから更にShift
キーを押しながら←
キーを4回連続で押したらどうなるでしょうか?
ファイル名の後ろから4文字が選択できます。
拡張子というのは基本的には4文字ですから、これはつまり、ファイル名の拡張子の部分が選択できたということです。
そして、この状態でコピーを行えばファイル名の拡張子の部分のみをコピーすることができます。つまり、上で解説したようにクリップボードにファイル名の拡張子の部分のみが記憶されることになります。
ここまで来れば、上で書いたように、GetClip
命令と分岐命令を使ってプログラムの中で分岐を行うことができるはずです。
そして、今クリップボードに記憶されているのは「エクスプローラ」で選択されているファイルの拡張子の部分なのですから、実際にGetClip
命令と分岐命令を使って分岐を行うと、このデータに基づいて分岐が行われることになります。
つまり、「エクスプローラ」で選択されているファイルの拡張子に応じてプログラムの中で別々の命令を実行することができるということになります。
どうやらこのやり方で良さそうです。
ですので、これをプログラム化しましょう。
上で説明した、ファイル名の拡張子のみをコピーするための操作を箇条書きにすると下のようになります。
F2
キーを押す。End
キーを押す。Shift+←
キーを押す(Shift
キーを押しながら←
キーを押す)。Shift+←
キーを押す。Shift+←
キーを押す。Shift+←
キーを押す。Ctrl+C
キーを押す。Esc
キーを押す。
もしかしたら「エクスプローラ」でキーボードのみを使ってファイル名を変更したことが今まで全くない方もおられるかもしれませんので簡単に上の操作を説明しますと、「エクスプローラ」でファイルを選択した状態でF2
キーを押すと選択したファイルの名前を変更することができる状態に移行することができます。
そして、End
キーやShift+←
キーを使ってファイル名の拡張子の部分のみを選択してCtrl+C
キーを押せば、Ctrl+C
キーはコピーを行うためのショートカットキーですから、ファイル名の拡張子の部分のみをコピーすることができます。
そして最後に、ファイル名の変更をキャンセルするためにEsc
キーを押せば、万事操作完了という訳です。
ですから、まずは今改造しようとしていた画像を半分の大きさにリサイズするプログラムの一番初めでこの操作をそのままプログラム化してやれば良いのです。
実際にプログラム化すると下のようになります。
プログラム5(プログラム3の改造、作成中1)
- 1
F2
F2
キーを押したことにする。- 2
End
End
キーを押したことにする。- 3
<r 4>
- 繰り返しを開始する。4回繰り返す。
- 4
LShift Down
- 左
Shift
キーを押したままでいることにする。 - 5
←
←
キーを押したことにする。- 6
LShift Up
- 左
Shift
キーを離したことにする。 - 7
</r>
- 繰り返しが完了していない場合には繰り返しの最初の命令に戻る。完了した場合には次の命令に進む。
- 8
LCtrl Down
- 左
Ctrl
キーを押したままでいることにする。 - 9
C
C
キーを押したことにする。- 10
LCtrl Up
- 左
Ctrl
キーを離したことにする。 - 11
Esc
Esc
キーを押したことにする。- 12
Application
Application
キーを押したことにする。
・・・
赤記した部分が今回追加した部分です。また、繰り返し命令が使える部分は繰り返し命令を使って書いています。
さて、ここまでの改造で分岐命令で必要になるデータをクリップボードに記憶するところまでは出来ました。
もう一度上の図を再掲しましょう。
つまり、この図の1つ目から2つ目の項目に掛けてはプログラム化することができましたので、次はGetClip
命令を使ってHiMacroExにクリップボードに記憶したデータを取り出させます。
プログラム5(プログラム3の改造、作成中2)
-
・・・
- 11
Esc
Esc
キーを押したことにする。- 12
GetClip
- クリップボードに記憶されているデータを分岐のために取り出す。
- 13
Application
Application
キーを押したことにする。
・・・
これで、後は分岐命令を使えば選択しているファイルの拡張子を基に分岐が行えるはずです。
それでは、次に、どのように分岐命令を書くかということですが、まず、上で書いたように分岐部分を分岐開始命令と分岐終了命令で囲むのは良いとして、次に、今分岐は拡張子で分岐しようとしているのですから、場合分け命令のデータ
の部分には具体的な拡張子を書けば良いということです。
まず、拡張子が画像ファイルの拡張子である場合に実行する命令を書いていきたいのですから、その場合の場合分け命令のデータ
の部分には具体的な画像ファイルの拡張子を書けば良い訳です。
画像ファイルの拡張子はファイルに保存されている画像の形式によって変わり、.bmp
、.jpg
、.png
、.gif
など幾つかあります。
他にもマイナーな画像ファイルの拡張子は幾つもあるのですが、マイナーなものまで考慮するのは大変ですので今回はメジャーなものだけを考えることにしましょう。ということで、今回は上の4つの拡張子のみを画像ファイルの拡張子と考えることにします。
ですから、プログラムには上の4つの拡張子に対して1つずつ場合分け命令を記述し、更に、それぞれの場合分け命令の直後に実行したい命令、すなわち、今回の場合は画像を半分の大きさにリサイズするための命令を記述すれば良いということになります。
つまり、今回の場合は、選択されているファイルが画像ファイルであるかどうかに基づいて別々の操作を行いたいのであり、画像ファイルの種類毎に別々の操作を行いたい訳ではありませんから、それぞれの場合分け命令の直後には全て同じ、画像を半分の大きさにリサイズするための命令列を記述するということになります。
そして、拡張子が上の4つのどれかである場合に実行する命令を記述し終わったら、最後に、拡張子が上の4つのどれでもない場合に実行する命令を記述しなければなりません。
つまり、場合分け命令のどれにも当て嵌まらなかった場合の命令を書くのですから、これにはデフォルト命令を使います。
という訳で、プログラム中の分岐命令の部分の概形は下のようになります。
プログラムの概形
-
・・・
<Switch>
- 分岐を開始する。
<Case .bmp>
- クリップボードから取り出したデータが
.bmp
である場合に次の命令から次の場合分け命令の前までの命令を順番に実行する。 <Case .jpg>
- クリップボードから取り出したデータが
.jpg
である場合に次の命令から次の場合分け命令の前までの命令を順番に実行する。 <Case .png>
- クリップボードから取り出したデータが
.png
である場合に次の命令から次の場合分け命令の前までの命令を順番に実行する。 <Case .gif>
- クリップボードから取り出したデータが
.gif
である場合に次の命令から次のデフォルト命令の前までの命令を順番に実行する。 <Default>
- クリップボードから取り出したデータが
.bmp
でも.jpg
でも.png
でも.gif
でもない場合に次の命令から分岐終了命令の前までの命令を順番に実行する。 </Switch>
- 分岐を終了する。
・・・
・・・
・・・
・・・
・・・
・・・
このようにすれば、プログラムを
- 選択しているファイルの拡張子が
.bmp
である場合 - 選択しているファイルの拡張子が
.jpg
である場合 - 選択しているファイルの拡張子が
.png
である場合 - 選択しているファイルの拡張子が
.gif
である場合 - 選択しているファイルの拡張子がそれ以外である場合
の5つの場合に分岐することができます。
そして、上でも書きましたが、最初の4つの場合には画像を半分の大きさにリサイズする操作を行うようにし、最後の1つの場合にはエラーメッセージを書いたメッセージボックスを表示するようにすれば良いということになります。
エラーメッセージには「画像ファイルを選択してください。」と表示することにしましょう。
ですから、完全なプログラムは下のようになります。
プログラム5(プログラム3の改造、完成(?))
- 1
F2
F2
キーを押したことにする。- 2
End
End
キーを押したことにする。- 3
<r 4>
- 繰り返しを開始する。4回繰り返す。
- 4
LShift Down
- 左
Shift
キーを押したままでいることにする。 - 5
←
←
キーを押したことにする。- 6
LShift Up
- 左
Shift
キーを離したことにする。 - 7
</r>
- 繰り返しが完了していない場合には繰り返しの最初の命令に戻る。完了した場合には次の命令に進む。
- 8
LCtrl Down
- 左
Ctrl
キーを押したままでいることにする。 - 9
C
C
キーを押したことにする。- 10
LCtrl Up
- 左
Ctrl
キーを離したことにする。 - 11
Esc
Esc
キーを押したことにする。- 12
GetClip
- クリップボードに記憶されているデータを分岐のために取り出す。
- 13
<Switch>
- 分岐を開始する。
- 14
<Case .bmp>
- クリップボードから取り出したデータが
.bmp
である場合に次の命令から次の場合分け命令の前までの命令を順番に実行する。 - 15
Application
Application
キーを押したことにする。- 16
H
H
キーを押したことにする。- 17
<r 5>
- 繰り返しを開始する。5回繰り返す。
- 18
↓
↓
キーを押したことにする。- 19
</r>
- 繰り返しが完了していない場合には繰り返しの最初の命令に戻る。完了した場合には次の命令に進む。
- 20
Enter
Enter
キーを押したことにする。- 21
1000
1000
ミリ秒待機する。- 22
LCtrl Down
- 左
Ctrl
キーを押したままでいることにする。 - 23
W
W
キーを押したことにする。- 24
LCtrl Up
- 左
Ctrl
キーを離したことにする。 - 25
Tab
Tab
キーを押したことにする。- 26
5
5
キーを押したことにする。- 27
0
0
キーを押したことにする。- 28
Enter
Enter
キーを押したことにする。- 29
LCtrl Down
- 左
Ctrl
キーを押したままでいることにする。 - 30
S
S
キーを押したことにする。- 31
LCtrl Up
- 左
Ctrl
キーを離したことにする。 - 32
LAlt Down
- 左
Alt
キーを押したままでいることにする。 - 33
F4
F4
キーを押したことにする。- 34
LAlt Up
- 左
Alt
キーを離したことにする。 - 35
<Case .jpg>
- クリップボードから取り出したデータが
.jpg
である場合に次の命令から次の場合分け命令の前までの命令を順番に実行する。 - 56
<Case .png>
- クリップボードから取り出したデータが
.png
である場合に次の命令から次の場合分け命令の前までの命令を順番に実行する。 - 77
<Case .gif>
- クリップボードから取り出したデータが
.gif
である場合に次の命令から次のデフォルト命令の前までの命令を順番に実行する。 - 98
<Default>
- クリップボードから取り出したデータが
.bmp
でも.jpg
でも.png
でも.gif
でもない場合に次の命令から分岐終了命令の前までの命令を順番に実行する。 - 99
MsgBox 画像ファイルを選択してください。
- メッセージボックスを表示する。
- 100
</Switch>
- 分岐を終了する。
・・・(15行目から34行目までと同じ)
・・・(15行目から34行目までと同じ)
・・・(15行目から34行目までと同じ)
完全なプログラムとは書きましたが、プログラムの全ての行を掲載するのは紙幅の関係上難しいので、36行目から55行目まで、57行目から76行目まで、78行目から97行目までの部分は省略させていただきました。これらの部分は15行目から34行目までの部分と全く同じになります。
画像を半分の大きさにリサイズするプログラムの更なる改造 #3
さて、前のセクションでプログラムを改造しましたが、非常に長ったらしいプログラムになってしまいました。
前回のプログラムと比べてそれほど動作自体は変わっていないのに、前回のプログラムが20行で上のプログラムが100行ですから、何と5倍もの長さになってしまっています。
しかし、これには明確な原因があります。
上のプログラムは選択しているファイルの拡張子に応じて5つの場合に分岐するようになっていましたが、その内の4つの場合は全く同じ操作を実行する全く同じ命令を記述していました。
つまり、上のプログラムでは分岐を実現するために前回作成したプログラムを4箇所でそのままコピーしてしまっているため、前回のプログラムと比べて何倍もの長さのプログラムになってしまったのです。
前回も似たようなことを書きましたが、プログラムを書く時には同じ内容を何度も繰り返し書くべきではありません。
大事なことなので何度でも繰り返し書きますが(プログラミングとは真逆で、このような、何らかの事柄を詳細に解説する記事においては大事なことを何度も繰り返し書くのは逆に重要なのです。勿論プログラミングでは絶対にやってはいけません)、プログラムの中に同じ内容が何度も出てくると、プログラムが非常に冗長になり、プログラムが非常に分かりにくいものになってしまいます。それは上のプログラムを見れば実感できるのではないでしょうか?
それから、繰り返し記述した部分の内容を変更しなければならなくなった時が殊更大変です。たとえば、繰り返し記述した部分にバグが含まれていたことが判明し、修正をしなければならなくなった場合には、繰り返し記述した部分を全て1つずつ修正していく羽目になります。
ですから、同じ内容が何度も繰り返し書かれていないプログラムこそが良いプログラムなのです。そういう意味では上のプログラムは非常に悪いプログラムだということです。
別に上のプログラムがおかしな動きをする、つまり、上のプログラムにバグがあるという訳ではないのですが、プログラムはバグがなければそれで良いという訳ではないのです。正しく動くプログラムの中にも、更に、良い書き方がされているプログラムと悪い書き方がされているプログラムの2つがあるのです。
そして、悪いプログラムを悪いプログラムのまま放置しておく訳にはいきません。それは様々な弊害をもたらし、最悪の場合プログラム作成自体を破綻させてしまう可能性さえ孕んでいるのです(今はまだ実感できないかもしれませんが、プログラムが大規模になればなるほどそのような危険性が顕著になってきます。ちなみに、悪い書き方がされているプログラムを、プログラムの動作自体は変えないで良い書き方に書き換えることをリファクタリングと言います)。
稀に、どうしても悪い書き方にならざるを得ないというプログラムもなくはないですが、極力悪い書き方は避けるべきです。
そして、特に上のプログラムの場合は少しの工夫で良いプログラムに書き換える、つまり、リファクタリングすることができます。
ですので、今度はこのリファクタリングを実際に行ってみましょう。
とは言え、どうすれば良いのでしょうか?
それには、少し考え方を変える必要があります。
これまでの考え方をもう一度再掲しましょう。
- 選択されているのが画像ファイルなら画像のリサイズを行う。
- 選択されているのが画像ファイル以外なら適切なエラーメッセージを表示する。
このように、選択されているのが画像ファイルである場合とそうでない場合にそれぞれで実行する操作を考えていたのでした。
しかし、実は、これと同じことを実現するのにはもう1つの考え方があるのです。それは下のような考え方です。
- 選択されているのが画像ファイルなら取り敢えずは何もしない。逆に、選択されているのが画像ファイル以外なら適切なエラーメッセージを表示して、プログラムの実行を中断する。その後で、画像のリサイズを行う。
どういうことか分かるでしょうか?
つまり、プログラムが最後まで実行された場合には必ず画像がリサイズされるものとしてしまいます。
その上で、選択されているのが画像ファイル以外である場合にはプログラム自体の実行を途中で止めてしまうのです。
このようにしてもやりたかったことは実現できます。
そして、このようにすると、分岐を行い、分岐が完全に終わった後で(つまり、分岐から「合流」した後で)画像のリサイズを行いますので、結果として画像のリサイズを行うための命令は1回しか書かなくて良いということになります。
上のプログラムの場合はそれぞれの分岐の中で画像のリサイズを行うための命令を書かなければならなかったので同じ命令列を4回も書く羽目になりましたが、分岐の外で書くことができれば1回しか書かなくて済むのです。
そして、本丸の操作(今回の例で言えば、画像をリサイズする操作)の命令を分岐の外で書けるようにするための考え方が、本丸の操作を行いたくない場合にはその前にプログラムの実行自体を中断してしまうという考え方なのです。
しかし、プログラムの実行を中断するのはどうすれば良いのでしょうか?
実は、HiMacroExにはプログラムの実行を中断するための命令も用意されています。HiMacroExは中々に便利が良いソフトなのです。
そして、それは<pause>
という命令です。
命令
<pause>
- プログラムの実行を中断する。
プログラムの中にこの<pause>
命令を書いておけば、プログラムの実行においてこの命令を実行したところでプログラムの実行が中断することになります。
正に上の用途で使用できる命令だということです。
それでは、この命令を使って上のプログラムを良いプログラムにリファクタリングしてみましょう。
そうすると、下のようになります。
プログラム5(プログラム3の改造、完成)
- 1
F2
F2
キーを押したことにする。- 2
End
End
キーを押したことにする。- 3
<r 4>
- 繰り返しを開始する。4回繰り返す。
- 4
LShift Down
- 左
Shift
キーを押したままでいることにする。 - 5
←
←
キーを押したことにする。- 6
LShift Up
- 左
Shift
キーを離したことにする。 - 7
</r>
- 繰り返しが完了していない場合には繰り返しの最初の命令に戻る。完了した場合には次の命令に進む。
- 8
LCtrl Down
- 左
Ctrl
キーを押したままでいることにする。 - 9
C
C
キーを押したことにする。- 10
LCtrl Up
- 左
Ctrl
キーを離したことにする。 - 11
Esc
Esc
キーを押したことにする。- 12
GetClip
- クリップボードに記憶されているデータを分岐のために取り出す。
- 13
<Switch>
- 分岐を開始する。
- 14
<Case .bmp>
- クリップボードから取り出したデータが
.bmp
である場合に次の命令から次の場合分け命令の前までの命令を順番に実行する。 - 15
<Case .jpg>
- クリップボードから取り出したデータが
.jpg
である場合に次の命令から次の場合分け命令の前までの命令を順番に実行する。 - 16
<Case .png>
- クリップボードから取り出したデータが
.png
である場合に次の命令から次の場合分け命令の前までの命令を順番に実行する。 - 17
<Case .gif>
- クリップボードから取り出したデータが
.gif
である場合に次の命令から次のデフォルト命令の前までの命令を順番に実行する。 - 18
<Default>
- クリップボードから取り出したデータが
.bmp
でも.jpg
でも.png
でも.gif
でもない場合に次の命令から分岐終了命令の前までの命令を順番に実行する。 - 19
MsgBox 画像ファイルを選択してください。
- メッセージボックスを表示する。
- 20
<pause>
- プログラムの実行を中断する。
- 21
</Switch>
- 分岐を終了する。
- 22
Application
Application
キーを押したことにする。- 23
H
H
キーを押したことにする。- 24
<r 5>
- 繰り返しを開始する。5回繰り返す。
- 25
↓
↓
キーを押したことにする。- 26
</r>
- 繰り返しが完了していない場合には繰り返しの最初の命令に戻る。完了した場合には次の命令に進む。
- 27
Enter
Enter
キーを押したことにする。- 28
1000
1000
ミリ秒待機する。- 29
LCtrl Down
- 左
Ctrl
キーを押したままでいることにする。 - 30
W
W
キーを押したことにする。- 31
LCtrl Up
- 左
Ctrl
キーを離したことにする。 - 32
Tab
Tab
キーを押したことにする。- 33
5
5
キーを押したことにする。- 34
0
0
キーを押したことにする。- 35
Enter
Enter
キーを押したことにする。- 36
LCtrl Down
- 左
Ctrl
キーを押したままでいることにする。 - 37
S
S
キーを押したことにする。- 38
LCtrl Up
- 左
Ctrl
キーを離したことにする。 - 39
LAlt Down
- 左
Alt
キーを押したままでいることにする。 - 40
F4
F4
キーを押したことにする。- 41
LAlt Up
- 左
Alt
キーを離したことにする。
プログラムの行数は41行となり、上のプログラムと比べれば半分未満と大幅に短くなりました。
そして、プログラミングにおいては鬼門である同じ内容の繰り返しも無事なくなりました。
上のプログラムはかなり良いプログラムへと生まれ変わりました。
なお、このプログラムを実行してみると、画像ファイル(拡張子が.bmp
か.jpg
か.png
か.gif
のファイル)に対しては正しくリサイズが行われ、画像ファイル以外に対しては下のようなエラーメッセージが表示されます。
つまり、やりたかったこともきちんと実現されています。
めでたしめでたしです。
分岐
分岐というプログラミングパターンは順次や繰り返しに比べると少し複雑ですが、プログラミングにおいては最も基本的なパターンの1つとなっており、実際のプログラムでも頻出するパターンです。
順次というのは上から下に向けて順番に命令が実行されていくパターンでした。
それから、繰り返しというのは上から下に向けて順番に命令が実行されているところを、繰り返し回数分だけは命令の実行を上に戻すというパターンでした。これにより、プログラムの1度の実行においてプログラムの中に書かれている同じ命令を複数回実行することができたのでした。
そして、分岐というのは上から下に向けて順番に命令が実行されているところを、状況に応じて幾つかの命令の候補の中から特定の命令のみを実行するというパターンです。これにより、プログラムの1度の実行においてプログラムの中に書かれている命令を1度も実行しないようにすることが可能となります。
繰り返しや分岐は順次というプログラミングの基本原則にほんの少し修正を加えます。
このように、上から下に向けて順番に命令を実行していくという基本はそのままに、特定の命令を複数回実行するようにする繰り返しや、1回も実行しなくする分岐により、非常に柔軟にプログラムを書くことができるようになるのです。
複数回実行しなければならない命令を書くには繰り返し命令を利用し、0回か1回実行しなければならない命令(1回も実行してはならないか1回だけ実行しなければならない命令)を書くには分岐命令を利用するということを覚えておくと、もしかしたらプログラムを書く際に役立つかもしれません。
つづく
今回の分岐命令を使ったプログラム作成はどうだったでしょうか。
分岐というものが使えるようになったおかげで、前回と比べてより多くのプログラムが簡単に作れるようになりました。
第2回から今回までプログラムに記述された命令がどのように実行されていくかについて解説してきました。命令の実行のされ方の基本に関してはもう十分に解説することができたかと思います。
次回は少し趣の違う話をしてみたいと思います。具体的には、プログラムにおいて計算を行ったり、計算結果を記憶しておく話です。
これにより、更に多くのプログラムが簡単に作れるようになります。
↓ ↓ ↓
