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

回答編集履歴

3

しゅうせい2

2019/01/21 04:19

投稿

jawa
jawa

スコア3020

answer CHANGED
@@ -68,7 +68,7 @@
68
68
  ちなみに、1つの操作ごとに`SendInput`を実行(計4回`SendInput`する)でも同じ結果が得られます。
69
69
 
70
70
 
71
- 非常に長いコードに見えますが、操作用の配列の中身は「入力キー」と「キーアップ/ダウン」の部分しか変更しておらず、同じ内容を毎回記述しています。
71
+ 非常に長いコードに見えますが、操作用の配列の中身は「入力キー」と「キーアップ/ダウン」の部分しか変更しておらず、他は同じ内容を毎回記述しています。
72
72
  これがコードが長く見ずらい原因となっていますので、以下のサンプルコードのように関数化して使用すると操作が多少楽になります。
73
73
 
74
74
  ```
@@ -98,7 +98,7 @@
98
98
 
99
99
  Public Const VK_SHIFT = &H10 'Shift
100
100
  Public Const VK_CTRL = &H11 'Contorol
101
- Public Const VK_ALT = &H12 'Contorol
101
+ Public Const VK_ALT = &H12 'Alt
102
102
 
103
103
  Public Const VK_A = &H41 '「A」
104
104
  Public Const VK_C = &H43 '「C」
@@ -146,6 +146,8 @@
146
146
 
147
147
  'SendInputを簡易化した関数
148
148
  Sub prcSendInput(VkKey As Integer, UpDown As Integer)
149
+ Dim inputevents(1) As INPUT_TYPE
150
+
149
151
  With inputevents(0)
150
152
  .dwType = INPUT_KEYBOARD
151
153
  .ki.wVk = VkKey

2

しゅうせい

2019/01/21 04:19

投稿

jawa
jawa

スコア3020

answer CHANGED
@@ -42,7 +42,6 @@
42
42
  .ki.time = 0
43
43
  .ki.dwExtraInfo = 0
44
44
  End With
45
-
46
45
  '--[V]キーアップ
47
46
  With inputevents(2)
48
47
  .dwType = INPUT_KEYBOARD
@@ -52,7 +51,6 @@
52
51
  .ki.time = 0
53
52
  .ki.dwExtraInfo = 0
54
53
  End With
55
-
56
54
  '--[CTRL]キーアップ
57
55
  With inputevents(3)
58
56
  .dwType = INPUT_KEYBOARD
@@ -66,13 +64,15 @@
66
64
  SendInput 4, inputevents(0), Len(inputevents(0)) '配列に格納した4つの操作を実行
67
65
 
68
66
  ```
69
- といった具合に、各キーのキーダウン、キーアップのタイミングを考慮しながら操作用の配列を作成し、それをまとめて実行ます。
67
+ といった具合に、各キーのキーダウン、キーアップのタイミングを考慮しながら操作用の配列を作成し、それをまとめて実行する、といった手順になります。
68
+ ちなみに、1つの操作ごとに`SendInput`を実行(計4回`SendInput`する)でも同じ結果が得られます。
70
69
 
71
- ちなみに、1つの操作ごとに`SendInput`を実行(計4回`SendInput`する)でも同じ結果となります。
70
+
72
- 操作用の配列の中身は「入力キー」と「キーアップ/ダウン」の部分しか変更ず、同じ内容を毎回記述しています。
71
+ 非常に長いコードに見えますが、操作用の配列の中身は「入力キー」と「キーアップ/ダウン」の部分しか変更しておらず、同じ内容を毎回記述しています。
73
72
  これがコードが長く見ずらい原因となっていますので、以下のサンプルコードのように関数化して使用すると操作が多少楽になります。
74
73
 
74
+ ```
75
- ```標準モジュール
75
+ '標準モジュール
76
76
  Public Declare Function SendInput Lib "user32.dll" (ByVal nInputs As Long, pInputs As INPUT_TYPE, ByVal cbsize As Long) As Long
77
77
 
78
78
  Public Type KEYBDINPUT
@@ -163,7 +163,7 @@
163
163
  「エラーの原因や回避策は後回しでいいから、とにかく目的が実現したいのだ!」
164
164
  という状況なのかもしれないので、別方向からのアプローチも提案してみます。
165
165
 
