この特集のトップページへ
Chapter 3:データストア層の構築

head2.gif 3.2.6 在庫の処理
 その時点の在庫数は,製品情報テーブルのSTOCKフィールドに格納することにした(Table 3-2参照)。だが,これだけでは製品の入出庫を管理することができない。そこで,新しく在庫情報テーブルを作り,製品の入出庫を管理することにする。在庫情報テーブルとは,「どの製品が,いつ,いくつ入庫または出庫したか」を管理するものである。当然のことながら,製品の在庫数は,在庫情報テーブルに記載された「入庫数の和−出庫数の和」ということになる。しかし,これだけでは面白くないので,「いつ入庫または出庫したか」だけではなく,「いつ入庫または出庫する予定であるか」も記録することにする。そうすれば,営業部のメンバーは伝票を作成するときに,必要な製品がいつまでに揃うのかを知ることができるようになる。

 ここでは,在庫情報テーブルをTable 3-11のように定義する。

Table 3-11 在庫情報テーブル

フィールド名

サイズ

NULL

解説

ID

数値型
(オートナンバー)

不可

レコードに対して唯一無二の値を割り当てる

DATE

日付型

不可

入庫および出庫の予定日

DUEDATE

日付型

入庫および出庫が実際に行われた日

CONFIRMEDFLAG Boolean型 入庫および出庫が実際に行われたかどうかのフラグ。行われていればTrue,まだ行われていなければFalse
PRODUCTID

数値型

不可

この明細の対象となる製品を示す製品番号。製品情報テーブルのIDフィールドに格納されているいずれかの値が格納される

NUMBER 数値型 不可 入庫および出庫の数量。入庫の場合には正の数を,出庫の場合には負の数を格納する
MEMO 文字型 80 摘要
SLIPID 数値型 出庫のとき,この出庫が生じるもととなった伝票の伝票番号。伝票情報テーブルのIDフィールドに格納されているいずれかの値が格納される

 在庫情報テーブルには,製品の入庫と出庫の両データを格納する。入庫のときには,製品の数を示すNUMBERフィールドの値を正で,出庫のときには負で示すことで,入庫と出庫を区別する。

 入庫と出庫は,その施行予定日をDATEフィールドに格納する。そして,実際に入出庫があった場合には,CONFIRMEDFLAGフィールドの値をTrueにし,その日をDUEDATEフィールドに格納する。また,このとき,製品情報テーブルのSTOCKフィールドに,在庫情報テーブルのNUMBERフィールドの値を加える。こうすることによって,製品情報テーブルのSTOCKフィールドは,その時点の在庫数を正しく示すようになる(Fig.3-12)。一般的にDATEフィールドに格納する日付とDUEDATEフィールドに格納する日付は一致するはずだが,入庫や出庫が予定どおりに行われなかった場合には,両者に格納される値が異なることもあり得る。

Fig.3-12 製品情報テーブルと在庫情報テーブルとの関係
fig3_12.gif

 ところで,製品の出庫とは,営業部から回ってきた伝票に記載された情報に基づき製品管理部のメンバーが顧客に製品を発送することである。そこで,在庫情報テーブル内の出庫レコード(NUMBERフィールドの値が負のもの)は,伝票が発送可能になったとき(伝票情報テーブルのCONSENTEDFLAGフィールドがTRUEに設定されたとき)に自動的に生成するようにする。

 このとき,どの伝票から発生した出庫なのかを管理する必要がある。なぜなら,伝票が削除された場合には,その伝票から生じた在庫情報テーブルの出庫レコードを削除する必要があるからである。そこで,在庫情報テーブルには,SLIPIDというフィールドを設け,出庫レコードを作成するもととなった伝票の伝票番号(伝票情報テーブルのIDフィールドの値)を格納し,出庫レコードと伝票とを連結できるようにした(Fig.3-13)。

Fig.3-13 在庫情報テーブルの出庫のレコード
fig3_13.gif

 なお,入庫レコードは,製品管理部の入庫担当者が手作業で追加することにする。実業務を考えれば,入庫用の伝票と連携させることも考えられるのだろうが,ここではそこまでシステムの範囲を広げることはしない。入庫レコードであれば,SLIPIDフィールドにNULLを格納する。

