回答編集履歴

3

しゅうせい2

2019/01/21 04:19

投稿

jawa
jawa

スコア3013

test CHANGED
@@ -138,7 +138,7 @@
138
138
 
139
139
 
140
140
 
141
- 非常に長いコードに見えますが、操作用の配列の中身は「入力キー」と「キーアップ/ダウン」の部分しか変更しておらず、同じ内容を毎回記述しています。
141
+ 非常に長いコードに見えますが、操作用の配列の中身は「入力キー」と「キーアップ/ダウン」の部分しか変更しておらず、他は同じ内容を毎回記述しています。
142
142
 
143
143
  これがコードが長く見ずらい原因となっていますので、以下のサンプルコードのように関数化して使用すると操作が多少楽になります。
144
144
 
@@ -198,7 +198,7 @@
198
198
 
199
199
  Public Const VK_CTRL = &H11 'Contorol
200
200
 
201
- Public Const VK_ALT = &H12 'Contorol
201
+ Public Const VK_ALT = &H12 'Alt
202
202
 
203
203
 
204
204
 
@@ -294,6 +294,10 @@
294
294
 
295
295
  Sub prcSendInput(VkKey As Integer, UpDown As Integer)
296
296
 
297
+ Dim inputevents(1) As INPUT_TYPE
298
+
299
+
300
+
297
301
  With inputevents(0)
298
302
 
299
303
  .dwType = INPUT_KEYBOARD

2

しゅうせい

2019/01/21 04:19

投稿

jawa
jawa

スコア3013

test CHANGED
@@ -86,8 +86,6 @@
86
86
 
87
87
  End With
88
88
 
89
-
90
-
91
89
  '--[V]キーアップ
92
90
 
93
91
  With inputevents(2)
@@ -106,8 +104,6 @@
106
104
 
107
105
  End With
108
106
 
109
-
110
-
111
107
  '--[CTRL]キーアップ
112
108
 
113
109
  With inputevents(3)
@@ -134,19 +130,23 @@
134
130
 
