Microsoft Access 掲示板

views
4 フォロー
6,283 件中 5,561 から 5,600 までを表示しています。
3

ちなみに、yossiさんが参考にした レコードがない場合も用紙の最後まで罫線を出力する関数
のレポートに対して、ご希望の表示にする場合は

受注コード ヘッダーのフォーマット時イベントに

Private Sub グループヘッダー0_Format(Cancel As Integer, FormatCount As Integer)
    Me.Page = 1
End Sub

と記述すれば、あとは 先の回答と同じ手順で出来るでしょう。

 
※ テキストボックス txtGC は、受注コードのグループフッターに配置すればいいでしょう。

RptFixRowFunc_07.accdbのレポートは
  関数の引数により、20行分の罫線を出力していますが、
  ページフッター( の高さ )で、2行分を消費するため、
  1ページに表示可能なデータの最大行数は 実質 18 となっています。
 
  したがって、合計金額表示用テキストボックスのコントロールソースは
   =IIf([Page] = -Int(-[txtGC] / 18), [合計], Null)

 
※ 今回は、[印刷時拡張] プロパティが「 いいえ 」のため、
  簡単にグループ毎のページ数が算出可能ですが、
 「 はい 」だと、この方法は使えず、難易度は高くなります。

1

件数が多くなった場合、合計が1ページ目にも2ページ目にも表記されてしまいます。
合計値を1ページ目には表記せずに最終のページのみ表記する方法がないでしょうか。

yossiさんが参考にしたコンテンツの現象 及び 要望を正確に申し上げるなら

  グループ毎のページ数が、( 1ページに収まらず )複数ページに及ぶ場合でも
  合計金額が全てのページに表示されてしまうため、
  グループ毎の最終ページにのみ、合計金額を表示する方法が知りたい

ではないでしょうか。

だとすると
参考になさるのは、こちらのほうがいいでしょう。
 

用紙の最後まで罫線を出力し、グループ毎に Page/Pages を表示する
掲示板で下記のような質問がありました。 hatena の Microsoft Access 掲示板|レポート背景にPDFを使用しデータを1行ずつ印刷する帳票作成|ツリー表示 > スレッドNo.2075 ここで問題になったのが、下記の2つを同時に設定すると、ページ数がグループ毎にならずに、すべて「1/1、1/1・・・」となってしまうという症状が発生するということです。 レコードがない場合も用紙の最後まで罫線を出力する - hatena chips ...
fc2

 
上記のコンテンツでダウンロードできる RptFixRowPagePages.accdb
のレポート R_納品書 を例にして説明すると

■ 手順1

 
受注コード のグループヘッダーへ、テキストボックスを新たに1つ配置します。
このテキストボックスの各プロパティを

  名前:        txtGC
  コントロールソース: =Count(1)
  可視:        いいえ

とします。


■ 手順2

 
このレポートは、ページ毎に最大15レコード表示できるようですから
ページヘッダーに配置されている
合計金額を表示するためのテキストボックス( 担当者氏名の直下にある )
のコントロールソースを

=IIf([Page] = 1, [合計], Null)

から

=IIf([Page] = -Int(-[txtGC] / 15), [合計], Null)

に変更します。


以上です。

8

( おまけ )

>> 5reito117さんの SQL を添削した正解例は、以下になります。
( 前回申し上げたとおり、煩雑で汚い SQL 文になりますから、この記述はお勧めしません )
 

SELECT Max( IIf( q.種別 = 0, q.勘定科目コード ) )  As ex1
     , Max( IIf( q.種別 = 0, q.勘定科目 ) )        As ex2
     , Max( IIf( q.種別 = 0, q.cost ) )           As 金額_資産
     , Max( IIf( q.種別 = 1, q.勘定科目コード ) )  As 勘定科目コード
     , Max( IIf( q.種別 = 1, q.勘定科目 ) )        As 勘定科目
     , Max( IIf( q.種別 = 1, q.revenue ) )        As 金額_負債
FROM
(
    SELECT IIf( x.勘定科目コード \ 1000 IN ( 1, 9 ), 0, 1 ) As 種別
         , x.勘定科目コード
         , x.勘定科目
         , x.[金額(資産)]                                  As cost
         , x.[金額(負債)]                                  As revenue
         , Count(1)                                       As gnum
    FROM 貸借対照表 x
       , 貸借対照表 y
    WHERE ( 
              ( x.勘定科目コード Between 1001 And 1999 )
                  OR
              ( x.勘定科目コード Between 2000 And 3001 )
                  OR
              x.勘定科目コード IN ( 9002, 9004, 9005 )
          )
      AND ( 
              ( y.勘定科目コード Between 1001 And 1999 )
                  OR
              ( y.勘定科目コード Between 2000 And 3001 )
                  OR
              y.勘定科目コード IN ( 9002, 9004, 9005 )
          )
      AND IIf( x.勘定科目コード \ 1000 IN ( 1, 9 ), 0, 1 )
              = IIf( y.勘定科目コード \ 1000 IN ( 1, 9 ), 0, 1 )
      AND x.勘定科目コード >= y.勘定科目コード
      AND Abs( x.[金額(資産)] ) > 0
      AND Abs( y.[金額(資産)] ) > 0
    GROUP BY x.勘定科目コード
           , x.勘定科目
           , x.[金額(資産)]
           , x.[金額(負債)]
) q
GROUP BY gnum
ORDER BY gnum ;
2
SUSUMU 2020/02/22 (土) 07:37:59 1a64f@9d2f0

