- ベストアンサー
ACCESS で深夜計算
いつもお世話になっております。 Access 2007で日報を作っていますが深夜計算のコードは次のように書きましたがうまくできなくて、どこでどんな間違いかも分からないです。教えていただきたいです。 If 22 <= 完了時間 <= 5 Then '完了時間は22時から朝の5時までなら深夜計算 深夜 = (完了時間 - #10:00:00 PM#) * 24 - 休憩 Else 深夜 = 0 End If 全然VBAのことが分からなくて書きましたので教えていただくと助かります。 よろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
shut0325です。 深夜の扱いですが、これは会社のルール(特に給与計算)も影響します。 例えば、交代制で深夜に通常勤務するパターンがある場合は、 「深夜だけど、残業ではない部分」というのも存在します。 また、休憩時間も、徹夜するようなときは、昼12時に1時間とって、夜の23時に1時間というパターンもあるかと思いますし、22時にとる場合もあります。そうなってくると、給与計算の結果は異なる可能性があるのです。 そうなってくると、勤務パターンをいくつか作り、それに対して、「遅刻・早退・残業・深夜勤務」と分けて処理する必要があります。 今回は、そのような2交代/3交代がないパターンで、徹夜する場合も区切りを一旦午前6時に設けるという方法で考えたいと思います。 考え方はシンプルで、前回のコードでのEndTimeを利用します。 午前2時に終わった場合、EndTimeは2+24=26(時)です。 つまり、深夜扱いに切り替わるの22時(22)を引けば、深夜時間が出てきます。 例えば、ETが19:00の場合どうなるでしょう? 答えは-3です。なので、「EndTime-22(時)が0より大きい場合は、その結果をMe.shinyaに代入し、それ以外の場合はMe.shinyaを0に」すれば良いのです。 問題は残業(Zan)との兼ね合いです。 単純に上記式のみであれば、残業m時間(うち深夜勤務n時間)となります。 場合によっては、通常勤務時間で深夜になる場合もあるでしょう。 そうなると面倒だという場合、 残業計算に入る前に、深夜時間を算出し、総勤務時間からそれ引いた上で、残業計算を行う一行を足す必要があります。 まず、ここまでのコードを下記に記します。 前回のコードの、 最初の方を書き換え+追加して下さい。 ----- Dim StartTime, EndTime, Kugiri, tuujou, Soukinmu,shinyakugiri,SinyaTime As Long:'追加 tuujou = 8: '通常勤務時間 8時間 Kugiri = 6: '変更 区切り時間 午前6時 shinyakugiri = 22:'追加 深夜区切り 22時 ----- 次に下記コードに2箇所追加記述します。 ----- '完了時間が 0時以上 5時以下 の場合、24時間足す。 If EndTime >= 0 And EndTime <= Kugiri Then EndTime = EndTime + 24 End If '追加 SinyaTime = EndTime - Shinyakugiri If SinyaTime > 0 Then Me.sinya = SinyaTime Else Me.shinya = 0 ----中略 '総勤務時間算出 Soukinmu = EndTime - StartTime - Me.kyukei '工数算出 Me.kousu = Soukinmu / tuujou '追加(Me.sinyaは前の処理で、深夜にかかっていない場合0なので、適切に計算される) Soukinmu = Soukinmu - Me.sinya -----以下略 以上ですが、最後に残った問題は休憩時間の処理です。 これはテキストボックスを追加して、「何時に」「どれだけ(時間)」というのが無いといけません。そうなってくると、今は開始時間/完了時間/休憩時間 の3つでよかったのですが、項目を増やすと入力が煩雑になり、面倒ですね。3回休憩する可能性があれば、3項目×2=6つ入力箇所が増えます。 一番楽なのは勤務形態によりますが、「22時以降の勤務は必ず1時間の休憩を取る。とらない場合でも、取った計算になる」とし、深夜扱いの時間を23時とする方法。 なので、22:30に完了した場合は、22時を超えた30分は深夜扱いにならない。 或いは、23時を超えている場合は無条件で1時間休憩が付与され、それ以前は休憩はなしでやったという扱いにする。 例:23:10→深夜時間は10分(休憩1時間引き) 22:30→深夜時間は30分(休憩なし) こういったパターンであれば、テキストボックスを追加することなく、解決できます。 ここから先は勤務形態で対応できる設計にする必要がありますので、それらを整理して明文化する事が先決となります。
その他の回答 (2)
- shut0325
- ベストアンサー率40% (490/1207)
やりたいことの雰囲気はわかります。コードもちょっと修正すれば大丈夫です。 VBAを覚えていくのにはそのように他人のコードを元に推測しながら自分で書き換えていくことはいい勉強になると思います。 ちょっとずつ解決していきましょう。 まず、前回作ったものでは、開始時間/完了時間 は 時刻(S)です。 これは内部では、0:00:00が0で始まり、23:59:59が0.9999,,,という値になります。 つまり内部で1は1日を表します。 なので、時間を算出する際に24をかけているのです。 (厳密には日付と関連するのですが、その辺は割愛します。) なので、例えば、開始時間:17:00 完了時間:3:00 休憩:1時間 を計算してみると、本来は、9時間のはずですが、-15時間になりませんか? 深夜計算の前にここを正しましょう。 ここを正しくするには、「完了時間が深夜0時から5時」の場合は、 計算を、(完了時間-開始時間)*24 ではなく、(完了時間+1-開始時間)*24 となります。 翌日の3時なので、24時間(1日)足す。と思ってもらえば良いです。 これをコードにすると、以下になります。 テキストボックスの名称が「開始時間→ST」「完了時間→ET」「休憩→kyukei」「工数→kousu」「残業時間→zan」となっている前提です。 前回は簡易な書き方をしましたが、変数を表しているのか、テキストボックス(の値)を指すのかがわかりづらく、混乱の元となると思ったので、少し明示的な書き方をします。 といっても、Dim文による変数の宣言と、Me.~~による、テキストボックスの指定だけです。 Me.~~という表記は「今のフォームのなかにある~~」という意味です。 なので、厳密には「今のフォームのなかにある、Aというコントロールの値(内容)」は Me.A.Value と書くのですが、Me.A や A でも大丈夫です。 ただ、他のフォームと連携するときなどはトラブルになるので、明示的な表記法を覚えておいたほうがいいと思います。 今回のコードは処理的には条件分岐が一箇所増えただけです。 長くなったので深夜計算は次回に持ち越します。 ---- Private Sub コマンド1_Click() Dim StartTime, EndTime, Kugiri, tuujou, Soukinmu As Long tuujou = 8: '通常勤務時間 8時間 Kugiri = 5: '区切り時間 午前5時 '処理がわかりやすくするために時刻(m日)を数値(n時間)に変換 StartTime = Me.ST * 24 EndTime = Me.ET * 24 '完了時間が 0時以上 5時以下 の場合、24時間足す。 If EndTime >= 0 And EndTime <= Kugiri Then EndTime = EndTime + 24 End If '総勤務時間算出 Soukinmu = EndTime - StartTime - Me.kyukei '工数算出 Me.kousu = Soukinmu / tuujou '総勤務時間が通常勤務時間以下の場合、 '残業時間は0、勤務時間は総勤務時間。 '総勤務時間が通常勤務時間より大きい場合、 '残業時間=総勤務時間-通常勤務時間 勤務時間=通常勤務時間 If Soukinmu <= tuujou Then Me.zan = 0 Me.kinmu = Soukinmu Else Me.zan = Soukinmu - tuujou Me.kinmu = tuujou End If End Sub -----
補足
Shut0325様 ありがとうございます。 前回の質問で締めたためどうしようと思って、自分で何とかコードを作ろうかなって簡単に思ったら全然ダメで、やっぱりここに頼るしかないです。 >>なので、例えば、開始時間:17:00 完了時間:3:00 休憩:1時間 を計算してみると、本来は、9時間のはずですが、-15時間になりませんか? 確かにこの時間に出ました。 今教えていただきたコードはうまくいけました。 ただし、深夜テキストボックスも設置しています。 そこでこれを加えました。 If Me.zan <= 5 Then Me.zan = Soukinmu - tuujou Me.kinmu = tuujou Else Me.sinya = Soukinmu - tuujou - 5 Me.zan = 22 - 17 End If ですが必ずにしても5時間通常残業をしない場合もあります。 たとえば10時に出勤し、退勤は23時場合: ST:10:00 ET:23:00 kinmu: 8 zan: 3 sinnya : 1 つまり通常勤務は8時間が超えるなら残業ですが22時以降は深夜となっています。 でも私は作ったコードはできないです。 いろいろ考えてこれも作ってみましたが If EndTime <= 22 Then Me.zan = Soukinmu - tuujou Me.kinmu = tuujou Else Me.sinya = Soukinmu - tuujou - Me.zan Me.kinmu = StartTime + 8 Me.zan = 22 - Me.kinmu - Me.kyukei End If やはりうまくいけません。 助けてください。 質問ばっかりですみません。 よろしくお願いします。
- ShowMeHow
- ベストアンサー率28% (1424/5027)
よくわかんないけど、ロヂック的には if 始業日=終業日 then if 終業時刻>22.0 then 深夜勤務=終業時刻-22.0 else 深夜勤務=0 end if else if 終業時刻>5.0 深夜勤務=7.0 else 深夜勤務=2+終業時刻 end if end if if 始業時刻>22.0 then 深夜勤務=深夜勤務+24-始業時刻 if 始業時刻>5.0 then 深夜勤務=深夜勤務-始業時刻 みたいにいくつかの時間帯に区切って考えたほうが良いと思う。 まあ、始業時間が必ず5:00以降、22:00前という前提であればこうする必要はないけど。 あと、時刻をどう扱うかは好みだけど、時刻データとして扱うより、分を小数として扱うほうがらくだと思う。 入力は分で入れて計算前に変換するってこと。 文法的な話をするなら、 if 22 <= 完了時間 <= 5 Then →if 22 <= 完了時間 and 完了時間 <= 5 Then 深夜 = (完了時間 - #10:00:00 PM#) * 24 - 休憩 これは、難しいね。 timediff使っても結局60進数の繰り上がり(下がり)をするとかしなくちゃいけなくなってくるし、、、 なんで、何時何分というのを 時+分/60 のような計算をして 6:30=6.5時 みたいに換算したほうが処理が楽ってこと。
補足
質問はあまりよくないですみません。 丁寧なご回答ありがとうございます。 前このコーナーで勤務間の計算を教えてもらいました。 kyukei = 1: '休憩時間 1時間 tuujou = 8: '通常勤務時間 8時間=1工数 勤務時間 = (完了時間 - 開始時間) * 24 - 休憩: '総勤務時間 工数 = 勤務時間 / tuujou: '工数算出 '総勤務時間が通常勤務時間以下の場合、 '残業時間は0、勤務時間は総勤務時間。 '総勤務時間が通常勤務時間より大きい場合、 '残業時間=総勤務時間-通常勤務時間 勤務時間=通常勤務時間 If 勤務時間 <= tuujou Then 残業 = 0 Else 残業 = 勤務時間 - tuujou 勤務時間 = tuujou End If 今回は深夜時間を加えたいと思いますがVBAは全く分からなくて勝手に想像してコードを作りました。 深夜計算は次のように 22時から朝の6時まで深夜に計算します。1時間休憩です。 上のコードはどういう風に加えたら深夜計算もできようになるんでしょうか? よろしくお願いします。
お礼
いろいろありがとうございます。 これでいけました。確かに深夜時間に入れるとすごくややこしくなります。 勤務形態で対応するしかないです。 本当に助かりました。 感謝です。