• ベストアンサー

VBAでCTRLキーが押されるまで処理を待つには

ExcelのVBAの処理で、処理結果を画面表示した後、 ユーザーが画面の内容を確認したら CTRLキーを押すと、 次の処理を続行するようにしたいのですが、 メッセージボックス(MSGBOX)などは表示しないで、 (画面表示内容以外のものは表示しないで) 処理を一時停止させて、CTRLキーが押されたら続行するには、 VBAでどのように記述すればよいでしょうか。 よろしくお願いします。(Windows10,Excel2016)

質問者が選んだベストアンサー

  • ベストアンサー
  • HohoPapa
  • ベストアンサー率65% (454/691)
回答No.2

他の方のコメントにもありますように、 一般的には採用しないインターフェースとは思いますが 時間もあり、興味を惹かれたので書いてみました。 よかったら参考にしてください。 なお、このコードはCntlキーが押されたかどうかではなく Cntlキーが押された状態か?を10ミリ秒間隔で監視することで実現していますので 10ミリ秒以上押し続ける必要があります。 実際に使ってみると、当方の環境では、 Cntlキーが押されたかどうかを判断しているがごとき動作をし、 違和感はありません。 また、Officeは32ビット版限定のコードです。 Option Explicit '参考url '  https://thom.hateblo.jp/entry/2019/03/10/125326 '  https://e-vba.com/keycode/ '//- API  ----------------------------- Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long) #If Win64 Then  Declare PtrSafe Function GetAsyncKeyState Lib _    "User32.dll" (ByVal vKey As LongLong) As Integer #Else  #If VBA6 Or VBA5 Then   Declare Function GetAsyncKeyState Lib _     "User32.dll" (ByVal vKey As Long) As Integer  #Else   Declare PtrSafe Function GetAsyncKeyState Lib _     "User32.dll" (ByVal vKey As Long) As Integer  #End If #End If '//----------サンプルコード Sub test()  '何らかの処理    PauseCntl    '何らかの処理 End Sub '//------ 'Cntlキーが押されるまで待つ関数 Sub PauseCntl()  Do   If IsShiftKeyPressed = True Then Exit Sub   Sleep 10   DoEvents  Loop End Sub Function IsShiftKeyPressed() As Boolean   Const KEY_PRESSED = -32768   '1000 0000 0000 0000 最上位ビットが1であることを示す。   IsShiftKeyPressed = (GetAsyncKeyState(vbKeyControl) And KEY_PRESSED) = KEY_PRESSED End Function

ID_20150222
質問者

お礼

教えていただきましたコードの動作を確認しました。 Excelアプリケーション画面を最小化した状態でも、 CTRLキーを押すまで停止していて、 CTRLキーが押されると続行されました。 挙動自体もまったく違和感はなく問題ありませんでした。 ありがとうございました。

その他の回答 (2)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.3

