<HOME  <お願い事項   <Access2002 TOP   <Access97 TOP   <サイト内検索
 MS-Access2000超入門部屋--出勤簿を作る
  1 2 3



で、これからが本番なんですけどね、

[日付]のフィールドを選んで、集計方法を「最小」にしてやります。
こうすることで、「2001/5/1の01001さんの入退出の記録の中でいちばん小さな値」を横に並べてくれます。

おなじ要領で「最大」を表示する列も1列作ってやります。
これで、「2001/5/1の火曜日に01001さんは8時4分にやってきて19時54分に帰った」と言えないこともないわけです。まあ、カード通さないで帰っちゃう人とかいるかもしれないからそこはそれ、まあ、これは参考資料ということで。
[日時の最小]じゃなんなので、出勤時刻と退勤時刻、みたいなかんじでフィールド名をつけておきましょうかね。

単に「出勤退勤時刻を知る」ということなら、このクエリがひとつあれば十分でしょう。
後は、きれいにレポート作ったり、社員番号で絞り込めるように工夫したりすればよいはず。中核になるテーブル/クエリがしっかりしていればいろいろ利用できるはずです。データベース作りでいちばん難しいのはテーブル設計です。「データベースでいちばん難しいのはVBA」とか言ってる人って怪しいですから、そういうこと言う人に振り回されないように気をつけてくださいね。

だいたい、テーブル作りから順番に進めていきますけど、テーブルから設計してはイケマセン。つまりは、どういう結果を出したいのか考えずにテーブル作りをすることはできない、っていうわけです。だから、難しいんですよ。
できるだけ柔軟に考えていくべきではありますけれど、テーブルというものにはある程度「パターン」があります。
この[入退出テーブル]のように、部屋を出入りするたびに1レコードずつデータが発生するような構造のテーブルなんて、テーブルの設計だけ考えている段階では思いつかないですよね。

こういうテーブルから、いかにして得たい結果を得るか、また、得たい結果を得るためにはどういう構造のテーブルにすべきか、ということを、行ったり来たりしながら繰り返し考えて、ようやくひとつのテーブルが出来上がるわけです。あるいは今回のように、他のシステムからある一定のレイアウトでデータが送られてくる場合などの場合は、クエリを使いこなす必要があります。集計クエリ(Σ)の仕組みや機能を深く知っておくと、得たい結果を得るためにどうすればいいのか、かなり理解が深まってくると思いますよ。


ではここからは、細かいとこを調節するために、どんな工夫が必要になるか、いくつか考えてみようと思います。
まず・・・今しがた作った集計クエリ、よく観察してみてください。5月4日っていうデータ、ないですね。5月3日の次が5月5日になってます。しかも5月5日は1行だけ。これはなぜ?・・・なんて思ってる人いませんよね。大丈夫ですね?

基のテーブルに5月4日のデータがないからですよ。あたりまえのことですけどないものは出ません。ないのに出てきたら気持ち悪いです。
なぜないのかって?しっかりしてくださいよ・・・入り口のカードリーダーにカードを通したときに1行記録されるんですよね。ってことは、5月4日には、誰もカードリーダーにカードを通さなかったんじゃないですか?つまり、誰も出勤してきてないんですよ。だから出てこないんです。

基のテーブルにはないけれど、5月4日も出したい・・・という場合は、どうすればいいんでしょう?
という場合の、方法のひとつです。別にこうやるって決まってるわけじゃないんですけどね。ひとつのアイディアと思って試してみてください。
5月だけなら、5月1日から31日までの日付の値を持った31行あるテーブルを用意します。[稼働日テーブル]とでも付けましょうかね。
もし、6月も7月も・・・将来的に、毎月同じようなことをやる可能性があるなら、1年分くらい、カレンダーみたいに日付だけ入ってるテーブルを作ります。


で、新しくクエリをひとつ作って、この[稼働日テーブル]と、さっき作ったクエリをくっつけます。
くっつけるフィールドは、「日付がおなじだったら」ですよ。結合線が出てきたら、結合線をダブルクリックします。

