プロが教える店舗&オフィスのセキュリティ対策術

いつもお世話になっております。
Access 2007で日報を作っていますが深夜計算のコードは次のように書きましたがうまくできなくて、どこでどんな間違いかも分からないです。教えていただきたいです。
If 22 <= 完了時間 <= 5 Then '完了時間は22時から朝の5時までなら深夜計算
深夜 = (完了時間 - #10:00:00 PM#) * 24 - 休憩 
Else
深夜 = 0
End If

全然VBAのことが分からなくて書きましたので教えていただくと助かります。
よろしくお願いします。

A 回答 (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分(休憩なし)

こういったパターンであれば、テキストボックスを追加することなく、解決できます。

ここから先は勤務形態で対応できる設計にする必要がありますので、それらを整理して明文化する事が先決となります。
    • good
    • 0
この回答へのお礼

いろいろありがとうございます。
これでいけました。確かに深夜時間に入れるとすごくややこしくなります。
勤務形態で対応するしかないです。
本当に助かりました。
感謝です。

お礼日時:2011/05/31 15:55

やりたいことの雰囲気はわかります。

コードもちょっと修正すれば大丈夫です。
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
やはりうまくいけません。
助けてください。

質問ばっかりですみません。
よろしくお願いします。

補足日時:2011/05/28 12:31
    • good
    • 0

よくわかんないけど、ロヂック的には



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時間休憩です。
上のコードはどういう風に加えたら深夜計算もできようになるんでしょうか?

よろしくお願いします。

補足日時:2011/05/27 16:03
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す