Excel (VBA)

Excel VBAに関するフォーラムです。
  • 掲示板への投稿には会員登録(無料)が必要です。会員登録がまだの方はこちら
  • 掲示板ご利用上のお願い」に反するご記入はご遠慮ください。
  • Q&A掲示板の使い方はこちらをご覧ください
トピックに返信
質問

 
(指定なし : 指定なし)
マクロで打刻出来るようにしたい
投稿日時: 24/09/02 13:06:56
投稿者: t.piece

教えてください。
下記の様に5つの作業がありそれぞれ開始時間と終了時間が開始と終了をクリックすると時間が表記出来るようにしたいのですが、どの様にマクロを組めば良いかご教授お願いいたします。
出来ればその日で終了出来ない場合もあるので繰り越しが出来るようにもしたいです。
すみませんが、宜しくお願いいたします。
作業A 作業B 作業C 作業D 作業E
開始時間 終了時間 作業時間 開始時間 終了時間 作業時間 開始時間 終了時間 作業時間 開始時間 終了時間 作業時間 開始時間 終了時間 作業時間

回答
投稿日時: 24/09/02 16:19:10
投稿者: QooApp

	A	B	C
1	作業A
2	始	終	作

 
これが横に5種類列挙されてるということですね
 
始:開始時刻記入欄
終:終了時刻記入欄
作:作業時間(終から始を引いた差)

回答
投稿日時: 24/09/02 17:15:36
投稿者: QooApp

Range("A2").Value = Format(Now, "yyyy/mm/dd-hh:mm:ss")

でボタン押下時刻を記述させれば開始も終了も設定できる
ボタンの作り方とか、ターゲットセルの変更は別途やるとして、Nowにある値を見たいデータ形式に揃えてフォーマット関数ではめればよし
 
    Dim startTime As Date
    Dim endTime As Date
    Dim diff As Double
    Dim days As Long
    Dim hours As Long
    Dim minutes As Long
    Dim seconds As Long
    Dim output As String
    
    ' セルA1とA2から開始時刻と終了時刻を取得
    startTime = Range("A2").Value
    endTime = Range("B2").Value
    
    ' 時刻差を計算(終了時刻 - 開始時刻)
    diff = endTime - startTime
    
    ' 差分を日、時間、分、秒に分解
    days = Int(diff)
    hours = Int((diff - days) * 24)
    minutes = Int((diff * 24 * 60) - (days * 24 * 60) - (hours * 60))
    seconds = Round((diff * 24 * 60 * 60) - (days * 24 * 60 * 60) - (hours * 60 * 60) - (minutes * 60), 0)
    
    ' day:hour:min:sec の形式に変換
    output = days & ":" & Format(hours, "00") & ":" & Format(minutes, "00") & ":" & Format(seconds, "00")
    
    ' 計算結果をセルB1に出力(例)
    Range("C1").Value = output

 
開始時刻は前述の現在の時刻を記述するだけで済むが、後者の終了時刻完了時は計算処理を実行するように複数関数呼び出しとなるだろう
 
作業Aで適用したものを同じ関数で実行したければターゲットのセル位置を動的に移動させればよし

回答
投稿日時: 24/09/02 18:19:57
投稿者: Suzu

具体的に、ユーザーにはどんな操作をさせようと お考えなのでしょうか?
 
作業種類として、A〜E があり、
 それぞれに 開始時刻・終了時刻 が あり、そこに、時刻を入力させれば 時間が算出される
 
どのように、A〜E を選択させるのでしょうか?
開始時刻・終了時刻を打刻するボタンがあるのは判りますが
それぞれの時刻への打刻用のボタンを用意するのでしょうか?
 
その場合
 Aの 開始時刻 ボタン、Aの終了時刻 ボタン
 Bの 開始時刻 ボタン、Bの終了時刻 ボタン
    :
 Eの 開始時刻 ボタン、Eの終了時刻 ボタン
の 10個のボタンを配置するのでしょうか?
 
アクティブなセルに現在時刻を入力するには、「ctrl」+「:」で 良いです。
 時間については一般関数でも良いかも知れません。
 

引用:
出来ればその日で終了出来ない場合もあるので繰り越しが出来るようにもしたいです。

の発言、例示された表から、縦方向に、日付順に並んでいる? とも推測できますが
その辺りは推測の域を出ないので何とも言えませんが・・
 
ただ、先の発言の「繰り越しが出来る」の発言の意図は理解しかねます。
どうありたいのか、もっと具体的に例示いただけますか?

回答
投稿日時: 24/09/03 10:43:25
投稿者: WinArrow

既にご指摘がありますが、
 