「稼働日テーブルの全レコードと・・・」というやつにします。

これで、「5月4日」というデータはクエリのほうにはないけど、[稼働日テーブル]にはありますからとりあえず「5月4日」という行が最低でも1行は出てくるようになります。でもって「誰も出勤していない」ということがわかるようになります。
結合線がやじるしになりましたね。

もし、[稼働日テーブル]に、5月分だけじゃなくて、1年分とか2年分とかの日付を作っている場合は、このままだと[稼働日テーブル]の全件出てきちゃって大変ですので、[稼働日テーブル]の[日付]フィールドに対して、「5月分だけ」とかいう感じで何らかの抽出条件を指定してやります。
例えばこんな感じ・・・。

あるいは、こんな感じです。


・・・開こうとすると、エラーになります?
いや、今の段階ではこのメッセージが出るのが正しいのです。

[稼働日テーブル]では、「日付時刻型」のフィールドを作りました。
一方、クエリの方の[出勤日]フィールドは、Format関数でYYYY/MM/DD形式にしたものを表記させてます。
Format関数のヘルプをもう一度読み返していただきたいとこなんですが、この関数、結果を「文字列で」返してきます。つまり、[出勤日]は日付時刻型ではなくテキスト型扱いになっているのです。

あたりまえですけれど、日付時刻型のフィールドとテキスト型のフィールドは、型が違うのでくっつきません。
なぜって?んもーしっかりしてくださいよー。日付時刻型のデータって、見た目「2001/5/9」になってるだけで、「にぜろぜろいちすらっしゅごすらっしゅきゅう」って数字が並んでるわけじゃないんですよ。内部的には37020です。2001/5/9 14:50は37020.6180555556です。これじゃあんまりなので、日付時刻型という独特のデータの持ち方にして、「何年何月何日」という表示に対応できるようにしてるわけです。だから曜日とか算出できたりするんですよね。

数値型とテキスト型だっておなじですよね。わたしたちが、データシートビューとかでびろーんと見ている数値や文字は、あくまでもわたしたちにとって見やすいようにいろいろ工夫されて出力されたもので、コンピュータ内部の扱いもソレというわけでは、ないんですもんね。
だからこそ、データ型というものをしっかり意識しないといけないわけです。


今作りかけのクエリは、どっか隅っこに置いといて、一つ前に作った集計クエリのデザインをもう一度見てみましょう。

このクエリによって出てくるデータの件数が5万件とか10万件とかある場合は、あんまりお奨めの方法ではありませんが・・・でもここまできたらしょうがないですね。さらに関数を使って、日付時刻型に変換します。外側にもうひとつ、Cdateという関数で覆ってやってください。これで、[出勤日]は日付時刻型の扱いになります。いちおう、データシートビューにして確認してみてください。多分、右寄せされて表示されると思います。確認できたら、このクエリ、保存しながら閉じましょう。
データの型、大切なことなんですよ。特にこうやって関数使って無理やり作り出したフィールドとかの場合は、その関数がどういう型のデータを返すものなのか、ヘルプ等々でしっかり確認しておかないといけませんね。気をつけよう。


で、作りかけのクエリのほうなんですけど、そっとデータシートビューにしてみましょう。
今度はちゃんと、結果が出てくれるんじゃないかと思います。
ところどころ歯抜けになってるとこ、ありますか?だーれも出勤しなかった日、っていうことになりますよね。

テーブル同士(今回はテーブルとクエリでしたけども)をクエリで結びつけるとき、「どっちのデータが主体になるのか」ということを考える必要があります。
通常は「両方のテーブル(またはクエリ)に存在しているデータをくっつける」というイメージになるので、この点を理解しておくとよいかもしれないですね。

こういうのをしっかり理解しておくことが「リレーションシップ」なんですよ。リレーションシップオブジェクト作ることがリレーションじゃないですから。。。リレーションというのはあくまでも、そのデータベース、その業務の中で矛盾が起きないようにそれぞれのテーブルの関係をしっかり取り決めてやること、またはその考え方のことを言うのであって、なんか具体的な操作とか機能のことじゃないので、こういうクエリを作りながら、理解を深めていってくださいね。やっぱし、実際にいろいろ作ってみながら理解をしていくのがいちばんだと思いますよ。