166
- 参考にしたサイトですが、これは質問者さんの環境ではエラーとなったという`CopyPicture`メソッドの解説ページです。
166
+ 参考サイトですが、これは質問者さんの環境ではエラーとなったという`CopyPicture`メソッドの解説ページです。
167
167
  [参考⇒セル範囲を画像としてコピーする(CopyPictureメソッド)|Excel VBA](https://www.moug.net/tech/exvba/0050118.html)
168
168
 
169
169
  上記の記事内に、以下のような記載があります。

1

追記

2019/01/21 04:15

投稿

jawa
jawa

スコア3020

answer CHANGED
@@ -10,4 +10,180 @@
10
10
  さしあたり
11
11
  [⇒Windows7で VB6 / VBA の SendKeys の問題について - アプリ仮想化奉行](https://tunemicky.blogspot.com/2012/08/windows7-vb6-vba-sendkeys-70.html)
12
12
  [⇒SendInputにてキーを送る - Yahoo知恵袋](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1380820093)
13
- などが参考になるでしょうか?
13
+ などが参考になるでしょうか?
14
+
15
+ 追記① SendInputでペイントを操作する
16
+ ---
17
+ 紹介した記事が難しかったとのことですので補足させていただきます。
18
+
19
+ `SendInput`は`SendKeys`に比べると少しやりとりが面倒です。
20
+
21
+ 例えば[Ctrl]+[V]というキー入力を送信する場合、`SendKeys`では
22
+ ```
23
+ SendKeys "^(v)", Wait '[Ctrl]を押しながら[V]
24
+ ```
25
+ という一文でできますが、`SendInput`では
26
+ ```
27
+ '--[CTRL]キーダウン
28
+ With inputevents(0)
29
+ .dwType = INPUT_KEYBOARD
30
+ .ki.wVk = VK_CTRL
31
+ .ki.wScan = 0
32
+ .ki.dwFlags = KEYEVENTF_KEYDOWN
33
+ .ki.time = 0
34
+ .ki.dwExtraInfo = 0
35
+ End With
36
+ '--[V]キーダウン
37
+ With inputevents(1)
38
+ .dwType = INPUT_KEYBOARD
39
+ .ki.wVk = VK_V
40
+ .ki.wScan = 0
41
+ .ki.dwFlags = KEYEVENTF_KEYDOWN
42
+ .ki.time = 0
43
+ .ki.dwExtraInfo = 0
44
+ End With
45
+
46
+ '--[V]キーアップ
47
+ With inputevents(2)
48
+ .dwType = INPUT_KEYBOARD
49
+ .ki.wVk = VK_V
50
+ .ki.wScan = 0
51
+ .ki.dwFlags = KEYEVENTF_KEYUP
52
+ .ki.time = 0
53
+ .ki.dwExtraInfo = 0
54
+ End With
55
+
56
+ '--[CTRL]キーアップ
57
+ With inputevents(3)
58
+ .dwType = INPUT_KEYBOARD
59
+ .ki.wVk = VK_CTRL
60
+ .ki.wScan = 0
61
+ .ki.dwFlags = KEYEVENTF_KEYUP
62
+ .ki.time = 0
63
+ .ki.dwExtraInfo = 0
64
+ End With
65
+
66
+ SendInput 4, inputevents(0), Len(inputevents(0)) '配列に格納した4つの操作を実行
67
+
68
+ ```
69
+ といった具合に、各キーのキーダウン、キーアップのタイミングを考慮しながら操作用の配列を作成し、それをまとめて実行します。
70
+
71
+ ちなみに、1つの操作ごとに`SendInput`を実行(計4回`SendInput`する)でも同じ結果となります。
72
+ 操作用の配列の中身は「入力キー」と「キーアップ/ダウン」の部分しか変更せず、同じ内容を毎回記述しています。
73
+ これがコードが長く見ずらい原因となっていますので、以下のサンプルコードのように関数化して使用すると操作が多少楽になります。
74
+
75
+ ```標準モジュール
76
+ Public Declare Function SendInput Lib "user32.dll" (ByVal nInputs As Long, pInputs As INPUT_TYPE, ByVal cbsize As Long) As Long
77
+
78
+ Public Type KEYBDINPUT
79
+ wVk As Integer
80
+ wScan As Integer
81
+ dwFlags As Long
82
+ time As Long
83
+ dwExtraInfo As Long
84
+ dummy1 As Long
85
+ dummy2 As Long
86
+ End Type
87
+
88
+ Public Type INPUT_TYPE
89
+ dwType As Long
90
+ ki As KEYBDINPUT
91
+ End Type
92
+
93
+ 'キー定数
94
+ Public Const INPUT_KEYBOARD As Integer = 1
95
+
96
+ Public Const VK_TAB As Integer = &H9 'Tab
97
+ Public Const VK_ENTER As Integer = &HD 'Enter
98
+
99
+ Public Const VK_SHIFT = &H10 'Shift
100
+ Public Const VK_CTRL = &H11 'Contorol
101
+ Public Const VK_ALT = &H12 'Contorol
102
+
103
+ Public Const VK_A = &H41 '「A」
104
+ Public Const VK_C = &H43 '「C」
105
+ Public Const VK_V = &H56 '「V」
106
+
107
+ Public Const VK_F4 = &H73 'F4
108
+
109
+ Public Const KEYEVENTF_KEYDOWN As Integer = 0
110
+ Public Const KEYEVENTF_KEYUP As Integer = 2
111
+
112
+ 'メイン関数
113
+ Sub SampleMain()
114
+ Dim rc As Long
115
+ ThisWorkbook.Worksheets("データ収集").Range("B51:L55").Copy
116
+
117
+ 'ペイント起動
118
+ rc = Shell("C:\Windows\System32\mspaint.exe", vbNormalFocus) '以降の処理でアクティブにしていないのならここでフォーカスを与える必要がある
119
+ '起動待ち1秒
120
+ Application.Wait Now + TimeValue("0:00:01")
121
+
122
+ '●貼り付け
123
+ prcSendInput VK_CTRL, KEYEVENTF_KEYDOWN '[CTRL]キーダウン
124
+ prcSendInput VK_V, KEYEVENTF_KEYDOWN '[V]キーダウン
125
+ prcSendInput VK_V, KEYEVENTF_KEYUP '[V]キーアップ
126
+ prcSendInput VK_CTRL, KEYEVENTF_KEYUP '[CTRL]キーアップ
127
+ '●全選択
128
+ prcSendInput VK_CTRL, KEYEVENTF_KEYDOWN '[CTRL]キーダウン
129
+ prcSendInput VK_A, KEYEVENTF_KEYDOWN '[A]キーダウン
130
+ prcSendInput VK_A, KEYEVENTF_KEYUP '[A]キーアップ
131
+ prcSendInput VK_CTRL, KEYEVENTF_KEYUP '[CTRL]キーアップ
132
+ '●コピー
133
+ prcSendInput VK_CTRL, KEYEVENTF_KEYDOWN '[CTRL]キーダウン
134
+ prcSendInput VK_C, KEYEVENTF_KEYDOWN '[C]キーダウン
135
+ prcSendInput VK_C, KEYEVENTF_KEYUP '[C]キーアップ
136
+ prcSendInput VK_CTRL, KEYEVENTF_KEYUP '[CTRL]キーアップ
137
+ '●終了
138
+ prcSendInput VK_ALT, KEYEVENTF_KEYDOWN '[ALT]キーダウン
139
+ prcSendInput VK_F4, KEYEVENTF_KEYDOWN '[F4]キーダウン
140
+ prcSendInput VK_F4, KEYEVENTF_KEYUP '[F4]キーアップ
141
+ prcSendInput VK_ALT, KEYEVENTF_KEYUP '[ALT]キーアップ
142
+
143
+ MsgBox "Paste?"
144
+ ThisWorkbook.Worksheets("データ収集").Range("A1").PasteSpecial
145
+ End Sub
146
+
147
+ 'SendInputを簡易化した関数
148
+ Sub prcSendInput(VkKey As Integer, UpDown As Integer)
149
+ With inputevents(0)
150
+ .dwType = INPUT_KEYBOARD
151
+ .ki.wVk = VkKey
152
+ .ki.wScan = 0
153
+ .ki.dwFlags = UpDown
154
+ .ki.time = 0
155
+ .ki.dwExtraInfo = 0
156
+ End With
157
+ SendInput 1, inputevents(0), Len(inputevents(0)) '配列に格納した1つの操作を実行
158
+ End Sub
159
+ ```
160
+
161
+ 追記② Excel上でセル範囲を図としてコピペする
162
+ ---
163
+ 「エラーの原因や回避策は後回しでいいから、とにかく目的が実現したいのだ!」
164
+ という状況なのかもしれないので、別方向からのアプローチも提案してみます。
165
+
166
+ 以下が参考にしたサイトですが、これは質問者さんの環境ではエラーとなったという`CopyPicture`メソッドの解説ページです。
167
+ [参考⇒セル範囲を画像としてコピーする(CopyPictureメソッド)|Excel VBA](https://www.moug.net/tech/exvba/0050118.html)
168
+
169
+ 上記の記事内に、以下のような記載があります。
170
+ >Excel 2007以降の[ホーム]タブ→[貼りつけ]→[図]→[図としてコピー]の機能、
171
+ >Excel 2003以前の[Shift]キーを押しながら[編集]メニューを選択した時に表示される[図のコピー]の機能と同じです。
172
+
173
+ これをマクロの記録でVBAコードにしてみましょう。
174
+
175
+ この操作を実際にシート上で行いそれを「マクロの記録」してみると、記録されたVBAでは`CopyPicture`メソッドは使用されていませんでした。(当方の環境Windows7/Office2010での結果です)
176
+
177
+ 記録されたのは、要約すると下記のようなコードでした。
178
+ ```
179
+ '対象範囲をコピー
180
+ Range("B51:L55").Copy
181
+ '貼り付け先を選択
182
+ Range("B1").Select
183
+ 'コピーしたセル範囲を「図として貼り付け」
184
+ ActiveSheet.Pictures.Paste.Select
185
+ ```
186
+ つまりセル範囲を普通にコピーして「図として貼り付け」ています。(そのままですね。)
187
+
188
+ 解決済みではありますが、まだ模索を続けられているようでしたらこちらも試してみてはいかがでしょうか。
189
+ 参考になれば幸いです。