Access VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


121 / 2272 ツリー ←次へ | 前へ→

【12944】dcount関数について ささや 16/2/18(木) 13:52 質問[未読]
【12948】Re:dcount関数について かるびの 16/2/19(金) 3:46 回答[未読]
【12949】Re:dcount関数について かるびの 16/2/19(金) 4:06 回答[未読]
【12950】Re:dcount関数について ささや 16/2/20(土) 10:26 お礼[未読]

【12944】dcount関数について
質問  ささや E-MAIL  - 16/2/18(木) 13:52 -

引用なし
パスワード
   アクセス初心者です。
次の3つのテーブルから、社員が担当している継続中の案件数を計算したいのですが

社員テーブル
 社員ID、社員名
案件テーブル
 案件ID、案件名、結果(継続中、成功、失敗)
関与テーブル
 ID、社員ID、案件ID

社員テーブル、関与テーブルを一対多、関与テーブルと案件テーブルを多対一で結合しています。

ここで、社員ごとに継続中の案件数を計算するクエリをつくりたいのですが、そのクエリで社員名などを編集できやるようにしておきたく、そのためには集計クエリを使わずにdcount関数を使えばいいようなのですが、関数の引数(とくに条件の部分)をどう記述すればいいのでしょうか。

よろしくお願いします。

【12948】Re:dcount関数について
回答  かるびの  - 16/2/19(金) 3:46 -

引用なし
パスワード
    冒頭から余談で恐縮ですが、
社員テーブルと案件テーブルは、多対多結合ですかね。

 そのため、両者の結合テーブルとして関与テーブルを設けたということなんでしょうね。

 で、社員テーブルと関与テーブルと案件テーブルは、一対多対一になるので、
この3つのテーブルを使って作ったクエリは、更新不可のクエリになると思うんですよね。

 更新不可のクエリになると、レコードの新規入力やレコードの訂正を行えなくなってしまいます。

 本題とは全く関係ありませんが、ちょっと気になったので、書いてみました。


 さて、本題のDCount関数についてです。

 DCount関数の第3引数(抽出条件)の書き方って難しいですね。
 私の初心者のころ散々悩まされました。ヘルプを見ても全く分からないんですね。
 でも、この第3引数の書き方なんですが、
アクセスを利用する際は、いろいろなところで使うことになります。
かなり重要度が高いです。
 是非マスターしてほしいと思います。


 で、第3引数の書き方ですが、その典型は、
   フィールド名 = 値
です。
 これを文字列として第3引数に指定します。


 ただ、値の書き方にはクセがあります。

 フィールド名のフィールドのデータ型がテキスト型の場合、
値はダブルコーテーションで囲います。例えば、
   氏名 = "かるびの"
です。
 ただ、第3引数全体が文字列となるため、
第3引数全体をダブルコーテーションで囲うことになります。
 そうすると、第3引数全体を囲うダブルコーテーションと、
値を囲うダブルコーテーションとを区別できなくなってしまいます。
 そこで、このような場合、
値を囲う方は、シングルコーテーションにします。例えば、
   氏名 = 'かるびの'
です。


 フィールド名のフィールドのデータ型が日付型の場合、
値はシャープで囲います。例えば、
   生年月日 = #2016/01/01#
です。


 フィールド名のフィールドのデータ型が数値型の場合、値は何も囲いません。
 例えば、
   数量 = 123
です。


 なお、複数の条件を指定する場合は、複数の「フィールド名 = 値」を AND や OR でつないだ文字列を第3引数に指定します。例えば、 
   "氏名 = 'かるびの' AND 数量 = 123"
です。

 ANDをダブルコーテーションの外に出してしまう奴が後を絶ちませんが、    
ANDをダブルコーテーションの外に出してしまうのは間違いです。


 次の問題は、DCount関数をクエリで使う場合、クエリのフィールドの値を使って
第3引数を設定することになるのが多いわけですが、それをどう表現するかですね。
 ヘルプでは、これがわかりにくいんです。


 少しはそちらでも考えてほしいので、御希望のこととはちょっと異なる例を使います。
 例えば、案件テーブルをベースとして、
案件に関わっている社員のうち、最大の社員IDを得るクエリを作るとします。
 この場合、最大の社員IDを得るための演算フィールドに設定する式は、
   DSum("社員ID","関与テーブル","案件ID = " & 案件ID)
となります。

 これをSQL文で書くと、

SELECT 案件ID
   ,案件名
   ,DSum("社員ID","関与テーブル","案件ID = " & 案件ID) AS 最大社員ID
FROM 案件テーブル

となります。

 で、DSum関数の第3引数ですが、
「"案件ID = " & 案件ID」における左側の「案件ID」は、
関与テーブル中の案件IDフィールドという意味です。
 左側の「案件ID」は、ダブルコーテーションの内側に入っているので、
