<HOME  <お願い事項   <Access2002 TOP   <Access97 TOP   <サイト内検索
 MS-Access2000超入門部屋--「7.5」は「7時間半」なのか?「7時間50分」なのか?



これは、ヒジョウに難しいテーマかもしれません。

例えば、テーブルに「経過時間」をおさめたいときって、皆さんどういうふうに考えます?
「7時間30分働いた」場合は、どういうふうに入力しますか?

多分、ですね。。。。
わたしの考えでは、7.5 と入力するのがふつうじゃないかなぁと思うんです。


7時間15分なら 7.25 、7時間45分なら 7.75 ・・・でないと、いろいろ面倒なことが出てきそうな気がします。

でも、これを、7.30って入力してる人、いらっしゃいますか?


7.30で「7時間30分のことです」という人。いえ、決して間違いとかそれじゃダメとかいうわけじゃないですよ。
でも、これだと、いろいろ面倒なことが起こるんじゃないでしょうか・・・。

この辺があいまいだと、悲劇の入口になりかねないのです。なので、こういうことをきちんと考えておくということはとても大切なことだと思います。
今日はそういう実験をしてみようと思います。
具体的な方法をお話するわけじゃありませんので、ぜひとも「時間に対する考え方」を養うようなお気持ちで読んでみてください。


ただ単に 7.5 とだけ入力し表示させればいいだけなら特に問題はないんです。
でも、例えば、下のようなテーブルがあって、

「労働時間」を2種類入力するようになってるとします。

このふたつの労働時間を足し合わせて、労働時間の合計を出したいなぁと思うんですが・・・。


その場合って、7.5+2.45=9.95 っていう計算で、オッケーでしょうか。

ふつうに足し算したら、そうなりますよね。

・・・計算はあってますよ。でもこういう考え方でいいんでしょうか?


「9時間95分?」それって 10時間35分 ってなってくれないと困るんだけど・・・。

この辺まで来ると、数字が苦手な方でも問題点が明確になってくるのではないでしょうか!?
そう。60で繰り上がるようにしてやらないといけないんですね。
でもそれ以前に、7.5が「7.5時間」なのか「7時間50分」なのか、入力した人がどういうつもりだったのか、その辺統一できてないとわけわかんなくなるってことです。


まず、なんでこんなことを考えなくてはならないのか、ということなんですが・・・。
時間って、必ずしも「10進数」ってわけじゃないですよね。

1時間は60分。
1分は60秒。
1日は24時間。
1年は365日。

バラバラ。1時間が10分だったり100分だったりするなら、別に難しいこと考える必要はないのです。
1時間が60分だから、大変なんです。

「15分間」というのは、60分間のうちの4分の1ですよね。

でも、100の4分の1は「25」ですよね。

だから、ふつうにコンピュータで足し算したり引き算したりするレベルで考えると、「1時間」が「1」なら、「15分」は「0.25」であるべきなのです。
要するに、単位をそろえて考えないといけない、ってことですね。
整数部分がごくごくふつうに10進数なのに、小数点以下が60進数で・・・なんてことに、なってませんか?皆さんのデータベース・・・。

といっても最初にも申しましたが、今回のように「労働時間の足し算」なんて場合に限って困ったことになる、と考えてくださいね。
ただ労働時間を表示させたいだけなのでしたら、入力した人、見る人の間で暗黙の了解が取れていて統一できてれば、別にどう入力しようと問題ないと思います。


7.5+2.45=9.95 みたいに計算をさせないといけない場合、どうやって考えていったらいいのでしょう。
と、いうことについて、いろいろ実験してみようではありませんか。


いろいろな関数などを組み合わせて、なんとか目的を達成させようと思うんですが、計算式の「検算」をするのにクエリを使いましょう。
具体的な実例とイメージが結びつかないかもしれませんが、とにかくまず、計算式の構造を考えてみましょう。具体的な使い方はそのうちイメージ沸いてくると思います。

クエリで計算式書くやり方は、みなさんオッケーですよね?
でははじめましょうか。労働時間2種類を入力するテーブルを選び、新規にクエリを作ったとします。
順番に進めていきますね。まずは[労働時間A]だけ例にとって考えてみましょう。いちおうグリッドに[労働時間A]を選んでおきますかね。なくてもいいんですけど、検算しにくいですから・・・。
で、オレンジ色のところに、式を入力していきます。

まず・・・。「小数点以下部分」を取り出したいなと思うんですが、少しずつ進めていきますね。
さいしょに「整数部分だけ」取り出してみましょう。

int関数というのを使えば、小数点以下を切り捨ててくれますよね。
Enterキーを押したりすると、勝手に式1とかカギカッコとかつきます。ヘンなエラーメッセージが出なければオッケーのはず。
int関数の詳細については、ヘルプを参照してください。