hirotonさん
コメントありがとうございます。

目的は、誤入力でエラー状態になると、プログラムが停止してしまう事を回避する事です。
おっしゃる通り誤入力を防ぐという手段でも回避は可能ですね。
早速設定しましたら、ありえない年月の入力はできなくなりエラー回避できるようになりました。
とりあえずこれで運用できそうです。

どうも、ありがとうございました。

7
mayu 2020/02/21 (金) 15:03:45 修正 a3615@61ad5

( 続き )

次に、勘定科目コード、種別、金額 の抽出条件全てを満たす
レコードを表示するためのクエリを作ります。
( SQLの結果に Q_表示対象 という名前を付けて保存します )

SELECT y.種別
     , x.勘定科目コード
     , x.勘定科目
     , x.[金額(資産)] As cost
     , x.[金額(負債)] As revenue
FROM 貸借対照表 x
   , T_条件     y
WHERE x.勘定科目コード Between y.コードfrom And y.コードto
  AND y.種別 Between 0 And 1
  AND Abs( x.[金額(資産)] ) > 0 ;

 

種別勘定科目コード勘定科目costrevenue
010018100-8100
018911200-1200
01999500000-500000
12000-120000120000
128887000-7000
13001-1000010000
090023200-3200
0900415000-15000

 
■ 仕上げのSQL

SELECT Max( IIf( q.種別 = 0, q.勘定科目コード ) )  As ex1
     , Max( IIf( q.種別 = 0, q.勘定科目 ) )        As ex2
     , Max( IIf( q.種別 = 0, q.cost ) )            As 金額_資産
     , Max( IIf( q.種別 = 1, q.勘定科目コード ) )  As 勘定科目コード
     , Max( IIf( q.種別 = 1, q.勘定科目 ) )        As 勘定科目
     , Max( IIf( q.種別 = 1, q.revenue ) )         As 金額_負債
FROM 
(
    SELECT x.種別
         , x.勘定科目コード
         , x.勘定科目
         , x.cost
         , x.revenue
         , Count(1) As gnum
    FROM Q_表示対象 x
       , Q_表示対象 y
    WHERE x.種別 = y.種別
      AND x.勘定科目コード >= y.勘定科目コード
    GROUP BY x.種別
           , x.勘定科目コード
           , x.勘定科目
           , x.cost
           , x.revenue
) q
GROUP BY gnum
ORDER BY gnum ;

 
■ 結果

ex1ex2金額_資産勘定科目コード勘定科目金額_負債
100181002000120000
189112002888-7000
1999500000300110000
90023200
900415000
6
mayu 2020/02/21 (金) 15:01:49 修正 a3615@61ad5

・1000番代と9002,9004,9005番代が左側、2000番代と3000番代が右側になるようにする。
この結果を出すためのSQLコマンドがうまくいきません

gnumの列を見ると並びがきれいに並ばなくなります。

左側に表示するコードと、右側に表示するコードに 規則性や共通点が無いですから

  AND x.勘定科目コード \ 1000 = y.勘定科目コード \ 1000

という区分けが、意味をなさなくなったのが原因です。

とはいえ、
SQL文の記述が、読みにくくて 見通しが悪い場合は
条件の分岐や、マジックナンバーの追記 といった手法を採用すると
記述がますます汚くなりますから
設計を見直したり工夫するのが、定番の解決方法になります。

■ 貸借対照表

勘定科目コード勘定科目金額(資産)金額(負債)
700X450-450
1000Z25000-25000
10018100-8100
102000
18911200-1200
1999500000-500000
2000-120000120000
28887000-7000
299900
300000
3001-1000010000
3002-1400014000
300300
8999A4000-4000
90005500-5500
9001450-450
90023200-3200
9003-80008000
900415000-15000
900500
9006-25002500
999954321-54321
 
