VBAで自動的にメモ帳に文字を入力させる
VBAではWin32APIを使って、外部アプリケーションとの連携を行うことが可能です。
ここではVBAからメモ帳(Notepad)に自動で文字列を入力する方法を紹介します。
利用するWin32APIは以下の4つです。
API名 | 説明 |
---|---|
FindWindow | 特定のクラス名・ウィンドウタイトルを持つアプリケーションのハンドルを取得します。 |
FindWindowEx | 親ウィンドウの中から特定の子ウィンドウ(例:入力欄)を探すために使います。 |
SetForegroundWindow | 対象アプリケーションをアクティブなウィンドウに切り替えます。 |
SendMessage | アプリケーションにメッセージ(今回は文字列)を指定するウィンドウへ直接送信します。 |
これらを組み合わせることで、「VBA → メモ帳へテキストを自動入力」という流れが可能になります。
API解説
1. FindWindow – ウィンドウ全体を探す
FindWindow は、指定されたクラス名またはウィンドウタイトルからウィンドウのハンドル(識別番号)を取得する関数です。
VBAでの宣言(64bit対応)
1 2 3 |
Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As LongPtr |
パラメータ
- lpClassName: ウィンドウのクラス名(”Notepad”など)
- lpWindowName: ウィンドウのタイトル(”無題 – メモ帳”など)
コード例
1 2 |
Dim hWnd As LongPtr hWnd = FindWindow("Notepad", vbNullString) |
2. FindWindowEx – 子ウィンドウや入力欄を探す
FindWindowEx は、親ウィンドウの中から特定の子ウィンドウ(例:入力欄)を探すために使います。
VBAでの宣言(64bit対応)
1 2 3 4 5 |
Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" ( _ ByVal hWndParent As LongPtr, _ ByVal hWndChildAfter As LongPtr, _ ByVal lpszClass As String, _ ByVal lpszWindow As String) As LongPtr |
パラメータ
- hWndParent: 親ウィンドウのハンドル(FindWindowで取得)
- hWndChildAfter: どの子ウィンドウから検索を始めるか(通常は 0)
- lpszClass: 子ウィンドウのクラス名(メモ帳の入力欄は “Edit”)
- lpszWindow: 子ウィンドウのタイトル(通常は vbNullString)
コード例
1 2 |
Dim hWndEdit As LongPtr hWndEdit = FindWindowEx(hWndNotepad, 0, "Edit", vbNullString) |
3.SendMessage – テキストを送る
SendMessage は、特定のウィンドウに命令(メッセージ)を送るAPIです。今回は”WM_SETTEXT”を使って、ウィンドウにテキストを入力しています。
VBAでの宣言(64bit対応)
1 2 3 4 5 |
Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" ( _ ByVal hWnd As LongPtr, _ ByVal wMsg As Long, _ ByVal wParam As LongPtr, _ ByVal lParam As String) As LongPtr |
定数(他にも複数あり)
Const WM_SETTEXT As Long = &HC
パラメータ
- hWnd: メッセージを送信する対象ウィンドウのハンドル
- wMsg: 送信するメッセージの種類(例:WM_SETTEXT)
- wParam: メッセージごとの追加情報(用途はメッセージによる)
- lParam: メッセージごとの追加情報。文字列や構造体など
コード例
1 |
Call SendMessage(hWndEdit, WM_SETTEXT, 0, "メッセージおくったよ") |
この命令で、対象のウィンドウ(例:メモ帳の入力欄)に文字列「メッセージおくったよ」が送信されます。
4. SetForegroundWindow – ウィンドウを最前面にする
SetForegroundWindow は、指定したウィンドウを画面の一番手前に表示します。必須ではないですが、一般的には使った方が分かりやすくなります。
VBAでの宣言(64bit対応)
1 2 |
Declare PtrSafe Function SetForegroundWindow Lib "user32" ( _ ByVal hWnd As LongPtr) As Long |
パラメータ
hWnd: 前面表示するウィンドウのハンドル
コード例
1 |
Call SetForegroundWindow(hWndNotepad) |
Excelのアクティブシートの内容をメモ帳に自動で送信するVBAコード
メモ帳を起動した状態で、以下のコードのSendSheetTextToNotepad()を実行すると、アクティブシートに書いてある内容を全てメモ帳に貼り付けます。
注意点として、メモ帳の既存の内容を上書きしますので、新規メモでの実行をお勧めします。
コードの内容はコメントに大体書いてる通りですが、以下の流れで処理を行っています。
- アクティブシートに入力されている全てのセル範囲を処理対象とします。
- シートの1行ごとに改行を入れて、全てのセルの文字列を連結します。
- FindWindow()でメモ帳のウィンドウハンドルを取得します。ウィンドウハンドルとはWindowsOSが管理しているアプリケーションウィンドウごとに割り当てられた番号です。
- FindWindowEx()でメモ帳の入力欄のハンドルを取得します。メモ帳本体ではなく入力部にSendMessageでテキストを送る必要があるためこの指定が必要です。
- SetForegroundWindow()でメモ帳を最前面に表示します。前面表示しなくてもセル文字列はメモ帳に張り付きます。
- SendMessage()でメモ帳の入力部に文字列を送信します。これによりメモ帳にセル文字列が表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
Option Explicit '// Win32 API 宣言(64bit用) Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As LongPtr Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" ( _ ByVal hWndParent As LongPtr, _ ByVal hWndChildAfter As LongPtr, _ ByVal lpszClass As String, _ ByVal lpszWindow As String) As LongPtr Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" ( _ ByVal hWnd As LongPtr, _ ByVal wMsg As Long, _ ByVal wParam As LongPtr, _ ByVal lParam As String) As LongPtr Declare PtrSafe Function SetForegroundWindow Lib "user32" ( _ ByVal hWnd As LongPtr) As Long Const WM_SETTEXT As Long = &HC Sub SendSheetTextToNotepad() Dim hWndNotepad As LongPtr '// メモ帳のウィンドウハンドル Dim hWndEdit As LongPtr '// テキスト入力部のハンドル Dim textToSend As String '// メモ帳に送信する文字列 Dim inputRange As Range '// シートのセル入力範囲 Dim r As Range '// ループ処理用の1セルのRange '// アクティブシートに入力されているセル範囲を対象とする Set inputRange = ActiveSheet.UsedRange '// 全セルをループして1行ごとに改行を付けて文字列化する For Each r In inputRange '// セルが空ではない場合 If Not IsEmpty(r.Value) Then '// セルの内容を文字列連結する。後ろにタブを付ける textToSend = textToSend & CStr(r.Value) & vbTab End If '// 列の最後の場合は改行を文字列に付ける If r.Column = inputRange.Columns(inputRange.Columns.Count).Column Then textToSend = textToSend & vbCrLf End If Next '// メモ帳のウィンドウハンドルを取得(★注意★:メモ帳の既存内容は上書きします) hWndNotepad = FindWindow("Notepad", vbNullString) '// メモ帳が起動されていない場合 If hWndNotepad = 0 Then MsgBox "メモ帳が見つかりません。起動してください。", vbExclamation Exit Sub End If '// テキスト入力部のハンドルを取得 hWndEdit = FindWindowEx(hWndNotepad, 0, "Edit", vbNullString) If hWndEdit = 0 Then MsgBox "メモ帳の編集領域が見つかりません。", vbExclamation Exit Sub End If '// メモ帳を前面に出す(しなくてもテキストは張り付く) Call SetForegroundWindow(hWndNotepad) '// テキスト送信(上書き) Call SendMessage(hWndEdit, WM_SETTEXT, 0, textToSend) '//MsgBox "シート内容をメモ帳に送信しました。" End Sub |
実行結果
以下のようにアクティブシートに入力します。
SendSheetTextToNotepad()を実行します。
このようにメモ帳に張り付きます。
複数のAPIを使うことになりますが、VBAからでも外部アプリケーションの制御を行うことが可能になります。