VBA入門
SendKeysメソッドとAppActivateステートメント

ExcelマクロVBAの基本と応用、エクセルVBAの初級・初心者向け解説
公開日:2013-06-07 最終更新日:2021-12-05

第121回.SendKeysメソッドとAppActivateステートメント


マクロVBAから直接連携操作できない他のアプリケーションに対しても、VBAのキーコード転送を使って操作することが可能です。
SendKeysメソッドを使い、アクティブなアプリケーションにキーコードを転送することで操作します。


これは、他のアプリケーションにキーホード入力をすることができるという事です。
もちろん、マクロが動作しているExcel自身にもキーコードを転送できます。

キーコードを転送するアプリケーションはアクティブなアプリケーションだけです。
アクティブではないアプリケーションにキーコードを転送したい場合は、
事前に、AppActivateステートメントでアクティブにしてからSendKeysを使います。


SendKeysメソッド

SendkeysはApplicationのメソッドです。
グローバル定義されているので、Applicationは省略できます。
キーストロークまたはキーストロークの組み合わせを、キーボードから入力したときと同様にアクティブウィンドウに渡します。
アクティブウィンドウに対してしか作用しませんので、必ず対象のアプリケーションをアクティブにしておきます。

SendKeys string[, wait]

名前付き引数については、以下になります。

string 必ず指定します。
転送するキーコードを表す文字列式を指定します。
wait 省略可能です。
名前付き引数 string の転送によって行われる処理が終了するまで、実行を一時中断するかどうかを次に示すブール型の値で指定します。
False(既定値) プロシージャの終了を待たずに次の行に制御を移します。
True 処理が終了するまで実行を一時中断します。

キーボード上の文字を渡すには、その文字をそのまま使います。
キーボード上の文字 A を表すには、名前付き引数 stringに"A"を指定します。
複数の文字は連続して設定します。
文字 A、B、C を表すには、名前付き引数 string に "ABC" と指定します。

プラス記号 (+)、キャレット (^)、パーセント記号 (%)、チルダ (~)、かっこ (( )) はそれぞれ SendKeys ステートメントで特別ない身を持ちます。
これらの文字を渡すには、文字を中かっこ ({ }) で囲んで指定します、プラス記号であれは {+} のように指定します。


特殊なキーを表す文字

キーを押したときに表示されない文字 (Enter キーや Tab キーなど)
このような文字ではなく動作を表すキーを指定するには、次に示すコードを使います。

キー コード
BackSpace {BACKSPACE}、{BS}、または {BKSP}
Ctrl + Break {BREAK}
CapsLock {CAPSLOCK}
Del または Delete {DELETE} または {DEL}
{DOWN}
End {END}
Enter {ENTER}または {~}
Esc {ESC}
Help {HELP}
Home {HOME}
Ins または Insert {INSERT} または {INS}
{LEFT}
NumLock {NUMLOCK}
PageDown {PGDN}
PageUp {PGUP}
PrintScreen {PRTSC}
{RIGHT}
ScrollLock {SCROLLLOCK}
Tab {TAB}
{UP}
F1 {F1}
F2 {F2}
F3 {F3}
F4 {F4}
F5 {F5}
F6 {F6}
F7 {F7}
F8 {F8}
F9 {F9}
F10 {F10}
F11 {F11}
F12 {F12}
F13 {F13}
F14 {F14}
F15 {F15}
F16 {F16}

Shiftキー、Ctrlキー、Altキーと他のキーとの組み合わせを指定するには、
通常のキーコードの前に次のコードを単独、または組み合わせて記述します。

キー コード
Shift +
Ctrl ^
Alt %

Shift キー、Ctrl キー、Alt キーを押しながら他のキーを押す場合は、キーのコードをかっこで囲みます。
Shift キーを押しながらEとCを押す操作を指定するには、"+(EC)" を使います。
Shift キーを押しながらEを押し、その後Shiftキーを離してCを押す場合は、"+EC" とします。


AppActivateステートメント

アプリケーション ウィンドウをアクティブにします。

AppActivate title[, wait]

指定項目 内容
title 必ず指定します。
アクティブにするアプリケーション ウィンドウのタイトル バーのタイトルを表す文字列式を指定します。
名前付き引数 title に Shell 関数によって返されるタスク ID を指定して、アプリケーションをアクティブにすることもできます。
wait 省略可能です。
名前付き引数 title で指定したアプリケーションをアクティブにする前に呼び出し側のアプリケーションにフォーカスを持たせるかどうかを、次に示すブール型 (Boolean) の値を使って設定します。
False(既定値) :呼び出し側のアプリケーションがフォーカスを持っていなくても、指定したアプリケーションをアクティブにします。
True:呼び出し側のアプリケーションがフォーカスを持つまで待機し、指定したアプリケーションをアクティブにします。

AppActivateでフォーカスが移っても指定したウィンドウの状態は変化しません。
たとえば、最小化されているウィンドウにフォーカスを移しても、そのウィンドウは最小化されたままです。