まず、入力に関するシートの表のレイアウトを説明しましょう。
具体的な入力方法としては
(1)ボタンを配置して、ボタンクリックでマクロを起動する方法
(2)セルをクリック以外の方法(ダブルクリック、右クリックなど)でマクロを起動する方法
等も説明しましょう。
 
おそらく、同時(開始〜終了の間)に複数の作業が存在するか?
などの制約条件も必要です。
終了が日を跨るという説明があるので、
時刻だけでは作業時間の計算が難しいですね。日付はどうするのか?
 
等、入力だけではなく、
そのデータの使い方を考慮したレイアウトにしましょう。
 

投稿日時: 24/09/04 11:46:19
投稿者: t.piece

Suzu さんの引用:
具体的に、ユーザーにはどんな操作をさせようと お考えなのでしょうか?
 
作業種類として、A〜E があり、
 それぞれに 開始時刻・終了時刻 が あり、そこに、時刻を入力させれば 時間が算出される
 
どのように、A〜E を選択させるのでしょうか?
開始時刻・終了時刻を打刻するボタンがあるのは判りますが
それぞれの時刻への打刻用のボタンを用意するのでしょうか?
 
その場合
 Aの 開始時刻 ボタン、Aの終了時刻 ボタン
 Bの 開始時刻 ボタン、Bの終了時刻 ボタン
    :
 Eの 開始時刻 ボタン、Eの終了時刻 ボタン
の 10個のボタンを配置するのでしょうか?
→そうですね。ボタンは10個必要となります。
 
アクティブなセルに現在時刻を入力するには、「ctrl」+「:」で 良いです。
 時間については一般関数でも良いかも知れません。
→現在時刻の入力の件ですがショートカットも考えたのですが、作業者はキーボードを使用しない(基本隠れている)がありますので、この様な方法をとりました。
 
引用:
出来ればその日で終了出来ない場合もあるので繰り越しが出来るようにもしたいです。

の発言、例示された表から、縦方向に、日付順に並んでいる? とも推測できますが
その辺りは推測の域を出ないので何とも言えませんが・・
 
ただ、先の発言の「繰り越しが出来る」の発言の意図は理解しかねます。
どうありたいのか、もっと具体的に例示いただけますか?

→仰る通り縦方向に日付が並びます。
9/3 開始8:30 終了17:00 7.5h
9/4 開始8:30 終了11:30 3h
この様な感じで完全に作業が終了しない限り縦方向に移動していく感じです。
ですので完全終了のボタンも必要なのかもしれません。
ご理解いただけたでしょうか。
すみませんが、宜しくお願いいたします。
 
 
 

投稿日時: 24/09/04 12:22:05
投稿者: t.piece

WinArrow さんの引用:
既にご指摘がありますが、
 
まず、入力に関するシートの表のレイアウトを説明しましょう。
具体的な入力方法としては
(1)ボタンを配置して、ボタンクリックでマクロを起動する方法
(2)セルをクリック以外の方法(ダブルクリック、右クリックなど)でマクロを起動する方法
等も説明しましょう。
 
おそらく、同時(開始〜終了の間)に複数の作業が存在するか?
などの制約条件も必要です。
終了が日を跨るという説明があるので、
時刻だけでは作業時間の計算が難しいですね。日付はどうするのか?
 
等、入力だけではなく、
そのデータの使い方を考慮したレイアウトにしましょう。
 

 
ご協力ありがとうございます。
そうですね。細かい点の説明がなく大変失礼いたしました。
レイアウトは下記のようになります。
操作についてはエクセルを起動後、作業は左からになりますので、左から順に開始(クリック)していく感じになります。
また、作業の重複はないので前の作業が終了しない限り、次の作業に移ることはありません。
 
      開始ボタン    作業途中ボタン    終了ボタン        開始ボタン    作業途中ボタン    終了ボタン        開始ボタン    作業途中ボタン    終了ボタン        開始ボタン    作業途中ボタン    終了ボタン        開始ボタン    作業途中ボタン    終了ボタン
    作業A                作業B                作業C                作業D                作業E        
日付    開始時間    終了時間    作業時間    日付    開始時間    終了時間    作業時間    日付    開始時間    終了時間    作業時間    日付    開始時間    終了時間    作業時間    日付    開始時間    終了時間    作業時間
9月2日    8:30:00    17:00:00    7:30:00                                                                
9月3日    8:30:00    11:30:00    3:00:00                                                                
                9月3日    11:30:00    14:30:00    2:00:00                                                
                                9月3日    14:30:00    17:00:00    2:30:00                                
                                9月4日    8:30:00    15:00:00    5:30:00                                
                                                9月4日    15:00:00    17:00:00    2:00:00                
                                                                            
                                                                            
 
