teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

試行しやすいように汎用化処理追加

2018/10/16 11:26

投稿

imihito
imihito

スコア2166

answer CHANGED
@@ -55,4 +55,61 @@
55
55
 
56
56
  この方法を使った場合の問題は、外部のマクロの処理時間がどの程度かかるのかわからない点です。
57
57
 
58
- 外部のマクロを実行する前に上記のサンプルを実行する必要がありますが、どの程度待てば良いのかがわからないため、ちゃんと処理できる保証がありません。
58
+ 外部のマクロを実行する前に上記のサンプルを実行する必要がありますが、どの程度待てば良いのかがわからないため、ちゃんと処理できる保証がありません。
59
+
60
+ ---
61
+
62
+ 181016追記:汎用化
63
+
64
+ ```vba
65
+ 'やっていることは`SendKeysToMsgBoxSample`とほぼ同じ
66
+ Public Sub SendKeysToMsgBoxSample2()
67
+ 'Enterキー送信、1000ミリ秒(1秒)待機、Excelを対象
68
+ AsyncSendKeys "{ENTER}", 1000, Excel.Application.Caption
69
+ Call MsgBox("Sample")
70
+
71
+ End Sub
72
+
73
+
74
+ '非同期SendKeys
75
+ 'keyStroke:送るキー文字列
76
+ 'delayMilliSec:待機ミリ秒
77
+ 'appCaption:対象のウィンドウのタイトル
78
+ Public Sub AsyncSendKeys( _
79
+ keyStroke As String, _
80
+ delayMilliSec As Long, _
81
+ appCaption As String)
82
+
83
+ 'デバッグ時は -NoExit スイッチを付けるとPowerShell側の状態を確認しやすい
84
+ '"powershell.exe -Sta -NoExit -Command " & ~
85
+ Const PsCmd = _
86
+ "powershell.exe -Sta -Command """ & _
87
+ "<# SendKeysなどを使うためのライブラリ読み込み #>" & _
88
+ "Add-Type -AssemblyName Microsoft.VisualBasic;" & _
89
+ "<# ちょっと待機(要調整) #>" & _
90
+ "Start-Sleep -Milliseconds $WaitMilliSec;" & _
91
+ "[Microsoft.VisualBasic.Interaction]::AppActivate('$Caption');" & _
92
+ "<# キー送信(VBAのSendKeysと同じ構文 #>" & _
93
+ "(New-Object -TypeName Microsoft.VisualBasic.Devices.Keyboard).SendKeys('$KeyStroke', $true);"""
94
+
95
+ Dim execCmd As String
96
+ execCmd = VBA.Replace(VBA.Replace(VBA.Replace(PsCmd, _
97
+ "$WaitMilliSec", delayMilliSec), _
98
+ "$Caption", appCaption), _
99
+ "$KeyStroke", keyStroke)
100
+
101
+ 'PowerShell で非同期実行
102
+ 'デバッグ時はvbHideを他のものにして、PowerShellのウィンドウが見えるようにする
103
+ Call VBA.Shell(execCmd, vbHide)
104
+ End Sub
105
+ ```
106
+
107
+ ```powershell
108
+ <# SendKeysを使うためのライブラリ読み込み #>
109
+ Add-Type -AssemblyName Microsoft.VisualBasic;
110
+ <# ちょっと待機(要調整) #>
111
+ Start-Sleep -Milliseconds $WaitSec;
112
+ [Microsoft.VisualBasic.Interaction]::AppActivate('$Caption');
113
+ <# キー送信(VBAのSendKeysと同じ構文 #>
114
+ (New-Object -TypeName Microsoft.VisualBasic.Devices.Keyboard).SendKeys('$KeyStroke', $true);
115
+ ```

1

文言修正

2018/10/16 11:26

投稿

imihito
imihito

スコア2166

answer CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  一応。MsgBoxの操作の強引な解決方法の案です。
12
12
 
13
- VBAのほとんどの処理は、「ある命令を実行したら次の命令へ進む」という同期処理です。
13
+ VBAのほとんどの処理は、「ある命令が完了したら次の命令へ進む」という同期処理です。
14
14
  そのため、`MsgBox`が表示された時点で、Excel上のVBAは入力待ちとなり動作が止まります。
15
15
  入力待ちの間は、`Excel.Application.OnTime`メソッドなどによる予約実行も行われません。
16
16