この記事で扱っていること
- csvファイルでデータベース状の情報管理をする方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
データをプログラム外部にファイル出力したり、そのファイル出力した値を読み込んでプログラムの中で使用するといった場面はプログラムを作るうえで頻繁にあると思います。
例えば、何かハードウェアで測定したデータをファイルに保存する、といったような、「保存されるデータがプログラム側で用意される」パターンのファイル出力方法はいくつかの記事で紹介してきました。
例えばTDMSという、測定データに特化したファイル形式については以下の記事などです。
一方で、ユーザーが何か情報を入力してその情報をまとめて保存するというケースもあると思います。いわゆる、データベースと呼ばれる類の情報のまとまりがイメージが近いかなと思います。
本記事では、そんなデータベース状の情報のまとまりとして、名前や性別などがまとまった「個人情報」の集合をcsvに保存する例を紹介しています。
もちろん扱うデータの形式や種類を変えれば「個人情報」以外でもいくらでも応用ができると思います。
どんな結果になるか
フロントパネルには、登録する情報を表のように表示させるための複数列リストボックスと、登録する情報を入力するスペース、既存ファイルから読み込むための機能、登録内容を削除する機能、そして登録情報をcsvに保存する機能を盛り込んでいます。
なお、以下の図で「名前」や「ID」などを入力する項目は枠で囲っているのでクラスタとしてまとまっているように見えると思いますが、クラスタにはしていません(もちろんクラスタにすることもできますが)。あくまで見栄えの問題で枠で囲ってみました。
情報を入力して登録ボタンを押すとリストボックスにその内容が反映されるようになります。
また、リストボックスの項目を選択した状態で削除ボタンを押すとその内容を削除することができます。
既存ファイルの編集を行う場合には、その既存ファイルを指定して読み取るボタンを押せば中身をリストボックスに表示させることができます。
保存には、保存先のcsvファイル名を指定した状態で完了ボタンを押します。
プログラムの構造
大枠は、イベント駆動型のステートマシンで作っています。
リストボックスやファイルに保存するデータは、クラスタとしてまとめています。上の図で「個人情報配列」とラベルを付けたワイヤ上をこのクラスタが通ります。データをシフトレジスタで各ステートで扱うことによって情報の追加や削除、表示をプログラム内で簡単に行えるようにしています。
それではそれぞれのステートを紹介します。
まずはinitializeステートです。プログラム実行時に複数列リストボックスの内容を一度空にするとともに、列ヘッダの情報を追加しています。
また、ブロックダイアグラム上で扱う入力情報のクラスタを初期化しています。フロントパネル上では例えば「身長」は数値制御器ですが、これらは最終的に文字列として表示したり保存したりするので、個人情報クラスタの中身は全て文字列にしています。
次にwait for eventステートです。ユーザーがフロントパネル上でどのボタンを押したかによって次のステートが決定されます。
各イベントは以下の図の通りです。それぞれに別々のステートを対応させるようにしています。
次はread fileイベントです。特に処理の速さやパフォーマンスを求める部分ではないので、ファイルIOの関数パレットにある、「区切られたスプレッドシートから読み取る」の関数が便利なのでこれをそのまま使用します。
読み取った2D文字列配列の結果をForループでまず1D配列として、クラスタにまとめるために指標配列の関数を使用して一つずつ取り出すようにしています。取り出したデータを名前でバンドル、これをForループの自動指標付け有効にした出力トンネルから出して、シフトレジスタに配線します。
このステートの後は、後述するupdateステートに移行します。
次はdelete itemステートです。やっていることは単純で、複数列リストボックスの中で選択された行のデータをシフトレジスタで回している個人情報クラスタから削除するだけです。
このステートについても、次にupdateステートに移行するようにします。
その次はadd itemステートです。フロントパネル上の「名前」や「ID」などの各種情報をクラスタに追加してシフトレジスタに配線しています。
今回の例では「性別」に対してメニューリング制御器を使用しているので、どの選択肢が選ばれたかで文字列を変えるためにケースストラクチャを使用しています。
こちらもまた、次のステートはupdateに移行するようにします。
次はupdateステートです。今までに紹介した他のステートがいったんこのステートになってからwait for eventステートに戻るようにしています。
やっていることは単純で、シフトレジスタで回していたデータを複数列リストボックスの情報として反映させるためのステートです。
項目名プロパティに、データを渡してやるだけですが、表示の都合上2次元配列転置をかませる必要があることに注意します。
次はfinishステートです。データを「区切られたスプレッドシートに書き込む」関数で保存しています。
最後にcancelステートです。キャンセルなので、今までの操作は何も保存せずに終了させます。
細かい設定を忘れずに
上で紹介したブロックダイアグラムの通りに組めばプログラムは完成しますが、使い勝手の面でフロントパネル上の制御器についていくつかデフォルトとは異なる設定をしている部分があります。
まずはファイルパス制御器の参照オプションです。
ファイルパス制御器を使用する場合、フォルダのアイコンをクリックしてパスを指定すると思いますが、デフォルトの設定だと新規ファイルを指定することができません。
「データベース保存先」のファイルパス制御器では新規ファイルを選ぶことになると思うので、参照オプションの設定を変えてあげる必要があります。
また、複数列リストボックスの設定も、行全体をハイライトするように設定しておいた方が削除するときにリストから項目を選ぶ際の見栄えがいいと思います。
ブロックダイアグラム上に表すアルゴリズムの方に加えて、こうしたちょっとした設定を変更するだけで、使い勝手や見栄えが結構変わったりします。デザインにこだわりすぎて時間使いすぎるのもよくないですが、せっかくLabVIEWはユーザーインタフェースとなるフロントパネルを簡単に作ることができるので、たまには意識してこだわってみるのも面白いと思います。
本記事では、データベース状の情報を管理して追加、削除、保存等を行うためのプログラムを紹介しました。
データそのものはクラスタとしてまとめておき、フロントパネルへの表示は都度専用のステート(update)で行うといった方法を使えば、どんなデータを扱う際にも同じように組むことができ応用がききやすいと思うので参考になればうれしいです。
ここまで読んでいただきありがとうございました。
コメント