○在庫のチェック

 さて,営業部のメンバーが伝票を入力するときの話だが,伝票に記載された製品が納期までに揃わなければ,その伝票はシステム側で受け付けないようにしたい。そうしておけば,在庫が足りないにもかかわらず,顧客から受注してしまうことがなくなるからである。

 その時点の製品の在庫数は,製品情報テーブルのSTOCKフィールドに格納される。よって,伝票内の明細に記された製品が足りるかどうかを調べるためには,製品在庫テーブルのSTOCKフィールドの値と,伝票内の製品の注文数とを比較すればよいように思われる。

 しかし,その方法ではうまくいかない。たとえば,ある製品の在庫が100個であるとする。このとき,製品情報テーブルにおいて,その製品を示すレコードのSTOCKフィールドの値は100である。さて,この状態でAという人がこの製品を30個注文したとする。これは在庫数以下であるから,受注することができる。次に,Aが受注した製品を発送するまえに,別のBという人が同じ製品を90個受注したとしよう。Fig.3-12で示したように,在庫数は入庫や出庫が実際に行われた時点で更新しているため,Aが受注した製品が発送されるまでのあいだ,STOCKフィールドの値は100のままである。よって,単純にSTOCKフィールドの値と注文数とを比較したのでは,Bによる90個の受注を受け付けてしまう。この状態は,Aが30個,Bが90個,合計で120個を受注しているということである。しかし,在庫は100個しかなく,Aの受注を受けた時点で本来の在庫は70個となるから,Bの90個の注文を受け付けたという処理は正しくない。このような処理を実装してしまった場合,Aの受注分が発送された時点で,Bの受注分を発送するだけの在庫が存在しないことが判明することになるだろう(Fig.3-14)。

Fig.3-14 単純にSTOCKフィールドの値を比較するだけの在庫のチェック
fig3_14.gif

 この問題を解決するため,その時点の在庫数を保存するSTOCKフィールドだけでなく,製品の予約数(すでに伝票が生成され,製品の発送を待っている製品の個数)を保持するため,BACKORDERフィールドを製品情報テーブルに追加する(Table 3-12)。

Table 3-12 予約数を追加した製品情報テーブル

フィールド名

サイズ

NULL

解説

ID

数値型
(オートナンバー)

不可

製品番号。レコードに対して唯一無二の値を割り当てる

PRODUCTNAME

文字型

64

不可

製品名

YOMIGANA 文字型 80 製品名のよみがな

PRICE

金銭型

不可

製品の価格

STOCK

数値型

不可

現在の在庫数

MEMO 文字型 80 摘要
BACKORDER 数値型 不可 在庫のうちすでに予約されている数

 そして,伝票を受け付けるたびに,その伝票内に記載された製品の数量をBACKORDERフィールドの値に加える。これによって,STOCKフィールドに保存されている在庫数のうち,BACKORDERフィールドに格納された数だけが予約されていることを意味するようになる。伝票を受け付けるときには,その製品の「在庫数−予約数」,すなわち「STOCKフィールドに格納された値−BACKORDERフィールドに格納された値」が伝票の注文数以上であることを調べればよい。先の例でいえば,ある製品の在庫が100個あるとき,STOCKフィールドの値は100である。この状況下でAが30個受注したとすると,BACKORDERフィールドには30が格納される。つまり,残りは100−30=70個ということになる。よって,Bが90個の受注を受けたとき,予約されていない在庫は70個しかないため,伝票の受付を拒否すればよい(Fig.3-15)。

Fig.3-15 予約数という概念を導入した在庫のチェック
fig3_15.gif

 ところで,伝票の在庫状況をチェックする場合,何も伝票の起票時点で在庫が揃っていなければならないというものでもない。製品は,伝票に記載された納期に間に合うように揃えればよいのである。すでに説明したように,在庫情報テーブルには,「製品が,いつ,いくつ入荷する予定か」という情報も格納されている。そして,製品の入庫と出庫はNUMBERフィールドの正負で区別するようにした。たとえば,1999年10月10日までに製品番号が10番の製品が全部でいくつ入荷する予定か(すでに入荷したものは省く)を調べるには,次のようなSELECT文を実行すればよい。

   SELECT SUM(NUMBER) FROM 在庫情報テーブル 
   WHERE PRODUCTID=10 AND DATE <=#99/10/10# 
   AND CONFIRMEDFLAG=False AND NUMBER > 0

 よって,もし1999年10月10日に納品する伝票であれば,その時点の在庫数に上記のSELECT文で取得した入庫予定数の合計を加えたものが伝票に記載された注文数以上であれば,その伝票を受け入れられるということになる(Fig.3-16)。

Fig.3-16 納品予定日を考慮した在庫のチェック
fig3_16.gif

 なお,納品予定日によるチェックは,あくまでも在庫が足りるかどうかを予定に従って判定しているだけである。製品の入庫が何らかの事情で遅れた場合,すなわち,在庫製品テーブルのDUEDATEフィールドに格納される日付がDATEフィールドに格納される日付よりも遅い場合には,伝票を受け付けたものの,在庫が足りなくなり,発送できないということになる。この場合には,納期より発送を遅らせるほかはない。この処理は,ビジネスアプリケーション側に実装するのではなく,それを利用するユーザー側で臨機応変に処理するようにする。具体的には,製品管理部のメンバーが営業部の担当者に「製品が間に合わない」と告げ,営業部の担当者が顧客に詫びて納期をずらしてもらったり,ほかの急ぎでない伝票をいったんキャンセルして在庫をやりくりしたり,といった運用上の工夫で対処することになるだろう。

prevpg.gif Chapter 3 10/22 nextpg.gif