ラベル 在庫管理 の投稿を表示しています。 すべての投稿を表示
ラベル 在庫管理 の投稿を表示しています。 すべての投稿を表示

2014-06-30

インスタント Web/WebDirect対応在庫管理テンプレート『FMEasy在庫 IWP/WD R1.5』を本日リリース

 本日、『FMEasy在庫 IWP/WD R1.5』(フリー版)のダウンロードと販売を開始。


 ホントは昨年末にインスタントWeb(IWP)に対応の「FMEasy在庫 IWP R1.5」としてリリースする予定が、同時期に IWP の後継WebDirect(WD)を含む FileMaker Pro 13 がリリースされ、「タイミング、悪!ヽ(`Д´)ノ」、 と思いつつ、「WDにも対応させよう」と思い直し、艱難辛苦の末、今日を迎えることができました\( ̄▽ ̄;)/。


 以下、 本製品についての若干のご説明。


製品概要


  『FMEasy在庫 R1.0』 に検索・入力支援機能を付加し、インスタントWebとWebDirectに対応させたのが本製品です。


製品種類

  • フリー版(無料) ― データ入力無制限
  • 開発版(価格:¥54,000、税込) ― FileMaker Pro 12/13 Advancedにより開発可

 本製品リリース後も、在庫管理テンプレート『FMEasy在庫 R1.0』(フリー版/開発版 ¥26,250)は引き続きダウンロード/購入可。

開発方針


こんな感じで開発してみました。

  1. インスタントWeb(IWP)/WebDirect(WD)の両方に対応させる
  2. 入出庫・在庫の基本機能は『FMEasy在庫 R1.0』をそのまま踏襲
  3. FileMaker/IWP/WD間で、できるだけレイアウトを共有する(下記※参照)
  4. 検索・入力支援機能 ― 取引先または商品のレコードが千~1万件を超す場合、FileMaker標準の 関連フィールドによる値一覧は実用に耐えない(特にWeb環境下) ― ので、検索・入力支援機能を搭載する(後述)
  5. 検索・入力支援機能の流用性 ― 本製品をカスタマイズして売上/入金/仕入/支払/受注/発注等々の機能を付加する場合、取引先、得意先、仕入先、商品の入力が必要となるが、その時に検索・入力支援機能を簡単に流用できるように設計する
  6. 検索・入力支援機能は FileMaker/IWP/WD の3プラットフォームで利用できること
  7. WDの実行速度を落とさないように、レイアウトテーマは前版「FMEasy在庫 R1.0」の「レトロ」から「クラッシック」に変更 ― この為、本製品R1.5と前版R1.0の画面がかなり異なっている

※レイアウト共有で工数減?

 レイアウトを共有するとレイアウトだけでなくスクリプトも共有できる可能性が高まり、工数削減につながりそうだが、レイアウトを弄る度にFileMaker/IWP/WD、3つのプラットフォームでレイアウトのズレを気にしなければならなくなり、実際の工数減に繋がるかは微妙です。
 おおざっぱな方 ― 多少、オブジェクトが被ったりズレたりしても気にしない人はレイアウト共有し、細かいことが気になる人はレイアウトを分けた方が幸せかもしれないです。

 それともかく、本製品はIWPの入力更新系画面を除き、できるかぎり3プラットフォーム間でレイアウトを共有しています。

検索・入力支援機能


本製品のキモはなんと言っても検索・入力支援機能。
下図はWebDirect環境のChromeの画面。

[取引先の検索・入力支援機能]

※取引先画面で検索支援機能を使う
“検索支援”クリック検索支援画面が開く→取引先名を入力して“表示”表示された一覧から目的とする取引先を選択クリック元の取引先画面に戻り選択した取引先が表示される。

※出庫/入力画面で入力支援機能を使う
“選”クリック入力支援画面が開く得意先または仕入先名を入力して“表示”表示された一覧から目的とする得意先/仕入先を選択クリック元の出庫/入庫画面に戻り選択した得意先/仕入先が入力される

注:実行元の画面により、検索・入力支援画面に表示されるボタン、表記、機能が若干異なります。



[商品の検索・入力支援機能]

※商品画面で検索支援機能を使う
“検索支援”クリック検索支援画面が開く商品名を入力して“表示”表示された一覧から目的とする商品を選択クリック元の商品画面に戻り選択した商品が表示される

※出庫/入力画面で入力支援機能を使う
明細の“選”クリック入力支援画面が開く商品名を入力して“表示”表示された一覧から目的とする商品を選択クリック元の出庫/入庫画面に戻り選択した商品が入力される
  • 実行元の画面により、検索・入力支援画面に表示されるボタン、表記、機能が若干異なります。
  • 入力支援画面で[伝票単価][数量]を入力すると、その値が入出庫明細の単価と数量に入力されます。



Blog連動


 いくつかの問題もあります。 例えば、インスタントWeb(IWP)/WebDirect(WD)では満足な印刷ができない。これは FileMaker Serverの問題ですが、回避策がないこともないです。
 それは、ネットワーク上に印刷専用の FileMaker クライアント(FileMaker Robot)を常に起動しておき、IWP/WDクライアント(ブラウザ)から印刷リクエストがないか常に監視し、リクエストがあればFileMaker Robotから印刷を行うようにスクリプトを作成し、そのスクリプトを常に実行した状態にしておきます。

 別の問題として、IWPではダイアログボックス表示のスクリプトステップが使用できないため、レコード削除実行時に確認のダイアログが表示されずに即刻レコードが削除されてしまう、ということがある。

 また、 WDは各種ブラウザとの互換性が低いがFileMaker クライアントの再現性が高いのでインストラネットで、IWPは各種ブラウザとの互換性が高いので不特定多数対象のインターネットで使用したいが、WD/IWPの同時使用は可能か…等。 こうした問題・課題について、できるだけ本Blogで取り上げていきたいです。


サポート

前版インシデント2→今版5インシデント(365日間有効)に!

 ご質問については、Blog 記事として回答させて頂くこともあります →例1とか例2とか。


講習とか


 本製品をベースに在庫管理を学んでみたいという方はこんなのとか、IWPをやってみたいという方はこんなのとか、WDとはなんぞやという方はこれとか、あります。

 それでは足りない!、開発支援とかコンサルティングを!という方はこちら

 その他の在庫関連記事を読む
 その他の WebDirect 関連記事を読む

(土屋)

2013-07-25

簡単? FileMakerで在庫管理(6) ―― 場所別在庫レコードの作成方法

 ブログ記事「簡単? FileMakerで在庫管理(3) ―― 倉庫など場所別に在庫数を把握する」では、倉庫等の場所別の在庫数算についてご紹介しました。
 今回は、同機能のキモとも言える場所別在庫レコードの作成方法についてユーザ様よりお問い合わせをいただいたので、以下にその概要をご紹介します。

場所別在庫レコードの作成方法

1.場所別在庫テーブルとそのレコードの作成方針


 先の記事で紹介した場所別在庫算出方法では、下図のような場所別在庫テーブルが必要となります。



 ここで必要十分なレコードは、在庫場所テーブルと商品テーブルのデカルト積となります。


例:
在庫場所TBのレコード
A(倉庫)
B(倉庫)
C(倉庫)

商品TBのレコード
X(商品)
Y(商品)
Z(商品)

場所別在庫TBレコード
AX
AY
AZ
BX
BY
BZ
CX
CY
CZ

 さて、場所別在庫テーブルでデカルト積となるようにレコードを生成すると、各倉庫の在庫(=[c場所別在庫数])に漏れはなくなりますが、倉庫に一度も入出庫が発生していない商品がある場合、余分なレコードが存在することになってしまいます。

 たとえば、倉庫Aにおいて商品Xは入出庫したことがあるが、商品Y、Zについては入出庫が一度も発生していない場合、AXレコードは必要ですが、AY、AZレコードは、通常は不要です。
 処理速度が遅くテーブル結合が貧弱な FileMaker では、余分なレコードを極力作成しないように設計すべきでしょう。

 ということで、今回の仕様においては、入出庫登録を行う際に場所別在庫テーブルに当該商品のレコードの登録有無をチェックして、未登録の場合のみ、レコード登録を行うようにします。


2.実装概要


◇リレーションシップ

場所別在庫_入出明細#出庫 (新設、出庫明細TBと場所別在庫TBのリンク用)
場所別在庫_入出明細#入庫 (新設、入庫明細TBと場所別在庫TBのリンク用、下図)
[このリレーションを使用して、このテーブルでのレコード作成を許可]の✔を忘れずに

◇スクリプト

g確定Btn (変更、OnRecordCommitで実行されるスクリプト)
  • 入庫/出庫画面のレコード確定(OnRecordCommit)時に、入出明細ポータルをチェックし、場所別在庫レコードが存在しなければ、同レコードを作成します。
    下図の赤いフィールドは場所別在庫_入出庫明細#入庫::在庫場所IDフィールドですが、これが空欄であるということは、[在庫場所ID]=5(座間倉庫)の当該商品の場所別在庫レコードが存在しないということを意味します。その場合は、[入庫場所ID]の値を[場所別在庫_入出庫明細#入庫::在庫場所ID]に入れ、場所別在庫レコードを作成します。
  • 本スクリプト実行時になんらかのエラーが発生した場合は、エラーが発生した旨のダイアログを表示し、ダイアログ内の“OK”ボタンでレコード確定を中止し、“レコード復帰”ボタンで明細行の作成をキャンセルするようにします。
    場所別在庫レコードの作成に失敗しているにも関わらず入出明細レコードのみ確定されると、その入庫数分の在庫はシステムから消失してしまうので注意が必要です。

3.その他

  • 万が一、関連する場所別在庫レコードがない入出明細レコードが発生した場合に備え、入庫/出庫テーブルに[c在庫場所ErrMsg]フィールドを作成し、エラーが発生した場合にのみ画面に表示する、というのは用心深い良いプラクティスと言えるでしょう。
  • 場所別在庫テーブルは巨大化しやすいので、場所別在庫が0で且つ入出庫が最近発生していない場所別在庫レコードを削除するバッチ処理を検討しておくことが望ましいです。

2013-07-24

簡単? FileMakerで在庫管理(5) ―― 倉庫間移動

 当ブログの在庫関連記事 簡単? FileMakerで在庫管理(3) ―― 倉庫など場所別に在庫数を把握するでは、「FMEasy在庫 R1.0」をベースに倉庫などの在庫場所別に在庫数を算出する方法について概容を説明しました。

 そんな折、「FMEasy在庫 R1.0(開発版)」のユーザ様から、倉庫間移動に関するご質問を頂戴しましたので、今回はその手法をご紹介します。

商品の倉庫間移動


 まず、下図の青色で囲った部分をご覧ください。



 出庫画面に移動先を入力するための[移動先ID]フィールドを配置しています。
 倉庫間移動が発生する場合、ユーザは移動先のIDを入力した後、“倉庫移動”ボタンをクリックします。すると、出庫画面で入力した出庫明細と同内容のデータが入庫にも作成されるという流れになります。


下準備


 取引先マスタに「倉庫間移動」という管理項目を登録しておきます。
 このとき、倉庫間移動の[取引先ID]は「41」であったと仮定してみます。


倉庫移動スクリプト


 倉庫移動ボタンに割り当てるスクリプト仕様はおおまかに以下のとおりです。
  1. $moveTo 変数に移動先IDをコピー。
  2. 出庫明細(ポータル)内のすべての商品ID/出庫数を $prodArrayに変数配列として格納。
  3. 新規ウインドウで入庫レイアウトを開き、新規レコードを作成。
  4. [入庫場所ID]フィールドには変数1、[仕入先ID]フィールドには「41」を入力。同時に[入庫日]、[担当ID]、[伝票区分]にも適切な値を入力。
  5. $prodArray 変数に格納した出庫明細の要素を、入庫明細の商品ID/入庫数に展開。同時に各[在庫場所ID]には $moveTo 変数に保持されている値を設定。
  6. 入庫レコード確定。

 このスクリプトの実行結果は下図のようになります。



注:
  • 入庫明細作成時、場所別在庫テーブルに座間倉庫用の商品が登録されているかチェックし、無ければ登録する。 ここをミスると、商品がシステム上から消失してしまうので、要注意。
  • 入庫画面の[備考2]に移動元のIDと[場所名](倉庫名)を記録するとわかりやすい。
  • 取引先テーブルに各倉庫名を登録、さらに在庫場所テーブルに[取引先ID]フィールドを新設し、そこに各在庫場所に対応する[取引先ID]値を記録し、[仕入先ID]には上記「41」の代わりに、その倉庫の[取引先ID]を入力するのも良い。
  • 社内倉庫間の移動であるから、[仕入単価]は適切に処理 ― 例えば0を入力― する。
  • 倉庫が隣接しておらず、日単位のタイムラグが発生する場合、“倉庫移動”実行タイミングや[入庫日]の値を考慮すること。

2013-01-29

簡単? FileMakerで在庫管理(4) ―― ExecuteSQLによる在庫数算出

 これまで FileMaker Pro による在庫算出の基本、繰越処理の考え方、複数倉庫の在庫算出方法についてご紹介してきましたが、今回は商品在庫を求める方法として、3 つのパターンをご紹介したいと思います。

在庫算出の 3 つのパターン

パターン1: FileMaker Pro で在庫算出専用の TOG を構成する方法


 弊社で配布しているシンプルな入出庫・在庫管理システム/テンプレート 「FMEasy 在庫」では、以下のようなリレーションシップを構成することによって、特定時点の商品在庫を算出しています。

ここでは |×| 以外のリレーションは無視して下さい。

※「簡単? FileMakerで在庫管理(1) ―― 在庫算出の基本」に類似リレーションの解説がありますので、参考にしてみてください。

 ユーザが商品レイアウト上の [g在庫基準日1]に任意の日付を指定すると、在庫算出開始点となる日付[g在庫基準日2]を決定します。
 [g在庫基準日2]~[g在庫基準日1]の範囲内の日付で発生した商品の[入庫数]と[出庫数]が対象となるようにリレーションシップを組み、対象となった[入庫数]、[出庫数]、および商品側の[繰越在庫数]を使って[g在庫基準日1]の在庫を求めます。

 このように考えた場合、商品テーブルの [c在庫数]の計算式は、たとえば次のようになります。

Case(IsEmpty(繰越情報::繰越日付) or g在庫基準日1 < 繰越情報::繰越日付; 導入時在庫数;繰越在庫数) - Sum(入出明細_商品::出庫数量) + Sum(入出明細_商品::入庫数量)

 この計算式は比較的単純ですが、リレーションが不細工なことと、[g在庫基準日1]や[g在庫基準日2]という管理フィールドを商品テーブルに持たせざるを得ない点には、スマートさがあまり感じられませんね。


パターン2:ExecuteSQL関数を使用する方法(JOINなし)


 FileMaker Pro 12 に新たに追加された ExecuteSQL 関数を使うことによって、商品の在庫を算出します。

 この方法を採用すると、入出庫数絞り込みのためのリレーションシップが不要となります。
 また、商品テーブルの[g在庫基準日1]フィールドおよび [g在庫基準日2]フィールドも不要となります。
 ユーザが日付を指定する[g在庫基準日1]は、ユーザインタフェース専用テーブル UI に移動してしまいましょう。



 上記のように、 入出明細TO さえあればリレーションは不要となります。単純なのがいいですね!
 それでは、商品テーブルの方に在庫算出用計算フィールド[cNoJoin在庫数]を追加し、計算式を以下のようにしてみましょう。


//$date は期間開始日、$date~ UI::g在庫基準日1 の入出庫の計を加減して在庫数を算出
Let ( 
    $date = 
      Case(
        IsEmpty(繰越情報::繰越日付) or UI::g在庫基準日1 < 繰越情報::繰越日付; Date( 1; 1; 1 );
        繰越情報::繰越日付 = UI::g在庫基準日1; 繰越情報::繰越日付 +1;
        繰越情報::繰越日付 +1
      );

    Case( IsEmpty( 繰越情報::繰越日付 )  or  UI::g在庫基準日1 < 繰越情報::繰越日付; 商品::導入時在庫数;商品::繰越在庫数 )
  - ExecuteSQL ( "SELECT SUM( \"出庫数量\" ) FROM \"入出明細\" WHERE \"商品ID\" ="  &  商品::商品ID & " AND (\ "入出庫日\" BETWEEN '" &
   GetAsText ( $date ) & "' AND '" & GetAsText ( UI::g在庫基準日1 ) & "') "; ""; "")
  + ExecuteSQL ( "SELECT SUM( \"入庫数量\" ) FROM \"入出明細\" WHERE \"商品ID\" ="  &  商品::商品ID & " AND ( \"入出庫日\" BETWEEN '" &
   GetAsText ( $date ) & "' AND '" & GetAsText ( UI::g在庫基準日1 ) & "') "; ""; "")

)

 ここでは $date が [g在庫基準日2]フィールドに代わって期間開始日となるため、 [g在庫基準日2]フィールドは不要となります。


パターン3:ExecuteSQL関数でJOINする方法


 最後は、ExecuteSQL に結合(LEFT JOIN)を組み込み在庫を算出する方法です。ここでは出庫テーブルと入庫テーブルを入出明細テーブルに JOINし、出庫.出庫日 と 入庫.入庫日 を WHERE 句で使用できるようにするため、入出明細テーブルの[入出庫日]も不要となります。

 パターン2と同様、配置するのは 入出明細TO のみで、リレーションは不要です。



 結合にはLEFT JOIN を使用していますが、INNER JOIN も使えます。RIGHT JOIN は FileMaker が非対応のようです。商品テーブルで商品在庫を求める計算フィールド[cSqlLeftJoin在庫数]を追加し、以下のような計算式を組み立てます。

Let (
    $date =
        Case(
            IsEmpty( 繰越情報::繰越日付 ) or UI::g在庫基準日1 < 繰越情報::繰越日付; Date( 1;1;1 );
            繰越情報::繰越日付 = 商品::g在庫基準日1; 繰越情報::繰越日付 +1;
            繰越情報::繰越日付 +1
        );

    Case( IsEmpty( 繰越情報::繰越日付 ) or UI::g在庫基準日1 < 繰越情報::繰越日付; 商品::導入時在庫数;商品::繰越在庫数 ) -

    (
        ExecuteSQL ( "SELECT SUM( \"出庫数量\" ) FROM \"入出明細\" LEFT JOIN \"出庫\" ON \"入出明細\".\"出庫No\" = \"出庫\".\"出庫No\" WHERE \"商品ID\" ="  &  商品::商品ID & " AND ( \"出庫日\" BETWEEN '" & GetAsText ( $date ) & "' AND '" & GetAsText ( UI::g在庫基準日1 ) & "' ) "; ""; "" )
    )
    +
    ExecuteSQL ( "SELECT SUM( \"入庫数量\" ) FROM \"入出明細\" LEFT JOIN \"入庫\" ON \"入出明細\".\"入庫No\" = \"入庫\".\"入庫No\"WHERE \"商品ID\" ="  &  商品::商品ID & " AND ( \"入庫日\" BETWEEN '" & GetAsText ( $date ) & "' AND '" & GetAsText ( UI::g在庫基準日1 ) & "' ) "; ""; "" )

)

 このように商品テーブルの[g在庫基準日1]フィールドと[g在庫基準日2]フィールド、在庫算出用のリレーションに加え、入出明細テーブルの[入出庫日]フィールドが不要となります。また、入出明細テーブルに[入出庫日]を設定するというスクリプトによる面倒な制御も不要になります。


 ExecuteSQL 関数のメリット


 ExecuteSQL を利用すると、本来不要なリレーションやグローバルフィールドを省けるため、データベースの正規化がしやすくなります。また、結合を使用すれば、スクリプトによる余分な制御も不要となります。

 ただ、実行速度的にパターン1~3 のどれが一番有利かは検証が必要です。それについては機会を改めてやりたいとは思っています。



(亀澤)

2012-12-20

簡単? FileMakerで在庫管理(3) ―― 倉庫など場所別に在庫数を把握する

 弊社では在庫管理システムの講習を行っていますが、時折「うちは在庫の保管場所が複数あるので、保管場所毎に在庫を管理したいのだが、おたくの講習は対応できる?」との問い合わせを受けることがあります。 

 実のところ、複数の在庫場所に対応した在庫管理システムの構築は難度が上がってしまうのですが、なんとかコアの部分だけでも本記事でご説明させていただきます。

倉庫など場所別に在庫数を把握する


 ここでは、『FMEasy在庫 R1.0』で複数の在庫場所を管理できるように、仕様変更してみることにします。
 これまでに弊社の在庫管理講習を受講された方、または『FMEasy在庫R1.0(開発版)』ユーザ、倉庫別在庫管理の考え方を学びたい方の参考になれば幸いです。

  1. テーブル設計
    1. 在庫場所テーブル (新設、倉庫/保管場所等管理用マスタ)
      • ID(主キー)
      • 場所名(テキスト)
    2. 場所別在庫TB(新設)
      • ID(主キー)
      • 場所ID(外部キー)
      • 商品ID(外部キー)
      • 導入時在庫数(数値、導入時に元々あった商品在庫数を在庫場所別に記録)
      • 繰越在庫数(数値、繰越処理実行時に特定時点の商品在庫数を在庫場所別に記録)
      • c場所別在庫数(場所別在庫算出用計算フィールド)
      • g在庫基準日1/g在庫基準日2(入出庫の期間特定用グローバルフィールド)
    3. 入庫テーブル/出庫テーブル(変更)
      • 入庫場所ID/出庫場所ID(新設、入出庫場所を登録)
    4. 入出明細TB(変更)
      • 在庫場所ID(新設、入庫テーブル/出庫テーブルの入庫場所ID/出庫場所IDをコピーする)

  2. リレーションシップ設計

  3. レイアウト(LAY)/スクリプト設計
    1. 在庫場所LAY(新設、場所別の在庫数をポータルに表示)
    2. 入庫LAY/出庫LAY(変更)
      • 入庫場所ID/出庫場所IDを配置する
      • OnRecordCommitで入庫場所ID/出庫場所IDを入出明細テーブルの在庫場所IDフィールドにコピー
      • OnRecordCommit時、必要に応じて場所別在庫レコードを作成(4-a参照)

  4. 考慮すべき事項
    1. 場所別在庫レコードを作成するタイミング
    2. 複数倉庫がある等、場所別に在庫を管理しようとすると、FileMakerの場合、どうしても場所別に商品を登録しておく専用テーブル(場所在庫テーブル)が必要になる。そこで、場所別在庫レコードを登録するタイミングが問題となる。余分なレコードをテーブルに極力保持しないためには、入出庫レコード登録時(OnRecordCommit)に、未登録商品の場所別在庫レコードを登録するように制御する。 
    1. 倉庫間移動に対応
      • 出庫時、倉庫1の出庫伝票を、入庫時、倉庫2の入庫伝票を作成
      • 倉庫2の入庫伝票作成漏れを防ぐ
      • 倉庫2の入庫伝票作成後の関連伝票更新をどう考えるか?
    2. 出入庫同時作成機能(商品の近接場所間移動時)
    3. その他


リレーションシップ


 まず、テーブルでキモとなるのが場所別在庫テーブルですね。このテーブルにより、場所別に商品在庫数の算出が可能となります。
 ここで特に重要なフィールドは、在庫場所ID、商品ID、c場所別在庫数(計算フィールド)です。なお、下図で場所名と商品名は商品テーブルと在庫場所テーブルを参照しています。

【場所別在庫テーブルを表形式レイアウトに表示】



在庫算出部分のリレーション。

↓ 


 入出明細テーブルには商品ID/在庫場所ID(出庫元/入庫先の在庫場所ID)と入出庫数が登録されているわけだから、入出明細テーブルと場所別商品在庫テーブル上記のようにリレートして、以下のように計算式フィールをを作ればよいでしょう。 

元々ある在庫+特定期間のSum(入庫数)-特定期間のSum(出庫数)

注:
 「元々ある在庫」は繰越処理が未実行であれば[導入時在庫数]、実行済であれば[繰越在庫数]となり、「特定期間」はユーザが指定する[g在庫基準日1]と、[g在庫基準日1]のOnObjectValidate/Saveで起動するスクリプトにより制御された[g在庫基準日2]の値により決まります。
 [g在庫基準日2]の設定値については、「簡単? FileMakerで在庫管理(2)」の図が参考になると思います。

 他にもリレーションシップの追加はあるのですが、難しくないので省略します。


レイアウトとスクリプト


 入庫/出庫レイアウトには、それぞれのテーブルで新設した[入庫場所ID]と[出庫場所ID](入出庫した場所を示すID)を登録し、OnRecordCommit時に入出庫明細テーブルの[在庫場所ID]にコピーします。
 なお、Commit時に、入出明細テーブルに入力されている[商品ID]で場所別在庫テーブルに未登録の商品は登録するという、第2のキモともいうべきスクリプトについては、できれば機会を改めて書きたいと思います。

【出庫レイアウト】


 最後に在庫場所別に商品在庫数を表示するレイアウト。ユーザが[在庫基準日]に日付入力することにより、その日付時点の各商品の在庫数が表示されます。


【在庫場所レイアウト】

ポータル部分に在庫数(=場所別在庫::c場所別在庫数)と商品テーブルの情報が表示されます。
以上、『FMEasy在庫』というテンプレートをベースにカスタマイズしてみましたが、半日強の時間でとりあえず場所別在庫数は表示できるようになりました。
 上述の場所別在庫のレコード作成処理や、繰越処理は別途作成しなければなりませんが、意外と実装に時間はかかりませんでした。


 (土屋)

2012-06-01

簡単? FileMakerで在庫管理(2) ―― 繰越処理の考え方

 今回は、繰越処理に伴う在庫算出について考えていきましょう。 在庫算出の基本については、以下の記事をご覧ください。

 簡単? FileMakerで在庫管理(1) ―― 在庫算出の基本


繰越処理の考え方


 入出庫のレコードが増えてくると、在庫算出時に合計する入出庫明細レコードが膨大になり、処理速度が低下します。
 そこで、在庫数の繰越処理を行うことによって、在庫算出処理を行うことにより、在庫数算出を高速化する必要があります。
 
 たとえば、商品Aの2011年6月~2012年5月の入出庫明細データが10万件あったとします。
 2012年5月31日時点の商品Aの在庫を算出しようとして、入出庫明細レコードを10万件を対象に、Sum(入庫明細::入庫数)-Sum(出庫明細::出庫数) をやっていては、処理時間が膨大になってしまいますが、繰越処理を実行することによって2012年4月末時点の商品Aの在庫数を商品テーブルに保管しておき、5月1日~5/31の入出庫明細レコードのみをSumの対象となるようにリレーションを組めば、Sumの対象となるデータは、単純試算では10分の1以下となります。

 次に在庫算出の計算式を、以下のように繰越処理を行った場合と、行ってない場合とでは、在庫算出の計算式が違ってきます。

A式: 導入時在庫数+(4/25以前の入庫計)-(4/25以前の出庫計)

B式: 繰越処理日≦在庫基準日の場合の在庫算出式
繰越在庫数+(4/1~4/25の入庫計)-(4/1~4/25の出庫計)


C式: 繰越処理日<在庫基準日の場合の在庫算出式
  導入時在庫数+(2/28以前の入庫計)-(2/28以前の出庫計)

 要はA、B、Cの式をCase分けして、ひとつにまとめる必要があるわけです。



繰越処理と制御


 さて、繰越処理で考えておかなければいけない重要なことが一つあります。それは、繰越処理日(上記例では3/31)以前のデータ、在庫に関していえば、3/31以前の入出庫レコードの出庫日と入庫日、出庫数と入庫数を変更不可にしておく必要があります。また、3/31以前の同レコードは削除させてはならないし、繰越処理日以前の入出庫日を持つ同レコードは作成させてもいけません。 

 その理由は、[繰越在庫数]との整合性がなくなってしまうからです。

やがて訪れるデータ削除の時期について:
 長期間使用するシステムでは、繰越処理を行ってもレコードはどんどん蓄積されていきます。当社が開発・保守を担うシステムでは百数十万件の入出明細データを持つテーブルがありますが、ほぼ定期的にデータ削除を行っています。小社では、FileMaker のテーブルの最大レコード蓄積数は200~300百万件を一つの目安としていますが、データの削除は、システム仕様、実行速度要求、保持データ数要求、バックアップポリシー等の諸事情を勘案し、システムが安定動作することを大前提に実行してください。一般ユーザがデータ削除を行う場合は、一括データ削除機能も必要になります。
 また、削除したデータを照会したい、といった要望も必ずといっていいほどユーザより提示されるので、できれば過去データの照会についても予め考慮してシステム設計を行います。


在庫管理は簡単か?


 残念ながら答えは NO です
 システム的には、繰越処理とそれに伴う伝票制御、旧データ削除時の処理を考慮せざるを得ず、在庫管理システムを作るのはやはり簡単ではない、というのが結論になります。

 また、繰越処理関連を適正に実装できたとしても、1カ月に同一商品の取引が数百回以上あるような業務では在庫算出処理の遅延も予想され、別の在庫算出手法(拙稿の「FileMaker V10による在庫管理、一考」の123を参照)の採用も選択肢に入れなければならないでしょう。



土屋

2012-05-27

簡単? FileMakerで在庫管理(1) ―― 在庫算出の基本

 本稿は2012年5月に投稿されたものです。2018年2月現在、最新の FileMaker のバージョンは 16 となっていますが、本稿及び続稿で記述した在庫に関するの設計手法は現在も有効と思われます。
 ただ、iBeacon/EddyStone の登場等や、記事に気になる点があったため、今回、加筆修正することにしました。また、SQLを使った在庫の繰越処理などについても加筆したいと思っているのですが、これについては別の機会にしたいと思います。
(土屋企画)

 本稿では FileMaker を使用した在庫算出の方法について考えます。ただ本論に入る前に、在庫算出の3つの手法を大雑把に見てみます。それぞれの手法に便宜的に名前を付けていますが、これらは筆者が勝手に名付けたもので、社会、業界で一般的に利用されている名称ではありませんので、他所で「入出庫小計差分法を採用したいのですが…」とか言っても、相手の方は「???」となるでしょう。

在庫算出3つの手法

入出庫小計差分法

  この手法は当方の様々な在庫管理システムで使用している方法で、FileMaker で在庫算出する際の一般的な手法と思われます。いつの時点の在庫を知りたいのか(以下[在庫基準日])を決め、その時点までの入庫数計と出庫数計を計算、その差分が在庫となります。下図の4/30時点の在庫は、4/30迄の入庫計=20と出庫計=6の差分で[在庫]=14となります。
 Excelでは、出庫数の横に在庫列を作成して「D4+B5-C5」などとすれば簡単に在庫が求められますが、リレーショナルデータベースではそうした計算はできません。なぜならリレーションの無い行同士の演算はできないからです。無理に外部キーを振ったり、スクリプトのループで加減演算しても、結局は破綻します。
この方法は比較的単純ですが、特定の商品が頻繁に取引されるようなシステムでは、在庫算出処理に想定外の時間を要する可能性があります。

在庫マスタ逐次書換法

本手法は下図のように入出庫に変動があった場合、在庫マスタの[在庫]フィールドを即時更新する、というものです。下図を例に説明すると、3/31に[入庫数]=10を入力してコミットすると、在庫マスタテーブルの商品Aの[在庫]は即刻10に更新され、4/1に[出庫数]=1を入力すると[在庫]は9に即更新されます。
この方法は、入出庫伝票更新時に在庫マスタを即更新するため、その後発生する在庫照会や在庫表印刷の処理では各商品の在庫算出を行うことはなく、高速です。ただ、実装方法が難しいこと、上述の在庫基準日を指定できないこと、入庫日と出庫日には未来の日付を入力できないことなど、デメリットは少なからずあります。 ただ、同一商品の入出庫が頻繁に発生し、リアルタイムに在庫を把握する必要がある業態では、この手法を採用することが多いでしょう。実は2009年に本手法に関する投稿とサンプルファイル(現在リンク切れ)を公開しています。興味があるかたはこちらをどうぞ。

ビーコン信号カウント法

近年リリースされた iBeacon/EddyStone(以下、ビーコン) は少ない電力(電池)でユニークな値(UUID/UID)を含む信号を数カ月~数年、0m~100mほどの範囲で発信する装置です。
土屋企画で使用するビーコン ― 左の小さいタグ型ビーコンは 40mm×28mm 
このビーコンを製品に取り付け、その信号を取得・処理することでほぼリアルタイムに商品の在庫を把握することができます。以下のシステム図は 、Raspberry Pi と呼ばれる超小型Linux機(価格は約3000円/台)を広い倉庫内に万遍なく配置、ビーコン信号を漏れなく取得し、データベースの在庫テーブルを更新するというものです。
 入出庫システムからは独立して、在庫数の把握が可能となります。

本手法はビーコンが高価(500円~数千円~)であること、取り付けが不能・不向きな製品があること、電池に寿命があり交換が必要なこと等、ビーコン特有の問題があります。ビーコンについてはこちらを参照してください。


在庫算出の基本

さて、それでは上述の「入出庫小計差分法」について以下そのしくみを見ていきます。

 「2012年6月20日時点の在庫」というような特定時点(在庫基準日)の在庫数を算出するために、以下のようなTOG(テーブル・オカレンス・グループ)を作成してみます。


 商品マスタと出庫明細と入庫明細をリレートするだけですのでシンプルですね。
実際アプリケーションでは、出庫明細や入庫明細を格納するための出庫と入庫のテーブルが必要ですが、ここでは省略します。
 以下は上記リレーション |×| で示された部分のリレーション編集イメージです。


 [g在庫基準日]は日付のグローバルフィールドという特殊なフィールドで、詳しくは FileMaker のマニュアルを参照してください。ユーザはこのフィールドで在庫算出の起点となる日付 ― 在庫基準日 を指定します。

 そして、こちらが在庫算出用フィールド=[c在庫数]の計算式です。

繰越在庫数- Sum(出庫明細_商品::数量) + Sum(入庫明細_商品::数量)


 システム導入時、[繰越在庫数]には各商品の導入時点での在庫数を入力します。導入時、在庫が無い商品については「0」を入力しておきます。
 上記の計算式もシンプルで、[繰越在庫数](=ここでは導入時点の在庫数)から[g在庫基準日]以前に出庫した商品数量を差し引いて、さらに[g在庫基準日]以前に入庫した商品数量を加え、在庫を算出しているだけです。
 [g在庫基準日]より後の日付の入出庫が[c在庫数]の計算式の対象とならないのは、上図「在庫算出TOG」のリレーションで「≧」によりそのように定義されているからです。
注:
  1. 本稿読者で「出庫明細/入庫明細テーブルに[出庫日]/[入庫日]があるのはおかしいではないか。  本来、この二つのフィールドは出庫ヘッダ/入庫ヘッダテーブルにあるべきで、冗長で正規化されていないではないか?」と考えた方 、 御尤もです。ただ、FileMaker 内蔵DBを使用し、在庫算出基準日を任意に指定可という仕様を前提にした場合、正規化を崩しても明細に日付を持たせるのが良い、というのが小社の知見です。
  2. 但し、ExecuteSQL 関数によるSQLクエリを使用して出庫と出庫明細、入庫と入庫明細を結合(JOIN)すれば、[出庫日]/[入庫日]がそれぞれの明細テーブルに存在しなくても、在庫数を取得することができます。ただ、FileMaker の結合は実行速度が非常に遅くなることがあるので、留意が必要です。この手法についてはこちらを参考にしてください。
  3. 上記1の通りに設計する場合、出庫ヘッダ/入庫ヘッダの[出庫日]/[入庫日]と、出庫明細/入庫明細テーブルの[出庫日]/[入庫日]は常に一致するようにシステム的に保証しなければなりません。ユーザがヘッダ部の[出庫日]/[入庫日]を変更することは頻繁にあるので、スクリプトトリガを使用して、うまく制御してください。

 上記の注2 の部分が少し面倒ですが、ここまでは比較的簡単にアプリを作成できると思います。

 ただ、入出庫レコードが数千、数万と増えるに従い、在庫(c在庫数)の表示には時間がかかるようになります。在庫算出処理の時間を短くするためには、繰越処理を行い、[c在庫数]の計算対象となる入出庫レコードを減らす必要があります。 繰越処理とそれに伴う処理については、 簡単? FileMakerで在庫管理(2)―― 繰越処理の考え方 をご覧ください。

TOG(テーブル・オカレンス・グループ) とは?

FileMaker Pro 7 以降に導入されたリレーションシップグラフでは、テーブルを別名、または同一名で定義して配置できます。
 たとえば「商品」というテーブルは、リレーションシップグラフ上では「商品Table1」、「商品テーブル」、「商品」など自由に名前をつけて配置したり、同一のテーブルを別名で複数配置したりできます。

 リレーションシップシップウィンドウに配置されたテーブルは、単に”テーブル”と呼ばれたり、テーブルのエイリアスあるいはTO(テーブル・オカレンス)と呼ばれることもあります。

 FileMaker界隈 では TO という呼び名が一般的になってきているようです。また、処理別やレイアウト別に TO をグループ化したものを TOG (テーブル・オカレンス・グループ)と呼んでいます。


 以下の動画では『FMEasy在庫 IWP/WD 1.5』という製品を使用し、在庫算出に関して説明しています。




 その他の在庫関連記事を読む

(土屋)

2009-12-25

FileMaker V10による在庫管理、一考 その3

前回作成した在庫アプリ(ZaikoTestV0.fp7)の課題メモ

0.在庫と商品のテーブル分離
複数ユーザによる同時アクセス競合をできるだけ回避するため、在庫と商品のテーブルは分離し、在庫以外の商品情報はもっぱら商品テーブルに持たせる。 在庫テーブルは在庫データ専用とする。

1.競合発生時の処理
1-1 書き込みループ 
ZaikoTestV0.fp7では在庫更新時に競合エラーが発生すると、最終保存時点までRevert(ロールバック)してしまうので、競合するユーザの在庫書き込み処理が終了し、自身の在庫書き込みが成功するまで、書き込みをループさせる(最大ループ数有)。

1-2 遅延オプション
FileMaker Server 10 Advanced を使用すると、スペック的には999ユーザまでが同時アクセス可能となる。 つまり、最大999ユーザが特定の商品の在庫数を同時更新する可能性がある。
人気の新商品のリリース時に膨大な数の受注が想定される場合は、逐次処理を行うのではなく、一定間隔で明細レコードを集計して、在庫を更新するようなオプションを考慮する。 もちろん、在庫の算出は、“一定間隔”の分、遅延する。

2.在庫算出時点
特定の日付を指定して、その日付時点の在庫数を算出する場合は、「商品別末日時点在庫テーブル」を作成して月次処理を行い、この際に各商品の末日時点の在庫数をこのテーブルに書き込む。
これにより、日付指定により在庫を算出する場合でも、クエリの対象となるデータを最大1~2カ月程度に限定できる(高速化)。

以上


【関連リンク】


2012/8/1追記:
当社の在庫管理の講習で使用してるサンプルシステム「FMEasy在庫」を公開しました。フリー版/開発版のダウンロードは→こちら

【FMEasy在庫 の画面】

2009-12-24

FileMaker V10による在庫管理、一考 その2

前回作成した在庫アプリは新規出庫しか在庫と連動していなかったので、出庫伝票の更新/削除時も在庫が変更するように、修正してみた。 どんなものか見てみたい方は下記からどーぞ(パスワードはかかってませんよ)




【関連リンク】

2012/8/1追記:
当社の在庫管理の講習で使用してるサンプルシステム「FMEasy在庫」を公開しました。フリー版/開発版のダウンロードは→こちら

【FMEasy在庫 の画面】

2009-12-11

FileMaker V10による在庫管理、一考

久々のFileMaker(以下、FM)の話題。
V9以前のFMでは、在庫を算出する場合は、在庫テーブルで以下のようにやっていたのではないだろうか?

在庫::在庫(計算) = 在庫::前月分在庫 - Sum(出庫明細::出庫数) + Sum(入庫明細::入庫数)


このやり方は簡単でいいのだけれど、出庫明細や入庫明細のレコード数が多いと、1つの商品の在庫の算出にさえ、数十秒から数分の時間がかかってしまう可能性がある。 よって、商品数と伝票枚数(商品取引)が多く、リアルタイムの在庫を即時把握したいような業種では、FMは使えなかった。
言い換えると、在庫や各種残高算等、あるテーブル(上例では、出庫明細、入庫明細)のフィールド値に基づき計算を行いその結果を他テーブルの(計算フィールドではない)フィールドに精度を確保しながら保存する、ということができないということは、1995年のV3リリース以来、FMの長年の弱点の一つであった。

そんなところにFM V10が現れたのは一年程前だったか。 このバージョンでFMはイベント発生時のスクリプト起動(以下、スクリプトトリガ)に対応した。 スクリプトトリガ、特に、レコード保存時にスクリプトを実行する「OnRecordCommit」により、上記の弱点が解消される可能性がでてきたように思われる。
以下、その原案。

1. 想定(目標)
以下のような簡単な在庫管理データベースがあり、出庫伝票作成時に各商品の出庫数を在庫数から差し引くことを目的とし、その実装(スクリプト)を考えてみる。
尚、出庫伝票は新規作成のみであり、明細の更新は不可(ホンナ無茶な)とする。

【図1】


【図2】

図1の出庫伝票で、[出庫数]に入力をしレコードを保存する動作を行った時に、在庫リストの[在庫数]の値が[出庫数]を差し引いた値に更新されればいい。 但し、このとき在庫リストの[在庫数]は計算ではなく、数値フィールドである、というのが今回の肝である。


2.実装
まずレコードを保存(Commit)時に在庫テーブルの[在庫数]フィールドから[出庫数]を差し引くスクリプトが必要である。

【図3】


という具合に、出庫明細を1行づつ移動して、関連する在庫レコードの[在庫数]から[出庫数]を差し引き、[在庫数]にセットする。 途中あるエラー処理は、[出庫数]更新時にエラーが発生した場合、このスクリプトで行ったすべての処理を取り消し、レコードを最後に保存した状態に戻すためのものである。

では、ユーザの操作(クリック)に依存せず、レコード保存(Commit)時に必ずこのスクリプトを実行するにはどうしたらよいか? ここでFM V10の新機能、スクリプトトリガの「OnRecordCommit」を使用する。 詳細はマニュアルを見ていただくとして、下図のように上記で作成したスクリプトを登録すればよい。

【図4】

以上で完了。


3.テスト
テストをしてみると、一応、機能する。
図1の出庫伝票入力後に保存を行うと、商品1~3の[在庫数]は正しく「9」に更新される。

また、[在庫数]更新時にエラーが発生すると、その出庫伝票が最後に更新されたときの状態に戻り、在庫レコードも元の状態に戻る。
たとえば、商品1と2の[在庫数]の更新には成功したが、商品3の[在庫数]の更新に失敗すると、すべての処理が取り消され、最後の保存状態に戻る。 このとき、出庫レコード自体が一度も保存されていなければ、明細レコードだけではなく、出庫レコードも保存されない(作成されない)筈である。 


4.課題
さて、上記のように当初の思惑は達成されたが、いくつかの課題と懸念がある。
  1. 今回は出庫伝票は新規のみである、ことを前提としているが、当然、これでは実用には耐ええない。出庫明細の更新、削除にも対応する必要がある。
  2. 在庫テーブルで極力競合が発生しないようにテーブル設計する必要がある。
  3. 十分なテスト --- マルチユーザで競合が発生しないこと、また競合発生時も整合性が確保されること。
  4. 上記実装が正しく機能しているか、検証する仕組みの構築

1.は面倒だか、明細の主キー、商品ID、更新前の[出庫数]と更新後の[出庫数]の差分を変数に記憶しておき、Commit時に個々の商品の[在庫数]からその差分を減算すれば、解決可能である。

クリティカルな環境で上記のような在庫ロジックを実装し、実際の運用まで持ち込むのはなかなか大変だと思われるが、在庫や残高の算出遅延が運用上のネックとなっているシステムでは、一考の価値があるのではなかろうかと。

以上

土屋


【関連リンク】

2012/8/1追記:
当社の在庫管理の講習で使用してるサンプルシステム「FMEasy在庫」を公開しました。フリー版/開発版のダウンロードは→こちら

【FMEasy在庫 の画面】