以上、すみませんが宜しくお願いいたします。        

投稿日時: 24/09/04 12:22:34
投稿者: t.piece

QooApp さんの引用:
Range("A2").Value = Format(Now, "yyyy/mm/dd-hh:mm:ss")

でボタン押下時刻を記述させれば開始も終了も設定できる
ボタンの作り方とか、ターゲットセルの変更は別途やるとして、Nowにある値を見たいデータ形式に揃えてフォーマット関数ではめればよし
 
    Dim startTime As Date
    Dim endTime As Date
    Dim diff As Double
    Dim days As Long
    Dim hours As Long
    Dim minutes As Long
    Dim seconds As Long
    Dim output As String
    
    ' セルA1とA2から開始時刻と終了時刻を取得
    startTime = Range("A2").Value
    endTime = Range("B2").Value
    
    ' 時刻差を計算(終了時刻 - 開始時刻)
    diff = endTime - startTime
    
    ' 差分を日、時間、分、秒に分解
    days = Int(diff)
    hours = Int((diff - days) * 24)
    minutes = Int((diff * 24 * 60) - (days * 24 * 60) - (hours * 60))
    seconds = Round((diff * 24 * 60 * 60) - (days * 24 * 60 * 60) - (hours * 60 * 60) - (minutes * 60), 0)
    
    ' day:hour:min:sec の形式に変換
    output = days & ":" & Format(hours, "00") & ":" & Format(minutes, "00") & ":" & Format(seconds, "00")
    
    ' 計算結果をセルB1に出力(例)
    Range("C1").Value = output

 
開始時刻は前述の現在の時刻を記述するだけで済むが、後者の終了時刻完了時は計算処理を実行するように複数関数呼び出しとなるだろう
 
作業Aで適用したものを同じ関数で実行したければターゲットのセル位置を動的に移動させればよし

 
ご回答ありがとうございます。
上記のマクロを記入し、ボタンを作成し、実行しましたが作業時間は出るのですが開始及び終了時間が出ない為、0:00となってしまいます。ボタンにこのマクロの読み込みも出来ないのですが、読み込みはどの様に行えば宜しいでしょうか。
すみませんが宜しくお願いいたします。

回答
投稿日時: 24/09/04 13:08:44
投稿者: QooApp

表組を張りたいときは、対象のテキスト範囲を選択した状態で入力欄の下のコードってボタン押すと表組として維持されますが通常のテキストだとずれます。
 
とりあえずB以降のは作業Aと同じ列構成なのはわかるのでいったん作業Aだけで表組を作り直してみてください。
送信前にプレビューボタンで構成が崩れていないか確認できます。
 
 
本件のような打刻システムを開発した経験があるので指摘しておくところがあるとすれば
打刻ミスによる修正は別途システム管理者や承認権限者(上長)へ修正申請を別ルートで用意しておく必要があります。
そこまで高精度で管理する必要が無ければ構いませんが、一度打刻すると再打刻しようとすれば差が発生するので当然データの破損につながる恐れがあります。
 
有名どころのサービスを参考に書きます。
OBC勤怠管理(奉行)の勤怠管理アプリではこのような場合
・開始ボタン(出社ボタン)
・終了ボタン(退勤ボタン)
があります。
 
また、一度出社時刻を打刻後、再度ボタンを押した場合、警告が表示されます。
警告に従って上書きを強行した場合は上書きされますがキャンセルした場合は元の時刻が残ります。
 
また、一定の時刻を基準にして前日の出社打刻時刻と今日の打刻時刻の線引きがあります。
これを超えると翌日の開始扱いになる境界なので重要です。
0時境界ならいいですが、AM8時以前は前日などのパターンも見たことがあります。
 
また、打刻漏れが発生した場合、別途アプリ内で未打刻申請を出し、
担当者の上長に通知が行きます。
上長が申請内容を確認して許可した場合に値が代入されます。
ここはシステマチックに進めるというよりは、未打刻が発生したら別途管理者に連絡してね。
システム管理者が個別に打刻更新するよ。
で構わないですが、人間はミスする生き物なので結構な件数が毎日届きます。
面倒であれば例外上書きモードとして検討したほうがおすすめでしょう。
 
また、日をまたいだのか、前日の作業がその日に被ったのか
判断できるのか。その条件はクリティカルな問題になると思うのでよく考えて実装が必要です。
 
▼あり得る例外
9/1 AM9時に開始 > 9/1の開始時刻に打刻
9/2 AM1時に終了 > 9/2の終了時刻に打刻されてしまった
 