グリッドが狭くて見にくいようでしたら、広げちゃいましょう。赤いとこドラッグすれば広がりますよ。
でもあんまりいきおい良くドラッグしないように注意してくださいね。そっとね。

式1、っていうのが「項目名」になるんですけど、これじゃワケわかんなくなりそう・・・ということでしたら、式1というところだけ書き換えますかね。
:を消さないように注意しながら、何か適当な項目名に変更しましょう。

小数点以下が切り捨てられてこうなりました↓

後は、これを利用して、引き算すれば小数点以下の値だけ取り出すことができると思います。

できました?ココまでオッケーデスカ?

さて・・・。労働時間Aは、それぞれ「7時間50分」「2時間30分」「2時間15分」というつもりで入力したのだとしましょう。
そうすると[A分]の方は「50分」「30分」「15分」ということになりますね。

なので、これを100倍すれば、「50」「30」「15」という値になるはずです。


ちょっと横道にそれますが・・・。
なぜ「データ型」なんてものがあるか、その辺のこと、だいたい把握なさってます???

Accessに限ったことではないんですけども、コンピュータの内部でのデータの扱いと、わたしたちが見ているデータの表示とは、必ずしも同じというわけではないんですね。特に数値型のフィールドとテキスト型のフィールドは、きちんと区別して考えないといけません。

7.50という数値型の値があったとします。
数値の場合、小数点を境にして、右方向に小数点以下の桁、左方向に整数部分が伸びていくことになります。基本的には、10増えると1桁分、左右どちらかに伸びていくようになってますね。したがって数値の場合、基準になるのは小数点の位置であって、「右端の桁」とか「左端の桁」という考え方は、ないのです。

「7.50の、右端の50だけ取り出したい」なんてことは、数値ではありえないことです。
なぜなら、わたしたちには「ななてんごぜろ」という4つの数値記号のならびに見えても、コンピュータ内部では全然違う扱いをしているからです。だから、「右から2桁分」といっても、「5と0の2文字」という見方は、しないんですね。コンピュータは。

でも、クエリのグリッドで、Accessで使用できる文字列関数をいくつか使ってみると、数値ではありますがとりあえず文字列っぽく扱って都合よく取り出してくれたりします。試してみましょうか。「テキスト型の値の、右側の2桁取り出す」ためには、Right関数っていうのがありましたよね。

こんなかんじ。Right関数が数値型のフィールドに対しても使えるかどうかは、もしかしたらAccessのバージョンによるかもしれません。試してみて同じようにできなかったら、ココの操作はやめて先に進んでください。

うーむ。どうやら、小数点も含めて、まるっきり「文字扱い」してくれてるみたいですね。

不ぞろいな小数点以下の桁の扱いがすごく難しいんですが、仮に「小数点以下2桁まで」という取り決めになっていたとすると、

↑このように、まず100をかけて

100倍した値を、文字列っぽく扱ってもらって、下2桁取り出すようにしてみます。

とにかく、右からの桁数がそろってれば、Right関数でもうまいこと取り出すことができそうです。

でもこれって↑左によってますね。。。ちゃんと数値として扱ってもらわないと足し算とかできない可能性もあるので・・・。

Val関数を使って、体裁整えましょうかね。カッコが増えてくると入力がややこしいかもしれませんが、どの()がどの関数のためのものか、その辺意識しながら入力していってください。だんだん計算式複雑になりますから、これくらいの長さの計算式のうちに慣れちゃってくださいね。丸写ししないでくださいよ。それではこんなページご覧いただいてる意味がなくなっちゃう。練習なんですから、正しくできなくても間違っちゃってもいいじゃないですか。とにかく「考え方」をまず養っていってくださいね。


上記2種類の方法どちらを使っても、とりあえず結果はこんな感じになると思います。

これで、「時間」と「分」に分けることができたんですね。
で、次にどうするか、というか、どう考えるか、というところなんですけども・・・。
今回問題になってるのは、「労働時間Aと労働時間Bを足したときの、分の部分の繰り上げ」なんですよ。
つまり、ふつうに足したんじゃ、95分とかになっちゃうのを、1時間35分ということで、[A時間]の方に1繰り上げたいんです。
でもそんなの無理です。

なので・・・。こういう場合にお勧めなのが、「まず、"分"に直して、それから足し算する」方法です。
やってみましょうか。まず、分単位にします

これはオッケーですよね。[A分]の方は文句ナシに分単位になってますから、[A時間]を分単位にすればオッケーのはず。
今回はクエリを利用してるということで、[A時間]、[A分]というフィールドをあらかじめ作っておくことができますから、計算式がわりとすっきり書けると思います。
ここから、足し算と掛け算が混じりますから、計算の優先順位に注意してってくださいね。

出ました?

で、おなじことを、[労働時間B]に対してもやるわけです。どんどん横に長くなっていきますので、ゆっくり進めてくださいね。

どんどん右側の空いているグリッドに式を作っていきますね。
次に、分単位になおした値同士を、足し算します。

