Tivoli Service Desk 6.0 Developer's Toolkit Script プログラミングの手引き
この章では、Developer's Toolkit でもっともよく使用されるデータ・タイプを紹介します。 データ・タイプ自体の説明に加えて、定数、変数、および式についての情報もあります。
データ・タイプは、変数または定数に含まれるデータのプロパティーを定義します。 使用できるプロパティーには次のものがあります。
Developer's Toolkit には、6 つの単純なデータ・タイプがあります。
ハンドルは、別の変数のアドレスを含む変数です。アドレスは、変数の位置です。ハンドルによって、プログラムは特定のリソースにアクセスすることができます。
ハンドル・タイプは、特定の用途をもち、他のタイプからは派生しません。 開発者は、ハンドルを使用して、操作が実行される論理エンティティーを識別します。以下にハンドル・タイプをリストします。
外部パラメーター・タイプは、単純タイプの注釈付きバージョンであり、Developer's Toolkit のインタープリターが外部 DLL を呼び出す前に Developer's Toolkit の値を正しい C または Pascal タイプに変換する時に役立ちます。
3 つの集合タイプは、独立型とすることはできませんが、ユーザー定義タイプを作成するために他のどのようなタイプとも一緒に使用することができます。
定数 とは、プログラムの実行中に変更されないままとなるアイテムまたは定数のことです 定数の宣言はすべて、知識ベースの CONSTANTS セクションで行われます。
知識ベースで定数を宣言するには、次のことを行わなければなりません。
定数宣言は、すべての Developer's Toolkit ステートメントと同様に、常にセミコロン (;) で終わります。
次の例では、各種のデータ・タイプを使用した定数宣言の例をいくつか示します。
CONSTANTS (* string constants *) fileName IS 'MYFILE.DAT'; pathName IS 'EADVISOR\ADVISOR\DATA'; driveName IS 'E:';
(* integer constants *) MAX_EMPLOYEES IS 500; ERROR_CODE IS -1;
(* real constants *) PI_VALUE IS 3.14159; MAX_SALARY IS 999999.99; LO_VALUE IS -5134.1348;
(* Boolean constants *) SAVE_TO_DISK IS TRUE; OVERWRITE_FILE IS FALSE;
(* date constants *) CHRISTMAS IS {12,25,1996}: DATE; BIRTH_DAY IS {2,13,1956}: DATE;
(* time constants *) START_OF_DAY IS {8,30,0}: TIME; END_OF_DAY IS {18,0,0}: TIME;
注: 国際ユーザーは、Developer's Toolkit の初期化での日付の「部分」の順序が (月、日、年) であり、地域で変わることがないということに注意しなければなりません。
変数は、プログラムの実行中に変わることがあるデータ・タイプを含む名前付きアイテムです。変数は、知識ベースの VARIABLES セクションで宣言されます。
知識ベースで変数を宣言するには、次のことを行わなければなりません。
次の例に示すように、変数名をコンマで区切ることによって、同じタイプの複数の変数を宣言することができます。
VARIABLES first_name, last_name : STRING; i,j : INTEGER; salary : REAL; married : BOOLEAN; entryDate : DATE; startTime : TIME;
代入演算子 (:=) で変数に値を割り当てます。
次のコードの断片は、先の例で定義された変数のいくつかの変数割り当てを示したものです。
first_name := 'Amy'; last_name := 'Alec'; i := 7; j := 32; salary := 37500.00; married := FALSE; entryDate := {1,31,1991}: DATE; startTime := {10,30,0}: TIME;
データ・タイプの変換が必要になることがあるかもしれません。データ変換 は、情報の表現方法に変更がある時に行われます たとえば、2 進数表現を 10 進数または 16 進数表現に、あるいは整数をストリングに変更することができます。
Developer's Toolkit は、変換される値を示すために中括弧 {} を使用します。
次の例では、中括弧の内側の値が整数に変換されます。
i := {s}: INTEGER;
Developer's Toolkit は、この行に至ると、次のことを行います。
値を変換しても、元の値は破棄されません。
次はデータ変換のもっと複雑な例であり、Developer's Toolkit が指定された 2 つの日付間の日数をどのように計算するかを示したものです。
d1 := {1,1,1990}: DATE; d2 := $Today; daysBetween = {d2}: INTEGER - {d1}: INTEGER;
これを行うために、Developer's Toolkit は、{d1} および {d2} に保管されている日付値を使用し、それを年間通算日の値に変換し、これらの値で減算します。
この例は、{d1} と {d2} が日付変数であり、変数 daysBetween が整数であることを前提としています。
Developer's Toolkit は、極度にタイプに依存した言語です。これは、1 つのタイプの変数を別のタイプの変数に割り当てると、エラーが起こるということを意味します。
たとえば、entryDate が日付変数で、startTime が時刻変数であるとした場合には、次のように割り当てると、実行時エラーが生成されます。
entryDate := startTime;
Developer's Toolkit は、整数および実数を自動的に変換します。たとえば、変数 i が整数であると想定した場合には、以下のステートメントでは次のようになります。
i := 37.0;
値 37 は、明示のタイプ変換を必要とせずに i 変数に割り当てられます。
同様に r が実数である場合には、以下のステートメントでは次のようになります。
r := i;
値 37.0 が r 変数に割り当てられます。
混合式は、正確度を保つために割り当てが行われるまで、実数として扱われます。
さらに、Developer's Toolkit は、必要な時には、すべてのデータ・タイプを自動的にストリングに変換します。 たとえば、ステートメントが次のようなものであったとします。
s := i;
これは、s 変数にストリング値 37 を割り当てます。
Developer's Toolkit でのストリングとは、単一引用符で囲まれた文字列のことです。 Developer's Toolkit は、次の操作を可能にするストリング処理演算子およびステートメントを提供します。
ストリングの演算子およびステートメントは、次のリストで要約しています。
s1 := 'F:\CODE'; s2 := 'PROGRAM.EXE'; s3 := s1 & '\' & s2;
この例では、s3 変数にはストリング F:\CODE\PROGRAM.EXE が入っています。 s1 と s2 の変数は、決して変更されることはなく、その元の値を保ちます。アンパーサンドを使用して、定数、変数、または式をいくつでも結合して、新しいストリングを作ることができます。またアンパーサンドは、連結を行う前に自動的に非ストリング値をストリングに変換します。以下はその例です。
s1 := 'The date is ' & $Today & 'and the time is ' & $Now;
この例では、Developer's Toolkit の定数 $Today (システム日付) および $Now (システム時刻) は、連結のために自動的にストリング形式に変換されます。
s := 'LIB(ase) FILE(qrpgsrc); s := StrUpper(s); (* now s = 'LIB(ASE) FILE(QRPGSRC) *)
注: 国際ユーザーの場合、Developer's Toolkit は、現在地域の適切な大文字化規則に従います。たとえば、"eclair" は、フランスおよびカナダのフランス語圏では "ECLAIR" になります。
s := 'LIB(ase) FILE(qrpgsrc); s := StrLower(s); (* now s = 'lib(ase) file(qrpgsrc) *)
注: 国際ユーザーの場合、Developer's Toolkit は、ワークステーションの現在所在地の適切なケース規則に従います。
~ 新規ストリングが挿入されるストリング変数
~ 挿入されるストリング
~ 新規ストリングが挿入されるストリング・パラメーター中の指標
例:
s := StrInsert('LIB(ASE) MBR(MYPROG)', 'FILE(QRPGSRC) ',10); (* now s = 'LIB(ASE) FILE(QRPGSRC) MBR(MYPROG) *)
注: 複数の地域のためにコードを書く国際ユーザーは、各種の断片および部分から文を「組み立て」ないようにしなければなりません。文がこのようにして組み立てられると、多くの言語で存在する性および性一致が破棄されます。
~ ストリング・パラメーターの名前
~ 開始指標
~ 削除される文字数
例:
s := StrDelete('LIB(ASE) FILE(QRPGSRC) MBR(MYPROG)',10,14); (* now s = 'LIB(ASE) MBR(MYPROG)' *)
~ ソース・ストリングの名前
~ ソース・ストリング内の開始指標
~ コピーされる文字数
例:
fileName := 'LIB(ASE) FILE(QRPGSRC) MBR(MYPROG)'; s := StrCopy(fileName,15,7); (* now S = 'QRPGSRC' *)
注: StrPos 検索では大文字小文字の区別はありません。C および他の一部のプログラム言語では、最初の位置は常に 0 ではなく 1 で指標付けされます。
2 番目のストリングを見つけることができない場合には、"0" の値が戻されます。以下はその例です。
company := 'Tivoli Systems'; loc := StrPos(company, 'Sys'); (*loc = 8*)
このコードが実行された後では、loc 変数に値の 8 が入ります。
例:
IF StrMatch(s,'*.BAK') THEN FErase(s); END;
Developer's Toolkit には、StrToken (破壊的ストリング・トークナイザー)、StrTrim、StrLTrim、および StrLength を含む他のストリング処理が組み込まれています。
次の表に要約しているように、Developer's Toolkit は、算術式および算術演算子をサポートします。
演算子 説明 + 2 つの数式を加算します (i:=3+5) - 別の数式から 1 つの数式を減算します (r:=3.7-2.0) * 2 つの数式を乗算します (i:=3.0*6) / 2 つの数式を除算します (r:=3.0/4.0) MOD 1 つの整数を別の整数で除算する時に余りを計算します (6 MOD 4=2)
これらの演算子に加えて、Developer's Toolkit は次の関数をサポートします。
三角関数 | 対数関数 | 指数 |
Sin | Log | Exp |
Cos | Ln | Power |
Tan | Sqrt | 適用されません |
ACos | 適用されません | 適用されません |
ASin | 適用されません | 適用されません |
ATan | 適用されません | 適用されません |
CosH | 適用されません | 適用されません |
SinH | 適用されません | 適用されません |
TanH | 適用されません | 適用されません |
次のように論理演算子の AND、OR、および NOT を使用して、複合ブール式を作成することができます。
b := (i > 0) AND (j = 0);
Developer's Toolkit は、短絡ブール評価を実行します。この形式の評価は、ブール式がその値の判別を必要とする限りにおいてのみ評価されることを保証します。
上記の例では、i が 0 である場合には、j が評価される前に、b 変数が FALSE の値と見なされます。ルールは次の通りです。
Developer's Toolkit は、ブール式で使用するために次の関係演算子を提供しています。
演算子 | 説明 |
< | より小 |
<= | より小か等しい |
> | より大 |
>= | より大か等しい |
= | 等しい |
<> | 等しくない |
注: 上にリストされた関係演算子は、2 つのストリングを比較する時には、大文字小文字を区別しません。これは、次の式は True であるということを意味します。
'F:\MYFILE' = 'f:\myfile'
次の演算子は、大文字小文字を区別する大文字小文字を区別するストリング比較で使用されるようになっています。
演算子 | 説明 |
<< | より小 |
<<== | より小か等しい |
>> | より大 |
>>== | より大か等しい |
== | 等しい |
<<>> | 等しくない |
例については、このページの注を参照してください。
単純なデータ・タイプと考えられますが、日付値は、月、日、および年の値を入手できる目に見えない構造を使用します。次の例に示すようにドット表記を使用してください。
dayValue := $Today.day; monthValue := $Today.month; yearValue := $Today.year; (* $Today is the system date*)
示しているように、日付式は、後にピリオドおよび日付の対応する値にアクセスするキーワード (day、month、または year) の 1 つを続けることができます。先の例では、 dayValue、monthValue、および yearValue は整数変数です。
ここで見るように、日付変数の月、日、または年の値を変更することができます。
d := $Today; d.year := d.year + 1;
上の例では、日付変数 d は現在のシステム日付値に割り当てられています。次に d の年は 1 ずつ増えます。
Developer's Toolkit は、無効日付からユーザーを保護します。次の例では、日付変数は、 "2/1/1999" の値を使用します ("1/32/1999" ではありません)。
d := {1,31,1999}: DATE; d.day := d.day + 1;
Developer's Toolkit は、2 つの日付の間の月、日、または年による差を計算するために、 DateDif 関数を提供しています。
DateDif は、3 つの引き数を必要とします。
例:
age := DateDif($Today,birthDate,$Years);
Developer's Toolkit は、時刻式を処理できるようにする幾つかの機能を提供しています。日付と同様に、時刻は時、分、および秒という複数の値を含みます。
時刻値の異なる部分にアクセスするのにドット表記を使用することができます (日付でも使用可能です)。
currentHour := $Now.hour; currentMinute := $Now.minute; currentSecond := $Now.second; (* $Now is the system time*)
時刻変数の特定部分を変更することもできます。
t := $Now; t.hour := t.hour + 3;
時刻変数 t には、現在時刻から 3 時間後の時刻が入っています。 時刻値は、真夜中に対処する内部 24 時間形式をもっています。次の例の結果は、{1,0,0}:TIME または 1 A.M.という値を含む t です。
t := {23,0,0}: TIME; t.hour := t.hour + 2;
Developer's Toolkit は、2 つの時刻の間の差を計算する TimeDif 関数を提供しています。次の例では、現在時刻と前の startTime との間の差が時分秒で計算されます。
hoursDiff := TimeDif($Now,startTime,$Hours); minutesDiff := TimeDif($Now,startTime,$Minutes); secondsDiff := TimeDif($Now,startTime,$Seconds);
配列は、同じデータ・タイプのデータ値のリストです。これは、構造化 データ・タイプでもあります。構造化データ・タイプによって、データに対して特定操作を実行することができます。
配列中のどの単一要素 (データ値) は、配列の名前とそれに続く指標式から構成される式によって参照することができます。配列中の要素は、1 から始まる順次的なものです。特定要素にアクセスするには、値 (すなわち指標) が使用されます。
次の例では、各指標は、大括弧で囲まれています。
VARIABLES name[10]: ARRAY OF String; ACTIONS name[1] := 'Tom'; name[2] := 'Dick'; name[3] := 'Harry';
この例では、name は、ストリングの配列です。name 変数は、1 - 10 の番号を付けられた要素中に最大 10 個の値を収めることができます。
配列は、一般的に変数によってアクセスされます。次の例は、name 配列の 10 個すべての値をファイルに書き込むことによって、一定の配列要素にアクセスするために整数変数がどのように使用されるかを示したものです。
FOR i := 1 TO 10 DO FWriteLN(outputFile,name[i]); END;
配列の定義された限界の外側の配列要素にアクセスしようとすると、実行時エラー・メッセージが現れます。エラーは、次のステートメントの両方によって生成されます。
name[-1] := 'Dick'; name[45] := 'Harry';
ストリング値は、文字配列として扱うことができます。次のコード例の終わりでは、 s 変数は値 G:\EADVISOR\ADVISOR\DATA をもちます。
VARIABLES s : STRING; ACTIONS s := 'F:\EADVISOR\ADVISOR\DATA'; s[1] := 'G';
Developer's Toolkit の配列は、動的にサイズ変更が可能です。すなわち、実行時に配列のサイズを変更することができます。配列のサイズを変更するには、Developer's Toolkit ステートメント SetArrayLength が使用されます。以下はその例です。
SetArrayLength(name,100);
この場合、前に宣言された 10 スロットの配列に 90 個の新規要素が追加されます。最初の 10 個のスロット中の情報は、どれも影響を受けません。次の例で示しているように、配列のサイズを減らすこともできます。
SetArrayLength(name,5);
この場合には、スロット 6 - 10 の値はすべて失われることになります。
配列と同様に Developer's Toolkit リストは、同じタイプの複数の値を含むことができる構造化データ・タイプです。リストは、大括弧で囲んだ整数によって指標付けすることもできます。
Developer's Toolkit では、完全なリンクされたリスト構造を作成するのに、アドレス、メモリー割り振り、またはメモリー割り振り解除を必要としません。リストは、配列より簡単にサイズ設定することができます。また、リストの途中に新規値を挿入することができます。これは、配列では厄介な処理です。
次の例は、リストの宣言および使用方法を示したものです。
VARIABLES name: List of String; ACTIONS ListInsert(name,'Tom'); ListInsert(name,'Dick'); ListInsert(name,'Harry');
このコード例の結論では、name は、'Tom'、'Dick'、および 'Harry' という 3 つの値を含むリストです。
すべてのリストでは、リスト中の現在の要素を示すポインターが維持されます。これは、リスト・ポインターと呼ばれています。リストに新規要素が挿入されると、リスト・ポインターが新しく挿入された要素を示します。前の例の終わりでは、現行ポインターは、'Harry' を示します。
次の例は、先のリストの途中に新規要素を挿入する方法を示したものです。
ListSetPos(name,1); ListInsert(name,'Ellen');
ここで Name には 'Tom'、'Ellen'、'Dick'、および 'Harry' という 4 つの値が含まれます。
注: 'Ellen' は、$ListInsert がデフォルトの $After であるので、2 番目の位置にあります。リスト・ポインターは 'Ellen' を示します。ListSetPos は、リスト・ポインターを指定の要素に移動します。
Developer's Toolkit は、リストを処理できるようにする他の多くの関数を提供しています。
関数 | 説明 |
ListDelete | リストから要素を除去します。 (ListDelete(name,2) では、前の例から 'Ellen' が除去されます。) |
ListLength | リスト中の要素の数を戻します。 |
ListNext | ポインターをリスト中の次の要素に移動します。 |
ListPrev | ポインターをリスト中の前の要素に移動します。 |
ListPos | 現行要素の指標を戻します。 |
ListFind | リストから指定の値をスキャンし、その値が見つかると、 TRUE を戻します。リスト・ポインターは、一致する値に移動します。たとえば、 ListFind(name,'Dick') は、TRUE を戻し、現行ポインターを 'Dick' に移動します。 |
ListSort | リストを昇順にソートします。 |
ListPush | リストの前面に新規要素を追加します。 |
ListPop | リスト中の最初の要素を除去して、戻します。 |
リストは配列と同様に指標付けが可能なので、以下のステートメントでは次のことが行われます。
s:= name[1];
これは、s 変数に値 'Tom' を割り当てます。
Developer's Toolkit は、リストの特殊なループ構造を提供しています。 FOR ステートメントは、リスト中の値を反復するために使用されます。 FOR...END でネストされたステートメントは、リスト中の各要素に対して 1 回実行されます。リスト・ポインターは、常にリスト中の最初の番号を示します。リスト中の現在アイテムは、ループを通るごとに 1 ずつ増えます。
次の例は、FOR ステートメントの使い方を示したものです。
FOR name DO FWriteLN(outputFile,name[$Current]); END;
前の例では、$Current と呼ばれる特殊な定数の使用法も示されています。この定数は、リストの現行要素にアクセスするために使用することができます。他のリスト定数には、次のものがあります。
これらの定数は、それぞれリストの最初と最後の要素にアクセスするために使用されます。 たとえば、行は次のようになります。
FWriteLN(outputFile,name[$First]); FWriteLN(outputFile,name[$Last]);
この場合、"Tom" と "Harry" が出力ファイルに書き込まれます。
Developer's Toolkit の多くのステートメントは、自動リスト・「チャンク」をサポートします。リスト・チャンクでは、ステートメントは、一定タイプの単一のアイテムかアイテムのリストのいずれかを受け入れます。
リストを渡すと、ステートメントがリスト中のすべての要素に適用されます。これは、暗黙の FOR ループをもつステートメントとしても参照されます。
WinWriteLN は、こうした 1 つのステートメントの例です。
WinWriteLN(myWindow,name);
このステートメントでは、変数 name のすべての値が myWindow と呼ばれるウィンドウに書き込まれます。Window ステートメントおよび SQL ステートメントの幾つかはリスト・チャンクをサポートしています。
配列およびリストは同じタイプの複数の値を収めることができますが、これとは異なり、レコードは異なるタイプの複数の値を収めることができます。
レコード・タイプ変数の宣言は、次の 2 つのステップからなる処理です。
注: レコード・タイプ変数を宣言する時には、Developer's Toolkit 言語を独自のデータ・タイプで拡張しています。
次のコード例を調べてください。
TYPES EmployeeRecord IS RECORD first_name, last_name: String; age : Integer; salary : Real; married : Boolean; hireDate : Date; startTime, stopTime : Time; END; VARIABLES employee: EmployeeRecord;
上の例では、EmployeeRecord と呼ばれる新規レコード・タイプを宣言しています。このレコードには、8 つのフィールドがあり、それぞれは単純なデータ・タイプです。
日付と時刻の場合のように、<variable>.<field> (ドット付き) 表記を使用して、レコード中のどのフィールドでも参照することができます。
たとえば、次の行を使用して、前に宣言された employee 変数を初期化することができます。
employee.first_name := 'Calbert'; employee.last_name := 'Chaney'; employee.age := 21; employee.salary := 2500000.0; employee.married := FALSE; employee.hireDate := {2,15,1993}: DATE; employee.startTime := {8,30,0}: TIME; employee.stopTime := {17,30,0}: TIME;
同じレコード・タイプの変数には割り当てに互換性があります。タイプ EmployeeRecord の変数 employee2 を宣言した場合には、次のステートメントを追加すると、employee 変数のすべてのフィールドが employee2 変数にコピーされることになります。
employee2 := employee;
レコードのリストおよび配列を作成することもできます。
employeeList: List Of EmployeeRecord;
レコード宣言にはリスト、配列、および他のレコードを含めることができます。たとえば、 EmployeeRecord 宣言は、次のようにして更新することができます。
EmployeeRecord IS RECORD first_name, last_name: String; age : Integer; salary : Real; married : Boolean; hireDate : Date; startTime, stopTime : Time; manages : List of String; END;
manages 値は、一定の従業員によって管理される従業員の名前を記録するために使用することができます。
Developer's Toolkit は、データベース・レコードの入力および出力を実行する幾つかのステートメントを提供します。
たとえば、次のステートメントは、前に宣言された employee 変数に EMPLOYEES テーブルからの行をロードするために使用することができます。
SQLSelectInto('SELECT * FROM EMPLOYEES WHERE EMPLOYEE_ID=105',employee);
Developer's Toolkit:
同様に、Developer's Toolkit によって、レコード中のフィールドをフォームにマップすることができます。フォームを完成させた後でユーザーが実行キーを押すと、レコード中で検査と処理が可能な対応するフィールドに画面上の情報がコピーされます。
レコードに加えて、ユーザー定義タイプを作成することができます。 ユーザー定義タイプは、プログラムに定義され、通常はデータ・タイプの組み合わせからなるデータ・タイプです。ユーザー定義タイプは、データ構造を作成するのによく使用されます。
変数宣言で使用するリスト、配列、レコード、および単純データ・タイプをどのように組み合わせても、データ・タイプ宣言で再使用可能な名前をその組み合わせに与えることができます。たとえば、次の例で示しているように、新規データ・タイプを定義することができます。
TYPES StringList = LIST OF STRING;
いったん宣言すると、LIST OF STRING の代わりに StringList を使用して変数を宣言することができます。
次のルールは、ユーザー定義データ・タイプと構造化データ・タイプの割り当て互換性を示したものです。
2 つの変数または式の間の割り当て互換性を検査する時には、Developer's Toolkit は、タイプ名が一致するかどうかを調べるだけです。レコード宣言が同一であるかどうかは、検査しません。
宣言された変数を初期化するということは、変数に初期値が割り当てられたということを意味します。次の例で示しているように、Developer's Toolkit によって、変数を宣言時に初期化することができます。
VARIABLES i {1} : INTEGER; s {'F:\MYFILE'} : STRING; d {2,11,1956} : DATE; l {'Tom','Dick','Harry'} : LIST OF STRING; r {'Steve','Wantz',32,189000.00,TRUE, {3,30,1986} : DATE, {6,30,0} : TIME, {4,30,0} : TIME, {'Tom','Dick','Harry'} : LIST OF STRING : EmployeeRecord;
一般には、変数名の後には次のものが続きます。
リスト、配列、レコードなどの構造化タイプの変数も同様にして初期化することができます。
初期値はタイプではなく、変数に関連しているということに注意してください。そこで次の行があるとします。
VARIABLES i, j {27}: INTEGER;
j 変数だけが初期化されます。i 変数は初期化されません。各変数は、個別に初期化しなければなりません。
Developer's Toolkit で初期化されていない、値をもっていない変数は、すべて $Unknown という値で始まります。これは、C および Pascal とは異なります。C および Pascal の場合には、変数がランダム値で始まります。
すべての変数をゼロ、1、または空ストリングに初期化すると、一般エラーが防止されます。以下はその例です。
newSalary := oldSalary*1.05;
このようにした場合には、変数 oldSalary は、 $Unknown 以外のものには初期化されず、$Unknown によって 1.05 が乗算されることになるので、実行時にエラーが起こります。
Tivoli Service Desk 6.0 Developer's Toolkit Script プログラミングの手引き