2017年2月14日火曜日

VBScriptではClass_Terminateが利用できる。。

でも私の大好きなJScriptでは利用できないようです。悲しい。MSからエコヒイキされているVBScriptが羨ましくてたまらない。

Class_Terminateとは、クラスが解放される時に発生するイベントです。
以下のソースを実行すると、二つのExcelが起動して、VBScriptから起動された方のExcelだけが、スクリプト終了時にQuitされます。



<job>
<script language=VBScript>
Class vbClass
Dim excel, bk
Private Sub Class_Initialize
MsgBox("Initializeします")
set excel = CreateObject("Excel.Application")
excel.Visible = true
set bk = excel.Workbooks.Add
bk.Sheets(1).Cells(1,1).Value = "VBScript"
End Sub
Private Sub Class_Terminate
MsgBox("Terminateします")
excel.Quit
End Sub
End Class
set x = New vbClass
</script>
<script language=JScript>
myClass = function(){
var excel = new ActiveXObject('Excel.Application')
excel.Visible = true
excel.Workbooks.Add().Sheets(1).Cells(1,1).Value = 'JScript'
var Class_Terminate = function(){ excel.Quit() }
}
c = new myClass()
// わざとエラー(aというオブジェクトは宣言していないのにa.bを参照)を発生させる
a.b = 1
</script>
</job>


VBScript側は明示的にClass_Terminateをcallしていませんが、script終了直前にクラスが解放されてTerminateイベントが発生し、callされています。「VBScript」の文字を追加しているので終了前に保存するか確認ダイアログが表示されます。


JScriptの方はそんなことは起きないのでJScript側から起動されたExcelには何も変化がありません。


これでどんな良いことがあるかと言うと、例えば上記サンプルではExcel.Visible = trueにしているのでスクリプトが終了しているのにExcelが残っていても手動で終了させれば良いのですが、Visible = falseのままコントロールして、後始末を忘れるか何かしらのエラーによりQuitせずにスクリプトが終了すると不可視状態のExcelプロセスが知らぬ間に溜まっていく状況になってしまいますが、Terminateイベント発生時にExcel.Quitするようにしておけば、そのような状況を回避できます。


VBScriptのTerminateイベントだけを利用するために、JScript側で「c = new vbClass()」とかやってみましたが、言語をまたいでクラス定義を利用することはできないようで、インスタンス作成の段階でエラーになりました。。

0 件のコメント:

コメントを投稿