9/1 AM9時に開始 > 9/1の開始時刻に打刻
9/1 PM5時に時刻打刻忘れ > 9/2になっても気付かなかった(管理者が更新しなかった)
9/2 AM9時に開始 > 9/2の開始時刻に打刻
9/2 PM5時に終了 > 9/1の終了時刻に打刻されてしまった
 
こういった問題を解決するために、打刻ボタン以外に、入力ターゲット日(動作上の扱い日)を設定する項目は必要でしょう。
 

回答
投稿日時: 24/09/04 16:11:12
投稿者: QooApp

t.piece さんの引用:

ご回答ありがとうございます。
上記のマクロを記入し、ボタンを作成し、実行しましたが作業時間は出るのですが開始及び終了時間が出ない為、0:00となってしまいます。ボタンにこのマクロの読み込みも出来ないのですが、読み込みはどの様に行えば宜しいでしょうか。
すみませんが宜しくお願いいたします。

 
原則Date型で定義されていれば動作するので
buttonの動作はbutton用の関数から汎用の時刻設定関数に代入するセルの座標情報を引数で与えればいいでしょう。
セルの書式はデフォルトのままで関数を実行した場合、yyyy/mm/dd hh:mmと結構大掛かりに表示される場合があります。書式設定は別途見たいように設定してください。
日をまたぐ場合があるという話なので「mm/dd hh:mm」くらいはいるんじゃないですかね。
 
Sub ボタンに登録する関数_A2()
    'A2セルの設定
    時刻設定 (ThisWorkbook.Worksheets("Sheet1").Cells(2, 1))
End Sub

Sub ボタンに登録する関数_B2()
    'B2セルの設定
    時刻設定 (ThisWorkbook.Worksheets("Sheet1").Cells(2, 2))
End Sub
.
.
.

Sub 時刻設定(r As Range)
    '注意:このまま実行した場合、ボタンに登録する関数_nnの座標しか設定しないので
    'それぞれのボタンの関数内で、何行目をメンテナンスするか決定する処理を組むこと。
    r.Value = Now
End Sub

回答
投稿日時: 24/09/04 18:36:25
投稿者: Suzu

これを何の為にマクロにしたいのでしょうか。
 
ご希望のレイアウトとなる様、疑似的にでも配置し
ユーザーが操作するときの操作をテストしてみてください。
 
作業A〜作業E まで専用で
 同じようなボタンが沢山横に並んでいる
 どのボタンを押したら良いのか すごい判りづらくありませんか?
 
私なら、”いやだ”と突き返します。
 
 
 

引用:
完全に作業が終了しない限り縦方向に移動していく感じです。

 
結局、終了時刻が、次の作業の開始時刻? であれば、終了と開始は別にしなくとも良いし、
 
引用:
作業の重複はないので前の作業が終了しない限り、次の作業に移ることはありません。

そうなら、表のレイアウトとしては
日    開始    A    B    C    D    E    終了
9/2    8:30    8:30                    17:00
9/3    8:30    11:30    14:30    17:00            17:00
9/4    8:30                8:30    15:00    17:00
でも充分なのでは?
 
日付で、横に並べた方が分かり易くありませんか?
 
 
記録の表と、見せたい表
一つにできたら確かに楽かもしれませんが、
 
ボタン沢山配置する事で 入力者側へ間違い易さを強いる事になり
コーディング者も面倒。
       仕様変更が出たら。その時には表の配置も変わるし・・コード全見直し
また、多分、データとしては、シート毎または、ブック毎 に人を分けていますよね?
 
 
9/2    阿部    A    8:30    17:00
9/3    阿部    A    8:30    11:30
9/3    阿部    B    11:30    14:30
9/3    阿部    C    14:30    17:00
9/4    阿部    D    8:30    15:00
9/4    阿部    E    15:30    17:00
 
のような記録用の表にデータを保存
必要に応じて マクロを用いて見たいフォーマットの表に成形する。
入力系と、出力系を別に考える方が管理としては楽です。
 
 
後半は、スルーしても構いませんが
入力者がつらい仕組みは、よっぽどでない限り 長続きしません。
入力者にも配慮した画面構成を検討ください。

回答
投稿日時: 24/09/05 14:32:30
投稿者: WinArrow

質問者さんが説明したレイアウトについて
  
操作性という面から考えて
私も”いやだ"といいます。
作業A→作業B→作業C・・・・という順番に作業するのですか?
1日の始まりは、何時ですか?終わりは何時ですか?
その1日の中に作業A〜E全てが存在するのですか?
 
>作業途中ボタン
このボタンは、どのような目的で存在するのですか?
 
そして、入力したデータをどのように使うのですか?
  
前レスにも書きましたが、入力だけではなく、データの利用まで考えて
設計しないと、行き当たりばったりになってしまいますよ。
 

トピックに返信