近頃、ツール作りの依頼が増えている。フリーであるものもあるが、商用利用はダメ、とか制限のあるものもある。やむなく自作することが増えている。
・該当するWindowsサーバーの環境調査(HotFixの適用具合やサービスパック、OSやプロセッサの情報などを引き抜く)ツール
・導入したシステムの環境調査ツール
・移行元のシステムから移行先のシステムへのほぼ自動移行ツール

なるだけ小回りが利くよう、PowerShellやExcel、Accessでの依頼が多い。

そういう中で、XMLをわんさか使うものがある。複数あるXMLを縦断的にチェックし、一覧表を作る、などだ。その元ネタ管理をAccessでさせるとどうかなと思ったが、XMLの情報をRDBの各項目に入れていく、というのもできなくはないが、やりたくない。そんなこと考えるのもアホらしくなってきたので「じゃあ、XMLをmemo型に突っ込んでおき、操作はパーサー使えばいいんじゃ?」と思いついた。Accessでの簡易にXMLハイブリッドDBを作るには、これがいいのかも。
memo型のバグがいくらかあるようだが、これで解決するならさせておこう。diffのツールなんかも併せて組み込めればいいのだが、と思いつつ、それはまた今度にする。

ExcelのShell関数を使い、処理が終わるまで待たせることができるのは先日書いたが、そうすると前の処理が終了してから次の処理を流す、ということも可能になる。対象はShellで呼び出せるものならいいので、DosコマンドでもPowerShellでも、実行形式のプログラムでもよいだろう。
そうすると、簡易的なジョブスケジューラーも作れてしまうのではないか。それもたいしたコードでなくてもいい。また、パラレルで動いていいものはパラレルで動作させることができるよう、スケジュールの記述を工夫すればよい。

ただ、問題がある。大型汎用機でのバッチ処理では、プログラム言語ではなくOSがエラーを返す。正常終了したか否かはプログラムに記載せずとも、ちゃんとジョブを呼ぶ側へ正常終了、ワーニング、エラーなどのステータスを返却してくれていたし、予定していた資源よりも多く使おうとしていたらそれも記録されるようになっていた。
オープン系ではそれをどうすればいいのだろう?プログラムではそれなりのコードを返すことはできる。しかし、ExcelのShell関数ではその取得は望めない。WaitForSingleObjectならどうだろうと調べると、なんかできるかもしれなさそうだ。
http://msdn.microsoft.com/ja-jp/library/cc429427.aspx

Excelを使う必要があるかというとないが、まあ、Jobを登録したり、状態をシート上で監視できるってことでどうだろう。そもそもサーバーにはOffice製品を入れないこともあるのでどうなんだか・・。


しかしながら、もしかするとプログラム側でも何か意識しておかないといけないかもしれないが、これで大型汎用機でのバッチ処理もどきができるかもしれない。本格的にやろうとするとジョブ監視プログラムも作成した方がいいのだろうけれど、・・。

PowerShellで変なツールをいくつか作っているので、それと組み合わせて試してみようと思う。
Windowsのサーバーの管理に、PowerShellが便利らしい。

過去にもくるーずさんのブログでインスパイアされ、いじったことがあったが、今回は折角なのでVBAからの呼び出しをしてみよう、と調べてみた。
どうやらVBAで参照設定をしてPowerShellを呼び出すようなことはできないらしい。ということで、shell関数で呼べばいいや、と試してみた。

もちろん、前提条件がある。
・powershellがインストールされていること
・powershellの実行ファイルにパスが 通っていること

で、

Call Shell("powershell c:\test.ps1" ,vbMinimaizedFocus ) などと書けば動いてくれ、ない。

実はpowershellには安全のため実行モードがある。デフォルトでは外部ファイルを実行することはできない。デジタル署名付きでないとダメとか、モードはいろいろあるが、次のようにしてみた。

Call Shell("powershell Set-ExecutionPolicy RemoteSigned -Force" ,vbMinimaizedFocus ) ' 実行を許可
Call Shell("powershell c:\test.ps1" ,vbMinimaizedFocus ) 'さっきの
Call Shell("powershell Set-ExecutionPolicy Ristricted -Force" ,vbMinimaizedFocus ) ' 再び実行を禁止

さて、実行するが、これもタイミングによっては動かない。なぜなら、Shellで起動するタスクは非同期だから

こういうときは、同期処理にしてしまうのがいい。
参考:http://www.geocities.co.jp/siliconvalley/4805/vbtips/vbtips053.htm


この中の Shell使用 をカスタマイズし、ひとつひとつの処理が順番に流れていくように変更したらバッチリであった。

そのあたりのソースはまた今度。