Accessの入門書を読んで、この「クエリ」という項目で、つまずいた人もいると思います。
Accessをマスターするにあたって最初の壁になるのかも知れません。
確かに、厳密に話し出すと非常に奥が深く、いろいろな機能があって、一言でクエリーといっても、
選択クエリ・更新クエリ・削除クエリ・ユニオンクエリ・・・・
それに、「クエリとは、元々、SQL文が・・・」などと説明し始めると、初めて聞く人にとっては、Accessを勉強する事が苦痛になってくるのではないでしょうか。
でも、心配する必要は、ありません。
「クエリ」は、使う人を苦痛にする為にあるものでは、ありません。大変、便利なものです。
その「便利さ」を順番に説明していけば、いつの間にか身に付いていると思います。
とりあえず、「選択クエリ」を使って、「クエリによる並び替え」や「クエリによる抽出」から勉強していきましょう。
「選択クエリとは?」説明するよりも、簡単に出来ますので、作ってみましょう。
ここでは「T_社員名簿」というテーブルを元に、「Q_社員名簿」というクエリを作ってみます。
「オブジェクト」の「クエリ」を選択し、「新規作成」ボタンをクリックします。
「クエリ」の「新規作成」ウィンドウが開くので、「デザインビュー」を選択し、「OK」ボタンをクリックします。
「テーブルの表示」ウィンドウで「T_社員名簿」を選択し、「追加」ボタンをクリックし、ウィンドウを閉じます。
(一旦閉じた「テーブルの表示」ウィンドウを再度表示したい場合は、「テーブルの表示」ツールバー をクリックします)
画面の上部に図のように「T_社員名簿」の項目を表示したボックスが表示されます。
この中で、表示したい項目を選択し、下部にある格子状のところにドラッグします。
※この格子状の部分をデザイングリッドと言います。
「フィールド」にドラックした項目の名前、「テーブル」にテーブル名が表示されます。
続いて画面左上の「データシートビュー」ボタン をクリックします。
データシートビューが表示されました。
このデータシートビューは、
「データシートによるデータ入力」「データシートによる検索」「データシートによる並び替え」
などで説明したテーブルのデータシートビューの使い方と全く同じです。
「T_社員名簿」のうち、選択した項目だけのデータシートができた
という事になります。
(画面左上の「デザインビュー」ボタン で、クエリの作成画面に戻る事が出来ます。)
最後に、閉じる時に、「Q_社員名簿」という名前をつければ、クエリの完成です。
これで、「T_社員名簿」というテーブルとは別に「Q_社員名簿」というクエリが出来た訳ですが、
ここで一番大切な事は、
「Q_社員名簿」は「T_社員名簿」をコピーしたものではない
とうい事です。
「Q_社員名簿」のデータシートビューで表示されているデータは、「T_社員名簿」の内容そのものです。
ですから、「Q_社員名簿」のデータシートビューを開いて、データの内容を変更したり追加や削除をした後に、「T_社員名簿」のデータシートビューを見れば、その内容は必ず反映されています。
要するに、
「Q_社員名簿」という窓ごしに「T_社員名簿」を見ている
という事です。
「クエリ」そのものにデータは存在しません。
そして、クエリを作成する際に、
「社員ID」と「氏名」の項目だけを選択したので、その内容だけが見えている
という事です。
当然、テーブルの全ての項目を選択してクエリを作れば、テーブルの全ての項目を見る事ができるクエリを作る事も可能です。
選択クエリでは、必ず、その元になるテーブルを指定する必要があります。
(もしくは、クエリを元にしたクエリを作る事も出来ます。)
これが「クエリ」の基本中の基本
という事になりますが、「選択クエリ」は、ただ単に、
「テーブル中から項目を選択する」という機能だけではありません。
次からの項目で順次、説明していきます。
手作業に比べ、コンピュータを使って事務処理をするメリットとして、
「データを簡単に並べ替えたり、条件を設定してデータを抽出したりする事が出来る」 という事があげられます。
特にデータベースソフトと呼ばれるだけあって、Accessは、そういった事が得意中の得意なのですが、
それも、すべて
「クエリの働き」
といっても過言ではありません。
では、まず、「クエリ」を使って並び替えする方法を説明していきましょう。
今まで表計算ソフトのExcelを使ってこられた方は、
「並び替えなんてExcelでも出来るよ」
と思われるかも知れません。
たしかに、Excelの方が手軽に並び替え出来るかも知れません。
しかし、後々の事を考えれば、「クエリ」を使っての並び替えがどのように便利か分かってもらえると思います。 それでは、両者の並び替え方法を比較していきましょう。
ここでは、例題として、「社員名簿」を「部署順・名前順・生年月日順」に並び替える方法を取り上げて見ましょう。
まずExcelからですが、
並び替えたいデータの範囲を指定して、
「メニュー」→「データ」→「並び替え」をクリックし、「並び替え」ウィンドウで、
「最優先されるキー」を「部署ID」にして、「OK」ボタンをクリックします。
部署順に並びました。
「名前順・生年月日順」も同様に操作します。
一見、簡単で便利なようにも思いますが、大きな欠点があります。それは、
「部署順・名前順・生年月日順のデータを見ようとすると、その都度、並び替えの操作をしなければならない」 という点です。
これが10件くらいのデータなら、そんなに手間ではありませんが、数百件・数千件ともなると大変です。
「それなら、部署順・名前順・生年月日順に並び替えた時点で、ファイル名を変えて、それぞれ、保存したら?」 という方法を思った人がいるかも知れませんが、そんな事をしたら、
今後、データを追加する度に、3つのファイルに同じデータを入力していかなくてはなりません。
それに、
追加したデータを含るため、再度並び替えを、やり直さなければなりません。
さて、それでは次に、Accessのクエリを利用した場合には、どのようになるのでしょうか?
「オブジェクト」の「クエリ」を選択し、「新規作成」ボタンをクリックします。
「クエリ」の「新規作成」ウィンドウが開くので、「デザインビュー」を選択し、「OK」ボタンをクリックします。
「テーブルの表示」ウィンドウで「T_社員名簿」を選択し、「追加」ボタンをクリックし、ウィンドウを閉じます。
「T_社員名簿」の全部の項目を選択し、(「T_社員名簿」のところをダブルクリックすると、全項目が選択されます。)図のように、ドラッグします。
「部署ID」の「並べ替え」を「昇順」(小さい順)にし、クエリの名前を「Q_社員名簿部署順」にして保存します。
今、作られたクエリ、「Q_社員名簿部署順」を選択し、「開く」ボタンをクリックすると、
部署順でデータが表示される事を確認して下さい。
同様に、「Q_社員名簿名前順・Q_社員名簿生年月日順」を作ります。
それぞれ開くと、「名前順・生年月日順」に表示される事を確認して下さい。
このように、それぞれのクエリを作っておけば、
部署順の一覧を見たい時は、「Q_社員名簿部署順」
名前順の一覧を見たい時は、「Q_社員名簿名前順」
生年月日順の一覧を見たい時は、「Q_社員名簿生年月日順」 を開けばいいのです。
あれ、それじゃあ、さっき、「Excelで、部署順・名前順・生年月日順に並び替えた時点で、ファイル名を変えて、それぞれ、保存したら?」って言ったのと、同じじゃないの?
という疑問が沸くかもしれません。
でも、全然、違うのです。
今、作った3つのクエリに、それぞれデータがあるわけではないのです。
データは、あくまで、テーブルに保存されているだけで、クエリは、開く瞬間に、部署順や名前順・生年月日順に並び替えてくれるだけなのです。クエリにデータを保存しているわけではありません。
ですから、「Q_社員名簿部署順」でデータを追加した後、「T_社員名簿」を開けば追加したデータは表示されますし、「Q_社員名簿名前順」でデータを削除すれば、「Q_社員名簿生年月日順」のデータも削除されています。
そして、データを削除したり、生年月日を修正しても、次に、それぞれのクエリを開けば、ちゃんと、最新の状態で、データが並び変わっています。
クエリによる並び替えとExcelとの違い、分かって頂けたでしょうか?
データの数が膨大になればなるほど、目的のデータをどれだけ簡単に早く見つけ出すかが課題となってきます。
クエリは、並び替えの設定と同様に、様々な条件によってデータを簡単に絞り込む事が出来ます。 それでは、
「クエリによる並び替え(Excelとの比較)」
で作ったクエリ「Q_社員名簿部署順」を変更して、
「管理部で80年代生まれの人」を抽出したクエリを作ってみましょう。
まず、「オブジェクト」のクエリ「Q_社員名簿部署順」を選択し、「デザイン」をクリックします。
「部署ID」の「抽出条件」に管理部の部署IDである200を入力します。
そして、ツールバーのボタンをクリックすると、
データが表示されます。
管理部の人のみが抽出されている事を確認して下さい。
再度、ツールバーのをクリックし、デザイン画面に戻ります。
今度は、「生年月日」の抽出条件に、「Between #80/01/01# And #89/12/31#」と入力します。
このように、「管理部であり、かつ、80年代生まれの人」という設定をする事が出来ます。
また、抽出条件を入力する行をずらせば、
「管理部か、または、80年代生まれの人」
という設定をする事も出来ます。
このBetween
○○ And
△△ という式は、○○から△△までの範囲を設定する式です。
また、日付型を指定する場合は、#80/01/01#のように文字の両側に#を付けるルールになっています。
つまり、この場合、「生年月日が1980年1月1日から1989年12月31日まで」という条件設定になります。
文字型の場合は、#でなく、「"」もしくは「'」で挟んで記述します。
(例)'上田' もしくは"上田"
数値型の場合は、そのまま数字を入力するだけです。
今度は、管理部で80年代生まれの人だけが抽出されました。
日付型のデータを抽出する場合は、#80/01/01#のように文字の両側に「#」を付ける、
文字型のデータを抽出する場合は、'上田' もしくは"上田"のように文字の両側に「'」もしくは「"」を付ける、
数値型の場合は、200のように、そのまま数字を入力するだけ、
という事は、「クエリによる抽出」で説明しました。
それでは、
ある項目に、何も入力されていないデータだけを抽出する
というのは、どうすればいいのでしょうか?
例えば、図のように「血液型」という項目が入力されていた時、
「血液型」が入力されていないデータのみを抽出する
という場合の事を考えてみましょう。
クエリで「血液型」の抽出条件で設定すればいい事は分かると思いますが、「何も入力しない」からと言って、抽出条件に何も入力しなければ抽出されません。
そこで、何も入力されていないという事で、
抽出条件に""と入力してみました。
このクエリを開いてもデータは何も表示されません。
何も入力されていない = ""
ではないのです。
この場合、どうすればいいのでしょう?
この場合、抽出条件に、Is Nullと入力します。
このクエリを表示すると、
このように、血液型が入力されていない人だけ抽出する事が出来ました。
何も入力されていない状態をNullといい、クエリで抽出する場合は、このようにIs Nullと記述します。
この時、”Is Null”と「"」で挟んでしまうと、
Is Nullという文字を抽出する
という事になってしまうので注意して下さい。「"」は不要です。
また、この条件とは逆に、
データが入力されているデータだけを抽出する(何も入力されていないデータを省く)
という場合は、
Is Not Null
と記述します。
次のテーブルは「郵便番号」と、その「住所」が入力されています。
このデータから、
住所が「池田市旭丘」のデータのみ抽出する
という場合のやり方は、「クエリによる抽出」で説明しましたが、復習も兼ねて、クエリを作ってみます。
このように、クエリを新規作成し、抽出条件に「池田市旭丘」と入力し、このクエリを開けば、該当するデータが1件表示されます。
それでは、
住所が「池田市」のデータを全て抽出する
といった場合は、どうすればいいでしょうか?
抽出条件に「池田市」とだけ入力しても、データは1件も表示されません。
この書き方では、抽出条件が住所と完全に一致していないとデータが抽出されないので、住所に「池田市」とだけ入力されているデータが1件も無ければ、表示されないのです。
では、どのようにすればいいのでしょうか?
この場合、抽出条件に、
Like "池田市*"
と入力します。
今度は、このクエリを開くと、該当する2件のデータが表示されます。
この命令は、
池田市で始まる住所すべて
という意味です。
ただし、この場合、先頭が「池田市」から始まらないと該当しないので、
「池田市旭丘」のデータを「大阪府池田市旭丘」に変更し、再度、クエリを開くと、このデータは表示されなくなります。
「池田市」という文字が含まれるデータすべて
という場合は、
Like "*池田市*"
というように「池田市」の両側に「*」をつけます。
同様に、
住所の最後が「町」で終わるデータ
という場合は、
Like "*町"
とします。
それでは、
「郵便番号」の3桁目が「2」のデータ
という場合は、どうすればいいでしょうか?
「郵便番号」の抽出条件に、
Like "*2*"
としてみましょう。
このように、3桁目に限らず、「2」が1文字でもあるデータは全て表示されます。
では、どうすれば、3桁目が「2」のデータを表示すればいいのでしょうか?
この場合は、
Like "??2????"
もしくは、
Like "??2*"
とします。
「*」は複数の文字、「?」は1文字単位を示しますので、「??2」で、「3桁目が2のデータ」という意味になります。
このように3桁目が「2」の郵便番号のデータのみ表示されました。
「選択クエリ」のところで、
選択クエリでは、必ず、その元になるテーブルを指定する必要があります。
(もしくは、クエリを元にしたクエリを作る事も出来ます。)
と説明しました。
この場合の「元になるテーブル・クエリ」は、1つとは限りません。
複数のテーブルやクエリを結合して1つのクエリを作成する
という事があります。
それは、何の目的で、どうのうな時に作るのか?
これから説明したいと思います。
まず、このデータシートを眺めて下さい。
これは「T_社員名簿」テーブルのデータシートですが、これを見て、何か気付く事は、ありませんか?
「部署ID」と「部署名」の両方を入力しておく必要があるのか?
という疑問が湧いてきませんか?
「部署ID」の項目は、部署順に並び替える時に「部署名順」では部署名の漢字のコード順に並んでしまう為、「組織順に並び替える為にも必要」という事は理解できると思いますが、
部署IDが50なら「技術開発室」
部署IDが100なら「営業部」
部署IDが200なら「管理部」
と決まっているのに、「部署ID」と「部署名」の両方を入力しないといけないのは効率が悪いですし、
部署IDに50、部署名に「管理部」と間違えて入力してしまう可能性もあります。
そこで「T_社員名簿」テーブルから「部署名」の項目を削除し、「T_部署」テーブルを作成します。
作成した「T_部署」テーブルにデータを入力します。
「T_部署」と「T_社員名簿」のデータは、それぞれ次のようになります。
このようにすれば「T_社員名簿」に「部署名」の項目は必要ないのです。
部署IDが100の高橋さんはら営業部、部署IDが50の前田さんは技術開発室という事が分かります。
ただし、いつも「T_社員名簿」と「T_部署」の両方のデータを開いて、見比べるのは不便です。
こういった時に、「T_社員名簿」と「T_部署」を結合したクエリを作成するのです。
実際に作ってみましょう。
「オブジェクト」の「クエリ」を選択し、「新規作成」ボタンをクリックします。
「デザインビュー」を選択し、「OK」ボタンをクリックします。
「テーブルの表示」画面が出るので、「T_社員名簿」を選択し「追加」ボタンをクリック、引き続き「T_部署」を選択し「追加」ボタンをクリックします。
「T_社員名簿」の「部署ID」から「T_部署」の「部署ID」にマウスをドラックします。
そうすると、線が引かれます。
「T_社員名簿」の全ての項目と「T_部署」の「部署名」を画面下部のデザイングリッドにドラッグします。
※「T_部署」の「部署名」は、どこにドラックしても機能上は問題ありませんが、データシートでは、この順番で表示されますので、分かりやすいように「部署ID」の後ろにドラックしました。
これでクエリが完成しました。「Q_社員名簿」という名前を付けて保存します。
このクエリを開いてみましょう。
次のように表示されます。
見た目は、最初の「T_社員名簿」のデータシートと同じですが、中身は違います。
「部署名」は「T_社員名簿」のデータでは無く、「T_部署」のデータが表示されているだけです。
確認の為、「部署ID」に「200」と入力してみましょう。
自動的に「部署名」に「管理部」と入力されるはずです。
ここで注意しないといけないのは、
例えば
「高橋さんの部署を営業部から管理部に変更したい」
という時、
「部署IDの100を200に変更」すれば問題ないのですが、
「部署名を営業部から管理部に変更」したら、どうなるでしょうか?
この「部署名」は「T_社員名簿」の「部署名」では無く「T_部署」の「部署名」です。
ですから、「部署ID」が100となっている人、全員の「部署名」が営業部から管理部に変更されてしまいます。
この点も確認して下さい。
「クエリによるテーブルの結合」の説明で、テーブルから別のテーブルを結合して参照表示する機能については理解できたでしょうか?
実は、このテーブルの結合で、もう1つ、重要な事を理解しておく必要があります。
まず、最初に、「T_社員名簿」テーブルを開き、データを1件追加して下さい。
ただし、その際、「部署ID」は入力しないで下さい。
一旦、「T_社員名簿」を閉じて、 「クエリによるテーブルの結合」で作成した「Q_社員名簿」クエリを開いて下さい。
先程、入力した「部署IDが入力されていないデータ」だけが表示されていません。何故でしょう?
それでは、その理由を説明していきます。
「Q_社員名簿」のデザイン画面を開いて下さい。
「T_社員名簿」と「T_部署」を結んでいる結合線のところで、マウスを右クリックするとサブメニューが表示されるので、
「結合プロパティ」をクリックします。
(結合線をダブルクリックでも構いません)
「結合プロパティ」ウィンドウが開きます。
「両方のテーブルの結合フィールドが同じ行だけを含める。」から、
「'T_社員名簿'の全レコードと'T_部署'の同じ結合フィールドのレコードだけを含める。」
にチェックを変更し、「OK」ボタンをクリックします。
結合線が「T_社員名簿」から「T_部署」への矢印に変わりました。
このクエリを保存し、再度、データシートを開いて下さい。
さっきまで表示されていなかった「部署IDが入力されていないデータ」も表示されました。
この「結合プロパティ」ですが、
「両方のテーブルの結合フィールドが同じ行だけを含める。」
にチェックを入れていると、
「T_社員名簿」と「T_部署」の両方に同じ値が入力されているデータだけを表示する
という設定になり、
「'T_社員名簿'の全レコードと'T_部署'の同じ結合フィールドのレコードだけを含める。」
にチェックを入れると、
「T_社員名簿」の全てのデータを表示し、もし部署IDが入力されていて、同じ部署IDが「T_部署」にあれば関連する部署名を表示する
という設定になります。
少し、ややこしかったでしょうか?
まぁ、あまり深く考えなくても、
「入力したいテーブルの側から参照表示したい側のテーブルに向かって矢印を引くように設定する」
と覚えておいても構わないでしょう。
このクエリは、「社員名簿」を入力する為のもので、「T_部署」は、「T_社員名簿」の「部署ID」を元に「部署名」を表示させる為のものですから、
「T_社員名簿」から「T_部署」に向かって矢印を引く
という設定にしておく訳です。
「クエリの結合プロパティ」までで、「T_社員名簿」と「T_部署」を結合したクエリ、「Q_社員名簿」が完成しました。
この「T_社員名簿」と「T_部署」を結合した状態で、更に、
並び替えの順番を「部署順・名前順・生年月日順」など、目的に応じたクエリを、それぞれ作りたい
という事はよくあります。
その場合、「クエリによる並び替え(Excelとの比較)」で説明したように、それぞれ、並び替えを設定したクエリを作成すればいいのですが、その際、
「T_社員名簿」と「T_部署」を結合して生年月日順に設定する
「T_社員名簿」と「T_部署」を結合して部署順に設定する
「T_社員名簿」と「T_部署」を結合して名前順に設定する
と、それぞれのクエリで、テーブルを元に作ってもいいのですが、もっと簡単な方法があります。
今迄、テーブルを元にクエリを作ったのと同じ手順でクエリを元にクエリを作る事もできるのです。
この場合、「Q_社員名簿」を元にしていて、既に「T_社員名簿」と「T_部署」の結合はされているので、ここでその設定をする必要はなく、ただ、並び替えの設定をするだけで作成できます。
今回は、「T_社員名簿」と「T_部署」だけの簡単な設定でしたが、場合によっては、沢山のテーブルに沢山のフィールドからクエリを作る時もあり、並び替え毎にそれぞれテーブルから作成するのは手間がかかります。
そんな時は、テーブルを結合した、元になるクエリを作っておき、並び順毎のクエリは、その元になるクエリから作るようにした方が手間をかけずクエリを作成できます。
「元のクエリをコピーして、それぞれ作れば手間がかからないのでは?」
という意見もあるかも知れませんが、その場合、テーブルの項目を追加したり、連結するテーブルを増やす場合、それぞれのクエリで、その設定をしなければならないので、クエリの数が多くなるとそのメンテナンスは大変です。
クエリを元にして作っておけば、そんな場合も、元になるクエリを変更するだけで、他のクエリでは、必要となる項目を引っぱってくるだけで済みます。
ただし、クエリを元にクエリを作った場合、直接、テーブルから作るよりも、クエリを開いた時に時間がかかる事があります。
特に、「クエリを元にクエリを作り、そのクエリを元に更に別のクエリ」
と重ね過ぎると、開く時の時間も遅くなりますし、複雑になりすぎて、難解なシステムとなってしまうので気を付けて下さい。
データ量やコンピュータの性能にもよりますが、クエリを開く時やフォームを開く時、フォームでコンボボックスを開く時など、遅くて困る時には、手間はかかっても、直接、テーブルを元にクエリを作る事により、速度が改善される事があります。
作る手間やメンテナンスを行う時の手間がかからない事を優先するか?
プログラムの速度を優先するか?
そんな事を考えながら作る事も大切です。
「リレーションシップ」とは、なんでしょうか?
ある入門書には、 「データベースファイルに、それぞれ違うデータを格納しているテーブルが複数ある時に、それらのテーブル間の結合関係をリレーションシップと言います。」 と書いてありました。
????分かります???
正確な定義を追求するよりも、とりあえず、実際に、このリレーションシップが、どんな働きをして、どう便利なのか、具体例で説明していきましょう。
「クエリの結合プロパティ」の説明で使った「T_社員名簿・T_部署」、この2つのテーブルを開いてみましょう。
そして、「T_社員名簿」の「社員ID 30・山田さんの部署IDに30」と入力して下さい。
普通に入力出来ました。
しかし、隣の「T_部署」テーブルを見て下さい。
「部署IDが30」という部署は、ありません。
でも、「T_社員名簿」の「部署ID」と「T_部署」の「部署ID」は、別のものですので、このように入力する事は可能です。
それでは、この2つのテーブルのデータシートを閉じて、ツールバーの「リレーションシップ」 をクリックすると、
「リレーションシップウィンドウ」が表示されます。
引き続き、ツールバーの「テーブルの表示」 をクリックすると、「テーブルの表示」ウィンドウが表示されるので、
「T_社員名簿」と「T_部署」を追加して下さい。
そして、この「T_社員名簿」と「T_部署」の「部署ID」をマウスでドラックして下さい。
なんだか、ここまでの説明に聞き覚えは無いでしょうか?
ここまでは、「クエリによるテーブルの結合」で説明したクエリでのテーブル結合と同じです。
ただし、「クエリによるテーブルの結合」と「リレーションシップ」は、同じものではありません。
ここからが違います。
「T_社員名簿」と「T_部署」の「部署ID」をマウスでドラックすると、次のような画面が表示されます。
ここで、「参照整合性」にチェックを入れて、「作成」ボタンをクリックして下さい。
次のようなメッセージが出てきて、リレーションを設定する事が出来ません。
何故、設定できないかと言いますと、この項目の最初に、
「T_社員名簿」の山田さんの「部署IDに30」と入力した、このデータが邪魔をしているのです。
要するにリレーションシップを設定し、参照整合性にチェックする事によって、
「T_社員名簿」の「部署ID」に入力されている値は、必ず、「T_部署」の「部署ID」にありますよ!
というデータとして正しい関係を常に監視してくれるのです。
その設定をする以前に、既に、違うデータが入っているので、設定そのものが出来ないのです。
一旦、リレーションシップの設定を中断し、
「T_社員名簿」の山田さんの「部署IDを50」に変更し、再度、リレーションシップの設定を行って下さい。
今度は、エラーメッセージも表示されず、無事に設定できました。
再度、「T_社員名簿」を開き、山田さんの「部署IDを30」に戻してみて下さい。
この行を保存しようとすると、エラーメッセージが表示され保存する事が出来なくなりました。
リレーションシップが監視してくれているので、矛盾するような設定は許してくれないのです。
次の図は、「リレーションシップと参照整合性」で参照した「T_社員名簿」と「T_部署」です。
リレーションシップの参照整合性が設定されています。
「T_社員名簿」の「部署ID」が「T_部署」に無いもの(50・100・200以外)に変更できない事は説明しました。
それでは、「T_部署」の「部署ID」を変更したら、どうなるのでしょうか?
営業部の「部署ID」を100から300に変更してみます。
「リレーションシップが設定されたレコードがテーブル'T_社員名簿'にあるので、レコードの削除や変更を行うことはできません。」
というメッセージが表示されました。
リレーションシップが設定されている為、営業部の「部署ID」を100から300に変更してしまうと、「T_社員名簿」の営業部(「部署ID」が200)の人との整合性が崩れてしまうからです。
それでは、一旦、データシートを閉じて、リレーションシップのウィンドウを表示し、
「フィールドの連鎖更新」にチェックして下さい。
先程と同じように「T_社員名簿」と「T_部署」のデータシートを開き、再度、「T_部署」の営業部の「部署ID」を100から300に変更して下さい。
今後は、エラーメッセージが表示されず変更されました。
それと同時に「T_社員名簿」の「部署ID」200の人の「部署ID」も300に変更されました。
要するに、
「参照整合性」にチェックが入っていれば、「フィールドの連鎖更新」にチェックが入っていても、いなくても、整合性は保たれているのですが、
「フィールドの連鎖更新」にチェックが入っていない場合は、
整合性を保つ為に「T_部署」の「部署ID」の変更を許さなかった
のですが、
「フィールドの連鎖更新」にチェックが入っていなる場合は、
整合性を保つ為に、「T_社員名簿」の関連する「部署ID」を「T_部署」の「部署ID」と同時に変更した
という事です。
「リレーションシップの連鎖更新」で「T_部署」の「部署ID」を変更した場合について説明しましたが、今度は「T_部署」の営業部のレコードを削除したら、どうなるでしょうか?
やはり、この場合も、整合性を保つ為に、メッセージが表示され、削除する事は出来ません。
今度も、リレーションの設定画面を表示して、「レコードの連鎖削除」にチェックをして下さい。
「T_部署」の営業部を削除すると、同時に「T_社員名簿」の営業部の人のデータも削除されました。
連鎖更新と同様じ理屈です。
連鎖削除もチェックをはずした場合は、データを削除しない事によって、整合性を保ち、
連鎖削除にチェックを入れた場合は、関連するデータを同時に削除する事によって、整合性を保っている
という事です。
ただし、「チェックを入れるか?チェックをはずすか?」これは大きな問題です。
今回の例のように、「T_社員名簿」と「T_部署」の場合、もし連鎖削除にチェックを入れれば、
部署のデータを1件削除する事によって、それに関連する社員のデータが全て削除されてしまう
事になるのです。
2件・3件の社員データとか、項目数が少ない場合は、たいした事にならないかも知れませんが、もしも何十件のデータとか、項目数が多い時には、間違えて1件の部署データを削除する事によって、大きな被害を出してしまう事になります。
見積書の見積先と見積先の会社データとリレーションシップを結んでいる場合などは、
1件の見積先を会社データから削除したら、その会社の見積書が全て削除されてしまった!
という事になってしまいます。
こういった場合には、チェックをはずしておいて、連鎖削除出来ないようにしておくべきです。
では、連鎖削除にチェックを入れるのは、どのような場合でしょうか?
例えば、見積書などは、1件の見積書に対して複数の明細行から構成されています。
そういった場合、見積書のメインテーブルと明細行のテーブルを作成し、この2つのテーブルを見積書のIDでリレーションを設定します。
この場合に連鎖削除のチェックをはずしておくと、
明細行があると、見積書を削除出来ない
という事になり、その前に明細行を全て削除する必要があります。
連鎖削除にチェックを入れておけば、
見積書を削除する事によって明細行も同時に削除されます。
テーブルの性質によって、連鎖削除にチェックを入れるか?はずすか?
判断する必要があります。
「クエリによるテーブルの結合」「クエリの結合プロパティ」で説明したように、クエリはデータの並び替えや抽出をするだけではなく、複数のテーブルの項目を表示する事も、できます。
項目の表示については、このようなテーブルやクエリにある項目だけではなく、
クエリ上で文字式や計算式を用いて、新たな項目を作成し表示する
という事もできます。
このように書くとピンと来ないかも知れませんが、実際の例で見れもらえばば、そんなに難しいものではない事が分かると思います。
次の例は、今迄、作成してきた「Q_社員名簿」のデザイン画面を開いたところです。
ここで、「ふりがな」の項目にカーソルを置いて、
メニューバーの「挿入→列」
をクリックします。
列が1つ、「氏名」と「ふりがな」の間に、挿入されました。
ここのフィールド行に、
部署氏名:[部署名] & " " & [氏名]
と入力します。
このクエリを保存し、データシートを開いてみましょう。
「氏名」の項目の次に、」「部署名」と「氏名」を結合した「部署氏名」という項目が表示されました。
先程、入力した文字式の「:」の左側がクエリ上の項目名、そして右側が項目を結合する文字式です。
この「部署氏名」という項目は、「部署名」+1スペース+「氏名」を表示する項目です。
表示専用ですので、ここで入力しようとしても入力出来ません。
試しに、部署名や氏名を変更してみて下さい。そのレコードが保存された瞬間(次の行に移動するか、
左の をクリックした時)に、「部署氏名」も変更されます。
14.クエリの式で「複数のテーブルを参照しました」というエラーの対処 |
「文字列を結合した項目を表示する」で入力した、
部署氏名:[部署名] & " " & [氏名]
という文字式に、「部署ID」も加え、
部署氏名:[部署ID] & ” ”&[部署名] & " " & [氏名]
と変更して、保存して下さい。
このクエリを開こうとすると、
「指定されたフィールド'[部署ID]がSQLステートメントのFROM句にある複数のテーブルを参照しました。」
というメッセージが表示され、開く事が出来ません。
これは、何故でしょうか?
このメッセージが出る原因は、
このクエリでは、「T_社員名簿」と「T_部署」の2つのテーブルがあり、「部署ID」は、その両方のテーブルに存在するからです。
要するに、
「部署ID」が「T_社員名簿」のものなのか?「T_部署」のものなのか?、分からない
という事です。
ですから、そこを、はっきりさせたらいいわけで、
部署氏名:[T_社員名簿].[部署ID] & ” ”&[T_社員名簿].[部署名] & " " &
[T_社員名簿].[氏名]
と変更して下さい。
今度は、ちゃんと表示されるはずです。
このように、
[テーブル名もしくはクエリ名].[フィールド名]
の形式にすれば、このエラーメッセージは出ません。
なお、「部署名」と「氏名」は、1つしか無かったので、テーブル名を記述しなくてもエラーは出なかった訳ですが、今後、クエリや元になるテーブルが変更された場合などに、このエラーが表示される可能性もありますし、
常に、
[テーブル名もしくはクエリ名].[フィールド名]
の形式で記述する事を、お勧めします。
※と言いながら、この講座の例では「テーブル名」を省く事が多々あります。極力、記載する内容を分かりやすくシンプルにする為に、そうしています。
ご了承下さい。
クエリでは、文字列だけではなく、計算結果を項目として表示する事もできます。
次のデータシートは、商品の数量・単価が入力されているテーブルです。
このテーブルを元にして、商品の金額を表示するクエリを作ってみましょう。
このように、表示したい項目(品名・単価・数量)をテーブルから引っぱってきて、計算式を、
金額:[単価] * [数量]
と入力するだけです。
この場合の「金額」は、ここで決めたフィールド名ですので、どのように付けても構いません。
分かりやすいフィールド名にしましょう。
ただし、既にフィールドとして存在する名前ですとエラーとなってしまうので、その点だけ注意しましょう。
データシートを開いてみましょう。
このように、計算結果が項目として表示されました。
この項目は計算結果ですから、変更する事は出来ませんが、「単価」や「数量」を変更すると、「金額」も再計算される事を確認して下さい。
クエリで、文字列を結合したり、計算した結果を表示フィールドとして表示する方法は、理解できたと思いまが、その際、関数を利用する事が出来ます。
Accessには様々な関数が用意されていて、これを利用する事によって、本来なら複雑な計算も簡単に行う事が出来ます。
例えば、次の例は、Int関数を使ったものです。
Int命令とは、引数(カッコの中の数字)の小数点以下を切り捨てる
というものです。
この場合でしたら、[数量]に入力された数字の小数点以下を切り捨てて、[数量切捨て]フィールドに表示する
という事になります。
データシートで確認してみます。
このようになります。
*ただし、この場合、[数量]のデータ型が整数型・長整数型など、小数点以下を扱えないと[数量]そのものに小数点以下の数字を保存できません。小数点型や通貨型にしておく必要があります。
関数は、クエリだけではなく、モジュールでも使う事が出来ます。
ただ、関数の機能をすぐに確認するには、クエリで上記なように記入するのが簡単で便利ですので、このクエリ編で説明しています。。
Accessには豊富な関数が用意されていますが、
「豊富過ぎて、どれを使っていいか分からない」
というところもあります。
そこで、よく使う・この関数を知っておくと便利
という事で、関数につきましては、「関数編」にて詳しく説明していきます。
次のような売上データを入力したテーブルがあります。
このデータは、売上日・商品・そして売上のあった数量を入力したものです。
このデータを元に、商品毎の売上数量の集計をしたい。
という事は、よくあると思います。
Excelなどでは、そういった場合、
その都度、集計の作業をしたり、
集計作業がやりやすいように、入力段階から商品毎に分けて入力する
といった工夫も必要です。
しかし、Accessの場合、
入力の段階では、そういった事は考慮する必要はなく、とりあえず、入力する順番とかは考えずに入力していきます。
そして、集計は、選択クエリの機能の一つである、「集計行」を利用します。
実際に、操作してみましょう。
まず、この「T_売上」テーブルを元にクエリを新規作成します。
そして、「商品名」と「数量」を「デザイングリッド」にドラックします。
そして、次に、「メニュー→表示→集計」をクリックします。
そうすると、「デザイングリッド」に「集計」行が表示され、
「商品名・数量」ともに、「グループ化」と表示されます。
これは、
「商品名・数量」共に、同じ値のものを1行として表示する
という設定になりますので、このままでは、「商品毎の集計」にはなりません。
そこで、「数量」の「集計行」を「グループ化」から「合計」に変更します。
今度は、
「商品名」が同じ値のものを1行として表示し、その「数量」の合計を表示する。
という事になり、「商品毎の集計表」が出来ました。
ここでの注意点として、3点程、挙げます。
1.
この集計行を使用すると、このクエリでは、データを修正したり、追加したり、削除する事は出来無い、読み表示専用のクエリとなります。
2.
このデザイングリッドに、例えば、「売上ID」等をドラックしてしまうと、
「売上ID」が同じで「商品名」が同じ値のものを1行として表示
という事になり、この場合の「売上ID」は主キーで、同じ値は存在しない為、実質、集計されていない表になってしまいます。
グループ化したい項目(この場合なら「商品名」)と、集計したい項目(この場合なら「数量」)のみを設定しましょう。
3.
「商品名」を1文字でも間違えると、別の商品として認識してしまい、別々に集計されてしまいます。
この点の対策としましては、
「クエリによりテーブルの結合」で説明したように、直接、売上テーブルに「商品名」の項目を設定するのではなく、
別途、商品テーブルを作成し、
「売上テーブル」には「商品ID」の項目を設定し、「商品ID」を入力する事により、「商品テーブルの商品名を表示する
という構造にする事をお薦めします。これによって、「1文字違う事によって別の商品と認識してしまう」といった操作ミスは、かなり防げます。
そして、以前に、「クエリを元にクエリを作成する」で説明したように、クエリは、テーブルからだけでは無く、クエリを元に別のクエリを作成する事も可能なので、
「計算した結果を項目として表示する」のように、「数量」と「単価」を掛けた「金額」という表示項目のクエリを作成し、そのクエリを元に、今回のやり方で集計すれば「金額を商品毎に集計する」といった事も簡単に出来ます。
「商品名」の代わりに「売上日」をグループ化すれば、売上日毎の集計表を作成する事も可能です。
この場合、
「売上日」のみをグループ化の項目に設定すれば、
売上日毎に売上た商品すべての数量の合計
となりますし、
「売上日」と「商品名」をグループ化の項目に設定すれば、
売上日毎の、更に、商品毎で集計したに数量の合計」
を表示するクエリとなります。
18.グループ化した内容を列として表示するクエリ(クロス集計クエリ) |
「テーブルの内容を集計するクエリ」で説明したように、ただ、項目をグループ化するだけならば、
「メニュー→表示→集計」で、集計行を表示して、必要に応じて、「グループ化」「合計」など、設定するだけで可能ですが、Accessでは更に、
集計した内容を列として表示する」クエリを簡単に作る事が出来ます。
「集計した内容を列として表示する」と言っても分かりづらいかも知れませんが、具体的な例で考えれば簡単です。
「テーブルの内容を集計するクエリ」で使ったデータを再度、使って説明します。
「テーブルの内容を集計するクエリ」では、この例を使って、
「商品毎の数量合計」や「売上日毎の数量合計」を表示するクエリを作成しましたが、
今後は、
「売上日」毎に、「それぞれの商品」が何台売れたか?
を一目で分かる表をクエリで作ってみます。
まず、この「T_売上」テーブルを元にクエリを新規作成します。
そして、「売上日」」「商品名」「数量」を「デザイングリッド」にドラックします。
ここまでは、普通の選択クエリです。
先程は、ここで、「メニュー→表示→集計」をクリックし、集計行を設定し、内容を集計するクエリを作った訳ですが、今度は、ここで、「メニュー→クエリ→クロス集計」を選択して下さい。
今度は、「集計行」に加え、「行列の入れ替え」という行が出来ました。
それでは、この「行列の入れ替え」に、それぞれ、
「売上日」→「行見出し」
「商品名」→「列見出し」
「数量」→「値」
と設定して下さい。
そして「集計行」は、それぞれ、
「売上日」→「グループ化」
「商品名」→「グループ化」
「数量」→「合計」
と設定して下さい。
更に、「売上日」の並び替えを「昇順」にします。
これで完成です。
このクエリを開いてみましょう。
このように、行に「売上日」で売上日順、列に「商品名」、そして表示されている内容は「数量の合計」
という表を簡単に作る事が出来ました。
このクエリを、
クロス集計クエリ
と言います。
これもクエリの一つですから、当然、「T_売上」テーブルの内容を変更して、再度、このクエリを開けば、変更した内容が反映されます。
「グループ化した内容を列として表示するクエリ(クロス集計クエリ)」で説明したように、クロス集計クエリを使用する事によって、データの分類を「列」として、その集計値を表示できる事は理解できたと思います。
ただし、このままでは、まだ問題点があります。
もう一度、作成したクロス集計クエリを開いてみます。
このデータシートの、
各項目の表示順(LANケーブル・ハードディスク・パソコン本体・プリンタ・ルーター)を変更したい
といった場合、どうすればよいか?
という点についてですが、
通常のクエリなら、クエリのデザイン画面で、デザイングリッドでの並び順によって、各項目の表示順を設定する事が出来ますが、クロス集計クエリの場合は、列は、テーブルの項目では無いので、表示する順番を設定する事が出来ません。
それでは、
このクエリを元にフォームを作成し、フォームで表示するようにすればよいのでは?
という事で、このクエリを元に表形式のフォームを作成してみました。
※「フォームとは?」参照
このように、フォームなら、テキストボックスの配置によって、自由に項目を配置する事が出来ます。
しかし、このようにフォームを作成した場合にも、まだ問題があるのです。
このフォームの元になっている「T_売上」テーブルから、
【売上日】2月6日【商品名】LANケーブル
のレコードを削除します。
そして、再度、先程のフォームを開くと・・・
このように、「LANケーブル」のところが全て、「#Name?」と表示されてしまいました。
要するに、フォームから見れば、
「LANケーブル」をクエリの項目として認識しているのに、その項目がみあたらない
という事で、このように表示されてしまうのです。
結局、クエリでも、フォームでも、やはり、問題があるようです。
しかし、この問題を、両方とも解決する簡単な方法があります。
まず、今回作成したクロス集計クエリのデザイン画面を開きます。
もし、クエリのデザイン画面で「プロパティ」が表示されていなければ、
マウスで「右クリック」→「プロパティ」でプロパティを表示します。
この時、もし、このプロパティのタイトルが「フィールドプロパティ」とか「フィールドリストプロパティ」などと表示されていたら、画面上部の何もないところをクリックし、「クエリプロパティ」が表示されるようにします。
このクエリプロパティの「クエリ列見出し」に、
"パソコン本体","プリンタ","ハードディスク","ルーター","LANケーブル"
と入力します。
そして、再度、このクエリを開きます。
このように、プロパティで指定した順番で、項目が表示されます。
また、データが無いはずの「LANケーブル」の項目もちゃんと表示されます。
そして、先程のフォームを開いても、
「LANケーブル」のところに「#Name?」は表示されません。
このように、クロス集計クエリの、クエリプロパティの、
「クエリ列見出し」に表示したい列の名前を入力する事によって、クロス集計クエリの列を固定にする事が出来ます。
|