アプリケーション ウィンドウのタイトル バーの文字列と、名前付き引数 title が完全に一致しているかどうかを比較することによって、どのアプリケーションをアクティブにするかが判別されます。
完全に一致するものが見つからないときは、title で始まるアプリケーションをアクティブにします。
一致するアプリケーション ウィンドウが複数ある場合は、 1 つが任意に選択されてアクティブになります。

titleの指定について
Shell 関数で起動したアプリケーションは、Shell関数の戻り値のタスク IDを指定します。
マクロVBAが起動されている自身のExcelは、Application.Caption を指定してください。
既に起動済みの他のアプリケーションの場合は、ウィンドウのタイトルを間違えずに指定してください。


SendkeysとAppActivateの使用例

以下はヘルプにある電卓でのSenkeysの使用例を極力正しく動作するように改変したものです。
実践的な使用例ではありませんが、
SendKeysを理解する為の練習として、簡単に試せるのが良いでしょう。

Dim ReturnValue, i
' 電卓を実行します。
ReturnValue = Shell("CALC.EXE", vbNormalFocus)

'起動時にスタート画面が長くかかる場合の対処
'秒数は適宜変更してください。
Application.Wait Now() + TimeSerial(0, 0, 3)

'電卓をアクティブに:起動待ち
On Error Resume Next
Do
  Application.Wait Now() + TimeSerial(0, 0, 1)
  DoEvents
  Err.Clear
  '電卓をアクティブにします。
  AppActivate "電卓"
Loop While Err

'1~20までの数字を送る
For i = 1 To 20
  '電卓にキーコードを転送して、
  SendKeys i & "{+}", True
Next

'和を求めます。
SendKeys "=", True
MsgBox "計算終了"
※ヘルプのままでは環境により動作しないのでVBAソースは変更しています。

Shell関数については、次回の、
第122回.Shell関数
・Shell関数の構文 ・Shell関数の使用例 ・起動したアプリの終了を待つ同期処理
こちらを参考にしてください。

Application.Wait

実行中のマクロを指定の時刻まで停止します。
指定の時間に達した場合、True を返します。

Application.Wait (Time)

Timeには、マクロを再開する時刻をExcelの日付の書式で指定します。


Sendkeysでは送信できないキーコード

プリントスクリーン(PrntScr)は、SendKeysでは送れません。

プリントスクリーン(PrntScr)を送るには、APIが必要になります。
以下のページにAPI(keybd_event )を使用したVBAサンプルを掲載しています。
全シートの画面キャプチャを取得する(keybd_event)
資料等の作成で、画面キャプチャすることがあると思います。そこで、全シートの画面キャプチャを、新規シートに全て取得するプログラムです。Alt+PrntScrnで、エクセルのウインドウのみキャプチャしています。


NumLockが解除されてしまう問題

SendKeysを実行すると、「NumLock」がOffになってしまう事があります。
というより、かなりの確率でOffになります。

上掲の電卓操作で、Windows10のExcelでは毎回Offになっていました。
キーボードにテンキーが無ければ気にならないところですが、
テンキー付きのキーボードでは、これは大変困ったことになるではないでしょうか。
これを回避するには、最後にNumLockキーを送信することで対応できます。

'NumLockが解除されてしまう事への対応
SendKeys "{NUMLOCK}"

これを最後に入れるということです。
しかし、
必ず「NumLock」が「Off」になるのなら、これで良いのですが、
もし、SenKeysを実行してもNumLockがOffになっていなかったら、逆にわざわざOffにしてしまう事になります。

NumLockがOffになっていればすぐに分かりますし、
キーボードを1回押すだけなので、気にしなければそれでも構わないと思いますが、
これでは困るという場合は、
以下のように、WScript.ShellのSendKeysを使用してください。

Public Function SendKeys(InpKeys As String, Optional Wait As Boolean = False)
  Static WSH As Object
  If WSH Is Nothing Then
    Set WSH = CreateObject("WScript.Shell")
  End If
  WSH.SendKeys InpKeys
End Function

プロシージャー名をApplicationの本来のメソッドSendKeysと同一にしているので、
これを同じプロジェェクト(同じブック)の標準モジュールに入れるだけで、
先の電卓操作のマクロVBAのままで動作します。
(このような実装方法をラップするという言い方をしたりします)

本来のSendKeysを使う場合と切り替えたい時は、Applicationから書き始めて、
Application.SendKeys ・・・
このように書けば、ApplicationのSendKeysメソッドが動作するようになります。

※WScript.ShellのSendKeysで問題が発生しないとは言い切れません。
上の電卓操作を何度か実行した限りでは大丈夫でしたが、
100%発生しないかどうか、別の問題があるかどうか等々・・・
キーコード送信は環境に依存しますので、使用するときは良く確認してください。
VBAのSendKeysよりは安定動作するという程度に考えた方が良いと思います。


Sendkeysについて

