トレーサビリティのデモアプリを作ってみよう

本チュートリアルの内容

開発 環境を確認する
前提とする環境

このチュートリアルでは、以下の開発環境を想定します。

  • PocketPC:Fujitsu LOOX FLX3AW (Microsoft(R) Pocket PC version 4.20.1081、.NET Compact Framework 3.5(.NET CF3.5)
  • 開発PC:Windows 7 Professional、Visual Studio 2008(VS2008) VC#、.NET Framework 4.0(.NET 4.0)
  • RFIDリーダライタ:Omron V720S-HMF01(マニュアル


環境の準備
開発環境を確認するためには、開発をするマシン(母艦)にVS2008とクライアントに必要なソフトをインストールする必要があります。インストール方法は、Looxを使った他のチュートリアルを参考にしてください。

.NET Compact Framework v3.5のCabファイル

ページの先頭へ

要求仕様を考え てみよう

■製品と部品の識別
今回のトレーサビリティシステムは、家電を取り扱います。家電は消費者の安心安全意識の高まりから、トレーサビリティシステムの必要性が叫ばれている製品です。また、それだけではなく、環境保全の立場からは、家電の中に含まれる有害物質を管理するという動きも進んでいます。EUが発効したRoHS指令などがそれに当たります。
ということで、家電のトレーサビリティにおいては、家電の本体だけではなく、その構成品の管理も必要となります。



管理をするためには、その製品・部品を一意に識別する必要があります。この一意の識別子は個体識別子と呼ばれます。工業製品の個体識別子の付与方法は、国際的な標準化団体であるGS1によって管理されています。

また、管理をするためには、この個体識別子を製品や部品に物理的につけておく必要があります。つける方法としては、文字として印字する、バーコードを印字するなどの方法のほかに、RFID(電子タグ、ICタグなどとも呼ぶ)という仕組みを使う方法があります。今回は、このRFIDを前提とします。
また、個体識別子は国際的に決められていると書きましたが、この個体識別子をRFIDの電子タグに書き込む方法も標準で決められています。これは、どう書くかを決めて置かないと、書いた人が意図した方法で読む人が情報を取り出せなくなってしまうからです。

このように個体識別子も書き込み方も標準では決まっていますが、このデモシステムでは、独自の方法で実施します。ただし、基本的な考え方は標準のものと同じです。

■個体識別子と電子タグへの書き込み方法
このデモシステムでの個体識別子の構造は次のようにします。

(メーカーに割当てられたID)+(製品種類に割当てられたID)+(製品のシリアル番号)

こうすることによって、世界に一つのIDを割り当てることが可能になります。デモシステムでは、メーカーに割当てるIDを000~FFF、製品種類のIDを00~FF、シリアル番号を000~FFFとします。

■ユースケース
では、トレーサビリティシステムはどのように使われることになるでしょうか。トレーサビリティシステムは、製造者が個体識別子を発番し、その情報を製品や部品に付与することになります。この時に、一つの完成品(例えばテレビ)に、複数の部品が付けられることになるので、完成品と部品の関係も管理する必要があります。

また、製造後の流通以降の段階では、基本的にこのテレビの単位で管理されることになります。管理される場所としては、メーカーの工場、倉庫、店舗、そして、実際に使用される家庭が考えられます。また、それぞれの場所で利用者はその製品がどのようなルートで流通されてきたかを確認できることになります。また、それだけではなく、その製品がどのような部品を使っているかの情報を確認する場合もあると考えられます。




■場所の識別
ユースケースを見て気づいたと思いますが、製品のトレーサビリティ情報を管理するためには、少なくとも、製品の個体識別子、その製品が存在した時間、そして、その製品が存在した場所を管理する必要があります。この「何が」「いつ」「どこに」あったかの情報がトレーサビリティシステムのトランザクションデータの基本となります。つまり、先ほどは、製品・部品の個体識別子が必要だと書きましたが、それ以外にも時間と場所についてもデータの方式を決める必要があります。

時間については、既にコンピュータでも標準的に扱われているため、標準方式がいくつか存在しているためにあまり大きな問題になりません。しかし、場所については、いまだにデファクトと呼ばれる存在が確立していないために、それぞれの場面でいろいろな方式がつかれています。緯度経度を使用すればよいような気もしますが、ビジネス上の意味を持たせるためには、やはり、何らかの識別子が必要になると考えられます。識別子としては、製品の個体識別子同様に構造化された識別子が管理上都合がよいと考えられますが、このデモシステムでは、構造を使用しない形式とします。

それでは、メーカーでテレビと部品が組みつけられ、出荷され、消費者が使用後に、リサイクル業者が引き取ってテレビを分解するときに、製品に含まれている部品の情報を確認するという流れでデモシステムを作ってみましょう。

ページの先頭へ

設計してみよう

■個体識別子と電子タグ
前の要求条件に適合する形で、システムを設計してみよう。まず、個体識別子については、先に書いたように、デモシステムでは、メーカーに割当てるIDを000~FFF、製品種類のIDを00~FF、シリアル番号を000~FFFとします。

また、電子タグについては、今回は、HF帯の電子タグを使用することとします。これは、現在業界で検討されている方式とは異なりますが、HF帯の方が取り扱いやすいため今回は、HF帯を使用します。
HF方式は13.56MHzの周波数帯を使用したシステムで、電波の出力によっても異なりますが、タグとタグの情報を読み取るアンテナの間の距離は約5cm~30cm程度になります。今回は、ISO/IEC15693という方式を使用します。

今回の個体識別子は、8バイトですので、8バイト分の領域が必要になります。ISO/IEC15693のメモリは下のようなメモリマップになっていますので、8バイトを00hバンクの1hページの4バイトを使用することとします。



■データベース
トレーサビリティ情報はデータベースで管理されることになりますが、それが、一つのデータベースになるのか、複数のデータベースになるのかは、わかりません。しかし、世界に、あるいは、業界に一つのデータベースを作ることは、独立した企業が合意できないだろうと考えられているため、一般的には、分散的になると考えられています。しかし、規制などで業界がどうしても対応する必要がある場合には、一つのデータベースでトレーサビリティ情報が管理されているケースもあります。今回のデモシステムでは、一つのデータベースで管理するという方式を採用します。

では、データベースはどのような構造になるでしょうか。付加情報などの管理を考えると複雑な構造になりますが、製品と部品のトレーサビリティデータだけを管理するのであれば、次のようなテーブルがあれば十分であると言えます。

製品テーブル(item_tbl):製品の個体識別子、製品名、製造メーカー、製造日等を管理するテーブル
フィールド 種別 説明 その他
itemId varchar(8) 製品の個体識別子 主キー
name varchar(20) 製品名
mfg varchar(20) 製造メーカー
date date 製造日

部品テーブル(part_tbl):部品の個体識別子、製品名、製造メーカー、製造日等を管理するテーブル
フィールド 種別 説明 その他
partId varchar(8) 部品の個体識別子 主キー
name varchar(20) 部品名
mfg varchar(20) 製造メーカー
date date 製造日

製品構成テーブル(struct_tbl):個々の製品において製品と部品の関係を管理するテーブル
フィールド 種別 説明 その他
itemId varchar(8) 製品の個体識別子 主キー
partId varchar(20) 部品の個体識別子 主キー

トレーサビリティテーブル(trace_tbl):製品のトレーサビリティデータを管理するテーブル
フィールド 種別 説明 その他
traceId int(5) 製品の個体識別子 主キー、自動
locId varchar(4) ロケーション識別子
process varchar(4) 場所での処理
date date 処理日

場所テーブル(loc_tbl):製品のトレーサビリティ情報が読み取られる場所情報を管理するテーブル
フィールド 種別 説明 その他
locId varchar(4) ロケーション識別子 主キー
name varchar(20) 場所名称

■通信
今回は、利用者が使用する端末として、PocketPC対応のPDAを使用することにし、サーバーはWindowsXPProfessionalのインストールされたPCを使用することにします。このような構成は、クライアントサーバー型のアプリケーションではごく普通の構成です。

しかし、クライアントとサーバー間の通信をどのようにするかについては、検討の余地があります。実装しやすいのは、クライアントとサーバーを接続するのに、サーバー側にインストールするDBと直接TCP/IPで接続する方式と、サーバーとクライアント間をHTTPで通信をする方式が考えられます。当然、TCPの上位にHTTPを乗せるために、HTTP通信の方がひと手間余計にかかりますが、その代わりに、HTTPのメリットである、プロキシの透過や豊富なライブラリを利用することができます。

今回は、DBとしてMySQLを利用するのですが、MySQLの場合に直接TCPと接続するためのライブラリも用意されていますので、今回は、TCPでの直接接続を利用することにします。

■クライアントアプリケーション
クライアントアプリケーションは大きく3種類必要になります。
  • 消費者がトレーサビリティ情報を閲覧するアプリケーション
  • リサイクル事業者がトレーサビリティ情報を閲覧するアプリケーション
  • その他の事業者がトレーサビリティ情報を更新するアプリケーション
では、それぞれについて、どのような動作になるかを考えてみます。

(1)利用者が情報を閲覧するアプリケーション
利用者が情報を閲覧するアプリケーションでは次のような処理が考えられます。
  1. 利用者が履歴を見たい家電のタグにPDAをかざし、家電ID取得ボタンを押す
  2. 家電に貼付されたタグから家電IDを読み出して、PDAの画面に表示する
  3. 表示された家電IDをもとにトレーサビリティ情報のDBにクエリをかける
  4. クエリ結果DBから受け取ってPDAに表示する
画面としては次のような画面が考えられるでしょう。




(2)リサイクル事業者が情報を閲覧するアプリケーション
リサイクル事業者が情報を閲覧するアプリケーションでは次のような処理が考えられます。
  1. 事業者が履歴を見たい部品のタグにPDAをかざし、家電ID取得ボタンを押す
  2. 部品に貼付されたタグから部品IDを読み出して、PDAの画面に表示する
  3. 表示された部品IDをもとにトレーサビリティ情報のDBにクエリをかける
  4. クエリ結果DBから受け取ってPDAに表示する
ここでは、特に部品のリサイクルを行うというシーンを想定します。工夫が必要なのは、流通や販売過程では、家電製品の記録しかとられていないため、部品と家電の親子関係から、履歴を表示する必要があるということです。

画面としては次のような画面が考えられるでしょう。



(3)その他事業者が情報を更新するアプリケーション
その他事業者が情報を更新するアプリケーションでは次のような処理が考えられます。
  1. 事業者が情報を更新したい家電のタグにPDAをかざし、家電ID取得ボタンを押す
  2. その時の処理を選択する(入荷か出荷)
  3. その処理を実施している場所を選択する
  4. PDAの更新ボタンを押してDBを更新する
ここでは、製品の流通ルートが決まっているケースを考え、クライアント端末に場所の情報が含まれていることを前提として議論を進めます。画面としては次のような画面が考えられるでしょう。



では、いよいよ実装してみましょう。

ページの先頭へ

実装して みよう(その1:シリアル通信)

それでは、実際にクライアントアプリケーションの実装をしてみましょう。ここでは、他のチュートリアルでPocketPCでのアプリケーション開発の概要を習熟しているという前提で説明を進めます。また、最初から全部を組み立てるのは難しいので、部分に分けて実装をしてみます。

■開発ツールと使用設定
今回は、開発ツールとして、Visual Studio 2008、.NET Compact Framework3.5を使用しました。.NETCompact Framework 2.0の場合には、シリアル通信の処理を行うのに手間がかかるので、間違いなく、3.5を使用してください。

■RFタグの読み取り部分
RFタグの読み取りには、Omron社製のCFインタフェースのRFIDリーダライタ(R/W)を使用します。このR/Wはシリアルインタフェースで制御ができるので、比較的簡単に利用することができます。プログラムの流れは次のようになります。

(シリアルポートのオープン)
       ↓
 (読み取りコマンド送信)
       ↓
  (受信データ処理)

また、この流れとは別に、シリアルポートでデータを待ち受けるイベント処理も記述します。その後、読み取りコマンドを画面上のボタンを押したときに送信側のシリアル通信バッファに送り込むことで、R/Wが読み取りコマンドをタグに向けて発し、戻ってきたデータが受信バッファに受け取られるという流れです。

シリアル通信ではCOMポートを使用します。通常は端末のCOM番号がわかっているので、それをそのまま実装してしまってもよいのですが、今回使用するCFタイプのR/Wの場合、COM番号がわからない場合もあるので、今回は、読み取りボタン以外に、接続ボタンとCOM選択ができるようにします。
画面配置は次のようになります。



画面を作る上で注意したいのは、ツールボックスのデバイスコンポーネントから「SerialPort」をドラッグアンドドロップ(画面へ)することを忘れないことです。また、画面に表示されたserialPort1をクリックすると、画面右のプロパティのところに、シリアルポートの設定画面が表示されます。これは、PDAとR/Wの間のプロトコルを決めるものです。ここでは、
  • Baurate: 9600
  • Databits: 8
  • parity: Even
  • StopBits: one
を選択しておきます。その他は、変更する必要がありません。
また、コンボボックスについては、COMポートの選択肢を書き込んでおきましょう。やり方は、画面上のコンボボックスをクリックし、プロパティの画面のアイテムを選択し、開いたウィンドウに選択する可能性があるCOM番号を書いておけば結構です。





では、実際のコードに書いていきましょう。まず、シリアルポートのオープン処理を書きます。画面の「接続」ボタンをダブルクリックしてください。すると、コードのタブ(Form1.cs)にボタン押下時の処理を記述できるスタブが表示されます。そこに、次のようなコードを記述します。

        private void button2_Click(object sender, EventArgs e)
        {
            // Set up COM port
            string cmport = this.comboBox1.Text;
            cmport = cmport + ":";
            serialPort1.PortName = cmport;
            serialPort1.Open();
        }

これは、コンボボックスで選択された番号をcmportという変数に格納し、その値をserialPort1インスタンスに設定し、シリアルポートをオープンするという処理です。

次に、読み取りコマンド送信処理を書きます。画面の「家電ID取得」ボタンをダブルクリックしてください。すると、コードのタブ(Form1.cs)にボタン押下時の処理を記述できるスタブが表示されます。そこに、次のようなコードを記述します。

        private void button1_Click(object sender, EventArgs e)
        {
            String cmd = "3120000001\r";
            byte[] byteCmd = Encoding.ASCII.GetBytes(cmd);
            serialPort1.Write(byteCmd, 0, byteCmd.Length);
        }

この処理は、まず、今回決めたIDの書き込み範囲を読み取るコマンドとして、3120000001\rを文字列変数に定義し、それをバイト列に変換して、送信側のシリアルバッファに書き込むという処理です。ちなみに、\rは改行コードで、受信側のR/Wはこのコードを受け取るまでは、一連のコマンドであると認識します。コマンドの詳細は、R/Wのマニュアルを参照してください。

次に、イベント処理を書きます。イベント処理はシリアルポートの設定の時と同様に、画面のserialPort1をまず選択します。その後、プロパティーのイベント処理(カミナリマーク)を選択します。そこに表示される「DataRecieved」をダブルクリックすると、シリアルの受信バッファにデータが来た時の処理を記述できるスタブが表示されます。そこに、次のようなコードを記述します。

        // イベント処理
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            string receivedData;
            Thread.Sleep(1000);
            try
            {
                receivedData = this.serialPort1.ReadExisting();
            }
            catch (Exception ex)
            {
                receivedData = ex.Message;
            }
            showDat(receivedData);
        }

このままでは、showDat(receivedData)のところにエラーが出ていると思います。このメソッドはまだ定義していません。このようにするのは、このイベント処理で取得したデータをイベント処理を使った他のスレッドに渡す必要があるためです。イベント処理は次のように記述しておいてください。また、スリープを入れているのは、シリアル通信のスピードが遅いためにデータの読み落としが多いのですが、それを予防するためです。

        // 読取IDの表示イベント処理
        private string recDat;
        private void showDat(string s)
        {
            recDat = s;
            this.Invoke(new EventHandler(showDatEventHandler));
        }
        private void showDatEventHandler(object sender, System.EventArgs e)
        {
            string itemId;
            if (recDat.Length >= 10) itemId = recDat.Substring(2, 8);
            else itemId = "try again";
            textBox1.Text = itemId;
            recDat = string.Empty;
            itemId = string.Empty;
        }

showDatはイベント処理を開始するためのメソッドで実際の処理は、EventHandlerの方に書かれています。受け取ったデータには、コマンドへのレスポンスと、受け取ったデータがセットになっていますので、ここでは、2ケタのレスポンスをsubstringメソッドで除去しています。また、受け取りが不安定になる場合があったので、この処理は、受け取った文字が10文字以上の場合のみ行い、その他の時には、再度読み取りボタンを押してもらうということで、try againと表示させることにしました。

以上で完成です。実際に動かしてみましょう。まずは、エミュレータで動かしてみてください。この例では、シリアル接続がうまくいっているかを確認するように「check」ボタンを入れてありますが、特に入れる必要はありません。



では、Cabファイルを作って、実機にインストールしてみましょう。Cabの作り方は、以下のリンクを参考にしてください。

配 置用スマートデバイスソリューションのパッケージ化

実際に動かしてみた写真は次のようになります。ここでは、FFFFFFFFと書かれているタグが読み取られています。



(ここまでのコード

ページの先頭へ

実装してみ よう(その2:データクエリー)

次に、クライアントからサーバーへの検索の部分の実装をしてみましょう。

■準備
クライアント~サーバー間の処理を実装する前に、DBの設定をしておきます。MySQLに設計で作成したDBとテーブルを作っておきます。製品・部品としては、次のようなデータを入れます。

コード:A01100001
(メーカー:A01、テレビ:10、シリアル:0001)
製品名:TV革命
製造メーカ:葵電気
製造日:2008-04-10
コード:A01900001
(メーカー:A01、電源:90、シリアル:0001)
製品名:100V電源ユニット
製造メーカ:葵電気
製造日:2008-01-04
コード:101110001
(メーカー:101、パネル:11、シリアル:0001)
製品名:液晶パネル17
製造メーカ:クリスタルキング
製造日:2008-02-01

場所の情報としては、次のようなデータを入れます。
コード:1001
場所:横須賀市葵電気工場
コード:2001
場所:横浜市GoGo電気配送センタ
コード:2002
場所:厚木市GoGo電気下荻野店
コード:3001
場所:厚木市神奈川工科大学企画
コード:3002
場所:厚木市神奈川工科大学

トレーサビリティ情報としては、次のようなデータを入れます。
製品コード:A01110001
場所コード:1001
処理:出荷
日時:2008-04-20
製品コード:A01110001
場所コード:2001
処理:入荷
日時:2008-04-21
製品コード:A01110001
場所コード:2001
処理:出荷
日時:2008-04-30
製品コード:A01110001
場所コード:2002
処理:入荷
日時:2008-05-01
製品コード:A01110001
場所コード:2002
処理:出荷
日時:2008-05-05
製品コード:A01110001
場所コード:3001
処理:入荷
日時:2008-05-06
製品コード:A01110001
場所コード:3001
処理:出荷
日時:2008-05-10
製品コード:A01110001
場所コード:3002
処理:入荷
日時:2008-05-11

また、テレビと電源ユニット、テレビと液晶パネルが親子関係であることをデータベースに格納しておきます。

(DB操作のSQL

■データベース検索
データベース接続には、MySQLのクライアント用のライブラリを使用します。用意したボタンを押すと、MySQLサーバーにTCP接続して、その結果を表示するという単純な流れになります。
検索結果は、リスト形式で返ってくるので、DataGridというオブジェクトを利用して、画面に表示します。
以上を踏まえて、画面にボタンを2つ、DataGridを2つ配置してください。また、家電IDを入力する場所として、テキストボックスを一つ用意しておいてください。



MySQLのライブラリを使用するためには、参照設定で、「MySQL.Data.CF」を選択しておく必要があります。これを使用するためには、MySQL Connector/NETをインストールしておく必要があります。これについては、MySQLのチュートリアルを参考にしてください。MySQL.Data.CFは、MySQL Connecterフォルダの中にあります。



また、コードのディレクティブとして次のような記述を追加します。

using MySql.Data.MySqlClient;

■家電情報および、履歴情報クエリ
このアプリケーションでは、家電情報と履歴情報の2つのクエリを実装します。これらのクエリで共通に家電IDを使用するので、共通に使用できる変数として、itemIdを定義しておきます。

private string itemId;

家電情報クエリのコードの記述には、まず、画面の「家電情報取得」ボタンをダブルクリックしてください。すると、コードのタブ(Form1.cs)にボタン押下時の処理を記述できるスタブが表示されます。そこに、次のようなコードを記述します。

        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text.Equals(""))
            {
                MessageBox.Show("家電IDが入力されていません");
            }
            else
            {
                itemId = textBox1.Text;
                //サーバーに接続
                string connstr = "userid=user1;password=user1;database=trace_db;Host=192.168.0.14;charset=utf8";
                MySqlConnection conn = new MySqlConnection(connstr);
                conn.Open();

                //データを格納するテーブルを作成
                DataTable dt = new DataTable();

                //SQL文と接続情報を指定し、データアダプタを作成
                string sqlMsg = "select name,mfg,date from item_tbl where itemId='" + itemId+"'";
                MySqlDataAdapter da = new MySqlDataAdapter(sqlMsg, conn);

                //データ取得
                da.Fill(dt);

                //データ表示
                dataGrid1.DataSource = dt;
                //新しいDataGridTableStyleの作成
                DataGridTableStyle ts = new DataGridTableStyle();

                //DataGridTableStyleをDataGridに追加する
                //DataGridColumnStyleを追加せずにDataGridTableStyleを追加すると、
                //DataGridColumnStyleオブジェクトのコレクションが自動的に作成される
                dataGrid1.TableStyles.Add(ts);

                //Columnの幅を変更する
                dataGrid1.TableStyles[0].GridColumnStyles[0].Width = 75;
                dataGrid1.TableStyles[0].GridColumnStyles[1].Width = 75;
                dataGrid1.TableStyles[0].GridColumnStyles[2].Width = 50;
            }

ここでは、DBとのコネクションを生成し、それに対して、SQLでクエリを送信します。DBとの接続は、ご自身の環境にあわせて設定してください。その後、検索結果をDataGridに格納し、そのデータを画面に表示するという流れになっています。DataGridの幅は適宜調整をしてみてください。

履歴情報クエリのコードの記述には、まず、画面の「履歴情報取得」ボタンをダブルクリックしてください。すると、コードのタブ(Form1.cs)にボタン押下時の処理を記述できるスタブが表示されます。そこに、次のようなコードを記述します。

        private void button2_Click(object sender, EventArgs e)
        {
            if (textBox1.Text.Equals(""))
            {
                MessageBox.Show("家電IDが入力されていませ");
            }
            else
            {
                itemId = textBox1.Text;
                //サーバーに接続
                string connstr = "userid=user1;password=user1;database=trace_db;Host=192.168.0.14;charset=utf8";
                MySqlConnection conn = new MySqlConnection(connstr);
                conn.Open();

                //データを格納するテーブルを作成
                DataTable dt = new DataTable();

                //SQL文と接続情報を指定し、データアダプタを作成
                string sqlMsg = "select trace_tbl.process,loc_tbl.name,trace_tbl.date from trace_tbl inner join loc_tbl where trace_tbl.locId=loc_tbl.locId and trace_tbl.itemId='" + itemId+"'";
                MySqlDataAdapter da = new MySqlDataAdapter(sqlMsg, conn);

                //データ取得
                da.Fill(dt);

                //データ表示
                dataGrid2.DataSource = dt;

                //新しいDataGridTableStyleの作成
                DataGridTableStyle ts = new DataGridTableStyle();

                //DataGridTableStyleをDataGridに追加する
                //DataGridColumnStyleを追加せずにDataGridTableStyleを追加すると、
                //DataGridColumnStyleオブジェクトのコレクションが自動的に作成される
                dataGrid2.TableStyles.Add(ts);

                //Columnの幅を変更する
                dataGrid2.TableStyles[0].GridColumnStyles[0].Width = 20;
                dataGrid2.TableStyles[0].GridColumnStyles[1].Width = 120;
                dataGrid2.TableStyles[0].GridColumnStyles[2].Width = 45;
            }
        }

これも基本的には家電情報取得と同じ流れになります。

以上で完成です。実際に動かしてみましょう。まずは、エミュレータで動かしてみてください。



では、Cabファイルを作って、実機にインストールしてみましょう。Cabの作り方は、以下のリンクを参考にしてください。

配 置用スマートデバイスソリューションのパッケージ化

実際に動かしてみた写真は次のようになります。



(ここまでのコード

■部品情報および、履歴情報クエリ
このアプリケーションでは、部品情報と履歴情報の2つのクエリを実装します。



MySQLのライブラリを使用するためには、参照設定で、「MySQL.Data.CF」を選択しておく必要があります。これを使用するためには、MySQL Connector/NETをインストールしておく必要があります。これについては、MySQLのチュートリアルを参考にしてください。MySQL.Data.CFは、MySQL Connecterフォルダの中にあります。



また、コードのディレクティブとして次のような記述を追加します。

using MySql.Data.MySqlClient;

家電情報の検索とほとんど同じですが、履歴情報のクエリのSQL文が異なります。これらのクエリで共通に部品IDを使用するので、共通に使用できる変数として、partIdを定義しておきます。

private string partId;

部品情報クエリのコードの記述には、まず、画面の「部品情報取得」ボタンをダブルクリックしてください。すると、コードのタブ(Form1.cs)にボタン押下時の処理を記述できるスタブが表示されます。そこに、次のようなコードを記述します。

        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text.Equals(""))
            {
                MessageBox.Show("部品IDが入力されていません");
            }
            else
            {
                partId = textBox1.Text;
                //サーバーに接続
                string connstr = "userid=user1;password=user1;database=trace_db;Host=192.168.0.14;charset=utf8";
                MySqlConnection conn = new MySqlConnection(connstr);
                conn.Open();

                //データを格納するテーブルを作成
                DataTable dt = new DataTable();

                //SQL文と接続情報を指定し、データアダプタを作成
                string sqlMsg = "select name,mfg,date from part_tbl where partId='" + partId + "'";
                MySqlDataAdapter da = new MySqlDataAdapter(sqlMsg, conn);

                //データ取得
                da.Fill(dt);

                //データ表示
                dataGrid1.DataSource = dt;
                //新しいDataGridTableStyleの作成
                DataGridTableStyle ts = new DataGridTableStyle();

                //DataGridTableStyleをDataGridに追加する
                //DataGridColumnStyleを追加せずにDataGridTableStyleを追加すると、
                //DataGridColumnStyleオブジェクトのコレクションが自動的に作成される
                dataGrid1.TableStyles.Add(ts);

                //Columnの幅を変更する
                dataGrid1.TableStyles[0].GridColumnStyles[0].Width = 75;
                dataGrid1.TableStyles[0].GridColumnStyles[1].Width = 75;
                dataGrid1.TableStyles[0].GridColumnStyles[2].Width = 55;
            }
        }

履歴情報クエリのコードの記述には、まず、画面の「履歴情報取得」ボタンをダブルクリックしてください。すると、コードのタブ(Form1.cs)にボ タン押下時の処理を記述できるスタブが表示されます。そこに、次のようなコードを記述します。

        private void button2_Click(object sender, EventArgs e)
        {
            if (textBox1.Text.Equals(""))
            {
                MessageBox.Show("部品IDが入力されていませ");
            }
            else
            {
                partId = textBox1.Text;
                //サーバーに接続
                string connstr = "userid=user1;password=user1;database=trace_db;Host=192.168.0.14;charset=utf8";
                MySqlConnection conn = new MySqlConnection(connstr);
                conn.Open();

                //データを格納するテーブルを作成
                DataTable dt = new DataTable();

                //SQL文と接続情報を指定し、データアダプタを作成
                string sqlMsg = "select trace_tbl.process,loc_tbl.name,trace_tbl.date from (trace_tbl inner join loc_tbl on trace_tbl.locId=loc_tbl.locId) left join struct_tbl on trace_tbl.itemId=struct_tbl.itemId where struct_tbl.partId='" + partId + "'";
                MySqlDataAdapter da = new MySqlDataAdapter(sqlMsg, conn);

                //データ取得
                da.Fill(dt);

                //データ表示
                dataGrid2.DataSource = dt;

                //新しいDataGridTableStyleの作成
                DataGridTableStyle ts = new DataGridTableStyle();

                //DataGridTableStyleをDataGridに追加する
                //DataGridColumnStyleを追加せずにDataGridTableStyleを追加すると、
                //DataGridColumnStyleオブジェクトのコレクションが自動的に作成される
                dataGrid2.TableStyles.Add(ts);

                //列"Column1"の幅を20にする
                dataGrid2.TableStyles[0].GridColumnStyles[0].Width = 20;
                dataGrid2.TableStyles[0].GridColumnStyles[1].Width = 120;
                dataGrid2.TableStyles[0].GridColumnStyles[2].Width = 50;
            }
        }

以上で完成です。実際に動かしてみましょう。まずは、エミュレータで動かしてみてください。



Cabファイルについては、省略します。

(ここまでのコード

ページの先頭へ

実装してみ よう(その3:データ更新)

次に、クライアントからサーバーへのデータ更新の部分の実装をしてみましょう。

■データベース更新
データベース接続等はこれまでと同様です。用意したボタンを押すと、MySQLサーバーにTCP接続して、そのデータを追加するという単純な流れになります。
登録データはすべてコンボボックスから選択できるようにします。
以上を踏まえて、画面にボタンを2つ(ただし1つは使用しません)、コンボボックスを6つ配置してください。また、家電IDを入力する場所として、テキストボックスを一つ用意しておいてください(試験用にtraceIdを入れるテキストボックスを使っていますが、これについては、データをauto incrementにすることで必要なくなります)。



MySQLのライブラリを使用するためには、参照設定で、「MySQL.Data.CF」を選択しておく必要があります。これを使用するためには、MySQL Connector/NETをインストールしておく必要があります。これについては、MySQLのチュートリアルを参考にしてください。MySQL.Data.CFは、MySQL Connecterフォルダの中にあります。



また、コンボボックスにはアイテムとして、処理については、「入荷」「出荷」、場所は今回使用する場所の場所識別子を、日付は、年、月、日を選べるように入れておきます。





また、コードのディレクティブとして次のような記述を追加します。

using MySql.Data.MySqlClient;

家電情報の検索とは異なりますが、データの更新で使用する家電IDをitemIdとして定義しておきます。

private string itemId;

履歴情報更新のコードの記述には、まず、画面の「履歴情報更新」ボタンをダブルクリックしてください。すると、コードのタブ(Form1.cs)にボタン押下時の処理を記述できるスタブが表示されます。そこに、次のようなコードを記述します。

        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text.Equals(""))
            {
                MessageBox.Show("家電IDが入力されていません");
            }
            else
            {
                itemId = textBox1.Text;
                string pr = comboBox1.Text;
                string loc = comboBox2.Text;
                string yr = comboBox3.Text;
                string mo = comboBox4.Text;
                string d1 = comboBox5.Text;
                string d2 = comboBox6.Text;

                //サーバーに接続
                string connstr = "userid=user1;password=user1;database=trace_db;Host=192.168.0.14;charset=utf8";
                MySqlConnection conn = new MySqlConnection(connstr);
                conn.Open();

                //SQL文を生成し、戻り値なしでコマンドを実行
                string sqlMsg = "insert trace_tbl (traceId,itemId,locId,process,date) values ("+textBox2.Text+",'"+itemId+"','"+loc+"','"+pr+"','"+yr+"-"+mo+"-"+d1+d2+"')";

                MySqlCommand cmd = new MySqlCommand(sqlMsg, conn);

                cmd.ExecuteNonQuery();

            }
        }

以上で完成です。実際に動かしてみましょう。まずは、エミュレータで動かしてみてください。



Cabファイルについては、省略します。

(ここまでのコード

実装してみ よう(その4:登録)

あとは、家電と部品の登録及び、これらの関係の登録が終われば、一通りの流れが完成します。実際には、RFタグを読み取る部分と、DBを更新する部分をひとまとまりにする必要がありますが、両者は独立になっているため、単純にくっつければ動くでしょう。
残りはチャレンジ問題としてやってみましょう。


ページの先頭へ

(作成:2012年2月1日、修正:2012年2月15日)