データベース千夜一夜第16回

プログラミングとSQL(4)
~販売データの入力処理(前編)
長谷川裕行
有限会社 手國堂

伝票番号の生成

お客様IDが入力されると、テーブル「顧客_mr」からそのIDをキーにして該当するレコードを抽出し、氏名や住所フィールドの値をラベルに表示します。同時に、この段階で新しい受注が発生したと見なせるので、新しい伝票番号を生成してラベル“lblSlipNumber”に表示します。伝票番号はテーブル「売上ヘッダ」と「売上明細」にレコードを追加する際にも必要となるため、グローバル変数“strSlipNumber”にも保存しておきます。


- 伝票番号の仕様 -

伝票番号は「日付(月日)+0埋め4桁の連番」という形で、例えば12月3日の3件目の受注なら「12030003」となります。

最終的には、1日の受注を終えたら「売上ヘッダ」と「売上明細」に記録されているレコードをすべてテーブル「累積売上_fx」に定着(リレーションを断ち切って、氏名、品名などの値を固定的に記録すること)しますが、今回は「売上ヘッダ」と「売上明細」に記録するまでの処理を作ります。

こういった処理では、定着したレコードの内容をさらに月単位でまとめ、年度の最後には1年の累積データとして別名あるいは別のデータベースに保存することが多いので、伝票番号の先頭に「年」を示す数値を付け足さないようにしています。特に重要なことではないので、例えば「0412030003」のような形で先頭に「年を示す値」を付け足しても構いません。


- 伝票番号生成の仕組み -

伝票番号は前半の日付部分と後半の連番とに分かれます。日付はテキストボックスtxtDateから簡単に取得できますが、問題は連番です。連番は「最初の受注のとき:1、2件目の受注のとき:2……」という具合に、受注のたびに1ずつ増えていきます。

この件数は受注した商品の数ではなく、顧客ごとの受注件数から導き出せます。従って、受注を1件ごとに記録している「売上ヘッダ」のレコード件数に1を加算した値が、新しい伝票の連番となります。

先述したように、このサンプルでは1日の受注をすべて「売上ヘッダ」に記録しておき、1日の最後にそれらを取りまとめて定着するという仕様なので、このような形で連番を取得できるのです。

1件の受注を完了した時点で即座にレコードを定着する仕様なら、連番の元になるレコード件数は「累積売上_fx」から取得することになります。その場合、日付によってレコードを絞り込むなど、少し面倒な処理が必要になるでしょう。


- 受注件数の取得 -

具体的な伝票番号の生成は、お客様IDの入力後に氏名などを表示する処理と共に行います。その下請けとなる「現在の受注件数を取得する処理~Functionプロシージャ“GetSlipCount”」の仕組みを説明しておきましょう。

これはFunctionプロシージャで、成功すれば現在の受注件数をInteger型の値で返し、失敗すれば-1を返します。失敗とは、主にデータベースの接続エラーです。

プロシージャの宣言に続いて、データベースへのアクセスを行うオブジェクト変数の宣言を行います。これは、既に何度も紹介してきた通りです。

   Private Function GetSlipCount() As Integer
   Dim objConnect As New SqlConnection
Dim objCommand As New SqlCommand
Dim objDataReader As SqlDataReader
Dim strSql As String

売上ヘッダのレコード件数を取得するため、SELECT命令に集計関数COUNTを用いたSQLを準備します。

    strSql = "SELECT COUNT(*) FROM 売上ヘッダ"

COUNT関数はテーブルのレコード数を32ビットのInt型(VB .NETのInteger型)で返す集計関数で、引数に*を指定すればすべてのレコード件数を返してきます。WHERE句を用いれば、特定のレコードだけに絞り込んだ件数を取得することも可能です。集計関数についてはまだ説明していないので、ここでは単純に「テーブルのレコード数を取得する」と捉えておいてください。

データベースに接続してSQLを発行するまでの処理は、既に何度も紹介してきたものと同じです。

     Try
   ↓接続文字列~コネクションの設定
objConnect.ConnectionString = _
"Persist Security Info=False;Integrated Security=SSPI;database=db1001ya;server=localhost"
objCommand.Connection = objConnect
↓接続を開いてCommandオブジェクトにSQLを設定
objConnect.Open()
objCommand.CommandText = strSql

CommandオブジェクトのExecuteReaderメソッドでSQLを発行し、その結果をDataReaderに受け取ります。これも、既に説明した通りです。

       objDataReader = objCommand.ExecuteReader()
objDataReader.Read()

レコード件数はDataReaderのReadメソッドを実行した後、DataReaderのGetxxxメソッドで取得します。Readメソッドの結果はレコードセット(行の集合)であって、COUNT関数の戻り値ではありません。

Getxxxメソッドは、取得する値の型によってGetInt16、GetInt32、GetDouble、GetDateTimeなど各種あります。型を間違えると正しい値が取得できません。ここでは32ビットのInt型の値を取得するため、GetInt32を用います。()内の引数は結果を格納したフィールドのインデックスで、0から始まります。COUNT関数が返すレコードは1件で先頭フィールドの件数が格納されているので、GetInt32(0)とします。

       GetSlipCount = objDataReader.GetInt32(0)
If GetSlipCount < 0 Then
   GetSlipCount = 0
End If

それ以降は、データベースの例外処理と接続を閉じる処理なので割愛します。



トップページ
全体の仕様を把握する
フォームのデザイン
データの準備
下請け処理~コントロールと変数の初期化
伝票番号の生成
伝票番号の仕様
伝票番号生成の仕組み
受注件数の取得
顧客情報と伝票番号の表示
レコードの追加~AddHeader
あとがき
Copyright © MESCIUS inc. All rights reserved.