質問編集履歴

3

スクリプトファイルの指定時に相対パスが使えるようにSet-Locationを追加、複数のスクリプトファイルを読み込んだり出来る様にStdinの利用を追加、出力時の余分な文字列を削除する関数の追加

2018/08/10 11:03

投稿

kamikazelight
kamikazelight

スコア305

test CHANGED
File without changes
test CHANGED
@@ -58,7 +58,7 @@
58
58
 
59
59
  ```vba
60
60
 
61
- Function MyPowershell(ByVal ScriptName As String, ByVal FunctionName As String, Argument As String) As WshExec
61
+ Function MyPowershell(Optional ByVal ScriptName As String, Optional ByVal FunctionName As String, Optional Argument As String, Optional Exec As WshExec, Optional ByVal StdinClose As Boolean = True) As WshExec
62
62
 
63
63
  'Powershellスクリプトを実行してWshExecオブジェクトとして返す
64
64
 
@@ -66,14 +66,106 @@
66
66
 
67
67
  Dim Wsh As New WshShell
68
68
 
69
- Dim Exec As WshExec
70
-
71
- Set Exec = Wsh.Exec("powershell -NoLogo -ExecutionPolicy RemoteSigned -windowstyle hidden -command " & ". '" & ScriptName & "';" & FunctionName & " " & Argument)
72
-
73
- Set MyPowershell = Exec
69
+ If StdinClose And FunctionName <> "" And Exec Is Nothing Then
70
+
71
+ '処理一括実行
72
+
73
+ Dim Cmd As String
74
+
75
+ If ScriptName <> "" Then
76
+
77
+ Cmd = ". '" & ScriptName & "';"
78
+
79
+ End If
80
+
81
+ Set Exec = Wsh.Exec("powershell -NoLogo -ExecutionPolicy RemoteSigned -windowstyle hidden -command " & "Set-Location -Path('" & ThisWorkbook.Path & "');" & Cmd & FunctionName & " " & Argument)
82
+
83
+ Else
84
+
85
+ '処理随時実行
86
+
87
+ If Exec Is Nothing Then
88
+
89
+ Set Exec = Wsh.Exec("powershell -NoLogo -ExecutionPolicy RemoteSigned -windowstyle hidden")
90
+
91
+ End If
92
+
93
+ Call Exec.StdIn.WriteLine("Set-Location -Path('" & ThisWorkbook.Path & "')")
94
+
95
+ If ScriptName <> "" Then
96
+
97
+ Call Exec.StdIn.WriteLine(". '" & ScriptName & "'")
98
+
99
+ End If
100
+
101
+ If FunctionName <> "" Then
102
+
103
+ Call Exec.StdIn.WriteLine(FunctionName & " " & Argument)
104
+
105
+ Else
106
+
107
+ StdinClose = False
108
+
109
+ End If
110
+
111
+ If StdinClose Then
112
+
113
+ Exec.StdIn.Close
114
+
115
+ End If
116
+
117
+ End If
118
+
119
+ Set MyPowershell = Exec
74
120
 
75
121
  End Function
76
122
 
123
+
124
+
125
+ Function MyPowershellStdOut(ByVal Exec As WshExec) As String
126
+
127
+ 'Powershellの返値を余分な文字を削除して返す
128
+
129
+
130
+
131
+ '標準出力を受け取る
132
+
133
+ Dim Str As String
134
+
135
+ Str = Exec.StdOut.ReadAll
136
+
137
+
138
+
139
+ '除外対象の文字列の削除
140
+
141
+ Dim BefStr As String
142
+
143
+ Dim RegExp_ As New RegExp
144
+
145
+ RegExp_.Pattern = "PS .:\.+?\n"
146
+
147
+ Do
148
+
149
+ BefStr = Str
150
+
151
+ Str = RegExp_.Replace(BefStr, "")
152
+
153
+ Loop While (BefStr <> Str)
154
+
155
+ RegExp_.Pattern = "PS .:\.+?> $"
156
+
157
+ Str = RegExp_.Replace(BefStr, "")
158
+
159
+ BefStr = Str
160
+
161
+ RegExp_.Pattern = "\n$"
162
+
163
+ Str = RegExp_.Replace(BefStr, "")
164
+
165
+ MyPowershellStdOut = Str
166
+
167
+ End Function
168
+
77
169
  ```