SendKeysはとても便利な機能なのですが、上記のような問題点以外にも、
対象のアプリケーションによっては、動作が安定しない場合も多いので使用には注意が必要です。

少なくとも、SendKeysを使ったマクロVBA動作中に、ユーザーが他のウインドウをあちこちクリックしてしまったら正しく動作させることはできません。
SendKeysを使う場合は、ユーザーにマクロVBA終了までは一切操作しない事を徹底させる必要があります。

他のアプリケーションを操作する手段が無い場合や、実現したいことが他のVBAの機能ではできない場合も時にはあるでしょう。
そのような場合は、
キーボード操作可能であるならば、基本的にはSendkeysを使ってキーボード操作と同じことが実現できます。
そういった場合の最終手段として考えると良いと思います。




同じテーマ「マクロVBA入門」の記事

第118回.ファイル操作Ⅱ(Print #)

VBAでファイル(CSV等)を扱う時は、最初に、ファイルを開き、その後に、読込み書込みを行い、最後に、ファイルを閉じます。ファイルを書き込む時には、Print#ステートメントを使います。Print#ステートメント シーケンシャル出力モード(OutputまたはAppend)で開いたファイルにデータを書き込むファイル入…
第119回.ファイルシステムオブジェクト(FileSystemObject)
・FileSystemObjectオブジェクトの使用方法 ・FileSystemObjectオブジェクトのプロパティとメソッド ・FileSystemObjectオブジェクトのメソッドの戻り値 ・FileSystemObjectオブジェクトの使用例 ・FileSystemObjectオブジェクトの関連記事と実践例
第120回.OnTimeメソッド
・OnTimeメソッドの構文 ・OnTimeメソッドの使用例 ・OnTimeメソッドの実践例
第121回.SendKeysメソッドとAppActivateステートメント
第122回.Shell関数
・Shell関数の構文 ・Shell関数の使用例 ・起動したアプリの終了を待つ同期処理
第123回.APIについて(Win32API)
・Declare ステートメン ・APIの使用例 ・いろいろなAPIについて
第124回.Workbookのイベントプロシージャー
・Workbookのイベント一覧 ・イベントプロシージャー追加のVBE操作 ・Workbook_Open:Workbookのイベント ・Workbook_BeforeClose:Workbookのイベント ・Workbook_SheetChange:Workbookのイベント
第125回.Worksheetのイベントプロシージャー
・Worksheetのイベント ・イベントプロシージャー追加のVBE操作 ・Activate:Worksheetのイベント ・BeforeDoubleClick:Worksheetのイベント ・BeforeRightClick:Worksheetのイベント ・Change:Worksheetのイベント ・SelectionChange:Worksheetのイベント ・全てのシートまたは複数のシートに対するイベント
第130回.テーブル操作の概要(ListObject)
・ListObjects コレクション ・ListObject オブジェクト ・テーブル操作のVBAコード
第131回.テーブル操作のVBAコード(ListObject,DataBodyRange)
・テーブル操作のVBAサンプル使用例 ・テーブルに設定 ・テーブルスタイル一覧 ・テーブルの存在確認 ・テーブルを範囲に変換 ・テーブルの範囲を再設定 ・テーブルのセルに値を入れる ・テーブルのセルの数式変更 ・テーブルの行・列のクリア ・テーブルの列の数式設定 ・テーブルの行挿入・削除 ・テーブルの列挿入・削除 ・テーブルのオートフィルター ・テーブルの並べ替え(ソート) ・テーブルの集計行挿入・削除・非表示 ・テーブルの右端に集計列追加 ・テーブルに新しい行列を含めない ・テーブルの使い方の基本 ・サイト内のテーブルに関するページ
第142回.テーブル全件処理とデータ最終行(ListObject,DataBodyRange)
・テーブル全件処理 ・テーブルの特定列のデータ最終行まで ・テーブルが拡張されないパターン ・サイト内のテーブルに関する他のページ


新着記事NEW ・・・新着記事一覧を見る

無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
累計を求める数式あれこれ|エクセル関数応用(2024-01-22)
複数の文字列を検索して置換するSUBSTITUTE|エクセル入門(2024-01-03)
いくつかの数式の計算中にリソース不足になりました。|エクセル雑感(2023-12-28)
VBAでクリップボードへ文字列を送信・取得する3つの方法|VBA技術解説(2023-12-07)
難しい数式とは何か?|エクセル雑感(2023-12-07)
スピらない スピル数式 スピらせる|エクセル雑感(2023-12-06)
イータ縮小ラムダ(eta reduced lambda)|エクセル入門(2023-11-20)
PIVOTBY関数(縦軸と横軸でグループ化して集計)|エクセル入門(2023-11-19)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.変数宣言のDimとデータ型|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.並べ替え(Sort)|VBA入門
8.条件分岐(IF)|VBA入門
9.マクロとは?VBAとは?VBAでできること|VBA入門
10.セルのクリア(Clear,ClearContents)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