だとして
まずは、条件を入力するためのテーブル T_条件 を作ります。
`sql
CREATE TABLE T_条件
(

      rid         AUTOINCREMENT  PRIMARY KEY
    , 種別        INT            NOT NULL
    , コードfrom  INT            NOT NULL
    , コードto    INT            NOT NULL
);


 
■ テーブルデータ

| rid | 種別 | コードfrom | コードto |
|-----|------|------------|----------|
| 1   | 0    | 1001       | 1999     |
| 2   | 0    | 9002       | 9002     |
| 3   | 0    | 9004       | 9005     |
| 4   | 1    | 2000       | 3001     |
| 5   | 2    | 4000       | 4999     |
| 6   | 3    | 5000       | 5999     |

5
reito117 2020/02/21 (金) 10:04:53

回答ありがとうございます。
教えて頂いた通りにできました。
また、教えて頂いて恐縮ですが下記の様にするにはどうすればいよいか教えて頂きたく。
・1000番代と9002,9004,9005番代が左側、2000番代と3000番代が右側になるようにする。

この結果を出すためのSQLコマンドがうまくいきません
↓書いたSQLコマンド
※テーブル名、損益計算書→貸借対照表
SELECT Max(IIf([貸借対照表].[勘定科目コード]<2000 Or [貸借対照表].[勘定科目コード]>9000,[貸借対照表].[勘定科目コード])) AS 勘定科目コード
, Max(IIf([貸借対照表].[勘定科目コード]<2000 Or [貸借対照表].[勘定科目コード]>9000,[貸借対照表].[勘定科目])) AS 勘定科目
, Max(IIf([貸借対照表].[勘定科目コード]<2000 Or [貸借対照表].[勘定科目コード]>9000,[貸借対照表].cost)) AS 金額_資産
, Max(IIf([貸借対照表].[勘定科目コード] Between 2000 And 3001,[貸借対照表].[勘定科目コード])) AS 勘定科目コード2
, Max(IIf([貸借対照表].[勘定科目コード] Between 2000 And 3001,[貸借対照表].[勘定科目])) AS 勘定科目2
, Max(IIf([貸借対照表].[勘定科目コード] Between 2000 And 3001,[貸借対照表].revenue)) AS 金額_負債, 貸借対照表.gnum
FROM (SELECT x.勘定科目コード
, x.勘定科目, x.[金額(資産)] AS cost
, x.[金額(負債)] AS revenue
, Count(1) AS gnum
FROM 貸借対照表 AS x
, 貸借対照表 AS y
WHERE x.勘定科目コード Between 1001 And 3001 Or x.勘定科目コード=9002 Or x.勘定科目コード=9004 Or x.勘定科目コード=9005
AND  y.勘定科目コード Between 1001 And 3001 Or y.勘定科目コード=9002 Or y.勘定科目コード=9004 Or y.勘定科目コード=9005
AND x.勘定科目コード \ 1000 = y.勘定科目コード \ 1000       
AND x.勘定科目コード >= y.勘定科目コード       
AND Abs( x.[金額(資産)] ) > 0       
AND Abs( y.[金額(資産)] ) > 0
GROUP BY x.勘定科目コード
, x.勘定科目
, x.[金額(資産)]
, x.[金額(負債)])  AS 貸借対照表
GROUP BY 貸借対照表.gnum
ORDER BY 貸借対照表.gnum;

返した結果が下記になります
勘定科目コード 勘定科目    金額_資産 勘定科目コード2 勘定科目2 金額_負債 gnum
9005    減価償却累計額  0          37
9004    立替金    70000   3001 預り金   50000 73

gnumの列を見ると並びがきれいに並ばなくなります。

何卒教えて頂きたくお願い致します。

4
名前なし 2020/02/20 (木) 17:16:35 97073@60c58

思った通りの形になりました。

本当にありがとうございました。

1
hiroton 2020/02/20 (木) 17:02:49 dbf30@f966d

誤った値を入力した場合に、処理を継続し、データがない状態を表示することは必要ですか?
テキストボックス「年月」の書式に「yyyy/mm」と設定してしまえばありえない数値の入力は防げます(ありえない数値を入力するとエラーが発生し入力が確定できなくなります)

3
hiroton 2020/02/20 (木) 16:26:36 修正 dbf30@f966d

売上金額を3列に増やして各列に条件を付けて集計しようということです

SELECT t受注一覧.受注ID,
 受注金額,
 Sum( iif( 日付 < #1/1/2020#, 売上金額)) AS 前月迄売上,
 前月迄売上 / 受注金額 AS 前月迄出来高,
 Sum( iif(日付 Between #1/1/2020# And #1/31/2020#, 売上金額)) AS 当月売上,
 当月売上 / 受注金額 AS 当月出来高,
 Sum( 売上金額) AS 累計売上,
 累計売上 / 受注金額 AS 累計出来高
FROM t売上明細 INNER JOIN t受注一覧 ON t売上明細.受注ID = t受注一覧.受注ID
GROUP BY t受注一覧.受注ID, 受注金額
HAVING t受注一覧.受注ID Like "18170*";

t売上明細を元に一部抜粋すると次のようなデータを集計(合計)する形になります

日付受注ID前月迄売上当月売上累計売上
2019/11/3018170-37,128,0007,128,000
2019/12/3118170-37,128,0007,128,000
2020/1/3118170-32,376,0002,376,000
2
名前なし 2020/02/20 (木) 14:51:03 8486c@60c58

返信ありがとうございます。

売上金額フィールドの複製 が勉強不足で良く分かりません。

新規のクエリで上記コードをそのまま貼り付けてみましたが
受注ID別に表示させるための 「like "18170*"」 の入力場所がよく分かりませんでした。

18170の現場を表示させる時には
---------前月迄売上 当月売上 累計
18170-1
18170-2
18170-3

というように表示させたく、売上明細にはそれ以外にも複数の受注IDの売上が入力されています。

1
hiroton 2020/02/20 (木) 14:11:14 修正 dbf30@f966d

WHERE句を使わずに、売上金額フィールドを複製してそれぞれに抽出条件を設定し集計するといいと思いますよ

Sum( iif( t売上明細.日付 < #1/1/2020#, t売上明細.売上金額)) AS 前月迄売上,
Sum( iif(t売上明細.日付 Between #1/1/2020# And #1/31/2020#, t売上明細.売上金額)) AS 当月売上,
Sum( t売上明細.売上金額) AS 累計売上
4

( 続き )

■ 損益計算書

勘定科目コード勘定科目金額(費用)金額(収益)
4001仕入25000-25000
4002売上原価00
4003発送費00
4004減価償却費500000-500000
4005広告宣伝費120000-120000
4006通信費7000-7000
4007水道光熱費10000-10000
4008租税公課00
4009給料00
4010旅費交通費-1400014000
4011支払保険料00
4012消耗品費4000-4000
4013雑損00
4014貸倒引当金繰入00
5001売上-35003500
5002商品売買益00
5003受取手数料00
5004受取家賃70-70
5005受取利息00
5006受取配当金00
5007雑益00
5008有価証券利息-100100
5009有価証券売却益00
5010固定資産売却益00
5011償却債権取立益-120120

 
■ SQL

SELECT x.勘定科目コード
     , x.勘定科目
     , x.[金額(費用)] As cost
     , x.[金額(収益)] As revenue
     , Count(1)      As gnum
     , Sum( IIf( x.勘定科目コード \ 1000 = 4, y.[金額(費用)], 0 ) ) As total_cost
     , Sum( IIf( x.勘定科目コード \ 1000 = 5, y.[金額(収益)], 0 ) ) As total_reve
FROM 損益計算書 x
   , 損益計算書 y
WHERE x.勘定科目コード Between 4000 And 5999
  AND y.勘定科目コード Between 4000 And 5999
  AND x.勘定科目コード \ 1000 = y.勘定科目コード \ 1000
  AND x.勘定科目コード >= y.勘定科目コード
  AND Abs( x.[金額(費用)] ) > 0
  AND Abs( y.[金額(費用)] ) > 0
GROUP BY x.勘定科目コード
       , x.勘定科目
       , x.[金額(費用)]
       , x.[金額(収益)]
ORDER BY x.勘定科目コード ;

 
■ 結果

勘定科目コード勘定科目costrevenuegnumtotal_costtotal_reve
4001仕入25000-250001250000
4004減価償却費500000-50000025250000
4005広告宣伝費120000-12000036450000
4006通信費7000-700046520000
4007水道光熱費10000-1000056620000
4010旅費交通費-140001400066480000
4012消耗品費4000-400076520000
5001売上-35003500103500
5004受取家賃70-70203430
5008有価証券利息-100100303530
5011償却債権取立益-120120403650
3

x.yは何のテーブルorクエリに該当するのでしょうか?(自己結合というもの?)

x と y は両方ともに 損益計算書 のことですが
既にご理解いただいてるように、自己結合 を駆使した場合は
同じ名前のオブジェクトを複数使用することになりますから
各々を区別するため、ユニークな名前を付与する必要があります。

from句の損益計算書 x,損益計算書 yは
損益計算書 As x,損益計算書 As yを単純に省略してるだけ?

はい。その通りです。
Microsoft Access では、エイリアスの利用において
FROM句の As は省略可能で SELECT句 の As は省略不可
という仕様になっています。

q=テーブルorクエリ名

テーブル名でもクエリ名でもないのですが、意味合いとしてはクエリになります。

SELECT x.勘定科目コード ...(略)... , x.[金額(収益)]

この部分で、一つの完結したクエリ( SQL文 )になり
Accessにおいても、名前を付けて保存する ことが可能です。
もちろん、保存せずに使用することも可能で
その場合は、インラインビューやサブクエリという言い方をします。

今回の場合だと、インラインビューになっていて
q というのは、インラインビューに付けた名前です。

このビューの役割は
4000番台 のコード と 5000番台 のコードそれぞれにグループ連番を付与することですが
累計計算も同時に出来たりしますから
以下にデモンストレーションを掲載しておきます。

2
reito117 2020/02/18 (火) 10:47:29

mayu様
前回に引き続きありあとうございます。

前回はmayu様の教えて頂いた集約関数のやり方で解決させて頂きましたので、
こちらの方はをあまり見ずに申し訳なく思っています。

上記について教えて頂きたく。
q=テーブルorクエリ名
x.yは何のテーブルorクエリに該当するのでしょうか?(自己結合というもの?)

それにちなんでfrom句の損益計算書 x,損益計算書 yは損益計算書 As x,損益計算書 As yを単純に省略してるだけ?
もしくは最初のx yと関係してる?

お手数ですが宜しくお願い致します。

1

前回の回答、2020/01/25 (土) 09:05:50 に記述した SQL へ
金額が 0 ではない科目が表示対象になるよう 抽出条件を加えれば
ご希望の結果になるでしょう。
 

SELECT Max( IIf( q.勘定科目コード < 5000, q.勘定科目コード ) )  As ex1
     , Max( IIf( q.勘定科目コード < 5000, q.勘定科目 ) )        As ex2
     , Max( IIf( q.勘定科目コード < 5000, q.cost ) )            As 金額_費用
     , Max( IIf( q.勘定科目コード > 4999, q.勘定科目コード ) )  As 勘定科目コード
     , Max( IIf( q.勘定科目コード > 4999, q.勘定科目 ) )        As 勘定科目
     , Max( IIf( q.勘定科目コード > 4999, q.revenue ) )         As 金額_収益
FROM
(
    SELECT x.勘定科目コード
         , x.勘定科目
         , x.[金額(費用)] As cost
         , x.[金額(収益)] As revenue
         , Count(1)      As gnum
    FROM 損益計算書 x
       , 損益計算書 y
    WHERE x.勘定科目コード Between 4000 And 5999
      AND y.勘定科目コード Between 4000 And 5999
      AND x.勘定科目コード \ 1000 = y.勘定科目コード \ 1000
      AND x.勘定科目コード >= y.勘定科目コード
      AND Abs( x.[金額(費用)] ) > 0
      AND Abs( y.[金額(費用)] ) > 0
    GROUP BY x.勘定科目コード
           , x.勘定科目
           , x.[金額(費用)]
           , x.[金額(収益)]
) q
GROUP BY gnum
ORDER BY gnum ;
1
hatena 2020/02/13 (木) 11:54:29 修正

下記と同じ内容の質問ですね。下記で回答が付いていますのでそちらで続けてください。

Access - Accessのショートカット配布可否について|teratail

3
db_sgl 2020/02/08 (土) 18:04:30 bfddf@029ad

アドバイスありがとうございます。
確かに2003はセキュリティ面でも厳しいので、さっそく2019を購入しました。

OutputメソッドでPDFは簡単にできました。
あとは、メール添付の方を、いろいろと試してみたいと思います。

8
和菓子 2020/02/07 (金) 14:15:29 05554@4b4f6

ありがとうございます。
初歩的なミスでお手数をお掛けしました。
何度もすみせんでした。

7

原因は、ウィンドウモードを「ダイアログ」に設定していることですね。
ダイアログで開くとそのウィンドウ以外は操作できなくなります。
ウィンドウモードを「標準」に変更してください。

6
名前なし 2020/02/05 (水) 15:46:05 846ee@4b4f6 >> 5

【レポートBを開く】ボタンは埋込マクロにしています。画像1

9
reito117 2020/01/31 (金) 11:01:53

回答ありがとうございます。

まさか回答頂けると思わなかったので驚きました。
でも教えて頂いたおかげで理解が出来ました。

gEXはグループ化のために作った計算式をフィールドに表示してみるとってことです

これで理解が出来ました。
group byの列は2つ同じ勘定科目コードを作成し、それをグループ化することで一行にできる。

それと同時にこのような事をすぐにわかる事が出来るのが本当にすごいと思いました。
自分もこのような難しい内容をすぐに出来る様になってみたいです。

本当に感謝しかありませんが、改めてありがとうございます。

5
hatena 2020/01/31 (金) 06:12:00 修正

レポートAに【レポートBを開く】ボタンを作成しています。

このボタンのクリック時のイベントプロシージャのコードを提示して下さい。

4
和菓子 2020/01/30 (木) 13:49:52 05554@4b4f6

レポートA・レポートB 共に「いいえ」にしています。

8
hiroton 2020/01/30 (木) 11:54:58 7cddf@f966d

集計直前の状態をイメージできるとわかると思いますよ
SQLからGROUP BY句を消し、集計関数のMAXもなくすと

ex1ex2金額_費用勘定科目コード勘定科目金額_収益gEX
4001仕入250004001
5001売上35004001
4002売上原価04002
5002商品売買益04002
4003発送費04003
5003受取手数料04003

こんな感じになります
gEXはグループ化のために作った計算式をフィールドに表示してみるとってことです

gEXでグループ化し、各列MAXをとれば、MAXといっても2レコードの内片方にしか値がないので必ずその値を拾ってきます

並べたいレコードがちょうどセットになるようなgEXを作ればいいので
q.勘定科目コード - IIf( q.勘定科目コード < 5000, 0, 1000 )GROUP BYだから何か特別なことをしているということはありません

ついでにORDER BYも同じ式を使っているので4001からきれいに並んでいるわけですね

7
reito117 2020/01/30 (木) 10:07:20

度重なる質問に対して誠にありがとうございます。
正直なところ力不足でまだ理解が追い付いていない部分もありますが、理解が出来る様に頑張っていきます。
また何かありましたら力を貸して頂ければ幸いです。

27
mayu 2020/01/29 (水) 19:33:07 修正 9b175@61ad5 >> 26

少し気になって、期首在庫は必要ないのでしょうか?
それによってはすべてアウトになりそうで^^;;

フック船長さんのテーブル構成だと、棚卸をおこなった時点で

 ・ 製品ID毎に、実在庫に対して過不足があった場合は
   過不足分の数量を登録したレコードを DB登録して 不整合を解消する。
 ・ 製品ID毎に、詳細テーブルは 実在庫分の数量を記載した1レコードのみ の状態にし、
   棚卸実行日以前の全レコードは、別の場所へバックアップした上で削除

のどちらかで実現可能でしょうし、
テーブル設計が きちんと出来ていることから
フック船長さんは こういった業務知識や手法を身につけている可能性が高いのではないか
というのが、私の見解です。 
 

上記でどうでしょうか?
クエリーでも使用できると思いますし、少し工夫すれば、期首在庫にも対応できるはず^^;;

N + 1 問題
に該当しています、とだけ。

3

レポートBの作業ウィンドウ固定が、はいになってませんか。なっていたら、いいえにしてください。

2
和菓子 2020/01/29 (水) 11:33:53 05554@4b4f6

お返事いただきありがとうございます。
言葉不足で本当に申し訳ございません。

レポート上のテキストボックスをクリックするのですか。
⇒はい。レポート上のテキストボックスをクリックして、入力フォームを立ち上げています。

レポートはレポートビューで開いているということですか。
⇒はい。レポートビューで開いています。

これは無理です。アクティブなオブジェクトは一つだけですので。
⇒勉強不足で申し訳ございません。

レポートAに【レポートBを開く】ボタンを作成しています。
レポートAを開いて(レポートA上にある)【レポートBを開く】ボタンをクリックすることで、レポートBを開いています。
この場合、レポートBがアクティブになっているのですが、各々の詳細セクションをクリックするなどして、
レポートAをアクティブにしたり、レポートBをアクティブにしたりしたいのです。(クリック動作でアクティブを切り替えたい)

教えていただいたコードをレポートAの詳細セクション⇒イベント⇒クリック時に入力してみましたが、レポートAをアクティブにすることができませんでした。

すみません…
あまりにも基礎が理解できていませんでしょうか…
申し訳ございません。

1

レポートを用い、テキストボックスをクリックすることで入力フォームを立ち上げる仕様にしています。

レポート上のテキストボックスをクリックするのですか。
レポートはレポートビューで開いているということですか。

先に開いた「レポートA」にフォーカスを移動することができません。(

いつ、どこでというのが不明確ですが、「レポートA」をアクティブにする(フォーカスを移動させる)のは、下記のコードになります。

    DoCmd.SelectObject acReport, "レポートA", False

(若しくは、どちらのレポートもアクティブにすることはできますか?)

これは無理です。アクティブなオブジェクトは一つだけですので。

26
スナフキン 2020/01/28 (火) 11:16:24 837f8@06760

横から失礼。
はじめまして、スナフキンと申します。
少し気になって、期首在庫は必要ないのでしょうか?
それによってはすべてアウトになりそうで^^;;

一応、標準モジュールに
Public Function F_出庫数(int製品ID As Integer, str年月 As String, Optional bln集計区分 As Integer = 0) As Double

    Dim strQuery As String

    If bln集計区分 = 0 Then
        strQuery = "SELECT SUM(S.出庫数量) AS 出庫数量 FROM 出庫詳細 S LEFT JOIN 出庫 SH ON S.出庫ID=SH.出庫ID WHERE S.製品ID=" & int製品ID & " AND Format(SH.出庫日,'YYYYMM')='" & str年月 & "'"
    Else
        strQuery = "SELECT SUM(S.出庫数量) AS 出庫数量 FROM 出庫詳細 S LEFT JOIN 出庫 SH ON S.出庫ID=SH.出庫ID WHERE S.製品ID=" & int製品ID & " AND Format(SH.出庫日,'YYYYMM')<'" & str年月 & "'"
    End If

    Dim cn As New ADODB.Connection
    Dim rec As New ADODB.Recordset

    Set cn = CurrentProject.Connection
    Set rec = cn.Execute(strQuery)

    If rec.EOF = False Then
        F_出庫数 = Nz(rec.Fields("出庫数量"), 0)
    Else
        F_出庫数 = 0
    End If

    rec.Close: Set rec = Nothing
    cn.Close: Set cn = Nothing

End Function

Public Function F_入庫数(int製品ID As Integer, str年月 As String, Optional bln集計区分 As Integer = 0) As Double

(出庫と同じなので省略)

End Function

上記参照設定でADOにチェックです^^/

を用意したとして
製品IDを1
2020年1月の場合

前月在庫数=F_入庫数(1,"202001",1)-F_出庫数(1,"202001",1)
当月入庫数=F_入庫数(1,"202001")、当月出庫数=F_出庫数(1,"202001")
当月在庫数=F_入庫数(1,"202001",1)-F_出庫数(1,"202001",1)+F_入庫数(1,"202001")-F_出庫数(1,"202001")

上記でどうでしょうか?
クエリーでも使用できると思いますし、少し工夫すれば、期首在庫にも対応できるはず^^;;

かな??

25

質問ですが作成していただいたSQL文にx.~やy.~と記載されていますが
どのような意味があるのでしょうか。
(IIF関数に必要な条件のようなものでしょうか)

xy は、 エイリアス と言って
SQL文の中で、一時的に テーブルやクエリに 別の名前をつけています。

 x ---> 製品 ( 実在のテーブル )のこと
 y ---> ユニオンクエリ ( SELECT 入庫詳細.製品ID ... DateSerial( ... , 0 ) ) のこと

私がエイリアスを付与する理由は、主に以下のようなものになります。

【 1 】
SELECT 句や WHERE 句 など、各句の中で
列の名前を エイリアスで修飾( エイリアス名.列の名前 )すると
どのテーブルの列を 射影や選択といった操作の対象としているのか、明確になります。

【 2 】
画数の多いテーブルやクエリに 画数の少ないエイリアス を付与すると
オブジェクト修飾する記述を用いた際に
タイピングが楽(?)で、SQL の見映えがすっきりするという利点があります。( 多分 )

【 3 】
SQL 文中で使用するテーブルやクエリの名前に 予約語や記号などが含まれていて
Microsoft が推奨していない 命名規則 になっている場合、
( 例えば T-table とか T名前(hoge) とか currency とか )
オブジェクト修飾の際に [] で括る記述を強要されて 非常に見映えが悪いため、
( [T-table].列名 とか [T名前(hoge)].列名 とか [currency].列名 とか )
せめて SQL文の中だけでも、まともな命名規則のオブジェクト名を付与したい

【 4 】
複数のオブジェクトに共通して存在する名前の列 を操作する場合だけは
 オブジェクト名.列名
というように、
どのオブジェクトを操作するのか、明確に指定する必要がありますが
( 今回の場合だと 製品ID が該当し、オブジェクト修飾しないとエラーになります )
列によって、修飾したり しなかったりという記述にしてしまうと
長文 SQL の場合は、可読性が落ちますし、一貫性も欠如してしまいます。

 
ですから、単一のテーブルのみを使用している SQL では
エイリアスの付与も、オブジェクト名の修飾も不要です。

24
フック船長 2020/01/27 (月) 16:55:39 f3309@31d50

mayu様
返信が遅くなり申し訳ありません。レポートを作成できました。ありがとうございます。

質問ですが作成していただいたSQL文にx.~やy.~と記載されていますがどのような意味があるのでしょうか。(IIF関数に必要な条件のようなものでしょうか)

見当違いで意味がないのであれば申し訳ありません。

6

GROUP BY q.勘定科目コード - IIf( q.勘定科目コード < 5000, 0, 1000 )

並びの肝の部分だと思うのですが、
この条件式でなぜこんなきれいな並びになるかわかりません。

勘定科目コードの 4000番台と5000番台の下3桁同士を
同じグループ( 母集団 )に所属させるための演算になります。
例えば

  ・ 4000 と 5000 が同じグループ ( 4000 - 0 = 4000, 5000 - 1000 = 4000 )
  ・ 4011 と 5011 が同じグループ ( 4011 - 0 = 4011, 5011 - 1000 = 4011 )
  ・ 4999 と 5999 が同じグループ ( 4999 - 0 = 4999, 5999 - 1000 = 4999 )

になります。
( 並び替えも演算結果の数値順になるよう、ORDER BY句に同様の式を記述しています )

したがって、

GROUP BY q.勘定科目コード - IIf( q.勘定科目コード < 5000, 0, 1000 )
ORDER BY q.勘定科目コード - IIf( q.勘定科目コード < 5000, 0, 1000 )

GROUP BY q.勘定科目コード Mod 1000
ORDER BY q.勘定科目コード Mod 1000

 
と記述しても 同様の結果を得ることが可能です。

5
reito117 2020/01/27 (月) 11:48:18

mayu様

回答ありがとうございます。
正に思う通りの内容を記載して頂いた上に、様々教えて頂き大変恐縮です。

SQLはわずかながらに読める程度なので後学の為に教えて頂きたいです。
教えて頂いた3つのうちの1つ、集計クエリでのGROUP BY句の部分です。
GROUP BY q.勘定科目コード - IIf( q.勘定科目コード < 5000, 0, 1000 )

並びの肝の部分だと思うのですが、この条件式でなぜこんなきれいな並びになるかわかりません。
色々と調べてみてもわからないので教えて頂きたくお願い致します。

4

hatenaさん、こんにちは。
各方面でのご活躍、いつも拝見させていただいております。
管理者権限での表の編集、承知いたしました。わざわざのご連絡、ありがとうございます。

3

mayuさん、いつも回答ありがとうございます。
質問の編集は私が管理者権限で行いました。見やすくする為にテーブルをマークダウン書式にしました。

2

2020/01/24 (金) 15:00:34 に私が回答した後
2020/01/24 (金) 19:11:55 に投稿内容が編集されているようですが
その上で未解決ということは、もしかすると SQLの扱いが初めて なのでしょうか。

SQLは、フォームやレポートのレコードソースへも直に記述できるため
記述場所としては、色々あるわけですが

クエリを作るという状況において
SQLをどこに記述すればいいのか わからない
ということでしたら、以下をご覧になるといいでしょう。
 

クエリ SQL文でクエリを編集する: ACCESSとVBAとシステム開発
 ACCESSのクエリデザイン画面は、SQLの構文が分からなくても、感覚的な操作でクエリを作成することが出来る、とても便利なツールです。  SQLを直接書けるレベルになっても、キーボードからテーブル名や項目名を入力しなくて良いので、ちょっとした検索や集計をするのに便利です。  SQLServerやOracleなどの本格的なデータベースを使用するようになっても、ACCESSのクエリの便利さを一度覚えると、ACCESSが手放せなくなります。  簡単なクエリを作る場合、ACCESSのクエリデザインの画面はとても便利ですが、扱う項目数やテーブル数が多くなったり、複雑な条件を入力する場合や、サブクエリを利用したい場合は、デザイン画面ではやりにくいことがあります。  複雑な条件の場合は、グリッド..
ACCESSとVBAとシステム開発

 
なお、

損益計算書

勘定科目コード勘定科目金額(費用)金額(収益)
4001仕入25000-25000
4006通品費7000-7000
4010旅費交通費-1400014000
5006受取配当金-100100
5008有価証券利息00

 
上記のように、勘定科目コードの属性毎に欠番がある場合、
 

Expr1000Expr1001金額(費用)勘定科目コード勘定科目金額(収益)
4001仕入25000
4006通品費70005006受取配当金100
5008有価証券利息0
4010旅費交通費-14000

 
下3桁で完全外部結合するのではなく
 

Expr1000Expr1001金額(費用)勘定科目コード勘定科目金額(収益)
4001仕入250005006受取配当金100
4006通品費70005008有価証券利息0
4010旅費交通費-14000

 
同属の科目を昇順に並べるだけの場合は、SQLのロジックにもう一工夫必要になります。
 

SELECT Max( IIf( q.勘定科目コード < 5000, q.勘定科目コード ) )  As ex1
     , Max( IIf( q.勘定科目コード < 5000, q.勘定科目 ) )        As ex2
     , Max( IIf( q.勘定科目コード < 5000, q.cost ) )            As 金額_費用
     , Max( IIf( q.勘定科目コード > 4999, q.勘定科目コード ) )  As 勘定科目コード
     , Max( IIf( q.勘定科目コード > 4999, q.勘定科目 ) )        As 勘定科目
     , Max( IIf( q.勘定科目コード > 4999, q.revenue ) )         As 金額_収益
FROM
(
    SELECT x.勘定科目コード
         , x.勘定科目
         , x.[金額(費用)] As cost
         , x.[金額(収益)] As revenue
         , Count(1)       As gnum
    FROM 損益計算書 x
       , 損益計算書 y
    WHERE x.勘定科目コード Between 4000 And 5999
      AND y.勘定科目コード Between 4000 And 5999
      AND x.勘定科目コード \ 1000 = y.勘定科目コード \ 1000
      AND x.勘定科目コード >= y.勘定科目コード
    GROUP BY x.勘定科目コード
           , x.勘定科目
           , x.[金額(費用)]
           , x.[金額(収益)]
) q
GROUP BY gnum
ORDER BY gnum ;

 
ただし、データベースというのは 本来
第三者が見ても「 行単位でデータ構造を把握できる形 」になっている必要があり、
関連のない複数のデータが同じ行に並んでいるのは、不自然と言っていいでしょう。

投稿文のタグに クエリ・フォーム・レポート の3つが付与されていることから
どのオブジェクトにおいても段組で表示したい のだと想像しますが
コードの体系別に2列表示したいだけなら、レポートのみで行うことをお薦めします。

1

どのようにすればいいか教えて頂きたくお願い致します。

3パターンの SQL を載せておきます。

■ 集計クエリ

SELECT Max( IIf( q.勘定科目コード < 5000, q.勘定科目コード ) )  As ex1
     , Max( IIf( q.勘定科目コード < 5000, q.勘定科目 ) )        As ex2
     , Max( IIf( q.勘定科目コード < 5000, q.[金額(費用)] ) )    As 金額_費用
     , Max( IIf( q.勘定科目コード > 4999, q.勘定科目コード ) )  As 勘定科目コード
     , Max( IIf( q.勘定科目コード > 4999, q.勘定科目 ) )        As 勘定科目
     , Max( IIf( q.勘定科目コード > 4999, q.[金額(収益)] ) )    As 金額_収益
FROM 損益計算書 q
WHERE q.勘定科目コード Between 4000 And 5999
GROUP BY q.勘定科目コード - IIf( q.勘定科目コード < 5000, 0, 1000 )
ORDER BY q.勘定科目コード - IIf( q.勘定科目コード < 5000, 0, 1000 ) ;

 
■ 自己結合

SELECT x.勘定科目コード As ex1
     , x.勘定科目       As ex2
     , x.[金額(費用)]   As 金額_費用
     , y.勘定科目コード
     , y.勘定科目
     , y.[金額(収益)]   As 金額_収益
FROM      損益計算書 x
LEFT JOIN 損益計算書 y
ON
( 
      ( x.勘定科目コード Between 4000 And 4999 ) 
  AND
      x.勘定科目コード = y.勘定科目コード - 1000
)
ORDER BY x.勘定科目コード ;

 
■ 完全外部結合

SELECT y.勘定科目コード As ex1
     , y.勘定科目       As ex2
     , y.[金額(費用)]   As 金額_費用
     , z.勘定科目コード
     , z.勘定科目
     , z.[金額(収益)]   As 金額_収益
FROM
(
    (
        SELECT 勘定科目コード
        FROM 損益計算書
        WHERE 勘定科目コード Between 4000 And 4999
        UNION
        SELECT 勘定科目コード - 1000
        FROM 損益計算書
        WHERE 勘定科目コード Between 5000 And 5999
    ) x
    LEFT JOIN 損益計算書 y
           ON x.勘定科目コード = y.勘定科目コード
)
LEFT JOIN 損益計算書 z
       ON x.勘定科目コード = z.勘定科目コード - 1000
ORDER BY x.勘定科目コード ;
3
Access大好き 2020/01/23 (木) 19:07:22 39c03@a34e4

テーブルに書き込もうかと思います。サーバにテキストファイルとして一括出力を考えていたのですが
無理そうですので。。