皆さん、こんにちは!
上越市を拠点にし、「FA設備・装置開発」と「画像処理」に強い会社、NSIです!
私達は豊富な経験と専門知識で、各種業界の自動化・システム化のお手伝いをしています。
すっかり春らしい気温になり、桜もちょうど見頃ですね。
4月から新生活が始まった方は、少しずつ慣れてきた頃ではないでしょうか?
たまにはひと息つきながら、今月を乗り切っていきましょう!
今回は、先日ハマった出来事を備忘録としてまとめます。
同じような状況の方に、この記事が役に立てば幸いです。
SendKeysの落とし穴
先日、VBAで「保存時にセルの入力チェックを行い、不備があればそのセルを編集状態にする」という処理を作っていました。不備があったセルの内容をまるごと削除するのは簡単ですが、それだとまた打ち直すのが面倒…。というわけで、セルをそのまま編集状態にして修正してもらうことにしました。
セルを編集状態にするには「ダブルクリック」か「F2キー」を押すのが一般的です。
今回はVBAで処理するので、「Application.SendKeys “{F2}”」という処理を記述して実行してみたところ…。
ここでまさかの落とし穴。
なぜかNumLockが勝手に切り替わるという謎の現象が発生してしまいました。
なぜNumLockが切り替わるのか?
結論から言うと、Application.SendKeysがNumLockの状態に干渉してしまうことが原因です。
SendKeys は、VBAからキー入力を擬似的に送信する機能ですが、このとき NumLock・CapsLock・ScrollLock などのトグルキーの状態は保存されません。そのため、F2キーを送信した際に、「NumLockがオフの状態でキーが押された」と誤って解釈されてしまい、NumLockの状態が勝手に変わってしまうことがあります。
※トグルキー … 押す度にON/OFFの状態を切り替えることができるキー(NumLock、CapsLockなど)のこと。
NumLockの切替を回避する方法
ズバリ、「SendKeysを使わない」というのがベストですが、どうしてもセルを編集状態にしたい場合もありますよね。Qiitaより(@nukie_53)様の記事を参考にして試したところ、NumLockが切り替わらずにF2キーの動作を再現できる方法が分かったのでご紹介します。
出典:
ソースコードはQiitaより(@nukie_53)様の記事を参考にさせて頂きました。
VBA.SendKeysでキーボードのロックが外れる現象への対策
まず、元のコードはこちら(ThisWorkbook 内に記載):
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim target As Range
' 対象のセル:B4
Set target = Range("B4")
' 数値かどうか確認
If Not IsNumeric(target.Value) Then
' 数値以外なら、セルを選択状態にする
MsgBox "セル B4 の値が数値ではありません。修正してください。", vbExclamation
target.Select
Application.SendKeys "{F2}"
'保存はキャンセル
Cancel = True
End If
End Sub
Application.SendKeys を使用しているため、NumLockの状態が切り替わってしまいます。
続いて修正版:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim target As Range
' 対象のセル:B4
Set target = Range("B4")
' 数値かどうか確認
If Not IsNumeric(target.Value) Then
' 数値以外なら、セルを選択状態にする
MsgBox "セル B4 の値が数値ではありません。修正してください。", vbExclamation
target.Select
wshSendKeys "{F2}"
'保存はキャンセル
Cancel = True
End If
End Sub
' ------------------------------------------------------------
' 以下のコードは、Qiita @nukie_53 様の記事より引用しています。
' 出典:https://qiita.com/nukie_53/items/f069a1e48cddca0024c2
Public Sub wshSendKeys(Keys As String, Optional Wait As Boolean = False)
'メモリ効率より動作速度を優先する場合
Static wshShell As Object
If wshShell Is Nothing Then Set wshShell = CreateObject("WScript.Shell")
Call wshShell.SendKeys(Keys, Wait)
End Sub
WScript.Shell の SendKeys をラップすることで、NumLock が切り替わる問題が発生しなくなります。修正内容としては、wshSendKeys というラップ関数を追加し、Application.SendKeys を wshSendKeys に置き換えるだけです。
修正版を実行してみましょう!
NumLockが発生しなくなりましたね。
最後に
今回は SendKeysを実行したときにNumLockが切り替わる現象と、その回避方法 についてご紹介しました。SendKeys 自体は便利な機能ですが、今回のように思わぬ落とし穴があることもあるため、使用には注意が必要です。
ここまで読んでいただき、ありがとうございました。
ご質問・ご要望・ご相談などは、下記お問い合わせフォームからお気軽にご連絡ください。
http://www.net-nsi.co.jp/toiawase.html

この記事が役に立ったらGoodボタンを押してね~