長くてすみません。 マクロで連続実行させているループを、キー操作で抜けたいのです。
例①のようなコードですと、「Return」「スペースキー」のいずれかでループを抜けられました。
例①
Sub 例1()
Do While ek = 0
ek = Eky(): DoEvents: Sleep 8 ' スペースの場合に 32を返す Returnの場合に 13を返す
Cells(12, 3) = WorksheetFunction.RandBetween(8, 976)
Loop
j = ek: Cells(13, 3) = ek
End Sub
Function Eky() As Single
Const tky = -32768 ' スペース32 エンター13で戻す
Eky = 0
If (GetAsyncKeyState(13) And tky) = tky Then
Eky = 13
ElseIf (GetAsyncKeyState(32) And tky) = tky Then
Eky = 32
End If
End Function
下のコードですと、「Return」は期待通りです。
「スペース」を押したときには期待通りの動作をしたりするときもあるのですが、Stopで止まらず、《単にマクロが終了し》、マクロ実行直前に選択していたExcelシートのセルに「スペースが入力された途中の状態」で終わるのです。スペースを押す前のループの動作は正常に見えます。
例②
Sub Macro1()
Dim r, n, m, p As Integer, s As Integer, ti, ti1, ti2, ti3, ti4, i, k(150) As Integer
r = 0: m = 0: ek = 0:
p = Cells(1, 10): s = Cells(2, 10) ' pは 1回の角度 sはsleepミリセコンド
ti = miri秒(): Cells(1, 1) = kk5: Cells(7, 1) = kk4
For i = 0 To 150: k(i) = p: Next: i = 5
Do While m < 360
ti1 = miri秒()
m = m + 1: Cells(9, 6) = Int(m * p / 360)
ActiveSheet.Shapes.Range(Array("Group 8")).IncrementRotation k(i)
Cells(3, 15) = (Cells(3, 15) + k(i)) Mod 360
Cells(3, 1) = kk5: Cells(8, 1) = kk4
ek = Eky(): Cells(3, 10) = ek: DoEvents: Sleep s:
If ek = 32 Then Stop ’ この位置でマクロの実行は止まらない
If Cells(3, 10) > 0 Then m = 9000:
Loop
Stop ’ この位置でもマクロの実行は止まらない
End Sub
Function miri秒()
Call GetLocalTime(T)
' 現在日時取得Tを 時刻以下ミリ秒までの数値にし,関数戻り値にする
' 注意 測定日を跨いでも忖度されない。年月日データを無視
kk1 = T.wHour: kk2 = T.wMinute: kk3 = T.wSecond: kk4 = T.wMilliseconds
kk4 = kk3 + kk4 / 1000
kk = kk1 * 3600 + kk2 * 60 + kk4: kk5 = kk1 & ":" & kk2 & ":" & kk3
miri秒 = kk
End Function
先頭に次も書いています。
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
Declare PtrSafe Sub GetLocalTime Lib "kernel32" (lpSystemTime As SYSTEMTIME)
Declare PtrSafe Function BeepAPI Lib "kernel32.dll" Alias "Beep" _
(ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Public T As SYSTEMTIME
Public d, th, tm, ts, s, t1, t2, t3, t4, t5
Public kk, kk1, kk2, kk3, kk4, kk5
とにかく、何が原因なのかが不明なので、絶体関係ないはずのコード部分も上には入れてあります。
スペースキーのクリックでも、[ If ek = 32 Then Stop ’ この位置でマクロの実行は止まらない]という位置で、きちんと、止まるようにしたいです。
スタート時の(時刻と、秒+ミリ秒) 実行中の(時刻と、秒+ミリ秒)を表示させ、
スペースかReturnでマクロを抜けて、実行時間をミリ秒単位で表示させています。
また、1秒に360度1回転する針の図形Array("Group 8")を表示しています。
最終的には、正確に0.97~1.03秒で1回転になるように、回転角度やsleep時間を、マクロ実行中に自動調整させたいと思っています。
No.1ベストアンサー
- 回答日時:
こんばんは
回答ではありません。
ご質問文のコードを見ているだけで検証などを行っていませんが、
気になる点を、グローバル変数 s が
Sub Macro1()
Dim r, n, m, p As Integer, s As Integer となっていますが
問題は無いのでしょうか、、どうだったか、、
あと止めたいところですが
Function Eky() As Singleを返しているけれどSingleで合っていますか?
変数ek はSingle? If ek = 32 は成立する? Integerでは?
変数ekの宣言が見当たらないのですけれどSingle?
エラー無く動くなら良いのですが、Option Explicit を使って
コンパイルして検証するのが良いのでは無いかと思いました。
No.4
- 回答日時:
こんにちは
返信を受けて、、
Application.Interactive = False
Application.EnableCancelKey = xlDisabled
途中での対応処理が難しいのとデバッグには向きません。また、
windowsAPIの兼ね合いもあるでしょうし、確かにやめた方が良いですね。
>Do While m < 360 は実行時間が短くないかな
これは、 >sはsleepミリセコンドとあり
m は単なるカウント変数でループ内のSleep は s のみの為
360回ループするには時間がさしてかからないのではと思った為です
不完全(表示されていないだけかも)なコードで無限ループやスタックの可能性のあるコードを試すのは躊躇しましたが
実際に試さないと解らない部分がありましたので試しました。
Sub 例1()についてですが、確かに上手く行く事もありますが
Cells(13, 3) = ekが実行されない事もありました。
例、なので深堀するのはやめて本題のMacro1を検証する事とします
書き直したコードを示します
(変数宣言、不要変数削除、WindowsAPI GetAsyncKeyState Lib追加)
Option Explicit
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
Declare PtrSafe Sub GetLocalTime Lib "kernel32" (lpSystemTime As SYSTEMTIME)
Declare PtrSafe Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Public T As SYSTEMTIME
'とりあえずそのままVariantで
Public d, th, tm, ts, s, t1, t2, t3, t4, t5
Public kk, kk1, kk2, kk3, kk4, kk5
Sub Macro1()
Dim ek As Single
Dim ti As Single, ti1 As Single
Dim r As Integer, m As Integer, p As Integer, s As Integer
Dim i As Integer, k(150) As Integer
'マルチ防止
With ActiveSheet.Shapes("Button 1").TextFrame.Characters
If .Text = "Macro1" Then
.Text = "実行中"
Else
Exit Sub
End If
End With
'出力セルクリアー
With ActiveSheet
.Range("A1:A3,A7:A8,F9").ClearContents
'セル入力モードを防ぐ為の暫定処置
.Shapes(2).Select
End With
'ご質問コード (Stop>Msgbox)
r = 0: m = 0: ek = 0:
p = Cells(1, 10): s = Cells(2, 10) ' pは 1回の角度 sはsleepミリセコンド
ti = miri秒(): Cells(1, 1) = kk5: Cells(7, 1) = kk4
For i = 0 To 150: k(i) = p: Next: i = 5
Do While m < 360
ti1 = miri秒()
m = m + 1: Cells(9, 6) = Int(m * p / 360)
' ActiveSheet.Shapes.Range(Array("Group 8")).IncrementRotation k(i)
Cells(3, 15) = (Cells(3, 15) + k(i)) Mod 360
Cells(3, 1) = kk5: Cells(8, 1) = kk4
ek = Eky(): Cells(3, 10) = ek: DoEvents: Sleep s: 'sって1秒?
If ek = 32 Then Stop ' MsgBox ("32") この位置でマクロの実行は止まらない
If Cells(3, 10) > 0 Then m = 9000:
Loop
MsgBox ("end") ' この位置でもマクロの実行は止まらない
'Stop 後 F5もしくはF8で下記を実行
ActiveSheet.Shapes("Button 1").TextFrame.Characters.Text = "Macro1"
End Sub
Function Eky() As Single
Const tky = -32768 ' スペース32 エンター13で戻す
Eky = 0
If (GetAsyncKeyState(13) And tky) = tky Then
Eky = 13
ElseIf (GetAsyncKeyState(32) And tky) = tky Then
Eky = 32
End If
End Function
Function miri秒()
Call GetLocalTime(T)
' 現在日時取得Tを 時刻以下ミリ秒までの数値にし,関数戻り値にする
' 注意 測定日を跨いでも忖度されない。年月日データを無視
kk1 = T.wHour: kk2 = T.wMinute: kk3 = T.wSecond: kk4 = T.wMilliseconds
kk4 = kk3 + kk4 / 1000
kk = kk1 * 3600 + kk2 * 60 + kk4: kk5 = kk1 & ":" & kk2 & ":" & kk3
miri秒 = kk
End Function
テストシートは添付図で
ボタンはフォームオブジェクト
Shapes(2)は直線コネクター
ボタンテキストで重複実行を抑止
A9セルに経過時間を関数で算出
テスト結果、必要箇所でStop しました。
Shapes(2)を選択させなかった場合(推測した不具合原因を排除しない場合)
spaceを押下した時 VBEの If ek = 32 Then Stop で
⇒のみ表示でストップ アクション(実行行移動など)をすると
プロジェクトのリセットダイアログが出力され キャンセルを押すと
実行プロセスがStopへ移動し止まる。
VBE表示でも非表示でも同様の事象(If ek = 32 Then Stop文頭にスペースが入る)でした。(いずれもシート上のボタンからの実行)
*APIのバックグランド処理は止めていません
検証OS、Office
Windows10 64bit Microsoft Office Home & Business 2013 32bit
の一部 Excel (15.0.5381.1000)
下記も所有していますが、未検証です
Microsoft Office Home and Business 2016 Premium
Microsoft Office Home & Business 2019
Microsoft 365 (会社)
あくまで私のローカルでの検証で再現できるかは分かりませんが
参考になれば、幸いです。
No.3
- 回答日時:
書き忘れましたので追記します
Sub 例1() でループを抜けましたとありますが
これは多分、誤解です。
Returnの時は Cells(13, 3) = ek が実行され13が出力されますが
スペースキーの時はCells(13, 3) = ekが実行されません
DoEventsでアプリケーションにイベントが渡り、セル入力モードで
VBAの実行が中止されるのだと思います
(この辺りのインスタンスやエラーログなどがどうなっているのか素人なので良く分かりません)
例1の実行前に、C13のセルをクリアして、例1を実行して、スペースキーを押すと、Cells(13, 3) = ekが実行されて、32の値が入ります。
その前後に何かのコードを書いても、そのコードは実行されます。
> DoEventsでアプリケーションにイベントが渡り、セル入力モードで
VBAの実行が中止されるのだと思います
実行中に、適当にキーを押しても、スペースキー、Returnキー、Escキー以外は、基本的に無視されます。
スペースキー、Returnキー、Escキー以外では、マクロはループ内を実行し続け、Cells(12, 3) = WorksheetFunction.RandBetween(8, 976)が更新されているのを目視出来ます。
No.2
- 回答日時:
#1です
#1の回答はご質問に対して頓珍漢なものでした。すみません
>スペースキーのクリックでも、[ If ek = 32 Then Stop ’ この位置でマクロの実行は止まらない]という位置で、きちんと、止まるようにしたいです。
ExcelでスペースキーとEnter(Return)キーの違いを考えてみました
Enterは確定キーなのでセルが移動する。
スペースキーはアクティブセルが入力モードになりスペースが入力される
入力モードの時VBAは実行されなかったかと・・
では、キーを無効にしたらVBAの実行は無効にならず進むのでは無いかと思います。
キーを無効にする方法は色々ありますが
こんな感じで試してみてください。
Declare PtrSafe Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Sub Macro1()
Dim r, n, m, p As Integer, s As Integer, ti, ti1, ti2, ti3, ti4, i, k(150) As Integer
Application.Interactive = False
Application.EnableCancelKey = xlDisabled
r = 0: m = 0: ek = 0:
p = Cells(1, 10): s = Cells(2, 10) ' pは 1回の角度 sはsleepミリセコンド
ti = miri秒(): Cells(1, 1) = kk5: Cells(7, 1) = kk4
For i = 0 To 150: k(i) = p: Next: i = 5
Do While m < 360
ti1 = miri秒()
m = m + 1: Cells(9, 6) = Int(m * p / 360)
ActiveSheet.Shapes.Range(Array("Group 8")).IncrementRotation k(i)
Cells(3, 15) = (Cells(3, 15) + k(i)) Mod 360
Cells(3, 1) = kk5: Cells(8, 1) = kk4
ek = Eky(): Cells(3, 10) = ek: DoEvents: Sleep s:
If ek = 32 Then Stop ' この位置でマクロの実行は止まらない
If Cells(3, 10) > 0 Then m = 9000:
Loop
Stop ' この位置でもマクロの実行は止まらない
Application.Interactive = True
Application.EnableCancelKey = xlInterrupt
End Sub
Function Eky() As Single
Const tky = -32768 ' スペース32 エンター13で戻す
Eky = 0
If (GetAsyncKeyState(13) And tky) = tky Then
Eky = 13
ElseIf (GetAsyncKeyState(32) And tky) = tky Then
Eky = 32
End If
End Function
Function miri秒()
Call GetLocalTime(T)
' 現在日時取得Tを 時刻以下ミリ秒までの数値にし,関数戻り値にする
' 注意 測定日を跨いでも忖度されない。年月日データを無視
kk1 = T.wHour: kk2 = T.wMinute: kk3 = T.wSecond: kk4 = T.wMilliseconds
kk4 = kk3 + kk4 / 1000
kk = kk1 * 3600 + kk2 * 60 + kk4: kk5 = kk1 & ":" & kk2 & ":" & kk3
miri秒 = kk
End Function
途中で止めた時に最後までF8などで実行しないと
Application.Interactive = True
Application.EnableCancelKey = xlInterrupt
が実行されないと思いますので、その場合は
イミディエイトウィンドウで実行するか
実行のタイミングを検討してください
Do While m < 360 は実行時間が短くないかな
コピペで書きましたがコンパイル出来なかったら修正してください
また頓珍漢な回答でしたら、忘れてください。
本日は夜遅くまでこちらを見れませんので 補足などがあっても
返信は遅くなります
うーん
「キーを無効に」はしたくないです。
> Do While m < 360 は実行時間が短くないかな
Do While m < 3600 でも構いませんが、とりあえず360回転(約6分)で仮実験を止めているだけです。
~~~~~~~~~~~~~~~~~~~~~~~~
元の質問文の下の部分が、表現不適切でした。
「スペース」を押したときには期待通りの動作をしたりするときもあるのですが、Stopで止まらず、《単にマクロが終了し》、マクロ実行直前に選択していたExcelシートのセルに「スペースが入力された途中の状態」で終わるのです。
正しくは、
① Sub Macro1()を直接に起動すると、期待通りの動作をします。
② Excelシート上の「スタート」ボタンで、Sub Macro1()を起動すると、スペースキーを押したときの動作がおかしい。Stopで止まらず、《単にマクロが終了し》、マクロ実行直前に選択していたExcelシートのセルに「スペースが入力された途中の状態」で終わるのです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) Excel VBAでフォルダ内の全テキストファイルの任意データを取得について 7 2021/12/18 16:00
- Visual Basic(VBA) 空のシートに関数を入れたい 2 2021/12/03 15:08
- Visual Basic(VBA) EXCEL VBA シート貼り付け 3 2021/11/15 12:33
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたいの続き 5 2023/01/24 00:16
- Visual Basic(VBA) EXCLE VBA シートクリックしたら該当シートコピー 1 2021/11/11 16:37
- Visual Basic(VBA) Excel VABについて 1.xlsm、VBA.xlsm2つのファイルがあり、1.xlsmにてVB 6 2021/12/13 17:46
- Visual Basic(VBA) excel VBAでメールを送る方法について 2 2021/11/03 15:34
- Visual Basic(VBA) 条件をつけてカウントする 4 2021/12/19 20:27
- Visual Basic(VBA) シート名をフォルダ名に変更 1 2021/12/01 15:59
- Excel(エクセル) エクセルVBAでオブジェクトが必要です 2 2022/09/10 16:37
このQ&Aを見た人はこんなQ&Aも見ています
-
これまでで一番「情けなかったとき」はいつですか?
これまでの人生で一番「情けない」と感じていたときはいつですか? そこからどう変化していきましたか?
-
スマホに会話を聞かれているな!?と思ったことありますか?
スマートフォンで検索はしてないのに、友達と話していた製品の広告が直後に出てきたりすることってありませんか? こんな感じでスマホに会話を聞かれているかも!?と思ったエピソードってありますか?
-
みんなの【マイ・ベスト積読2024】を教えてください。
積読、ついついしちゃいませんか?そこでみなさんの 「2024年に買ったベスト積読」を聞きたいです。
-
【選手権お題その3】この画像で一言【大喜利】
とあるワンシーンを切り取った画像。この画像で一言、お願いします!
-
【選手権お題その2】この漫画の2コマ目を考えてください
サッカーのワンシーンを切り取った1コマ目。果たして2コマ目にはどんな展開になるのか教えてください。
-
GetAsyncKeyState() を利用するときの良い方法は
Visual Basic(VBA)
-
VBA マウスクリックとキーボードの判定のGetAsyncKeyStateについて教えてください
Visual Basic(VBA)
-
VBAでGetAsynckeyStatekのエラー
PowerPoint(パワーポイント)
-
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~1/20】 追い込まれた犯人が咄嗟に言った一言とは?
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・【選手権お題その3】この画像で一言【大喜利】
- ・【お題】逆襲の桃太郎
- ・自分独自の健康法はある?
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・ちょっと先の未来クイズ第6問
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ローマ字→カタカナへ変換(エク...
-
マクロ 実行ボタンを押さずに...
-
EXCELのセルへ、デジタル時計を...
-
Excel VBA のdebug(F8キー) が...
-
エクセル グラフの軸の最小値最...
-
エクセルのマクロ機能で前のシ...
-
Wordで「原稿用紙○枚」を換算す...
-
ワードからエクセルへ貼り付け...
-
TeraTermのマクロについて
-
Excelの改ページ 同シート内で...
-
エクセルで複数のシートをまと...
-
マクロ ブックをマクロなしでコ...
-
Wordの画面を左右にスクロール...
-
EXCEL2000 VBA マクロ実行中に...
-
秀丸エディタに検索履歴を記憶...
-
Excelマクロでオプションボタン...
-
【エクセル】 キーを押すと、...
-
Excelのワークシート上に検索窓...
-
開いているフォルダを全て閉じ...
-
エクセルで土日列の非表示方法...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ローマ字→カタカナへ変換(エク...
-
マクロ 実行ボタンを押さずに...
-
Excel VBA のdebug(F8キー) が...
-
エラーになってないのにVBA...
-
Excelを開いた時に表示さ...
-
EXCELのセルへ、デジタル時計を...
-
ワードからエクセルへ貼り付け...
-
複数ファイルにある特定のシー...
-
エクセルのマクロ機能で前のシ...
-
Wordの画面を左右にスクロール...
-
エクセル グラフの軸の最小値最...
-
モジュール内のマクロを全て実...
-
Excelマクロでオプションボタン...
-
TeraTermのマクロについて
-
VBAでEXCELに埋め込んだPDFを開...
-
EXCEL2000 VBA マクロ実行中に...
-
マクロボタンをある条件の時に...
-
ワードで画像を自動で挿入する方法
-
開いているフォルダを全て閉じ...
-
Wordで「原稿用紙○枚」を換算す...
おすすめ情報
原因がわかりました。 ①マクロをVBEで実行するときは問題ないのですが、EXCELシートの図形をクリックして「登録してあるマクロ」に実行を移すと、入力バッファーにクリックデータが残っている。②マクロ実行中にトラップのキー操作をすると、マクロがキャッチする1回分のキー値だけでなく、同じキー値が数回分残っているらしく、それが想定外の状況を引き起こす。
で、次のように直したところ、「この部分の処理」については、期待通りになりました。
続きは 別の捕捉
文字制限がきつすぎです。自己回答も出来ない?ので、新規質問を起こして、そこに現状の解決策を書きます。 もっと良い方法があったら、教えてください。
ここに 質問の形で投稿しました。
https://oshiete.goo.ne.jp/qa/12838313.html