DSum関数の第2引数に指定された「関与テーブル」のフィールドだということになります。

 一方、右側の「案件ID」は、案件テーブル中の案件IDフィールドの値という意味です。
 というのは、右側の「案件ID」は、ダブルコーテーションの中に入っていません。
 案件テーブルをベースにしたクエリの中で、ダブルコーテーションの外にいるわけですから、
右側の「案件ID」は、案件テーブルのフィールドです。

 そして、案件テーブルのフィールドであるということは、クエリにおいては、
レコードごとに異なる値をとるということです。
 したがって、右側の「案件ID」は、
案件テーブル中の案件IDフィールドの値を意味することになります。


 そこで、例えば、クエリで案件IDフィールドの値が456であるレコードにおいて、
DSum関数がどうなるかというと、
案件テーブル中の案件IDフィールドは456なのですから、
   "案件ID = " & 案件ID 
という文字列式は、
   "案件ID = " & 456
ということになり、この式が計算されて
   "案件ID = 456"
ということになります。

 そして、当該レコードの「最大社員ID」フィールドには、
   DSum("社員ID","関与テーブル","案件ID = 456")
が返す値が表示されるということになります。

 
 敢えて、そのものズバリの回答とはせず、少し回り道をした回答にしてみましたが、
以上のことを踏まえて、自分で考えてみてください。

【12949】Re:dcount関数について
回答  かるびの  - 16/2/19(金) 4:06 -

引用なし
パスワード
    書き忘れです。


 クエリの演算フィールドでDCount関数やDSum関数など、D系関数と呼ばれる関数を使うと、
クエリがものすごく重くなります。
 つまり、クエリを開こうとしても、クエリがなかなか開いてくれないということになります。

 どのくらいクエリが重くなるかは、パソコンの性能や、各テーブルのレコードの件数次第なので、
何とも言えませんが、
私の認識としては、クエリでD系関数は使ってはいけないと考えています。


>ここで、社員ごとに継続中の案件数を計算するクエリをつくりたいのですが、そのクエリで社員名などを編集できやるようにしておきたく、
 解説本などを読むと、クエリでレコードを編集するということが堂々と書いてありますが、
クエリで編集するというのはデータベースの使い方として外れています。

 エクセルでは、データの保存、データの計算、データの表示、データの入力・訂正、データの印刷
を全てワークシートでやってしまいますが、
アクセスでは、それら別々のオブジェクトで行います。
 データの保存はテーブル、データの計算はクエリ、データの表示とデータの入力・訂正はフォーム、データの印刷はレポートです。

 確かに、テーブルやクエリでも、データの表示や入力・訂正はできますが、
それは本来の使い方ではないので、人間にとっての使いやすさを追求することができません。


 今回の場合、メイン/サブ形式のフォームを使うことができるかもしれません。

 メインフォームには、社員テーブルのデータを表示するようにし、
サブフォームには、集計クエリを表示するようにし、
メインフォームとサブフォームとを社員IDでリンクさせます。


 ただ、どこかの掲示板での回答のため、途中までサンプルを作ってみたのですが、
メインフォームをデータシートにした場合は、思い通りにならなかったんですね。
 メインフォームを帳票フォームにしたら、どうだろうかとも思うのですが、
こちらの方は未実験です。


 とはいえ、クエリから入力した方が人間にとって使いやすいということも考えられるので、
メイン/サブ形式のフォームがベストだとは言い切れませんけどね。

【12950】Re:dcount関数について
お礼  ささや  - 16/2/20(土) 10:26 -

引用なし
パスワード
   ▼かるびの さん:

とてもわかりやすくて丁寧な説明をありがとうございました。

・ダブルコーテーションとシングルコーテーションの違い
・Andなどが入る場合の構文
・"[社員ID]" &[社員ID] の意味など
まさに知りたかったことを全部教えていただいて大変助かりました。
おかげでDCOUNT関数で担当件数を計算することができました。

ところで、計算できたはいいのですが、関与テーブルをベースに計算したため、
これを社員テーブルと結合するクエリをつくると一社員一テーブルにならない
問題が起きることが分かりました。

そこで、アドバイスいただいたように、サブフォームでフォームに表示させ、
その部分だけ集計クエリで担当件数を計算しすることにしました。
(もともと本当は社員フォーム上で入力をできるようにしたかったのですが、
サブフォームの仕組みや関連付けの方法がわからず避けていました。)
いろいろ調べてどうにか、
社員のほかのフィールド値が社員フォーム上で編集可能にしたまま
担当件数もフォーム(サブフォーム)に表示するという目的が達成できました。

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

121 / 2272 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
1078188
(SS)C-BOARD v3.8 is Free