LabVIEWを触ったことがない方に向けて、それなりのプログラムが書けるようになるところまで基本的な事柄を解説していこうという試みです。
シリーズ19回目としてある程度の規模のプログラムを作るにはかかせないタイプ定義のお話しです。
この記事は、以下のような方に向けて書いています。
- タイプ定義って何?
- タイプ定義と指定タイプ定義の違いがわからない
もし上記のことに興味があるよ、という方には参考にして頂けるかもしれません。
なお、前回の記事はこちらです。
タイプ定義とは
今回はタイプ定義の話をします。これは、簡単に言えば「データタイプのマスターを用意する」という操作になります。マスター用に拡張子ctlというファイルを用意して、タイプ定義した制御器などの複製時に役立ちます。
・・・なんじゃそりゃ、って感じですよね。まずは何となくのイメージを示すと以下の図のような感じです。マスターと呼ばれるものを用意しておいて、これを編集するだけで、そのマスターから作られた子にも変更が反映される、という状態になります。
上の図の「子」がVI上の制御器や表示器になります。ただし、実際にマスターから作られたものを「子」とは表現しません。便宜上このように読んでみました。
「これを知っていないとプログラムが書けない」というものではないのですが、知っておくとかなり便利なのでぜひ覚えてもらいたいと思います。
ただし、その便利さが本当に実感できるのはある程度プログラムを書けるようになったり、「ステートマシン」というプログラムのデザインの一種を使いこなせるようになってからになります。なので今は「そういう機能があるんだな」程度で大丈夫です。
タイプ定義は様々な制御器、表示器に対して設定することができます。ただよく使うシーンというのはある程度限られていて、クラスタや列挙体に対して使うことが多いと思います。そこでこれらを例にタイプ定義について紹介していきます。
タイプ定義の作り方と性質
まずクラスタに対してのタイプ定義です。試しに、数値とブールの制御器が一つずつ入ったクラスタを作ったとします。
作ったら、これと全く同じものを2つ、複製します。合計3つが表示された状態ですね。
真ん中のクラスタに対して右クリックして、タイプ定義に指定を選択します。また、一番右も同様にタイプ定義に指定を選択します。
次に、真ん中のクラスタに対して右クリックして「タイプ定義を開く」を選択します。新たなウィンドウが表示されるので、このウィンドウを保存します。これは拡張子がviではなくctlとなります。
次に、一番右に対してもタイプ定義を開くを選択します。選択したら表示されるウィンドウで、「指定タイプ定義」を選択します。
その後、ファイルメニューから「変更を適用」とし、開いたウィンドウを保存します。こちらも拡張子はviではなくctlです。
これで準備完了です。今、三つのクラスタを用意しました。一番左は、単にクラスタを用意しただけの状態、真ん中はタイプ定義と指定したもの、一番右はさらに指定タイプ定義としたものです。
なお、見た目上分からないと思われがちですが、ブロックダイアグラムを見ると、タイプ定義をしているか否かについては判断することができます。ブロックダイアグラムで端子の右上に黒い三角形がついていると、それはタイプ定義されたものだとわかります。ただし、タイプ定義なのか指定タイプ定義なのかは判断できません。
これらのクラスタに対して、さらに文字列制御器を追加することを考えます。
まず、一番左のクラスタには問題なく文字列制御器を追加できます。
ところが、二番目、三番目のクラスタに文字列制御器を追加しようとすると一番目のクラスタと違って、文字列制御器が「浮いて」しまう状態となります。
これがタイプ定義した効果です。タイプ定義をしたことで、「データタイプ(今回の場合クラスタ)をある状態に定義した」ことになります。
定義がされた際のクラスタは、数値制御器とブール制御器を一つずつ持っていました。この状態を「定義」としています。そこに文字列制御器を入れようとすると、定義を崩すことになります。タイプ定義された状態のクラスタはそれを許しません。
定義したクラスタではなくなってしまうので、そのような変更は受け付けない!ということで文字列制御器を追加することはできなくなっています。
次に、クラスタの枠を変更することを考えます。まず一番左のクラスタについては問題なく枠を変更できます。真ん中のクラスタについても枠の大きさを変更することができます。
しかし、一番右のクラスタについては枠の変更すらできません。
ここに、「タイプ定義」と「指定タイプ定義」の違いがあります。「指定タイプ定義」はより強力な定義で、外観(枠の大きさや色など)の変化も許しません。外観までもきっちり「定義」しているからです。
では、どうしても変更を加えたい場合にはどうすればいいでしょうか?
答えは簡単で「定義」そのものを編集すればいいのです。この「定義」したものをマスターと呼びます。タイプ定義が「データタイプのマスターを用意する」と表現した理由はここにあります。
マスターの編集はとても簡単です。タイプ定義したクラスタを右クリックしてタイプ定義を開くを選択して表示されるウィンドウ上でクラスタを編集するだけです。
このウィンドウ上の情報は拡張子がctlというファイルで保存されているのでした。定義を残しておくために保存する、ということですね。なお、指定タイプ定義であっても拡張子は同じctlです。
なお、ctlファイル、つまりタイプ定義のクラスタを編集している間、そのクラスタが置かれていたVIのフロントパネルを見ると、クラスタがグレーアウトしているのが分かると思います。これは、いま定義を編集している状態ですよ、ということを表しています。
定義を変更しても、ctlファイル上で変更を適用をしない限り元のVIのフロントパネル上のクラスタに反映させることはできないので注意が必要です。
これらの項目の編集の流れはタイプ定義でも指定タイプ定義でも全く同じです。
タイプ定義するメリット
このようなことをする利点があるのか?と思う方がいるかもしれません。実際大いにあります。
特にステートマシンという組み方をする場合には列挙体を使用している場合にその恩恵に大きくあやかれるので列挙体でのタイプ定義を例にとります。
まずは、次のような「初期化」、「ステート1」、「終了」という三つの項目を持つ列挙体を用意してみましょう。
用意出来たら、これを複製します。実際同じ列挙体を一つのプログラムで複数個所で使うという使い方は良くあり得ます。くどいようですが、ステートマシンというプログラムの組み方を採用する場合には必須の操作と言っていいと思います。
複製したら、どちらの列挙体でもいいので、列挙体の項目を追加してみます。その後、二つの列挙体の中身を比べてみてください。
当然ですが、二つの列挙体はもはや別物同士ですよね?二つはもともと片方を複製して作ったものですが、編集は片方にしか行っていないため、「編集された方」と「編集されなかった方」とでは項目の内容が異なっています。
しかし、実際にはこれが意図した動作ではない場面が多いと思います。似たような項目を持つけれど項目数がバラバラな列挙体を使う、よりかは、どの列挙体も共通した項目を持っている状態のほうが使いやすいためです。
基本的に一つのプログラムの中で、ある列挙体を用意しこれがプログラムの複数個所で使用される場合、すべての列挙体は同じ内容を持っていなければ意図した動作をしないことが起こりえます。
ここでタイプ定義の出番になります。
列挙体に対してもタイプ定義をする方法はクラスタに対する方法と全く同じで、列挙体を右クリックしてタイプ定義に指定を選択するだけです。編集する場合も、一度タイプ定義を開いて、マスターとなっている列挙体を編集して、編集後に変更を反映させます。
クラスタの説明のところで紹介したように、タイプ定義は、定義されたものと全く同じデータを持つものです。そのため、一つマスターの列挙体を作っておいて、あとはこのマスターを編集すれば、そのマスターを基にした列挙体はどれであっても、マスターと同じ項目を持つはずです。
実際に見ていきましょう。先ほどの列挙体を使用します。項目が4つの方の列挙体をタイプ定義にしたら、これを複製します。
そうしたら、片方の列挙体を右クリック、タイプ定義を開きます。開いたら列挙体の項目を増やします。この編集時、右クリックしたものはもちろん、複製されたもう一つのタイプ定義列挙体(「列挙体3」)もグレーアウトしていることに注目します。
編集が終わったら、タイプ定義で変更を適用してみます。さぁ、この状態で三つの列挙体の項目を確認してください。
列挙体から複製したものも、同じ列挙体項目になっていますよね?これがタイプ定義のメリットです。
一度タイプ定義にしてしまえば、その後に複製した列挙体であったとしても、マスターの変更をすることで、複製したものすべてに同じ変更をいっぺんに、確実に反映させることができます。
逆に、タイプ定義していないと複製した項目がたくさんあったときにそれらを全ての複製した端子に手動で反映させる羽目になり、これはバグのもとになります。 もちろん、このメリットは列挙体ではなくクラスタを使用した場合にも適用されますし、それ以外のデータタイプについても同様です。
このタイプ定義の活用法を知っているのと知らないのとでは、プログラムを書く際の効率が全然違います。なんでもかんでもやみくもにタイプ定義しなければいけないという話ではないですが、項目が後から変更される可能性がありかつ一つのプログラムで複数個所使われるような制御器に対しては基本的に設定しておいて損はないです。
タイプ定義の話も一通り済んで、いよいよステートマシンの話に移っていけます。・・・が、そこに進む前に、「複数のプログラムの管理」の仕方について準備する必要があります。
というのも、以前扱ったサブVI、そして今回扱ったctlファイル、これらを複数組み合わせてステートマシンを作るのですが、こういった「様々なファイル」は丁寧に管理する必要があるためです。
そんな複数のファイルを扱うための機能がプロジェクトエクスプローラです。次回はこれについて扱い、その後にようやくステートマシンの話を紹介しようと思います。
もしよろしければ次の記事も見ていってもらえると嬉しいです。
ここまで読んでいただきありがとうございました。
コメント