小生はAPIを使うべき課題は、(理由は薄弱だが)避けてきました。しかし WEBで調べてみると、キーの押し下げを捉えるコードは、APIで、 https://liclog.net/getasynckeystate-function-vba-macro-catia-v5/ などに記事があります。 質問の課題そのものへの回答ではないのですが、 標準モジュールに下記を貼り付けます。 Option Explicit #If Win64 Then Declare PtrSafe Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Integer #Else Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Integer #End If '---------------------------------------------------------------------------------------------' Function ESCPress() As Boolean Const KEY_PRESSED = -32768 ESCPress = (GetAsyncKeyState(vbKeyEscape) And KEY_PRESSED) = KEY_PRESSED End Function '---------------------------------------------------------------------------------------------' Function UPPress() As Boolean Const KEY_PRESSED = -32768 UPPress = (GetAsyncKeyState(vbKeyUp) And KEY_PRESSED) = KEY_PRESSED End Function '---------------------------------------------------------------------------------------------' Function DownPress() As Boolean Const KEY_PRESSED = -32768 DownPress = (GetAsyncKeyState(vbKeyDown) And KEY_PRESSED) = KEY_PRESSED End Function '---------------------------------------------------------------------------------------------' Function RightPress() As Boolean Const KEY_PRESSED = -32768 RightPress = (GetAsyncKeyState(vbKeyRight) And KEY_PRESSED) = KEY_PRESSED End Function '---------------------------------------------------------------------------------------------' Function LeftPress() As Boolean Const KEY_PRESSED = -32768 LeftPress = (GetAsyncKeyState(vbKeyLeft) And KEY_PRESSED) = KEY_PRESSED End Function Function PressCtrl() As Boolean Const KEY_PRESSED = -32768 PressCtrl = (GetAsyncKeyState(vbKeyControl) And KEY_PRESSED) = KEY_PRESSED End Function '---------------------------------------------------------------------------------------------' Sub CATMain() MsgBox "キー入力ループ開始" Do If ESCPress = True Then Exit Do 'Escキーが押された時、ループから抜け出す DoEvents 'これが無いと最悪の場合CATIAがフリーズ If UPPress = True Then '上矢印キーが押された時は以下の処理を行う MsgBox "上矢印キーが押されました" End If If DownPress = True Then '下矢印キーが押された時は以下の処理を行う MsgBox "下矢印キーが押されました" End If If LeftPress = True Then '左矢印キーが押された時は以下の処理を行う MsgBox "左矢印キーが押されました" End If If RightPress = True Then '右矢印キーが押された時は以下の処理を行う MsgBox "右矢印キーが押されました" End If '--- If PressCtrl = True Then '右矢印キーが押された時は以下の処理を行う MsgBox "CTRLキーが押されました" End If Loop MsgBox "キー入力ループから抜け出しました" End Sub ーーー これで、Sub CATMain()部を選択して、実行(状態に)すると、プログラムで、待機状態になり、 CTRLキーを押すと、CTRLを押したと、Msgboxが表示されます。 この後に、したい処理を書くと、良いわけですが、ループ中だし、実行後どれだけの時間の間待てばよいか、保証はないわけです。  だから、多分質問者のしたいことを賄うのは、適してないように思います。 だから他の方法を考えるべきと思いますが。 ーーー Application.OnkeyなどというのもVBAにあるが、CTRL+何かのキーの組み合わせを検知するもののようです。マクロ実行のショートカットキー的使用など。 ーー 上記のコードはWEBから拾ったものをそのまま、2つ組み合わせたので、 (上下左右の)矢印キーとCTRLキーの5つのどれかを検出コードになっています。 余分なら矢印キーの4か所のFunction-EndFunctionコード行を削除してみてください。 他キーの例も参考になると思ってそのままにしました。

ID_20150222
質問者

お礼

教えていただきましたコードの動作を確認しました。 回答にも書かれていましたように余分な部分を削除して、 最小限必要な部分のみにしてCATMainを呼び出すことにより、 したいことが実現できました。 ありがとうございました。

  • kon555
  • ベストアンサー率52% (1750/3357)
回答No.1

 ご希望の「CTRLキーを押すと次の処理を続行する」という機能を実装しようとすると、ループ処理を延々と回してユーザー操作を監視し続ける必要があり、正直なところ現実的ではありません。  マクロの一時停止と再開は、基本的にはStopステートメントでやるのが定石です。 https://lilia-study.com/excel/excel-vba/stop.html  ただこの場合、再開にはVBE画面からの操作が必要ですので「ユーザーが画面の内容を確認したら」というようなユーザー操作想定には向きません。    なので「 CTRLキーを押すと」の部分を諦める事をオススメします。  一時中断前をマクロ1、中断後をマクロ2として分割し、中断画面に再開ボタンを作っておいて、それをクリックしたらマクロ2実行、とすれば無理なく実装できます。

ID_20150222
質問者

お礼

回答ありがとうございます。 教えて頂きましたことは今後の参考にさせていただきます。