仮に[合計]という項目名にしたとしますね。これが、[労働時間A]と[労働時間B]の合計値で、いちおう目的は達成できたことになります。

あとは、これをどういう形で表示させたいか、ということになりますね。


また、10.35 みたいに、数値っぽく表示させます?これで「10時間35分」と読ませる?
うーん・・・その方がいいですか?まあ、今までの流れからいったら、そうなりますかね・・・。

んじゃあ、右の空いてるグリッドに、こんなふうな式を作ります。
項目名はとりあえず適当についたままの状態にしました。とりあえずやってみましょう。
左側は、[合計]を60で割り、小数点以下を切り捨てます。

右側は、Modという演算子を使います。これは、割り算した「あまり」だけ出すときに使うものです。関数じゃないので、+とか−とかと同じように使います。

で、ここからが正念場。このふたつの列の値を、&でくっつけて、間にドットを入れます。

文字列同士をつなげるやり方、皆さんオッケーデスカ?

なんかそれっぽくなってきました。↓

ただ表示させるだけなら、書式の「右寄せ」するだけでいいと思いますが、より数値っぽく扱うためにVal関数などを使って

完成です。フー。すごい大変。


これを、なんとかひとつの式でできないもんか・・・ただ式が長くなるだけでさほど難しいことはないと思いますよ。
要するに、今まで作ってきた各計算式を組み合わせればよいはずです。

↑これで、[労働時間A]を分単位にできますよね。これだけでもけっこう複雑になりますね。カッコが多くなるし・・・。
だから、ひとつずつコツコツ見てきたんですよ。いきなりこんな式作れって言われても、難しいですもん。

これに、[労働時間B]を足しこむところまで含めると、こうなります。

ひとつの式で書こうとすると、かなり長くなりそうですね・・・。
上の式で出た答えを60で割ることで、「時間」の部分を出すことができますね↓ intで端数処理をすることをお忘れなく。

で、この後ろに、小数点代わりのドットと、Mod演算子で出した「あまり」部分をくっつければ、完成です。

答え: Val(Int(((Int([労働時間A])*60)+(([労働時間A]-Int([労働時間A]))*100)+(Int([労働時間B])*60)+(([労働時間B]-Int([労働時間B]))*100))/60) & "." & (((Int([労働時間A])*60)+(([労働時間A]-Int([労働時間A]))*100)+(Int([労働時間B])*60)+(([労働時間B]-Int([労働時間B]))*100)) Mod 60))

↑こんな感じでしょうか。


こういう処理を作る場合、おすすめなのが、あらかじめ「分単位で入力」してもらうという方法です。

ご覧いただいたように、小数点以下の値を取り出したり、単位をそろえたりしなくてはならないのでとても面倒なんです。なので、できるだけ後々の手間を省くように入力させる、というのが、強いては最も効率のよいデータベースになっていくと思うんですよ。

あるいは、「時間」と「分」をバラバラにして、別々に入力させるとか。

[分]の方だけ足し算して、60で割ってIntした値を[時間]の方に足してやればいいわけですよね。
具体的にどうするか、ってことじゃなくて、どういう計算式にすればいいのか、そこんとこをイメージしてくださいね。

こういうテーブル設計が不可能であったり、既にもうたくさん入力してしまっていて後戻りできない場合などは、今までお話してきたような考え方に基づいてもっとも効率のよい計算方法を見出していってください。

とにかく、単位をそろえること、入力のルールを統一すること。これがポイントです。
人によって、7時間半を「7.5」と入力する人もいれば「7.3」と入力する人もいるんですけど〜なんてのは論外ですんで、こんなことにならないように。
コンピュータはおばかさんです。そんな高度な判定できませんよ。入力する側がちゃんと考えて入力しませんとね。

結局は、そういうことです。


最後にちょこっとだけ、実用例を・・・このクエリ、なんか適当な名前を使って保存したとして・・・。
グリッドの「並べかえ」の下に「表示」っていうチェックボックスがありますよね。このチェックを外すと、その列、表示されなくなります。
また、列幅をぐーっと縮めちゃうだけでもいいかもしれません。必要な列だけ表示されるようにして、このクエリを使って、日々の入力をしていけば・・・。

労働時間A、Bを入力すれば、ちゃんと、両方を足した答えがすぐ出るはずです。

このクエリを基にして作ったフォームを通じて入力する場合でも同様。
ふたつのテキストボックスを埋めれば、合計時間がちゃんと計算されると思います。

今回はクエリを使いましたけど、テキストボックスのコントロールソース欄とか、自分で作ったプロシージャに組み込む場合なども、基本的には今まで見てきた考え方とそれぞれの計算式が土台になります。基本的な考え方をマスターしてしまえば、状況に応じて結果を出すことができると思いますので、まずは、「どう入力していったら一番よいのか」「入力された値の扱いはどうしたらいいのか」を考えて、応用していってください。