[Q_出勤退勤]だけだと、「実働日のみ」のデータになります。これに[稼働日テーブル]を加えて結合の方向を決めてやれば、「5月は1日から31日まであって、でもって、何日と何日が実働日だったか」みたいな感じの出力結果になります。どんなふうに結果を出したいか、によって、[稼働日テーブル]みたいなのを別途用意しておく必要が出てくるかもしれないですね。


[稼働日テーブル]側に、一覧に出したいレコードがしっかりそろってればイケる、というトコを利用して、もう一工夫してみようかな。
上のクエリだと、5/5にはひとりしか出勤しなかったので、他の4人のデータはないですよね。
出勤してもしなくても、とにかく毎日5人の様子がわかるように出したい場合は・・・。

[稼働日テーブル]は今、2001/5/1のレコードは1レコードですけども、2001/5/1の01001さんのレコード、2001/5/1の01002さんのレコード・・・という具合に、1日のレコードを5レコード分にしちゃえばいいんですよね。

[稼働日テーブル]を作り直してもいいんですけど、めんどくさいしなぁ。
とりあえず、[社員マスタ]を作ってみました。わたしは手抜きで「社員番号」しか作らなかったですけど(データ型は[入退出テーブル]の社員番号とあわせてくださいね)、社員名とか部署とか並べれば、いろいろつかえると思います。

こんな感じで、人数分、社員番号を入れておきます。
で、[稼働日テーブル]と[社員マスタ]をあわせて、こんなふうに「結合線のないクエリ」を作ります。
もし、[社員マスタ]に[社員名]とかも作ったのなら、いっしょに横に並べちゃってもいいですよ。

どう結合させていいかわからないので、

という具合に、手当たり次第結合になります。

なので、[稼働日テーブル]が31件あって、[社員マスタ]が5件あったら、31×5で155件の結果が出てくるわけです。ほんとならこんな結果あってはならないですけども、こういうときうまいこと利用してしまうのも手ですね。
ただ、注意が必要なのは、これって「リレーションシップ」という面から見るとあってはならない結合ですから、このクエリを通じてデータの書き換えとか追加はできません。データシートビューの下のほうにある「新規追加ボタン」、グレーになってますよね。結合の仕方があいまいですからね・・。この状態でデータ入力されちゃったらどうしていいかわかんない、と、Accessが申しているわけです。そりゃあそうですよね。

場合によっては相当な件数になることも予想されますから、このクエリの中である程度抽出条件で絞れるようなら、絞った方がいいでしょう。
わたしは今回はここで、「5月分だけ」という抽出をしてみました。なので、31×5で、155件。

別段、件数に制限があるわけじゃないんですけどね。基のテーブルの中のレコード件数ならまだしも、クエリで出力した結果が10万件とか20万件とかになるなんて、そんなデータ見る気します?テーブルにデータをためて、クエリで必要な分だけ取り出す、というのがデータベースのセオリーですよ。「何件くらいまで大丈夫なんですか?」なんてことを疑問に思う前に「必要なものだけ取り出す」工夫を先に考えたいもんです。

で、このクエリに名前をつけて保存します。[Q_稼働日]とでもしますかね。


このクエリと、最初に作った[Q_出勤退勤]クエリを使って、クエリを作ります。
もちろん結合の仕方は、[Q_稼働日]の全件、です。
いずれは、並べ替えの指定も、しておいた方がいいかもしれないですね。まあ、とりあえず見てみますか。
曜日もここで出しましょうか。[Q_出勤退勤]の[曜日]を並べただけだと、[Q_出勤退勤]に存在してない日だと、曜日が空っぽになっちゃいますもんね。

よく意味がわからない??という方は、[Q_出勤退勤]の[曜日]も、グリッドに選んでみてください。多分、ところどころ空欄になっちゃうと思いますので。
もちろん空欄になっててもいいのならそれでもいいんですけどもね。