135
131
  ```
136
132
 
137
- といった具合に、各キーのキーダウン、キーアップのタイミングを考慮しながら操作用の配列を作成し、それをまとめて実行ます。
133
+ といった具合に、各キーのキーダウン、キーアップのタイミングを考慮しながら操作用の配列を作成し、それをまとめて実行する、といった手順になります。
138
-
139
-
140
-
134
+
141
- ちなみに、1つの操作ごとに`SendInput`を実行(計4回`SendInput`する)でも同じ結果となります。
135
+ ちなみに、1つの操作ごとに`SendInput`を実行(計4回`SendInput`する)でも同じ結果が得られます。
142
-
136
+
137
+
138
+
139
+
140
+
143
- 操作用の配列の中身は「入力キー」と「キーアップ/ダウン」の部分しか変更ず、同じ内容を毎回記述しています。
141
+ 非常に長いコードに見えますが、操作用の配列の中身は「入力キー」と「キーアップ/ダウン」の部分しか変更しておらず、同じ内容を毎回記述しています。
144
142
 
145
143
  これがコードが長く見ずらい原因となっていますので、以下のサンプルコードのように関数化して使用すると操作が多少楽になります。
146
144
 
147
145
 
148
146
 
147
+ ```
148
+
149
- ```標準モジュール
149
+ '標準モジュール
150
150
 
151
151
  Public Declare Function SendInput Lib "user32.dll" (ByVal nInputs As Long, pInputs As INPUT_TYPE, ByVal cbsize As Long) As Long
152
152
 
@@ -328,7 +328,7 @@
328
328
 
329
329
 
330
330
 
331
- 参考にしたサイトですが、これは質問者さんの環境ではエラーとなったという`CopyPicture`メソッドの解説ページです。
331
+ 参考サイトですが、これは質問者さんの環境ではエラーとなったという`CopyPicture`メソッドの解説ページです。
332
332
 
333
333
  [参考⇒セル範囲を画像としてコピーする(CopyPictureメソッド)|Excel VBA](https://www.moug.net/tech/exvba/0050118.html)
334
334
 

1

追記

2019/01/21 04:15

投稿

jawa
jawa

スコア3013

test CHANGED
@@ -23,3 +23,355 @@
23
23
  [⇒SendInputにてキーを送る - Yahoo知恵袋](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1380820093)
24
24
 
25
25
  などが参考になるでしょうか?
26
+
27
+
28
+
29
+ 追記① SendInputでペイントを操作する
30
+
31
+ ---
32
+
33
+ 紹介した記事が難しかったとのことですので補足させていただきます。
34
+
35
+
36
+
37
+ `SendInput`は`SendKeys`に比べると少しやりとりが面倒です。
38
+
39
+
40
+
41
+ 例えば[Ctrl]+[V]というキー入力を送信する場合、`SendKeys`では
42
+
43
+ ```
44
+
45
+ SendKeys "^(v)", Wait '[Ctrl]を押しながら[V]
46
+
47
+ ```
48
+
49
+ という一文でできますが、`SendInput`では
50
+
51
+ ```
52
+
53
+ '--[CTRL]キーダウン
54
+
55
+ With inputevents(0)
56
+
57
+ .dwType = INPUT_KEYBOARD
58
+
59
+ .ki.wVk = VK_CTRL
60
+
61
+ .ki.wScan = 0
62
+
63
+ .ki.dwFlags = KEYEVENTF_KEYDOWN
64
+
65
+ .ki.time = 0
66
+
67
+ .ki.dwExtraInfo = 0
68
+
69
+ End With
70
+
71
+ '--[V]キーダウン
72
+
73
+ With inputevents(1)
74
+
75
+ .dwType = INPUT_KEYBOARD
76
+
77
+ .ki.wVk = VK_V
78
+
79
+ .ki.wScan = 0
80
+
81
+ .ki.dwFlags = KEYEVENTF_KEYDOWN
82
+
83
+ .ki.time = 0
84
+
85
+ .ki.dwExtraInfo = 0
86
+
87
+ End With
88
+
89
+
90
+
91
+ '--[V]キーアップ
92
+
93
+ With inputevents(2)
94
+
95
+ .dwType = INPUT_KEYBOARD
96
+
97
+ .ki.wVk = VK_V
98
+
99
+ .ki.wScan = 0
100
+
101
+ .ki.dwFlags = KEYEVENTF_KEYUP
102
+
103
+ .ki.time = 0
104
+
105
+ .ki.dwExtraInfo = 0
106
+
107
+ End With
108
+
109
+
110
+
111
+ '--[CTRL]キーアップ
112
+
113
+ With inputevents(3)
114
+
115
+ .dwType = INPUT_KEYBOARD
116
+
117
+ .ki.wVk = VK_CTRL
118
+
119
+ .ki.wScan = 0
120
+
121
+ .ki.dwFlags = KEYEVENTF_KEYUP
122
+
123
+ .ki.time = 0
124
+
125
+ .ki.dwExtraInfo = 0
126
+
127
+ End With
128
+
129
+
130
+
131
+ SendInput 4, inputevents(0), Len(inputevents(0)) '配列に格納した4つの操作を実行
132
+
133
+
134
+
135
+ ```
136
+
137
+ といった具合に、各キーのキーダウン、キーアップのタイミングを考慮しながら操作用の配列を作成し、それをまとめて実行します。
138
+
139
+
140
+
141
+ ちなみに、1つの操作ごとに`SendInput`を実行(計4回`SendInput`する)でも同じ結果となります。
142
+
143
+ 操作用の配列の中身は「入力キー」と「キーアップ/ダウン」の部分しか変更せず、同じ内容を毎回記述しています。
144
+
145
+ これがコードが長く見ずらい原因となっていますので、以下のサンプルコードのように関数化して使用すると操作が多少楽になります。
146
+
147
+
148
+
149
+ ```標準モジュール
150
+
151
+ Public Declare Function SendInput Lib "user32.dll" (ByVal nInputs As Long, pInputs As INPUT_TYPE, ByVal cbsize As Long) As Long
152
+
153
+
154
+
155
+ Public Type KEYBDINPUT
156
+
157
+ wVk As Integer
158
+
159
+ wScan As Integer
160
+
161
+ dwFlags As Long
162
+
163
+ time As Long
164
+
165
+ dwExtraInfo As Long
166
+
167
+ dummy1 As Long
168
+
169
+ dummy2 As Long
170
+
171
+ End Type
172
+
173
+
174
+
175
+ Public Type INPUT_TYPE
176
+
177
+ dwType As Long
178
+
179
+ ki As KEYBDINPUT
180
+
181
+ End Type
182
+
183
+
184
+
185
+ 'キー定数
186
+
187
+ Public Const INPUT_KEYBOARD As Integer = 1
188
+
189
+
190
+
191
+ Public Const VK_TAB As Integer = &H9 'Tab
192
+
193
+ Public Const VK_ENTER As Integer = &HD 'Enter
194
+
195
+
196
+
197
+ Public Const VK_SHIFT = &H10 'Shift
198
+
199
+ Public Const VK_CTRL = &H11 'Contorol
200
+
201
+ Public Const VK_ALT = &H12 'Contorol
202
+
203
+
204
+
205
+ Public Const VK_A = &H41 '「A」
206
+
207
+ Public Const VK_C = &H43 '「C」
208
+
209
+ Public Const VK_V = &H56 '「V」
210
+
211
+
212
+
213
+ Public Const VK_F4 = &H73 'F4
214
+
215
+
216
+
217
+ Public Const KEYEVENTF_KEYDOWN As Integer = 0
218
+
219
+ Public Const KEYEVENTF_KEYUP As Integer = 2
220
+
221
+
222
+
223
+ 'メイン関数
224
+
225
+ Sub SampleMain()
226
+
227
+ Dim rc As Long
228
+
229
+ ThisWorkbook.Worksheets("データ収集").Range("B51:L55").Copy
230
+
231
+
232
+
233
+ 'ペイント起動
234
+
235
+ rc = Shell("C:\Windows\System32\mspaint.exe", vbNormalFocus) '以降の処理でアクティブにしていないのならここでフォーカスを与える必要がある
236
+
237
+ '起動待ち1秒
238
+
239
+ Application.Wait Now + TimeValue("0:00:01")
240
+
241
+
242
+
243
+ '●貼り付け
244
+
245
+ prcSendInput VK_CTRL, KEYEVENTF_KEYDOWN '[CTRL]キーダウン
246
+
247
+ prcSendInput VK_V, KEYEVENTF_KEYDOWN '[V]キーダウン
248
+
249
+ prcSendInput VK_V, KEYEVENTF_KEYUP '[V]キーアップ
250
+
251
+ prcSendInput VK_CTRL, KEYEVENTF_KEYUP '[CTRL]キーアップ
252
+
253
+ '●全選択
254
+
255
+ prcSendInput VK_CTRL, KEYEVENTF_KEYDOWN '[CTRL]キーダウン
256
+
257
+ prcSendInput VK_A, KEYEVENTF_KEYDOWN '[A]キーダウン
258
+
259
+ prcSendInput VK_A, KEYEVENTF_KEYUP '[A]キーアップ
260
+
261
+ prcSendInput VK_CTRL, KEYEVENTF_KEYUP '[CTRL]キーアップ
262
+
263
+ '●コピー
264
+
265
+ prcSendInput VK_CTRL, KEYEVENTF_KEYDOWN '[CTRL]キーダウン
266
+
267
+ prcSendInput VK_C, KEYEVENTF_KEYDOWN '[C]キーダウン
268
+
269
+ prcSendInput VK_C, KEYEVENTF_KEYUP '[C]キーアップ
270
+
271
+ prcSendInput VK_CTRL, KEYEVENTF_KEYUP '[CTRL]キーアップ
272
+
273
+ '●終了
274
+
275
+ prcSendInput VK_ALT, KEYEVENTF_KEYDOWN '[ALT]キーダウン
276
+
277
+ prcSendInput VK_F4, KEYEVENTF_KEYDOWN '[F4]キーダウン
278
+
279
+ prcSendInput VK_F4, KEYEVENTF_KEYUP '[F4]キーアップ
280
+
281
+ prcSendInput VK_ALT, KEYEVENTF_KEYUP '[ALT]キーアップ
282
+
283
+
284
+
285
+ MsgBox "Paste?"
286
+
287
+ ThisWorkbook.Worksheets("データ収集").Range("A1").PasteSpecial
288
+
289
+ End Sub
290
+
291
+
292
+
293
+ 'SendInputを簡易化した関数
294
+
295
+ Sub prcSendInput(VkKey As Integer, UpDown As Integer)
296
+
297
+ With inputevents(0)
298
+
299
+ .dwType = INPUT_KEYBOARD
300
+
301
+ .ki.wVk = VkKey
302
+
303
+ .ki.wScan = 0
304
+
305
+ .ki.dwFlags = UpDown
306
+
307
+ .ki.time = 0
308
+
309
+ .ki.dwExtraInfo = 0
310
+
311
+ End With
312
+
313
+ SendInput 1, inputevents(0), Len(inputevents(0)) '配列に格納した1つの操作を実行
314
+
315
+ End Sub
316
+
317
+ ```
318
+
319
+
320
+
321
+ 追記② Excel上でセル範囲を図としてコピペする
322
+
323
+ ---
324
+
325
+ 「エラーの原因や回避策は後回しでいいから、とにかく目的が実現したいのだ!」
326
+
327
+ という状況なのかもしれないので、別方向からのアプローチも提案してみます。
328
+
329
+
330
+
331
+ 以下が参考にしたサイトですが、これは質問者さんの環境ではエラーとなったという`CopyPicture`メソッドの解説ページです。
332
+
333
+ [参考⇒セル範囲を画像としてコピーする(CopyPictureメソッド)|Excel VBA](https://www.moug.net/tech/exvba/0050118.html)
334
+
335
+
336
+
337
+ 上記の記事内に、以下のような記載があります。
338
+
339
+ >Excel 2007以降の[ホーム]タブ→[貼りつけ]→[図]→[図としてコピー]の機能、
340
+
341
+ >Excel 2003以前の[Shift]キーを押しながら[編集]メニューを選択した時に表示される[図のコピー]の機能と同じです。
342
+
343
+
344
+
345
+ これをマクロの記録でVBAコードにしてみましょう。
346
+
347
+
348
+
349
+ この操作を実際にシート上で行いそれを「マクロの記録」してみると、記録されたVBAでは`CopyPicture`メソッドは使用されていませんでした。(当方の環境Windows7/Office2010での結果です)
350
+
351
+
352
+
353
+ 記録されたのは、要約すると下記のようなコードでした。
354
+
355
+ ```
356
+
357
+ '対象範囲をコピー
358
+
359
+ Range("B51:L55").Copy
360
+
361
+ '貼り付け先を選択
362
+
363
+ Range("B1").Select
364
+
365
+ 'コピーしたセル範囲を「図として貼り付け」
366
+
367
+ ActiveSheet.Pictures.Paste.Select
368
+
369
+ ```
370
+
371
+ つまりセル範囲を普通にコピーして「図として貼り付け」ています。(そのままですね。)
372
+
373
+
374
+
375
+ 解決済みではありますが、まだ模索を続けられているようでしたらこちらも試してみてはいかがでしょうか。
376
+
377
+ 参考になれば幸いです。