関連するQ&A

  • [Ctrl]+FをVBAで表現

    EXCELで、[Ctrl]+Fを押すと、[検索]の画面がでてきます。 ”[Ctrl]+Fを押して、[検索]の画面を出力させる”ということを VBAで書くことはできるのでしょうか? 現在EXCEL2000を使っています。

  • Excel-VBAでタイマー処理

    お世話になります。 Excel-VBAでユーザフォームを操作したいのですが、VBの場合ツールボックスにタイマーコントロールがありますが、Excel-VBAの場合ツールボックスにタイマーコントロールがありません。 タイマー処理はどうしたら良いのでしょうか?

  • CTRLキーが押しっぱなしの状態

    キーボードから文字の入力ができません。CTRLキーが押しっぱなしの状態になってしまっているようです。 メモ帳を起動し、「S」を入力すると、名前を付けて保存のウィンドウが表示されます。(CTRL+Sの挙動)  ・再起動しても変わらず  ・ユーザー補助の固定キーは使用していない  ・セーフモードで起動しても変わらず  ・起動ディスクから起動し、DOS画面だとアルファベットの入力が出来る  ・システムの復元をしようとしても、「次へ」をクリックしても進まない 最終的にはシステムリカバリだとは思いますが、その前にやれることは無いでしょうか?

  • 押されているキーの評価について

    Excel2002のVBAです。 次のコードで押されたキーを判別していますが、Altの時だけ、 キーを離なしても、離したあと1度だけ、押されていると評価 されてしまいます。 これは回避できないのでしょうか? '--------------------------- Declare Function GetAsyncKeyState Lib "user32.dll" _ (ByVal vKey As Long) As Long '--------------------------- Private Sub CommandButton1_Click() If GetAsyncKeyState(vbKeyControl) <> 0 Then MsgBox "CTRLキーを押しながらクリックされました。" End If If GetAsyncKeyState(vbKeyShift) <> 0 Then MsgBox "Shiftキーを押しながらクリックされました。" End If If GetAsyncKeyState(vbKeyMenu) <> 0 Then MsgBox "Altキーを押しながらクリックされました。" End If End Sub

  • ctrlキー+F について

    Windows XPでOutlook Express6、Microsoft Office Excel2003を使用しています。Outlook Express6とエクセルを同時に開いている状況で、Outlook Express6画面をアクティブにしてctrlキー+F を押すとメールの作成画面になります。エクセルをアクティブにしてctrlキー+Fで検索画面が出ます。しかし、ここで語を検索しようとしても検索ができません。Outlook Express6を閉じてエクセルだけの場合は支障なく機能します。Outlook Express6、エクセル同時に開いている状態でこれを正常に機能させる方法があれば教えて下さい。

  • Access2000VBAで前に記述したコードが終わる前に次に進みます・・・

    フォームを開いた後、Msgboxを表示させたくて、Access2000VBAのOpenイベント又はLoadイベントに、Msgboxを記述しました。 ところが、フォームが開く前にMsgboxが表示されてしまします。フォームが開いた後Msgboxを表示させるためにはどうしたらよいのですか? また、ADOで接続したテーブルの数値型フィールドの合計値を計算して、計算結果をテキストボックスに代入するコードを記述した後、このテキストボックスの値をMsgboxに表示させるコードを記述たところ、計算を終える前にMsgboxが表示されてしまいます。 前のコードが確実に実行された後、次のコードの処理に進む様にするにはどうすればよいのですか?

  • エクセルVBAでメッセージを表示する

    エクセルVBAでメッセージを表示する時は、 Msgbox "表示する内容" と記述しますが、これだと[OK]をクリックするまで エクセル本体が全く操作できなくなってしまいます。 メッセージボックスを表示させた状態で、エクセルを操作できるようにすることは 出来ますでしょうか?

  • VBA 制限時間を、一時停止させたい

    Excel VBAでの質問です。Excel2007使用です。 ユーザーフォームに制限時間と、制限時間を一時停止させるコマンドボタンを作りたいです。制限時間(60分)は、下ので実行できたのですが、一時停止ができるか、わかりません。 Private Sub 制限時間_Click() Dim myTime As Date Dim myLImit As Date myLImit = Now + TimeValue("1:00:00") Do While myLImit > Now DoEvents myTime = myLImit - Now 分表示.Caption = Minute(myTime) & "分" 秒表示.Caption = Second(myTime) & "秒" Loop msgbox "終了です。" Unload Me End Sub できれば、ボタンを押すとmsgbox"一時停止"を表示させ、表示させている間は、制限時間を一時停止させたいです。制限時間、一時停止ができれば、違うコードでもかまいません。 どうぞよろしくお願いします。

  • VBAのイベント処理について

    VBAのイベント処理について お世話になってます。現在、VBAでアプリケーションを作成しています。 1つのフォームに4つのテキストボックスと1つのボタンが配置されており、それぞれイベントが設定されています。 その中のテキストボックスに関するイベントなのですが、1つのテキストボックスに対してKeyPress、KeyDown、MouseUp、AfterUpdate、以上4つのイベントを作成します。 フォームに配置されている4つのテキストボックスすべてに、上記で示したイベントを作成する必要がありますが、各イベントにおける処理の内容はオブジェクト名が違うだけで全く同じです。 ひとつひとつイベントを作成していけば、処理目的は満たせそうですが、ソースがかなり長くなってしまいます。ひとつのオブジェクトに対してこれらの処理をひとまとめにする様な記述方法はありませんでしょうか?考え方だけでも教えていただければ幸いです。 質問が長くなってしまい申し訳ありません。回答宜しくお願い致します。

  • EXCEL で VBA ヘルプの表示(F1キー)

    EXCEL で VBA を使うのですが F1キーを押したとき、ヘルプがでる方法を教えてください たとえば、VBA のプログラムでmsgbox にフォーカスして F1キーを押したとき、ヘルプが表示される 方法を教えてください 今は、F1キーを押しても何も起きない状態です

専門家に質問してみよう