電子書籍の厳選無料作品が豊富!

VBAに詳しい方、教えて下さい!
内容ですが、VBAでストップウォッチ機能を追加し決まったシートに
その秒数を張り付けていきたいです。
その中で今困っていることが下記のところです。
【やりたいこと】
1 START/STOPボタンを1回押すとB2:C3セルが時間観測を開始します
2 ENTERキーを押していくと作業内容の上側のセルだけ秒数が入ります
  (2行飛ばしで秒数が入っていきます)
 ↑この実行はNo1の時間観測中だけ有効にしたいです。
 時間観測していないときはENTERキーを押しても処理しないようにしたいです。
3 {RIGHT}”→”キーを押していくと6行目(作業内容1)の次の列に秒数が入ります
 これもNo2と同じようにNo1の時間観測中だけ有効にしたいです。
 時間観測していないときは{RIGHT}”→”キーを押しても処理しないようにしたいです。

今現在のコードは下を参照下さい
お手数おかけしますがご教授願います。

Option Explicit

Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private cnt As Range
Private blnStop As Boolean
Private blnStart As Boolean
Private dblTimer As Double
Private bLap As Double
Private cntLap, No, No2, i, j, k, S, F, X, Z, V, R As Long

Sub StartStop()
If blnStart = True Then
blnStop = True
Exit Sub
End If
bLap = 0
cntLap = 0
blnStart = True
blnStop = False
dblTimer = Timer
Do Until blnStop = True
Cells(2, 2) = Int((Timer - dblTimer) * 100) / 100
Sleep 1
DoEvents
Loop
blnStart = False
blnStop = False
End Sub

Sub Enter_set1()
'キー割り当て用
Application.OnKey "{ENTER}", "nui" 'テンキーのエンターキーのみ
Application.OnKey "~", "nui" 'キーボードのエンターキーのみ
End Sub

Sub nui()
'X = 18
V = 6
R = Cells(Rows.Count, 1).End(xlUp).Offset(-6, 0).Row - 1
If 2 >= Z Then
Z = 2
If R >= No2 Then
No2 = No2 + 2
Sleep 1
Cells(No2 + 4, Z) = Round(Timer - dblTimer, 2)

Else
Z = Z + 1
No2 = 0
No2 = No2 + 2
Sleep 1
Cells(No2 + 4, Z) = Round(Timer - dblTimer, 2)
End If
Else
If R >= No2 Then
No2 = No2 + 2
Sleep 1
Cells(No2 + 4, Z) = Round(Timer - dblTimer, 2)
Else
Z = Z + 1
No2 = 0
No2 = No2 + 2
Sleep 1
Cells(No2 + 4, Z) = Round(Timer - dblTimer, 2)
End If
End If

End Sub
Sub RIGHT_set1()
'キー割り当て用
Application.OnKey "{RIGHT}", "RGT" 'キーボードのエンターキーのみ
End Sub

Sub RGT()
Z = Z + 1
No2 = 0
No2 = No2 + 2
Sleep 1
Cells(No2 + 4, Z) = Round(Timer - dblTimer, 0)
End Sub

Sub LapSplitClear()
S = 6
F = Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row - 2
'F = 25
Do While F >= S
Range(Cells(S, 2), Cells(S, 16)).ClearContents
S = S + 2
Loop
Cells(2, 2) = 0
Z = 0
No2 = 0
End Sub

因みに
ThisWorkbook には下記コードが入ってます
Private Sub Workbook_Open()
Call Enter_set1
Call RIGHT_set1
End Sub

Sheet1(Sheet1) には下記コードが入ってます

Private Sub Worksheet_Activate()
Call Enter_set1
Call RIGHT_set1
End Sub

Private Sub Worksheet_Deactivate()
Application.OnKey "~"
Application.OnKey "RIGHT"
End Sub

「Excel VBA マクロ実行中のみテン」の質問画像

質問者からの補足コメント

  • No1さん
    すいません。
    STOPが効かないのは自分が不手際でした。

    No.2の回答に寄せられた補足コメントです。 補足日時:2021/01/25 14:13
  • たまにですが、セルに値が入らないときがあります。エンターキーなどは反応していると思われますが。。

      補足日時:2021/01/28 10:41

A 回答 (16件中11~16件)

No4です



No5様のヒントをいただいて思いつきましたが、
・現状ではStartStopを押した後は、キーが効かない
状態ということでしょうか?

うっかりと、現状はできていてるものを、「Stop後はキーを効かなくしたい」ものと解釈してしまっていました。
ご提示のコードがそれなりに複雑なので、テストをせずに、またまた失礼をいたしました。

現状で、キーが効かないのを効くようになさりたいのであれば、No5様の指摘の通りの原因だと想像されますので、
>Do Until blnStop = True
>Cells(2, 2) = Int((Timer - dblTimer) * 100) / 100
>Sleep 1
>DoEvents
>Loop

のところを、OnTimeを利用して、VBAを開放してあげるような構成に変更すれば、多分、実現可能であろうと思います。

後で時間ができたときに試してみますね。
(今度はちゃんとテストいたします)
    • good
    • 0
この回答へのお礼

あなたに会えてよかった

