Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


851 / 13645 ツリー ←次へ | 前へ→

【77959】勤怠システムを自作したい 作りたい初心者 16/2/20(土) 23:11 質問[未読]
【77960】Re:勤怠システムを自作したい β 16/2/21(日) 8:30 発言[未読]
【77961】Re:勤怠システムを自作したい 作りたい初心者 16/2/21(日) 11:04 お礼[未読]
【77966】Re:勤怠システムを自作したい β 16/2/21(日) 17:30 発言[未読]
【77962】Re:勤怠システムを自作したい ichinose 16/2/21(日) 11:15 発言[未読]
【77963】Re:勤怠システムを自作したい β 16/2/21(日) 12:31 発言[未読]
【77964】Re:勤怠システムを自作したい ichinose 16/2/21(日) 16:53 発言[未読]
【77965】Re:勤怠システムを自作したい β 16/2/21(日) 17:22 発言[未読]

【77959】勤怠システムを自作したい
質問  作りたい初心者  - 16/2/20(土) 23:11 -

引用なし
パスワード
   今勤怠システムをつくるためにエクセルVBAのユーザーフォームを勉強しています。
名前をコンボボックスで選択し、オプションボタンで操作を指定、リアルタイムな時間表示を行い、操作ボタンをクリックするとその時刻で打刻されるエクセルシートにはデータを格納していくというプログラムを作りたいと考えています。

で、現時点ではリアルタイムな時刻表示をするにはどうしたらいいのか迷っています。

アイディアを頂きたく存じます。

【77960】Re:勤怠システムを自作したい
発言  β  - 16/2/21(日) 8:30 -

引用なし
パスワード
   ▼作りたい初心者 さん:

1つの方法のサンプルとして。
ユーザーフォームに Label1 と CommandButton1 を配置してください。

●ユーザーフォームモジュール


Private Sub CommandButton1_Click()
  DoLoop = Not DoLoop
  If DoLoop Then
    CommandButton1.Caption = "時刻表示中止"
    Application.OnTime Now(), "今何時"
  Else
    CommandButton1.Caption = "時刻表示再開"
  End If
End Sub

Private Sub UserForm_Initialize()
  CommandButton1.Caption = "時刻表示中止"
  DoLoop = True
  Application.OnTime Now(), "今何時"
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
  DoLoop = False
End Sub

●標準モジュール

Public DoLoop As Boolean

Sub 今何時()
  
  Do While DoLoop
    UserForm1.Label1.Caption = Now
    DoEvents
  Loop
  
  UserForm1.Label1.Caption = "時刻表示お休み中"
  
End Sub

【77961】Re:勤怠システムを自作したい
お礼  作りたい初心者  - 16/2/21(日) 11:04 -

引用なし
パスワード
   ▼β さん:
迅速に教えてくださりありがとうございます、サンプル実行したところ動作しました、ここまで分かれば自分なりにアレンジして使えそうです。
おそらく次はデータベース関係でご質問させていただくことになりそうですが、その際はまたよろしくお願い致します。

【77962】Re:勤怠システムを自作したい
発言  ichinose  - 16/2/21(日) 11:15 -

引用なし
パスワード
   ▼作りたい初心者 さん:
>で、現時点ではリアルタイムな時刻表示をするにはどうしたらいいのか迷っています。

VBAの関数 Now関数または、ワークシート関数のNow()関数(VBA内では、[Now()]と記述)

この二つぐらいの投稿で十分だと思いますが、ちょっと私的新発見があったので
投稿します。


新規ブックにて

ユーザーフォームを作成してください(UserForm1)。

このUserForm1には、 ラベル(Label1)とコマンドボタン(CommandButton1)を
一つずつ配置してください。


UserForm1のモジュール


Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private 表示 As Boolean
'==============================================================
Private Sub CommandButton1_Click()
  表示 = Not 表示
  If 表示 Then
    CommandButton1.Caption = "時刻表示中止"
    dspclock
  Else
    CommandButton1.Caption = "時刻表示再開"
  End If
End Sub
'================================================================
Sub dspclock()
  Do While 表示
    Label1.Caption = Now()
    DoEvents
  Loop
End Sub
'===============================================================
Private Sub UserForm_Activate()
  CommandButton1 = True
End Sub
'=================================================================
Private Sub UserForm_Terminate()
  表示 = False
End Sub


標準モジュールに

