Microsoft Access 掲示板

在庫数の算出 / 20

29 コメント
views
4 フォロー
20
フック船長 2019/12/27 (金) 11:41:19 f3309@31d50

hiroton様
確認取れました。ありがとうございました。

通報 ...
  • 21
    フック船長 2020/01/09 (木) 18:14:06 f3309@31d50 >> 20

    明けましておめでとうございます。

    上記のクエリを基にレポートをウィザードで作成しようとしますとクエリのフィールド名が表示しません。どのように行えばレポートを作成できるのでしょうか?

    23

    >> 1のテーブル構成では、出庫詳細 と 入庫詳細 のフィールド名が、共に「 数量 」なのに
    >> 5のSQL文では、出庫詳細 と 入庫詳細 のフィールド名が「 入庫数量 」及び「 出庫数量
    また、製品テーブルの 製品型番 というフィールドは 投稿文に掲載されておらず、実際の有無が不明。

    こういった情報の欠落や矛盾は、ご自身で修正いただくとして
    ご希望の結果は 以下のような SQL で表現できるでしょう。

    PARAMETERS [Forms]![フォーム1]![表示月] DATETIME ;
    SELECT Format$( Nz( [Forms]![フォーム1]![表示月], Date() ), 'yyyy\年m\月' ) As 年月
         , x.製品ID
         , x.製品型番
         , x.製品名
         , Sum(
               IIf( y.入出庫日 
                      < DateSerial( Year( CDate( Nz( [Forms]![フォーム1]![表示月], Date() ) ) )
                                  , Month( CDate( Nz( [Forms]![フォーム1]![表示月], Date() ) ) )
                                  , 1 )
                  , y.入出庫数 * y.入出庫区分
                  , 0
               )
           ) As 前月在庫
         , Sum(
               IIf( y.入出庫日 
                        >= DateSerial( Year( CDate( Nz( [Forms]![フォーム1]![表示月], Date() ) ) )
                                     , Month( CDate( Nz( [Forms]![フォーム1]![表示月], Date() ) ) )
                                     , 1 )
                        And
                    y.入出庫区分 > 0
                  , y.入出庫数
                  , 0
               )
           ) As 入庫
         , Sum(
               IIf( y.入出庫日 
                        >= DateSerial( Year( CDate( Nz( [Forms]![フォーム1]![表示月], Date() ) ) )
                                     , Month( CDate( Nz( [Forms]![フォーム1]![表示月], Date() ) ) )
                                     , 1 )
                        And
                    y.入出庫区分 < 0
                  , y.入出庫数
                  , 0
               )
           ) As 出庫
         , Sum( y.入出庫数 * y.入出庫区分 ) As 当月末在庫
    FROM 製品 x
    INNER JOIN
    (
        SELECT 入庫詳細.製品ID
             , 入庫.入庫日        As 入出庫日
             , 入庫詳細.入庫数量  As 入出庫数
             , 1                  As 入出庫区分
        FROM 入庫
        INNER JOIN 入庫詳細
                ON 入庫.入庫ID = 入庫詳細.入庫ID
        WHERE 入庫.入庫日 
                  <= DateSerial( Year( CDate( Nz( [Forms]![フォーム1]![表示月], Date() ) ) )
                               , Month( CDate( Nz( [Forms]![フォーム1]![表示月], Date() ) ) ) + 1
                               , 0 )
        UNION ALL 
        
        SELECT 出庫詳細.製品ID
             , 出庫.出庫日
             , 出庫詳細.出庫数量
             , -1
        FROM 出庫
        INNER JOIN 出庫詳細
                ON 出庫.出庫ID = 出庫詳細.出庫ID
        WHERE 出庫.出庫日
                  <= DateSerial( Year( CDate( Nz( [Forms]![フォーム1]![表示月], Date() ) ) )
                               , Month( CDate( Nz( [Forms]![フォーム1]![表示月], Date() ) ) ) + 1
                               , 0 )
    ) y
    ON x.製品ID = y.製品ID
    GROUP BY x.製品ID
           , x.製品型番
           , x.製品名
    ORDER BY x.製品ID ;
    

     
    中間クエリを作らず、SQLを一筆書きで記述してますので
    内容について少し解説しておきます。ポイントは3つ。

    【 1 】
    FROM句のサブクエリになっているユニオンクエリでは
    製品・入荷先・出荷先 各テーブルの列は不要ですから、内部結合を必要最小限に留め、
    抽出条件は、最初に評価されるクエリ( 一番内側 )に設定することで 処理を高速化できます。

    【 2 】
    SELECT句では IIF関数を使って条件分岐させることで
    当月在庫と前月在庫を一度に計算します。
    ( 入庫・出庫に関しても同様 )
    こうすると、クロス集計クエリを作る必要もなく、構造を単純化できます。

    【 3 】
    指定月のパラメータは
    フォームのコントロールによる 日付の入力 を想定していますけど
    入力をスキップすると、自動的に現在の月が設定されます。

  • 22

    クロス集計クエリを使ったクエリを基にするとそうなるようです
    クロス集計クエリ(Q入出庫明細のクロス集計クエリ)にクエリ列見出しを設定しておくとレポートウィザードでもフィールド名が表示されるようになります