2016-02-16
ExcelVBA覚書 Shellとかリモート実行とか
忘れる前にメモっとく。
VBAからコマンド実行を非同期で行う時に使うShell関数。
第2引数にvbMinimizedNoFocusを設定すると、コマンドプロンプトは非表示になって、裏側で走る仕組みにできるそうな。
Dim cmd_buf As String Dim res As Double cmd_buf = "cmd /c sqlcmd -S {DB-Source} -U {DB-UserId} -P {DB-UserPw} -d {DB-Name} " _ & " -Q ""EXEC {プロシージャ名} {*}, '{*}' """ res = Shell(cmd_buf, vbMinimizedNoFocus)
{}書きは環境に合わせて変更
{*}はストアドの引数で、文字列の場合はシングルクォーテーションで囲む。
Shellの戻り値はタスクIDで、「0」がかえってきたら動いていないということらしい。
非同期なので勝手に動いて、勝手に終わる。
終わったらウィンドウをアクティブにするとかすると、終わったことがわかるらしい。
If res > 0 Then Call AppActivate(res)
と、こんな感じかね。
ふむふむ、しかしだね、裏側で勝手に動いているわけで、下手にPCシャットダウンしちゃうと、処理が途中で終わっちゃう!ってところが怖い。
で、次。
リモート環境にあるバッチファイルを実行する方法。
'server:リモートサーバ(user_id/user_pwでログイン) 'exe_name:実行ファイル, exe_position:実行ファイルのパス Public Function ExecuteRemoteExe(server As String, user_id As String, user_pw As String _ , exe_name As String, exe_position As String) As Boolean Const AUTHENTICATION_LEVEL_PKT_PRIVACY = 6 Dim obj_locator As Object Dim obj_server As Object Dim obj_process As Object Dim res As Long Dim pid As Long On Error GoTo ErrExecute Set obj_locator = CreateObject("WbemScripting.SWbemLocator") Set obj_server = obj_locator.ConnectServer(server, "root\cimv2", user_id, user_pw) obj_server.Security_.authenticationLevel = AUTHENTICATION_LEVEL_PKT_PRIVACY Set obj_process = server.get("Win32_Process") res = obj_process.Create(exe_position, Null, Null, pid) Select Case res Case 0 ExecuteRemoteExe = True Case 2 Msgbox "アクセスできませんでした。" Case 9 Msgbox "パスが正しくありません。" Case 21 Msgbox "パラメータが正しくありません。" Case Else Msgbox "バッチを実行できませんでした。" End Select ErrExecute: Set obj_process = Nothing Set obj_server = Nothing Set obj_locator = Nothing End Function
これでリモートのバッチファイルを実行することができる。
できるんだけど、これもこっち側のPCを切ってしまうと、バッチも終わってしまう・・・
なんとかならんか。