お忙しい中、申し訳ないです。
StartStopを押した後はキーが効かない状態ということでしょうか?
→そうですね。startした後(実行中)は効かないです。stopした後(実行中でない状態)はキーが効きます!
キーは効くようにしたいです。

テストまで申し訳ないです!!
自分の力量ではここまでが限界だったので本当に助かります。
ありがとうございます!

お礼日時:2021/01/25 18:02

横から失礼します



Do Until blnStop = True
Cells(2, 2) = Int((Timer - dblTimer) * 100) / 100
Sleep 1
DoEvents
Loop
実行中にキー操作による別VBA処理を実行させるのは無理ではないかと
タイマー表示(実行)部分を別インスタンスで実行すれば、、、と思いますが、やってみないと判りません。(例えば、javascriptでタイマーを作成しておきVBAから呼び出し表示、終了など)
ちなみにUserFormを作成してvbModeless実行しても、LabelやTextBoxに表示する場合もdo loopなどで更新しなければならないと思うのでキーによるVBA実行は出来ないと思います。(直接シートなどの操作は可能ですが)


>時間観測中だけ有効にしたいです。
すでに回答にあるように、blnStartフラグを利用して設定、解除をすれば良いかと思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます!
blnStartフラグを利用して解除というのは
No1さんのコードで出来るってことでしょうか?お手数おかけして申し訳ないですがご教授下さい。

お礼日時:2021/01/25 17:04

No3です



>キーを押しても変化はなく、STARTしたままSTOPできなくなってしまいました。。。
STOPはきくようになったみたいですが、キーは有効にならないままですか?

No3の

' キーを有効化
 Call Enter_set1
 Call RIGHT_set1

の部分までちゃんと記述してありますでしょうか?
それで、キーが有効になるはずなのですけれど・・・?
    • good
    • 0
この回答へのお礼

回答ありがとうございます!
ちゃんと記述はしましたがルーチン実行中はキーが効かないです。
ルーチン実行中でなければ今までと変わらず出来るのですが。。。
あと、private sub workbook_openなどの無効化はコードを消せばいいんですよね?
その状態でsub startstop()に下記コードを追加しましたが変化しなかったです。

お礼日時:2021/01/25 16:58

No2です



コードを見てみたら、キーを拾っているのですね。
No1、No2の回答はちゃんと見ていませんでした。
どうやら寝ぼけていたようです。No1、No2は忘れてください。
大変失礼いたしました。

・・・で、ご質問を改めて確認すると
「StartStopのルーチンを実行中だけ、キー処理を有効にしたい」
ということと認識いたしました。



ご提示のコードでは、
ブックオープン時とシート表示時のイベントでキーを有効にして、シート非表示(=別のシートに移動など)には無効になるようにしてあります。
その部分が、
>因みに~
以下に挙げられている部分です。

ご質問の内容が、「当該シートだけで動作すれば良い」(=他のシートではこの機能は利用しない)という意味と解釈してもよいのなら、まず、
・Private Sub Workbook_Open()
・Private Sub Worksheet_Activate()
・Private Sub Worksheet_Deactivate()
のイベント処理を無効にしてしまいます。

その上で、Sub StartStop()の最初の部分を

Sub StartStop()
If blnStart = True Then
blnStop = True
' キーを無効化
 Application.OnKey "{ENTER}"
 Application.OnKey "~"
 Application.OnKey "RIGHT"
Exit Sub
End If
' キーを有効化
 Call Enter_set1
 Call RIGHT_set1

に置き換えることで、処理が実行中のみ有効になると思います。
    • good
    • 0
この回答へのお礼

早急な回答ありがとうございます。
早速上記コードにてトライしてみましたが
キーを押しても変化はなく、STARTしたままSTOPできなくなってしまいました。。。

お礼日時:2021/01/25 14:10

No1です。



もう一回見たら、タイトルが
>マクロ実行中のみテンキー操作できるようにしたい
でしたね。
逆かと思って勝手に勘違いしたみたいです。失礼しました。

とは言え、保護の機能を逆に利用すれば実現できると思います。
この回答への補足あり
    • good
    • 0
この回答へのお礼

回答ありがとうございます!
保護機能を逆に利用するとのことでしたが、保護機能を使用したことがないのでサンプルなどあれば教えていただきたいです。お手数おかけして申し訳ないです。。

お礼日時:2021/01/25 11:02

こんばんは



文章を斜め読みしただけですが、「シートの保護」を利用すればよいのではないでしょうか?
記入させたくないセルだけロックして、「選択不可」にしてしまえば、入力はできなくなります。
こちらの方が、キー入力を制御するよりもはるかに簡単ですので。

マクロから値を記入しているような雰囲気なので、UserInterfaceOnly:=Trueにしておけば、保護がかかったままで、マクロからの値の変更等は可能になります。

以下の例は、Sheet1のB:E列のセルだけ選択不可にする例です。
(範囲はよくわからないので、サンプル用に適当です)
Sub Sample()
With Worksheets("Sheet1")
 .Cells.Locked = False
 .Columns("B:E").Locked = True
 .Protect UserInterfaceOnly:=True
 .EnableSelection = xlUnlockedCells
End With
End Sub

※ 手操作から対象セル範囲に入力等をすることがなければ、一度、保護をかけておきさえすれば、後はそのままでもよいと思います。
    • good
    • 0

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

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