自動翻訳によりレイアウトの一部が崩れます

生産スケジューラと生産計画のフレクシェ > サポート > 開発者向け情報 > Windows Script Componentsによるスクリプティング

Windows Script Componentsによるスクリプティング

Windows Script Components(以下、WSC)と呼ばれる技術(かつては「スクリプトレット」と呼ばれていました)を利用することにより、本格的な開発環境を利用することなく、テキストエディタだけで手軽にFLEXSCHEで利用するさまざまなCOMコンポーネント(アドイン、外部メソッド、外部ファンクション)を実装することができます。

WSC自体は技術的には様々なスクリプティング言語に対応できるようになっていますが、このセクションでは後述のFLEXSCHEスクリプト雛形生成ツールがサポートしているVBScriptとJScriptにだけ言及しています。WSCの知識を持たない開発者でもこのツールを利用すればまったく不自由なくスクリプティングを始められます。

なお、「スクリプト」「スクリプティング」という用語は、広義にはテキストファイルに記述されたコードをそのまま解釈・実行させることを、あるいはその言語体系を指しますが、ここではWSC内でのコーディング、あるいはさらに限定してFLEXSCHEスクリプト雛形生成ツールで生成した雛形をベースにしたFLEXSCHEのモデル操作を指す狭い意味で用いるものとします。

VBScriptとJScript

FLEXSCHEのWSCスクリプティングでの利用を想定しているスクリプティング言語はVBScriptJScriptです。これらのスクリプト言語には変数の型宣言がありません(データそのものには型があります)。

VBScriptはVisualBasicをベースとして設計されたスクリプト言語です。プログラミング言語のとしては設計にかなり癖がありますが、VisualBasicの開発者が多いことと、COMとの親和性のが高い(もともとCOM自体がVBでの利用を想定して設計されたという経緯があります)ことから、スクリプティングに適しているといえます。

JScriptは、もともとJavaの設計を参考にデザインされたHTML上のスクリプト言語であるJavaScriptのMicrosoft版バリエーションです。Javaの設計を継承してスクリプト言語としての設計は素直であることと、多くの開発者を擁しているところにアドバンテージがあります。ただし、COMとの親和性はそれほど高くないので、そのギャップを吸収する必要があります。WSCGenを利用すれば、生成される雛形にはそのための仕組みが組み込まれているため、このギャップをほとんど意識せずにすみます。

以下の表でVBScriptとJScriptを比較します。

  VBScript  JScript 
コード表記 
Function Foo(Arg1,Arg2)
  …
  Foo = [retval]
End Function

Sub Foo(Arg1,Arg2)
  …
End Sub
function Foo(arg1,arg2)
{
  …;
  return [retval];
}

function Foo(arg1,arg2)
{
  …;
}
メッセージ表示
MsgBox message 
alert(message);
代入
[variable] = [value]
set [var] = [object] 
[var] = [value or object];
   

特に、VBScriptで変数にオブジェクトを代入する場合は"set"文にしなくてはならないことに注意してください。

VBScriptの注意事項

if文中の条件式はすべて評価される

if分の中にand/or論理演算子で並べられた各項は、その前の項の評価結果の真偽にかかわらず、必ず評価されてしまいます。つまり、下の誤例のように1項目が真であることを前提とした項を2項目に書いてしまうとランタイムエラーが発生することになります。このような場合は、if文自体を多階層化しなくてはなりません。

 誤)
if opRec.IsBound and opRec.Frozen then
 …
end if 
 正)
if opRec.IsBound then
  if opRec.Frozen then
    …
  end if
end if
Functionは戻り値の受け取りの有無によって呼び出し方が異なる

Function呼び出しの戻り値を参照するかどうかによって、表記方法が異なります。以下が参照する場合の表記です。

v = Foo( 1, 2 )
if Foo( 1, 2 ) then …

次が参照しない場合です。

Foo 1, 2

ただし、引数が1個の場合は

Foo( 1)

としてもエラーにはなりません。これは"(1)"という式がFooの引数であるとみなされるためです。

ステートメントの途中での改行

コードの横方向の文字数を減らすためにステートメントの途中で改行する場合は、行末に"_"を入れなくてはなりません。さもないとステートメントが途切れているとみなされてエラーになります。

form.AddControl "btnAdd", "button:追加(&A)", _
  "align_right:listA/width"

JScriptの注意事項

ガベージコレクション対策

COMでのオブジェクト参照は参照カウント方式で管理されています。VBScriptではこの方式がそのまま実装されており、オブジェクトを参照する変数のスコープから抜けるとオブジェクト参照が解放されます。一方JScriptはガベージコレクション(Garbage Collection)方式が採用されているため、スコープを抜けるなどして見かけ上の参照が無くなった後でも、ガベージコレクションが実行されるまではオブジェクトへの参照が残ってしまいます。このことは、特にFLEXSCHEのProjectオブジェクへの参照が残っている状態ではプロジェクトを閉じることができないというトラブルの原因となってしまいます。これを回避するためには、一般に処理の最後(アドインの出口など)で