Sub test()
  UserForm1.Show
End Sub

これでtestを実行して試してみてください


時計表示がされると思います。
このプロフラムに近い物を理由は不明ですが、10年以上前に作った覚えがあります。
Win2000+Excel2000か2002だったと思います。


私的新発見とは・・・。

時刻をラベルに表示し、あたかも時計が動いているように見せるためにラベルに時刻を表示し続けるのがポイントだという事はちょっとVBAを学べはわかります。

プロシジャーで言うと、

Sub dspclock()
  Do While 表示
    Label1.Caption = Now()
    DoEvents
  Loop
End Sub

これなんですが、

この中で Doevents という記述がありますが、これ入れないとUserForm1は、真っ白のままで何も表示されない状態になってしまいます。

そこでワンクッションのつもりでDoeventsをはさむと見事にデジタル時計が表示される
のですが・・・・。

Excel2000Or2002の時、作ったものだと Doeventsだけを入れてループさせると
CPUの占有率が100%になってしまう現象が見られました。

時計を表示させるぐらいで100%ではやばい ということでAPIのSleepをDoeventsと
一緒に使う事で占有率は、まあいいだろうという程度に下がりました。
この時の経験等で DoeventsとSleepは、セットで使う癖が今でも付いています。

今回の質問で投稿した内容、Doeventsだけでも
CPU占有率は25%程度だったことが私的発見でした。

10年前に作成したストップウォッチでも同様の結果でした。
Win7+Excel2010で試した結果です。


因みに


Sub dspclock()
  Do While 表示
    Label1.Caption = Now()
    DoEvents
    Sleep 50
  Loop
End Sub

なんてすると、占有率は、0%〜2%程度でした。


βさんのコード時計表示中に閉じるボタンクリックでコードが終わらない可能性がありますよ!!

【77963】Re:勤怠システムを自作したい
発言  β  - 16/2/21(日) 12:31 -

引用なし
パスワード
   ▼ichinose さん:

いつも、ありがとうございます。

>βさんのコード時計表示中に閉じるボタンクリックでコードが終わらない可能性がありますよ!!

ichinoseさんのコードでは Terminateイベントを使っておられますね。
私のコードでは QueryClose を使ったわけですけど、閉じるボタンで
QueryClose が実行されないケースがあるということでしょうか?

ご教示いただければ幸いです。

【77964】Re:勤怠システムを自作したい
発言  ichinose  - 16/2/21(日) 16:53 -

引用なし
パスワード
   >ichinoseさんのコードでは Terminateイベントを使っておられますね。
>私のコードでは QueryClose を使ったわけですけど、閉じるボタンで
>QueryClose が実行されないケースがあるということでしょうか?

ユーザフォームの閉じるイベントは関係ないです。
やってみれば、わかります。
QueryCloseとTerminateの違いは、QueryCloseは、ユーザフォームの消去を状態によって
制御できるが、Terminateはできない ですよね?

現状、QueryCloseでは、閉じない制御をしているわけではないのです。

βさんのコードでは、
QueryCloseでもTerminateでもイベントは実行されています。

問題はイベント実行後です。
イベントは実行されているのですから、標準モジュールのループは抜けます。

が、その後、

UserForm1.Label1.Caption = "時刻表示お休み中"

こんなコードがあるのです。
ということは、一旦UnloadされたUserForm1は再びLoadされます。

Loadされれば、最初に発生するのがInitializeイベントですよね!!

プログラムは終わりませんよね!!

【77965】Re:勤怠システムを自作したい
発言  β  - 16/2/21(日) 17:22 -

引用なし
パスワード
   ▼ichinose さん:

>UserForm1.Label1.Caption = "時刻表示お休み中"
>
>こんなコードがあるのです。
>ということは、一旦UnloadされたUserForm1は再びLoadされます。

まさしく!!!
ありがとうございました。

【77966】Re:勤怠システムを自作したい
発言  β  - 16/2/21(日) 17:30 -

引用なし
パスワード
   ▼作りたい初心者 さん:


ichinoseさん指摘通り、よくないサンプルでした。
私のコードを参考にしていただくなら、
標準モジュールの UserForm1.Label1.Caption = "時刻表示お休み中" を消し
ユーザーフォームモジュールの CommandButton1.Caption = "時刻表示再開" の下に
Label1.Caption = "時刻表示お休み中" を入れてください。

851 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free