この記事では、LabVIEWでプログラムを書く上で、工夫次第で「ケース」をうまく扱うことができるような書き方について、どのような方法があるかの例を紹介しています。
ここでいう、「うまく扱う」とは、ケースの数を減らしたり、ケースの場合分けを煩雑にさせないための工夫のことです。
なお、「ケース」は必要があって設けるものなので、本来はおいそれと少なくできるものではありません。
ただ、似たような内容の処理を行うものをいちいち分けなくても、まとめて書くことでプログラム全体の見やすさを向上させることはできます。
テクニックとしてはLabVIEW初心者の人が積極的に使った方がいいものではないかもしれませんが、考え方は役に立つと思います。
ケースとは
まずそもそも「ケース」とは何なのかについてですが、この記事では
- ケースストラクチャ
- イベントストラクチャ
といった、分岐が関係する処理を指します。
通常、いわゆる条件分岐を行わせる場合にLabVIEWではケースストラクチャを使用します。
ユーザー操作による何かしらのイベントに応答して処理を実行する場合に使用するイベントストラクチャも、「各イベントという条件に応じて処理を分けている」という意味で、ケースストラクチャと似たような性質を持ちます。
これら条件に応じて処理を変える処理を書く場合に、LabVIEWではストラクチャという「枠」を用いて、ラベル名で条件の内容を書きます。
実はここにLabVIEWが他のテキスト言語系のプログラムに対して弱点とされる部分があり、「全てのケースを一度に見えない」ことになります。
テキスト言語であれば、各条件に対する処理がスクロールするほど長くなっている場合はさておき、一画面で各条件に対する処理は表示させることができる一方で、LabVIEWは原理的に各条件の処理を一目で確認することができません。
ファイルに表示させるということは以前紹介しましたが、使い勝手はイマイチかもしれません(自分で記事を書いておいてなんですが)。
もちろん、工夫次第では無効ストラクチャを用いて全ケースの内容を表示させるようなことはできなくはないですが、ケースの数が多いとそれだけブロックダイアグラムを圧迫するのは変わりません。
仕様上、すべてのケースを一度に見るのが難しいのであれば、せめてケースの数を少なくすることで開発やデバッグをやりやすくするための工夫をこらせないかを考えてみます。
また、条件分岐についても、ブールの関数を駆使して複雑にするより、すっきり条件を表すことで条件追加等も行いやすくなる場合があります。
本記事で紹介している例は少ないですが、常に先々のデバッグや機能追加等の便利さを考えた実装を心掛けるのがベターだと思います。
ケースを少なくする工夫
ケースストラクチャの使用を回避する
選択関数で代用できる処理の場合には選択関数を使用してケースストラクチャの使用を回避できます。
この方法はどのような場合でもできるわけではなく、また、条件分岐がTrueかFalseの二者択一である場合に限られますが、どちらの条件の場合の処理も一目で確認することができるようになります。
例えば以下では、配列をソートしたものをそのまま扱うかあるいはソートを反転させたものを扱うかをケースストラクチャおよび選択関数で表現しています。
当然どちらも結果は同じになるのですが、選択関数を使用した方はTrue、Falseいずれの場合の処理も一目で見ることができています。
これに限らず、選択関数を使用してケースストラクチャの出番をそもそも減らせる機会は意外とあると思います。
ただし、どちらかしか処理する必要がないのに余分に処理をしているという意味で、パフォーマンスは落ちるかもしれません。あくまで見やすさ重視です。
複数のブールの状態を一つのケースで表す
例えば以下のようなプログラムがあるとします。
フロントパネルにおいてあるブールボタンはどれもスイッチ動作になっていて、複数のボタンをTrueの状態にすることが可能で、OKボタンを押したら、押されたボタンの組み合わせによって処理を変えるようなプログラムです。
ここでの「処理」は、どのボタンが押されたかを表示すること、としています。
これを実装するのに、各ボタンのブールの状態をそのまま扱っていると、orやandを使用して条件がややこしくなりそうです。
一方で、ブールの結果を配列としてひとまとめにしてしまい、これを数値に変換すれば、各ブールの状態の組み合わせは特定の数値と1対1対応するので、ケースストラクチャが一つで済みます。
例えばボタンA、B、Cの順で配列にしてこれを数値に変換した場合、ボタンAが押された状態は「001」なので1に相当します。
同様に、ボタンBが押された状態は「010」で2に、ボタンCが押された状態は「100」で4に相当し、ボタンAとCが押された状態は「101」なので5に相当する、といった具合です。
この実装方法の場合、後からボタンを追加したとしても、その追加したボタン分がブール配列の一番最後に来るようにすれば、ケースを増やすだけでそのボタンが増えたことによる処理の増加に対応できます。
orやandを駆使して、あるいはケースストラクチャを入れ子にして実装するよりは見通しが良くなりますし、ケースの中で「AとBがTrueのとき」などといったサブダイアグラムラベルをつけておくことでより見やすくなります。
似たようなイベントではリファレンスを使用する
例えば、ブールボタンを押すことで何かしらのイベントを発生させるような処理があった場合に、イベントをそれぞれ別に登録しておくと、イベントの数がいたずらに多くなることがあります。
以下のプログラムのようにボタンが3つあり、それぞれのボタンを押すと「1が押されました」などと表示するようなプログラムを、イベントストラクチャで実装することを考えます。
一つのイベントケースに複数のイベントソースを割り当てると、どのイベントソースによってそのイベントが発生したかを区別しないと意図した処理を行えないことがあります。
そんな場合にはイベントデータノードを駆使して、どのボタンが押されたかをプログラム的に判断させることで解決できます。
イベントデータノードとは以下の図の左の方にある「制御Ref」と表示されたもので、この場合、そのイベントを発生させた元になっている制御器のリファレンスを表しているので、このリファレンスをプロパティノードに配線し、ラベルのテキストプロパティを使用することで、どの制御器のイベントだったのかをラベル名で取得できます。
あとはこの文字列の内容で処理を分けるようにします(この文字列をケースストラクチャのケースセレクタに配線する)。
プログラムを簡単にする目的で、ラベル名を「プログラムで処理しやすい」名前にしておくのも手なのですが、それだと表示されている字面が格好悪い、という場合には、ラベルではなくキャプションのテキストで同じことをやるのも手です。
この場合には、プロパティノードでキャプションのテキストプロパティを使用して上記と同じような条件分岐を行っていきます。
本記事では、ケースを減らすための工夫について紹介しました。
グラフィカルなプログラミング言語であるからこその不便さとも言えそうなケースの問題ですが、やり方次第でプログラムを簡潔に書けることもあるので、参考になればうれしいです。
ここまで読んでいただきありがとうございました。
コメント