78
170
 
79
171
 
@@ -100,9 +192,13 @@
100
192
 
101
193
  'LoopCountに設定されている数分同時実行を行う
102
194
 
103
-
195
+ 'Boundary の指定以上は随時実行に変更
104
-
196
+
197
+
198
+
105
- Const LoopCount As Long = 5
199
+ Const LoopCount As Long = 10
200
+
201
+ Const Boundary As Long = 5
106
202
 
107
203
 
108
204
 
@@ -114,27 +210,53 @@
114
210
 
115
211
  For i = 0 To LoopCount
116
212
 
213
+ If i <= Boundary Then
214
+
117
- Set Exec(i) = MyPowershell(ThisWorkbook.Path & "\t est.ps1", "test", """入力テスト" & i & "`r`n二行目の入力テスト""")
215
+ Set Exec(i) = MyPowershell(".\t est.ps1", "test", """入力テスト" & i & "`r`n二行目の入力テスト""")
216
+
217
+ Else
218
+
219
+ Set Exec(i) = MyPowershell(".\t est.ps1")
220
+
221
+ End If
118
222
 
119
223
  Next i
120
224
 
121
225
 
122
226
 
227
+ '追加の実行
228
+
229
+ Dim j As Long
230
+
231
+ For j = 0 To LoopCount
232
+
233
+ If j > Boundary Then
234
+
235
+ Set Exec(j) = MyPowershell(, "test", """入力テスト" & j & "`r`n二行目の入力テスト""", Exec(j))
236
+
237
+ End If
238
+
239
+
240
+
241
+ Next j
242
+
243
+
244
+
123
245
  '結果の取得
124
246
 
125
- Dim j As Long
126
-
127
247
  Dim Str() As String
128
248
 
249
+ Dim k As Long
250
+
129
251
  ReDim Str(LoopCount)
130
252
 
131
- For j = 0 To LoopCount
253
+ For k = 0 To LoopCount
132
-
254
+
133
- Str(j) = Exec(j).StdOut.ReadAll
255
+ Str(k) = MyPowershellStdOut(Exec(k))
134
-
256
+
135
- Next j
257
+ Next k
136
-
137
-
258
+
259
+
138
260
 
139
261
  '結果の表示
140
262
 

2

タイトルの修正

2018/08/10 11:03

投稿

kamikazelight
kamikazelight

スコア305

test CHANGED
@@ -1 +1 @@
1
- VBAから完全非表示、非同期でPowershellスクリプト引数付で実行して、尚且つ 返値を受け取りたい
1
+ VBAからPowershellスクリプトを完全非表示、非同期、引数付で実行して、尚且つ 返値を受け取りたい
test CHANGED
File without changes

1

Sub test()にてMyPowershell実行時最終の引数の指定が間違っていたため修正

2018/08/10 07:34

投稿

kamikazelight
kamikazelight

スコア305

test CHANGED
File without changes
test CHANGED
@@ -114,7 +114,7 @@
114
114
 
115
115
  For i = 0 To LoopCount
116
116
 
117
- Set Exec(i) = MyPowershell(ThisWorkbook.Path & "\t est.ps1", "test", """入力テスト" & i & " `r`n二行目の入力テスト""")
117
+ Set Exec(i) = MyPowershell(ThisWorkbook.Path & "\t est.ps1", "test", """入力テスト" & i & "`r`n二行目の入力テスト""")
118
118
 
119
119
  Next i
120
120