project = null;
CollectGarbage();

としてやる必要があります。

なお、WSCGenで生成されたJScriptの雛形では暗黙に確実な参照の解放を行っているため、このようなことを意識する必要はありません

日時(DATE)型の明示的変換

COMやVBScriptで利用している日時型(DATE型)と、JScriptのDateオブジェクトの間には互換性がありません。また、DATE型が単純な日時であるのに対し、Dateオブジェクトにはタイムゾーン情報が含まれており、相互運用のためにはそのための変換も必要となります。

SDLibモジュールのISDLUtilityインターフェースは、Dateオブジェクトから取得、あるいは設定できるミリセカンド値とDATE型の間の変換を行う次のメソッドを提供しています。ただしDATE値、ミリセカンド値にはそもそもタイムゾーン情報は含まれないので、タイムゾーンは意識していません。

ISDLUtility.TimeToMS( time )
ISDLUtility.TimeFromMS( ms )

また、WSCGenで生成された雛形内であれば、DATE型とDateオブジェクトの相互変換に次の関数を使うことができます。この場合はDateオブジェクトに含まれるタイムゾーン情報を加味されます。

VBDateFromJDate( jsdate )
VBDateToJDate( time )
存在しないプロパティの取得がエラーとして検出されない

<?components?>インストラクションのerror属性をtrueに設定(後述)しているにも関わらず、JScriptで存在しないプロパティを取得しよとしても(本来であれば指摘されるべき)エラーが指摘されないという問題がありますので、。

project.NotExistingMethod(); エラーが指摘される
project.NotExistingProperty = v; エラーが指摘される
v = project.NotExistingProperty; エラーが指摘されない

WSCの表記内容

FLEXSCHEのスクリプティングに際してWSCファイルに記述すべき要素について概観します。基本的にはFLEXSCHEスクリプト雛形生成ツール(WSCGen)が自動で生成するため、これらを意識すべき機会は実際にはほとんどないでしょう。WSCについてのさらに詳しい(あるいは一般的な)情報を必要とされる場合は以下のリンク先をご覧ください。

スクリプトコンポーネントチュートリアル(Microsoft社MSDNへのリンク)
componentsインストラクション

デバッグに関する設定をします。詳しくは下記をご覧ください。

registration要素

このWSCファイルが定義するCOMモジュールのprogID等の情報を設定します。

reference要素

外部のタイプライブラリを参照し、定数の名前空間を利用できるようにします。WSCGenが生成する雛形ではGUI(名前空間"FLEXSCHE")とCore(名前空間は"SData")が参照されます。

object要素

COMオブジェクトを予め生成して変数にバインドします。WSCGenが生成する雛形ではSDLib.Utilityのインスタンスが生成されて、変数"sdlutil"から利用できるようになっています。

public要素

COMインターフェースを通して公開されるメソッド、プロパティの情報が記述されます。WSCGen雛形ではSelfRegistrationおよびアドイン、外部メソッド、外部関数のエントリー関数とそのシグネチャが公開されます。

script要素

スクリプト本体を記述します。JScriptのためのWSCGen雛形では、いくつかの関数が暗黙に定義されています。

デバッグ

WSCのデバッグにはいくつかの方法があります。FLEXSCHEスクリプト雛形生成ツール(WSCGen)の利用を前提としたものについては、詳細はそちらも参照してください

エラー発生行によるデバッグ

スクリプト雛形生成時にWSCGenの「エラーメッセージ」チェックボックスにチェックするか、WSCファイルの<?components?>インストラクションのerror属性をtrueに設定すると、ランタイムエラーが発生したときに、行番号情報を含むエラーメッセージが表示されますので、行番号を表示できるテキストエディタを利用していれば、エラー発生位置を容易に特定できます。

メッセージボックスによるデバッグ

VBScriptであればMsgBoxステートメント、JScriptであればalert関数(これはJScriptではなく、WSCGenが提供しているものです)を使って、随所でメッセージボックスを表示することができます。ここに有用な情報を表示することで効率的にデバッグできます。

デバッガによるデバッグ

Micorosoft Visual Studioのスクリプトデバッグ機能やMicrosoft Officeなどに付属するスクリプトデバッガを利用すれば、挙動の怪しい箇所を集中的にトレース実行したり、値を参照することができます。この機能を有効にするためには、スクリプト雛形生成時にWSCGenの「デバッグ」チェックボックスにチェックするか、WSCファイルの<?components?>インストラクションのdebug属性をtrueに設定しておく必要があります。

VBScriptであればStop文を、JScriptであればdebugger文を適切な箇所に埋め込んでおけば、下のダイアログが表示されてデバッガを起動することができます。

なお、この設定をしてあるとエラー発生時にも上のダイアログが表示されてデバッガを起動することができますが、エラー発生後はエラー行の先に進むことはできないので、値を参照することはできてもそれ以上トレース実行を続けることはできません。