IBM Books

管理およびプログラミングの手引き OS/2 版、Windows NT 版、Unix 版


Net.Data のマクロ開発

Net.Data のマクロは、 Net.Data のマクロ言語の連続した構成要素で構成されるテキスト・ファイルで、 以下のことを行います。

Net.Data のマクロには、図 19 に示されているように、 宣言パーツと表示パーツという 2 つの構成部分があります。

図 19. マクロ構造
Figure dtwa1107 not displayed.

これらのパーツは、複数回、任意の順序で使用することができます。 マクロのパーツおよび構成要素の構文については、 Net.Data 解説書 を参照してください。

許可のためのヒント : Web サーバーが、 確実に、このファイルへのアクセス権限を持つようにします。 詳しくは、Net.Data がアクセスするファイルへのアクセス権の授与を参照してください。

本章では、Net.Data のマクロを構成しているさまざまなブロックと、 マクロ・ファイルを記述するために使用できる方法について考察します。


Net.Data マクロの分析

マクロは、以下の 2 つのパーツで構成されています。

このセクションでは、簡単な Net.Data のマクロを使って、 マクロ言語の要素を例示します。 このマクロの例は、REXX プログラムに渡す情報をプロンプト指示するフォームを提供します。 このマクロは、この情報を、ompsamp.cmd と呼ばれる REXX プログラムに渡します。 このプログラムは、ユーザーが入力したデータをそのまま返します。 次に、この結果が、HTML の 2 ページに表示されます。

まず最初に、マクロ全体を見渡し、次に各ブロックを詳細に見てみましょう。

%{ **********************       DEFINE block        ************************%}
%DEFINE {
   page_title="Net.Data Macro Template"
%}
 
%{ ********************** FUNCTION Definition block ************************%}
%FUNCTION(DTW_REXX) rexx1 (IN input) returns(result)
{
  %EXEC{ompsamp.cmd %}
%}
 
%FUNCTION(DTW_REXX) today () RETURNS(result)
{
      result = date()
%}
 
%{ **********************      HTML Block: Input    ************************%}
%HTML(INPUT){
<html>
<head>
<title>$(page_title)</title>
</head><body>
<h1>Input Form</h1>
Today is @today()
 
<FORM METHOD="post" ACTION="OUTPUT">
Type some data to pass to a REXX program:
<INPUT NAME="input_data" TYPE="text" SIZE="30">
<p>
<INPUT TYPE="submit" VALUE="Enter">
 
</form>
 
< hr>
<p>[<a href="/">Home page</a>]
</body></html>
%}
 
%{ **********************    HTML Block: Output     ************************%}
%HTML (OUTPUT) {
<html>
<head>
<title>$(page_title)</title>
</head><body>
<h1>Output Page</h1>
<p>@rexx1(input_data)
<p><hr>
<p>[<a href="/">Home page</a> |
<a href="input">Previous page</a>]
</body></html>
%}

サンプルのマクロは、DEFINE、FUNCTION、および 2 つの HTML ブロック、 という 4 つの主要なブロックで構成されます。 1 つの Net.Data のマクロに、複数の DEFINE、FUNCTION、 および HTML ブロックを持つことができます。

この 2 つの HTML ブロックには、HTML などのテキスト表示ステートメントを入れます。 これにより、Web のマクロの作成が簡単になります。 HTML について詳しければ、マクロの作成は、単に、 サーバーで動的に処理されるマクロ・ステートメントと、 データベースに送信する SQL ステートメントの追加を行うだけになります。

マクロは HTML 文書に類似しているように見えますが、Web サーバーは、 Net.Data から CGI、Web サーバー API、 または Java サーブレットを使用してマクロにアクセスします。 マクロを起動するには、Net.Data は、処理すべきマクロの名前、 およびそのマクロの表示すべき HTML ブロック、 という 2 つのパラメーターを必要とします。

マクロが呼び出されると、Net.Data はそのマクロ・ファイルを最初から処理していきます。 以下のセクションでは、Net.Data がマクロ・ファイルを処理していくとどうなるかを見てみます。

DEFINE ブロック

DEFINE ブロックには、 後で HTML のブロックで使用する DEFINE 言語構成要素および変数の定義が含まれます。 以下の例は、1 つの変数定義を持つ DEFINE ブロックを示しています。

%{ **********************       DEFINE Block        ************************%}
%DEFINE {
   page_title="Net.Data Macro Template"
%}

1 行目はコメントです。 コメントは、 %{%} で囲まれた任意のテキストです。 コメントは、マクロの任意の場所に置くことができます。 その次のステートメントが、DEFINE ブロックの始まりです。 1 つの定義ブロックに、複数の変数を定義することができます。 この例では、page_title という 1 つの変数だけが定義されています。 変数の定義を行うと、$(page_title) という構文を使用して、 この変数をマクロの任意の場所で参照することができます。 変数を使用すると、後でマクロを全体にわたって変更することが容易にできるようになります。 このブロックの最後の行 %} は、DEFINE ブロックの終了を確認するものです。

FUNCTION ブロック

FUNCTION ブロックには、HTML ブロックが呼び出す関数の宣言が含まれます。 関数は、言語環境によって処理され、プログラム、SQL 照会、 あるいは ストアード・プロシージャーを実行することができます。

以下の例では、2 つの FUNCTION ブロックを示します。 1 つは外部 REXX プログラムへの呼び出しを定義し、 もう 1 つはインライン REXX ステートメントを含みます。

%{ ********************** FUNCTION Block **********************************%}
%FUNCTION(DTW_REXX) rexx1 (IN input) returns(result) { <-- この関数は 1 つのパラメーターを
                                                       受け取り、外部 REXX プログラムで割り当てられた
                                                       変数 'result' を返します。                                                      
     %EXEC{ompsamp.cmd %}  <-- 関数は "ompsamp.cmd" という外部 REXX プログラムを実行します。
%}
 
%FUNCTION(DTW_REXX) today () RETURNS(result) {
      result = date()  <-- この関数のただ 1 つのソース・ステートメントは、インラインに含まれています。
%}

最初の関数ブロック rexx1 は、REXX 関数宣言です。 この宣言が次に、ompsamp.cmd と呼ばれる、 外部の REXX プログラムを実行します。 1 つの入力変数 input は、この関数によって受け取られ、 自動的に外部の REXX コマンドに渡されます。 REXX コマンドはまた、result と呼ばれる 1 つの変数を戻します。 REXX コマンドにおける result 変数の内容は、 OUTPUT ブロックに含まれる @rexx1() 関数呼び出しの起動に置き換わります。 ompsamp.cmd のソース・コードに示されるように、 REXX のプログラムにより、 変数 input および result に直接アクセスすることができます。

/* REXX */
result = 'The REXX program received "'input'" from the macro.'

この関数のコードは、その関数に渡されたデータをそのまま返します。 この結果のテキストは自分の好きなようにフォーマットすることができます。 それには、@rexx1() 関数呼び出し要求を、 通常のマークアップ・スタイルのタグでくくります (たとえば、 <b> あるいは <em> のように)。 result 変数を使用しなくても、 REXX のプログラムは、REXX の SAY ステートメントを使用すれば、 HTML のタグを標準出力に書き込むことができたはずです。

2 番目の関数ブロック today も、REXX プログラムを参照します。 しかし、この場合の REXX プログラム全体は、関数宣言それ自身に含まれています。 外部プログラムは必要ありません。 インライン・プログラムは、REXX および Perl の関数では許可されています。 その理由は、これらのプログラムは、動的な解析および実行ができる、 インタープリター言語だからです。 インライン・プログラムは、管理すべき独立したプログラムの必要がないので、 単純であるという優位点を持っています。 最初の REXX の関数は、インラインとしてハンドルすることも可能です。

HTML ブロック

HTML ブロックは、Web ページのレイアウトを定義し、変数を参照し、関数を呼び出します。 HTML ブロックは、マクロからのエントリー・ポイント、 およびエグジット・ポイントとして使用されます。 HTML ブロックは常に Net.Data マクロ要求内に指定され、 それぞれのマクロは少なくとも 1 つの HTML ブロックを持つ必要があります。

マクロの例にある最初の HTML ブロックには、 INPUT と名前が付けられています。 HTML(INPUT) には、 1 つの入力フィールドを持つ簡単なフォームの HTML が含まれます。

%{ **********************      HTML Block: Input    ************************%}
%HTML (INPUT) {               <--- この HTML ブロックの名前を識別します。 
<html>
<head>
<title>$(page_title)</title><--- 変数を置換します。
</head><body>
<h1>Input Form</h1>
Today is @today()             <--- この行では関数の呼び出しをします。
 
<FORM METHOD="post" ACTION="OUTPUT">  <--- このフォームが実行されると
                                           "OUTPUT" HTML ブロックが呼び出されます。
REXX プログラムに渡すデータを入力します。
<INPUT NAME="input_data"      <--- "input_data" はフォームが実行された時に定義され、
TYPE="text" SIZE="30">             このマクロ内のどこででも参照可能になります。
                                   これは入力フィールドに入れられたユーザー・タイプが
                                   何であっても、そのタイプに初期化されます。
<p>
<INPUT TYPE="submit" VALUE="Enter">
 
< hr>
<p>
[
<a href="/">Home page</a>]
 </body><html>
%}                            <--- HTML ブロックを閉じます。

ブロック全体は、HTMLのブロック識別子、%HTML (INPUT) {...%} で囲まれます。 INPUT は、このブロックの名前を識別します。 名前には、任意の英数字、下線、またはピリオドを使用することができます。 HTML の <title> タグは、変数置換の例を含んでいます。 変数 page_title の値が、フォームの表題に取って代わります。

このブロックはまた、関数呼び出しを持っています。 式 @today() は、関数 today への呼び出しです。 この関数は、前述の FUNCTION ブロックで定義されます。 Net.Data は、today 関数の結果、すなわち現在日付を、 @today() 式が配置されているのと同じ場所に挿入します。

FORM ステートメントの ACTION パラメーターは、 HTML ブロック間あるいはマクロ間のナビゲーションの例を提供します。 ACTION パラメーターの別のブロックの名前を指定すると、 フォームが処理依頼されたときに、そのブロックにアクセスします。 HTML フォームからの入力データはどれも、暗黙の変数としてブロックに渡されます。 これは、このフォーム上で定義される単一の入力フィールドにもあてはまります。 フォームが処理依頼されると、このフォームに入力されたデータは、 変数 input_data に入れられ、 HTML(OUTPUT) ブロックに渡されます。

マクロが同じ Web サーバー上にある場合、 相対参照を持つ他のマクロの HTML ブロックにアクセスすることができます。 たとえば、ACTION パラメーター ACTION="../othermacro.d2w/main" は、 マクロ othermacro.d2w の main と呼ばれる HTML ブロックにアクセスすることができます。 フォームに入力されたデータはどれも、 もう一度変数 input_data に入れられて、 このマクロに渡されます。

Net.Data を起動する場合、変数を URL の一部として渡します。 たとえば、以下のようにします。

<a href="/cgi-bin/db2www/othermacro.d2w/main?input_data=value">Next macro</a>

マクロのフォーム・データのアクセスまたは操作は、 フォーム内に指定された変数名を参照して行います。

この例における次の HTML ブロックは、HTML(OUTPUT) ブロックです。 これには、HTML のタグ付け、 および HTML(INPUT) の要求により処理された出力を定義する、 Net.Data のマクロ・ステートメントが含まれます。

%{ **********************    HTML Block: Output     ************************%}
%HTML (OUTPUT) {
<html>
<head>
<title>$(page_title)</title><--- 再度、置換しています。
 
</head><body>
<h1>Output Page</h1>
<p>@rexx1(input_data)  <--- この行では、関数 rexx1 を呼び出し、
                            引き数 "input_data" を渡します。
<p>
< hr>
<p>
[
<a href="/">Home page</a> |
<a href="input">Previous page</a>]
%}

HTML(INPUT) ブロックと同じように、このブロックも、 変数および関数呼び出しを置換するための Net.Data マクロ・ステートメントを持つ、 標準の HTML です。 再度、page_title 変数はこの title ステートメントに置換されます。 そして、前と同じように、このブロックは関数呼び出しを含みます。 この場合、このブロックは、関数 rexx1 を呼び出し、 変数 input_data の内容をこの関数に渡します。この変数は、 このブロックが Input ブロックで定義されたフォームから受け取ったものです。 任意の数の変数を関数に渡したり、関数から受け取ったりすることができます。 関数定義は、渡される変数の数および使用法を指定します。


Net.Data のマクロ変数

Net.Data により、Net.Data マクロの変数を定義したり、 参照したりすることができます。 さらに、これらの変数を、マクロから言語環境に渡したり、 また言語環境から受け取ったりすることができます。

変数の型によって、または事前定義値があるかどうかによって、 Net.Data の変数を定義することができます。 定義方法に基づき、これらの変数を以下の型に分類することができます。

以後のセクションでは、以下について説明します。

識別子の効力範囲

識別子は、変数あるいは関数呼び出しで、可視 になります。 すなわち、識別子が宣言されたり初期化されたときに参照することができる、という意味です。 識別子が可視になっている領域は、その効力範囲 と呼ばれます。 効力範囲には、次の 5 つのタイプがあります。

変数の定義

Net.Data マクロにおける変数の定義方法には、以下の 3 つの方法があります。

フォームまたは照会ストリング・データから受け取った変数の値は、 Net.Data マクロにおいて DEFINE ステートメントにより設定された変数の値をオーバーライドします。

変数の参照

定義済みの変数を参照して、その値を戻すことができます。 Net.Data のマクロにおいて変数を参照するには、 その変数名を $() の内側に指定します。 たとえば、以下のようにします。

$(variableName)
$(homeURL)

Net.Data が変数参照を検出すると、Net.Data は、 その変数参照を変数の値で置き換えます。 変数参照は、 ストリング、変数参照、および関数呼び出しを含むことができます。

変数名は動的に生成することができます。 リストの番号が拡張機能で決定できない場合には、この手法で、 ループを使用して、実行時に作成されるリスト用の、 さまざまなサイズの表や入力データを処理することができます。 たとえば、HTML 形式要素のリストが生成できます。この要素は、 SQL 照会から戻されたレコードに基づいて生成されます。

変数をテキスト表示ステートメントの一部として使用するには、 マクロの HTML ブロックでそれらの変数を参照します。

無効な変数参照 : 無効な変数参照は、空ストリングに分解されます。 たとえば、変数参照に感嘆符 (!) などの無効文字が含まれる場合、 参照は空ストリングに分解されます。

有効な変数名は、必ず英数字または下線で始まっている必要があります。 変数名に使用できるのは、英数字 (ピリオドを含む)、 下線、およびハッシュです。

例 1: リンクにおける変数参照

変数 homeURL を定義した場合:

%DEFINE homeURL="http://www.ibm.com/"

ホーム・ページは $(homeURL) として参照でき、 以下のようにリンクを作成します。

<A href="$(homeURL)">Home page</A>

変数の参照は Net.Data マクロの多くの部分で行うことができます。 本章における言語構成要素をチェックして、 マクロのどの部分で変数参照が使用できるかを判別してください。 変数が、それが参照されたときに未定義である場合、Net.Data は空ストリングを戻します。 変数参照は単独では変数を定義しません。

例 2: 動的に生成される変数参照

任意の数の要素を持つ SQL SELECT ステートメントを実行場合を考えてください。 以下の ROW ブロックを使用して、 入力フィールドを持つ HTML 形式を作成することができます。

...
   %ROW {
<input type=text name=@dtw_rconcat("I", ROW_NUM) size=10 maxlength=10>
%}
...

入力フィールドを作成したからには、おそらく、 その形式を処理用のマクロに実行依頼するときに入力した値に、 アクセスしたくなるでしょう。 次のようにループを符号化して、可変長リストの値を検索することができます。

<PRE>
... 
@dtw_assign(rowIndex, "1")
%while (rowIndex <= rowCount) {
The value entered for row $(rowIndex) is: $(I$(rowIndex))
@dtw_add(rowIndex, "1", rowIndex) %} 
...
</PRE>

Net.Data はまず、I$(rowIndex) 参照を使用して、変数名を生成します。 たとえば、最初の変数名は I1 となります。 次に、Net.Data はその値を使用して、変数の値を決定します。

例 3: ネストされた変数参照および関数呼び出しを持つ変数参照

%define my = "my"
%define u = "lower"
%define myLOWERvar = "hey"
$($(my)@dtw_ruppercase(u)var)   

変数参照は、値 hey を戻します。

変数の型

マクロでは以下の型の変数が使用できます。

Net.Data によって特定の方法を定義される変数に、ストリングを割り当てると、 ENVVAR、LIST、条件リストなどの変数は、定義された方法ではもはや動作しません。 すなわち、このような変数は、ストリングを含む単純変数になります。

各変数の構文および例については、Net.Data 解説書 を参照してください。

条件変数

条件変数を使用すると、IF 、THEN 構成要素と類似の方法を使用して、 変数に対して条件値を定義することができます。 条件変数を定義する場合は、変数が取ることができる 2 つの値を指定することができます。 参照する最初の変数が存在する場合は、条件変数は最初の値を取得します。 そうでない場合は、条件変数は 2 番目の値を取得します。 条件変数の構文は、次のようになります。

varA = varB ? "value_1" : "value_2"

varB が定義される場合は、 varA="value_1"、そうでない場合は、 varA="value_2" となります。 これは、次の例のように、IF ブロックを使用するのと同じことになります。

%IF ($(varB))
    varA = "value_1"
%ELSE
    varA = "value_2"
  %ENDIF
 

条件変数をリスト変数と一緒に使用する例については、 リスト変数を参照してください。

環境変数

Net.Data 要求を処理しているプロセスまたはスレッドに対し、 Web サーバーが使用可能とする環境変数を参照することができます。 ENVVAR 変数を参照する場合、Net.Data は環境変数の現行値を同じ名前で戻します。

環境変数を定義するための構文は以下のとおりです。

%DEFINE var=%ENVVAR

var は、定義される環境変数の名前です。

たとえば、変数 SERVER_NAME は、以下の環境変数として定義することができます。

%DEFINE SERVER_NAME=%ENVVAR

そして、参照は以下のように行います。

The server is $(SERVER_NAME)

出力は以下のようになります。

The server is www.software.ibm.com

ENVVAR ステートメントについての詳細は、Net.Data 解説書 を参照にしてください。

実行可能な変数

実行可能な変数を使用すると、変数参照から他のプログラムを呼び出すことができます。

DEFINE ブロックのEXEC 言語構成要素を使用して、 Net.Data のマクロに実行可能変数を定義します。 EXEC 言語要素のさらに詳しい情報については、 Net.Data 解説書 の言語構成要素の章を参照にしてください。 以下の例では、変数 runit が定義され、 実行可能なプログラム testProg が実行されます。

%DEFINE runit=%EXEC "testProg"

runit は、実行可能な変数になります。

Net.Data は、Net.Data のマクロ内で、有効な変数参照に出会うと、 実行可能なプログラムを実行します。 たとえば、有効な変数参照が、 Net.Data のマクロの変数 runit に対して行われると、 プログラム testProg が実行されます。

簡単な方法は、別の変数定義から、実行可能な変数を参照することです。 以下の例は、この方法の一例を示しています。 変数 date は、実行可能な変数として定義され、 dateRpt には、実行可能な変数への参照が含まれます。

%DEFINE date=%EXEC "date"
%DEFINE dateRpt="Today is $(date)"

$(dateRpt) が Net.Data のマクロに現れるごとに、 Net.Data は、実行可能なプログラム date を検索し、 それを見つけると、以下のように戻します。

Today is Tue 11-07-1999

Net.Data がマクロ内で実行可能な変数に出会うと、 Net.Data は、以下の方法によって、参照されている実行可能なプログラムを探します。

  1. Net.Data の初期設定ファイルの EXEC_PATH で指定されるディレクトリーを検索する。 詳細については、EXEC_PATHを参照してください。

  2. プログラムが見つからない場合は、システムの PATH 環境変数、 あるいはライブラリー・リストで定義されるディレクトリーを、システムが検索する。 実行可能なプログラムが見つかれば、Net.Data は、そのプログラムを実行します。

制約事項 : 実行可能変数を、 それが呼び出す実行可能なプログラムの出力値に設定しないでください。 前の例では、変数 date の値は NULL です。 DTW_ASSIGN 関数呼び出しでこの変数を使用し、その値を別の変数に割り当てると、 割り当て後の新規の変数の値も NULL になります。 実行可能変数の目的はただ 1 つ、その変数が定義するプログラムを呼び出すことです。

実行するプログラムにパラメーターを渡すことができます。 それには、変数定義の際に、そのプログラム名と一緒にそのパラメーターを指定します。 次の例では、距離と時間の値が、 プログラム calcMPH に渡されています。

%DEFINE mph=%EXEC "calcMPH $(distance) $(time)" 

この次の例では、システム日付をレポートの一部として戻します。

%DEFINE database="celdial"
 %DEFINE tstamp=%EXEC "date"
 
%FUNCTION(DTW_SQL) myQuery() {
SELECT CUSTNO, CUSTNAME from dist1.customer
%REPORT{
%ROW{
<A HREF="/cgi-bin/db2www/exmp.d2w/report?value1=$(V1)&value2=$(V2)">
$(V1) $(V2) </A> <BR>
%}
%}
%}
 
%HTML(report){
<H1>Report made: $(tstamp) </H1>
@myQuery()
%}

各レポートは、追跡がしやすくなるように日付を表示します。 この例ではまた、顧客番号と名前を、別の Net.Data のマクロのリンクに書き込んでいます。 レポートの任意の顧客をクリックすると、 exmp.d2w という Net.Data のマクロが呼び出され、 顧客番号と名前を Net.Data のマクロに渡します。

隠し変数

隠し変数を使用すると、変数の実際の名前を、 Web ブラウザーを使用して Web ページ・ソースを見ているアプリケーション・ユーザーから、 隠すことができます。隠し変数を定義するには、以下のようにします。

  1. HTML ブロックにおける最後の変数参照の後に、 隠したいストリングごとに変数を指定する。 変数は、HTML ブロックで使用された後、以下の例のように、 常にDEFINE 言語要素を使用して定義されます。 $$(variable) 変数が参照され、次に定義されます。

  2. 変数が参照されている HTML ブロックで、1 つのドル記号ではなく、 2 つのドル記号を使用して、変数を参照します。 たとえば、$(X)ではなく、$$(X) とします。

    %HTML(INPUT){
    <FORM ...>
    <P>Select fields to view:
    shanghai<SELECT NAME="Field">
    <OPTION VALUE="$$(name)"> Name
    <OPTION VALUE="$$(addr)"> Address
    ...
    </FORM>
    %}
     
    %DEFINE {
    name="customer.name"
    addr="customer.address"
    %}
     
    %FUNCTION(DTW_SQL) mySelect(){
      SELECT $(Field) FROM customer
    %}
     
    ...
    

    Web ブラウザーが HTML のフォームを表示すると、 $$(name) および $$(addr) は、 $(name) および $(addr) にそれぞれ置き換えられます。 その結果、実際の表と列名は、HTML のフォームに表示されることはありません。 アプリケーションのユーザーは、真の変数名が隠されているのかどうかを知ることができません。 ユーザーがフォームを処理依頼すると、HTML(REPORT) ブロックが呼び出されます。 @mySelect() が FUNCTION ブロックを呼び出すと、 $(Field) は、SQL ステートメントにおいて、 SQL 照会の customer.name、 あるいは customer.addr で置き換えられます。

リスト変数

リスト変数を使用して、値が区切られたストリングを作成します。 リスト変数は、WHERE あるいは HAVING 節に見られるような、 複数項目を持つ SQL 照会を構成するのに、特に役にたちます。 リスト変数の構文は、次のようになります。

%LIST " value_separator " variable_name

推奨 : ブランクは重要です。 ほとんどの場合、値の区切り文字の前後にスペースを挿入します。 ほとんどの照会は、値の区切り文字に、 ブールあるいは数学演算子を使用します (たとえば、AND、OR、あるいは >)。 次の例は、条件変数、隠し変数、およびリスト変数の使用例を示したものです。

%HTML(INPUT){
<FORM METHOD="POST" ACTION="/cgi-bin/db2www/example2.d2w/report">
<H2>Select one or more cities:</H2>
<INPUT TYPE="checkbox" NAME="conditions" VALUE="$$(cond1)">Sao Paolo<BR>
<INPUT TYPE="checkbox" NAME="conditions" VALUE="$$(cond2)">Seattle<BR>
<INPUT TYPE="checkbox" NAME="conditions" VALUE="$$(cond3)">Shanghai<BR>
<INPUT TYPE="submit" VALUE="Submit Query">
</FORM>
%}
 
%DEFINE{
DATABASE="custcity"
 %LIST " OR " conditions
cond1="cond1='Sao Paolo'"
cond2="cond2='Seattle'"
cond3="cond3='Shanghai'"
whereClause= ? "WHERE $(conditions)" : ""
%}
 
%FUNCTION(DTW_SQL) mySelect(){
SELECT name, city FROM citylist
$(whereClause)
%}
 
%HTML(REPORT) {
@mySelect()
%}

HTML のフォームでは、ボックスがチェックされていない場合、 conditions は NULL となり、 照会では whereClause もまた NULL になります。 そうでない場合は、whereClause は、OR で区切られた選択値を持ちます。 たとえば、3 都市がすべて選択される場合は、SQL は以下のようになります。

SELECT name, city FROM citylist
WHERE cond1='Sao Paolo' OR cond2='Seattle' OR cond3='Shanghai'

次の例は、Seattle が選択されると、その結果、 次のような SQL照会になることを示しています。

SELECT name, city FROM citylist
WHERE cond1='Seattle'

表変数

表変数は、関係しあうデータの集合を定義します。 これには、列見出しの行を含めた行および列のセットが含まれます。 表は、Net.Data のマクロでは、以下のステートメントのようにして定義されます。

%DEFINE myTable=%TABLE(30)

%TABLE の後に続く数字は、この表変数が含むことができる行数の制限です。 行数に制限のない表を指定するには、次の例のように、デフォルトを使用するか、 ALL を指定します。

%DEFINE myTable2=%TABLE
%DEFINE myTable3=%TABLE(ALL)

表を定義すると、表はゼロの行とゼロの列をとります。 表に値を代入するには、表を OUT または INOUT パラメーターとして関数に渡すか、 Net.Data によって提供される組み込み表関数を使用する以外に方法はありません。 DTW_SQL 言語環境は、SELECT ステートメントの結果を表に自動的に書き込みます。

DTW_REXX または DTW_PERL など、非データベース言語環境の場合、 言語環境もまた表の値を設定する責任を負います。 ただし、言語環境スクリプトまたはプログラムは、表の値をセルごとに定義します。 言語環境による表変数の使用方法に関する詳細については、 言語環境の使用を参照してください。

表変数の名前を参照することにより、関数間で表を渡すことができます。 表の個々の要素は、関数の REPORT ブロックで、 あるいは Net.Data 表関数の使用によって、 参照することができます。 REPORT ブロック内の表の各要素へのアクセスに関しては 表処理変数を、 表関数を使用して表の各要素にアクセスすることについては 表関数を、 参照してください。 表変数は、通常、SQL 関数の値が代入され、 次に、SQL 関数あるいは別の関数のいずれかにパラメーターとして渡された後、 その関数におけるレポートへの入力として使用されます。 表変数を、IN、OUT、あるいは INOUTパラメーターとして、 任意の非 SQL 関数に渡すことができます。 表は、SQL関数には、OUT パラメーターとしてのみ渡すことができます。

表変数を参照すると、表の内容は、 DTW_HTML_TABLE 変数の設定に基づき表示およびフォーマットされます。 以下の例では、myTable の内容が表示されます。

%HTML (output) {
  $(myTable)
}

表の列名とフィールドの値は、1 を原点に持つ配列要素としてアドレス指定されます。

各種変数

これらの変数は、Net.Data で定義された変数で、 以下の目的のために使用することができます。

各種変数は、Net.Data が決定する定義済みの値、 あるいはユーザーが設定する値を持つことができます。 たとえば、Net.Data は、Net.Data が処理中の現行ファイルに基づいた、 DTW_CURRENT_FILENAME 変数の値を決定します。これに対して、Net.Data は、 タブや改行文字で作られた余分なスペースを削除するかどうかを指定することができます。

定義済みの変数は、マクロ内では変数参照として使用され、 ファイルの現在の状態、日付、あるいは関数呼び出しの状態に関する情報を提供します。 たとえば、現行ファイルの名前を検索するには、以下を使用することができます。

%REPORT {
<p>This file is <i>$(DTW_CURRENT_FILENAME)</i>.</P>
}

変更可能な変数値は、一般には、DEFINE ステートメント、 あるいは @DTW_ASSIGN() 関数を使用して設定され、 Net.Data のマクロの処理方法に影響を与えます。 たとえば、空白スペースを削除するかどうかを指定するには、 以下の DEFINE ステートメントを使用することができます。

%DEFINE DTW_REMOVE_WS="YES"

有効な各種変数のリストおよびその構文と例については、 Net.Data 解説書 の変数の章を参照してください。

表処理変数

Net.Data は、REPORT および ROW ブロックで使用するための表処理変数を定義します。 これらの変数を使用して、SQL 照会および関数呼び出しからの値を参照します。

表処理変数には、Net.Data が判別する事前定義値があります。 これらの変数によって、SQL 照会または関数呼び出しの結果セットから値を、 処理中の列、行、またはフィールドで参照することができます。 また、処理されている行の数に関する情報、 あるいはすべての列名のリストにアクセスすることができます。

たとえば、Net.Data は、SQL 照会からの結果セットを処理しながら、 現行の列名ごとに、変数 Nn の値を、N1 を最初の列に、N2 を 2番目の列に、 というようにして割り当てます。 Web ページ出力の現行列名を参照することができます。

表処理変数を、変数参照としてマクロ内で使用します。 たとえば、処理中の現行列の名前を検索するには、以下を使用することができます。

%REPORT {
<p>Column 1 is <i>$(N1)</i>.</P>
}

表処理変数はまた、照会の結果に関する情報を提供します。 マクロにおいて変数 TOTAL_ROWS を参照して、以下の例のように、 SQL 参照からどれだけの行が戻されたかを表示することができます。

Names found: $(TOTAL_ROWS)

表処理変数の中には、他の変数あるいは組み込み関数により影響されるものがあります。 たとえば、TOTAL_ROWS は、DTW_SET_TOTAL_ROWS という SQL の言語環境変数をアクティブにして、 以下の例のように、SQL 照会あるいは関数呼び出しからの結果を処理するときに、 Net.Data が TOTAL_ROWS の値を割り当てるように、要求します。

%DEFINE DTW_SET_TOTAL_ROWS="YES"
...
 
Names found: $(TOTAL_ROWS)

有効な表処理変数のリストおよびその構文と例については、 Net.Data 解説書 の変数の章を参照してください。

レポート変数

Net.Data は、マクロにより生成された Web ページ出力を、 デフォルトのレポート・フォーマットで表示します。 デフォルトのレポート・フォーマットは、<PRE> </PRE> タグを使用して、 表形式で表示されます。 出力を表示するための命令をもつ REPORT ブロックを定義して、あるいは、 デフォルトのレポートが生成されるのを防ぐためのレポート変数の 1 つを使用して、 デフォルトのレポートを取り消すことができます。

レポート変数は、Web ページ出力の表示方法、 およびデフォルトのレポートと Net.Data 表と一緒に使用する方法を、 カスタマイズするのに役立ちます。 レポート変数は、使用する前に、DEFINE ステートメント、 あるいは @DTW_ASSIGN() で定義されなければなりません。

レポート変数は、スペーシングを指定し、デフォルトのレポート・フォーマットを取り消し、 HTML の表の出力対デフォルトの表出力を指定して、他の表示機能を指定します。 たとえば、ALIGN 変数を使用すると、 表処理変数に対して前後のスペースを制御することができます。 以下の例では、ALIGN 変数を使用して、 照会により戻されるリストの各列名をスペースで区切ります。

%DEFINE ALIGN="YES"
...
<p>Your query was on these columns: $(NLIST)

START_ROW_NUM レポート変数により、どの行で、 照会の結果の表示を始めるかを決定することができます。 たとえば、以下の変数は、Net.Data が、 照会の結果の表示を 3 番目の行から始めるように指定しています。

%DEFINE START_ROW_NUM = "3"

また、Net.Data がデフォルトの形式設定に HTML のタグを使用するかどうかを、 決定することもできます。 DTW_HTML_TABLE を YES に設定すると、 テキスト・フォーマットの表ではなく、HTML の表が作成されます。

%DEFINE DTW_HTML_TABLE="YES"
 
%FUNCTION(DTW_SQL){
SELECT NAME, ADDRESS FROM $(qTable)
%}

有効なレポート変数のリストおよびその構文と例については、 Net.Data 解説書 の変数の章を参照してください。

言語環境変数

言語環境変数は、言語環境と共に使用され、 言語環境による要求処理の方法に影響を与えます。

これらの変数を使用することにより、 データベースへの接続の確立、Java アプレットの代替テキストの提供、NLS サポートの使用可能化、および、 SQL ステートメントが正常に実行されたか判別するなどのタスクが実行できます。

たとえば、SQL_STATE 変数を使用すれば、 データベースから戻される SQL の状態値にアクセスしたり、表示することができます。

%FUNCTION (DTW_SQL) val1() {
 select * from customer
%REPORT {
 ...
   %ROW {
 ...
%}
 SQLSTATE=$(SQL_STATE)
%}

この次の例では、アクセスすべきデータベースを定義する方法を示しています。

%DEFINE DATABASE="CELDIAL"

有効な言語環境変数のリストおよびその構文と例については、 Net.Data 解説書 の変数の章を参照してください。


Net.Data の関数

Net.Data には、ユーザーのアプリケーションで使用するための、 組み込み関数が提供されています。これにはワードおよびストリング処理関数、 または表変数関数の検索および設定をする関数があります。 また、たとえば外部プログラムやストアード・プロシージャーを呼び出すため、 アプリケーションで使用する関数を定義することができます。

ユーザー定義の関数
たとえば、外部プログラムやストアード・プロシージャーを呼び出すため、 アプリケーションで使用するために定義する関数。

Net.Data 組み込み関数
ユーザーのアプリケーションで使用するため Net.Data が提供する関数。 ワードおよびストリングを操作する関数、および表変数の設定をする関数などがあります。

次のセクションでは、以下のトピックについて説明します。

関数の定義

ユーザー自身の関数をマクロに定義するには、FUNCTION ブロック、 または MACRO_FUNCTION ブロックを使用します。

FUNCTION ブロック
Net.Data マクロから呼び出され、言語環境で処理されるサブルーチンを定義します。 FUNCTION ブロックには、言語ステートメント、 または外部プログラムの呼び出しが含まれなくてはなりません。

MACRO_FUNCTION ブロック
Net.Data マクロから呼び出され、言語環境ではなく、 Net.Data により処理されるサブルーチンを定義します。 MACRO_FUNCTION ブロックには、 HTML ブロックで使用可能ないずれのステートメントも含むことができます。

構文 : 関数を定義するには、以下の構文を使用してください。

FUNCTION ブロック:

%FUNCTION(type) function-name([usage] [datatype] parameter, ...) [RETURNS(return-var)] {
  executable-statements
  [report-block]
  ...
  [report-block]
  [message-block]
%}

MACRO_ FUNCTION ブロック :

%MACRO_FUNCTION function-name([usage] parameter, ...)  {
  executable-statements
  report-block
  ...
  report-block
%}

ここで、

type
初期設定ファイルにおいて構成されている言語環境を識別します。 言語環境は、特定の言語プロセッサー (これは、実行可能なステートメントを処理します)、 および Net.Data と言語プロセッサーとの標準インターフェースを提供します。

function-name
FUNCTION または MACRO_FUNCTION ブロックの名前を指定します。 関数呼び出しは、@ 記号を前に付けた function-name を指定します。 詳細については、関数の呼び出しを参照してください。

複数の FUNCTION または MACRO_FUNCTION ブロックを同じ名前で定義し、 それらの同時に処理することができます。 各ブロックは、すべて、同じパラメーター・リストを持たなければなりません。 Net.Data が関数を呼び出すと、同じ名前を持つすべての FUNCTION ブロック、 または同じ名前を持つ MACRO_FUNCTION ブロックは、 Net.Data のマクロにおける定義順に実行されます。

usage
パラメーターが、入力 (IN) パラメーターか、 出力 (OUT) パラメーターか、それとも両方のタイプ (INOUT) かを指定します。 この指定は、 FUNCTION ブロックまたは MACRO_FUNCTION (あるいはその両方) にパラメーターが渡されるのか、 またはそこから受け取られるのかを示しています。 usage のタイプは、別のusage のタイプにより変更されるまで、 パラメーター・リストのその後に続くパラメーターすべてに適用されます。 デフォルトのタイプは IN です。

datatype
パラメーターのデータ型。 言語環境プログラムの中には、渡されるパラメーターのデータ型を予想するものがあります。 たとえば SQL 言語環境は、ストアード・プロシージャーを呼び出す際に、 それらを予想します。 使用中の言語環境がサポートするデータ型についての詳細は、 言語環境の使用を参照してください。

parameter
関数呼び出し時に指定される対応する引き数の値で置き換えられる、 ローカルな効力範囲を持つ変数の名前。 実行可能ステートメント、あるいは REPORT ブロック内の、 たとえば $(parm1) というパラメーター参照は、 そのパラメーターの実際の値で置き換えられます。 さらに、パラメーターは、言語環境に渡されて、 その言語の自然構文を使用する実行可能ステートメントから、 あるいは環境変数として、アクセス可能となります。 パラメーター変数変数の参照は、 FUNCTION または MACRO_FUNCTION ブロックの外では無効です。

return-var
このパラメーターを、RETURNS キーワードの後に指定して、 特殊な OUT パラメーターを識別します。 戻り変数の値は関数ブロックに割り当てられており、 その値は、マクロ内で関数が呼び出された位置に戻されます。 たとえば次の文の <p>My name is @my_name(). において、 @my_name() は戻り変数の値で置き換えられます。 RETURNS 節を指定しなければ、関数呼び出しの値は以下のようになります。

executable-statements
変数の置換および関数処理の後で、 処理のための指定された言語環境に渡される言語ステートメントのセット。 executable-statements には、 Net.Data の変数参照および Net.Data の関数呼び出しを含むことができます。 executable-statements には、 HTML ブロックで許可される実行可能ステートメントが組み込まれます。

FUNCTION ブロックの場合、Net.Data は、すべての変数参照を変数の値に置き換え、 すべての関数呼び出しを実行し、関数呼び出しをその結果値に置き換えます。 その後で、実行可能なステートメントが言語環境に渡されます。 各言語環境は、ステートメントを異なる方法で処理します。 実行可能なステートメントあるいは実行可能なプログラムの呼び出しについての詳細は、 実行可能な変数を参照してください。

MACRO_FUNCTION ブロックの場合は、実行可能なステートメントは、 テキストと Net.Data マクロ言語構成要素との組み合わせです。 この場合、言語環境は全く関与しません。 Net.Data が言語プロセッサーとして働き、実行可能なステートメントを実行するためです。

report-block
FUNCTION ブロックまたは MACRO_FUNCTION ブロックの出力処理のため、 1 つ以上の REPORT ブロックを定義します。 レポート・ブロックを参照してください。

message-block
MESSAGE ブロックを定義します。このブロックは、 FUNCTION ブロックによって戻された任意のメッセージをハンドルします。 メッセージ・ブロックを参照してください。

最外部のブロックにあり、Net.Data マクロで呼び出される前の関数を定義します。

関数での特殊文字の使用

構文上有効な組み込みプログラム・コード (REXX または Perl など)として、 Net.Data の言語構成要素構文と一致する文字を、 関数ブロックの言語ステートメント・セクションで使用すると、 これらの文字は、Net.Data の言語構成要素として、間違って解釈され、 マクロ内で予測不能な結果が発生する可能性があります。

たとえば、Perl 関数は COMMENT ブロック区切り文字 %{ を使用するかもしれません。 マクロが実行されると、文字 %{ は、COMMENT ブロックの先頭と解釈されます。 Net.Data は、次に、COMMENT ブロックの終わりを検索し、 関数ブロックの終わりを読み取ったときに、検出したと判断します。 Net.Data は、次に、関数ブロックの終わりを検索し始めます。 そして、関数の終わりを検出できないと、エラーを発行します。

以下のメソッドの 1 つを使用して、COMMENT ブロックの区切り文字を使用するか、 あるいは、Net.Data が特殊文字として解釈する区切り文字を持たずに、 ユーザーの組み込みプログラム・コードとしての Net.Data の特殊文字を使用します。

たとえば、以下の Perl 関数では、COMMENT ブロックの区切りを表す文字 %{ が、 Perl 言語ステートメントの一部として含まれます。

%FUNCTION(DTW_PERL) func() {
  ...           
  for $num_words (sort bynumber keys %{ $Rtitles{$num} }) {
    &make_links($Rtitles{$num}{$num_words});          
  }   
  ... 
%}   

Net.Data が %{ 文字を、Net.Data の COMMENT ブロック区切り文字ではなく、 Perl ソース・コードとして解釈するように、以下のいずれかのように関数を再度記述します。

メッセージ・ブロック

MESSAGE ブロックにより、関数呼び出しの成功あるいは失敗を基にして、 関数呼び出し後の進め方を決定することができ、 関数の呼び出し側に情報を表示することができます。 メッセージを処理する際、Net.Data は、 言語環境変数 RETURN_CODE を FUNCTION ブロックへの関数呼び出しごとに設定します。 RETURN_CODE は、関数呼び出し時には、MACRO_FUNCTION ブロックには設定されません。

MESSAGE ブロックは、連続したメッセージ・ステートメントで構成され、 各メッセージ・ステートメントは、戻りコード値、メッセージ・テキスト、 および取るべきアクションを指定します。 MESSAGE ブロックの構文は、Net.Data 解説書 の言語構成要素の章に示されています。

MESSAGE ブロックは、グローバルあるいはローカルな効力範囲を持つことができます。 MESSAGE ブロックが、FUNCTION ブロックで定義されている場合は、 その効力範囲は、その FUNCTION ブロックに対してはローカルです。 MESSAGE ブロックが、最外部のマクロ・レイヤーで指定されている場合は、 MESSAGE ブロックは、グローバルな効力範囲を持ち、 Net.Data のマクロで実行されるすべての関数呼び出しに対してアクティブになります。 2 つ以上のグローバルな MESSAGE ブロックを定義している場合は、 最後に定義されたブロックがアクティブになります。

Net.Data は、以下のルールを使用し、 関数呼び出しからの RETURN_CODE 変数の値を処理します。

  1. ローカルな MESSAGE ブロックを 完全一致で検査する。 指定に応じて、抜け出るか、続行します。

  2. RETURN_CODE が 0 でない場合は、 +default または -default に対して、 ローカルな MESSAGE ブロックを検査する。これは、RETURN_CODE の符号に依存し、 指定に応じて、抜け出るか、続行します。

  3. RETURN_CODE が 0 でない場合、ローカルな MESSAGE ブロックを、 defaultで検査する。指定に応じて、抜け出るか、続行します。

  4. グローバルな MESSAGE ブロックを 完全一致で検査する。 指定に応じて、抜け出るか、続行します。

  5. RETURN_CODE が 0 でない場合は、グローバルな MESSAGE ブロックを、 +default あるいは -default で検査する。これは、 RETURN_CODE の符号に依存し、指定に応じて、抜け出るか、続行します。

  6. RETURN_CODE が 0 でない場合、グローバルな MESSAGE ブロックを、 defaultで検査する。指定に応じて、抜け出るか、続行します。

  7. RETURN_CODE が 0 でない場合、 Net.Data の内部デフォルト・メッセージを発行し、抜け出る。

以下の例は、グローバルな MESSAGE ブロックと、 関数の MESSAGE ブロックを持つ Net.Data のマクロのパーツを示しています。

%{ global message block %}
%MESSAGE {
     -100     : "Return code -100 message"   : exit
      100     : "Return code 100 message"    : continue
   +default : {
This is a long message that spans more
than one line. You can use HTML tags, including
links and forms, in this message. %}   : continue  
%}
 
%{ local message block inside a FUNCTION block %}
%FUNCTION(DTW_REXX) my_function() {
  %EXEC { my_command.cmd %}
%MESSAGE {
     -100     : "Return code -100 message"   : exit
      100     : "Return code 100 message"    : continue
     -default : {
This is a long message that spans more
than one line. You can use HTML tags, including
links and forms, in this message. %}   : exit  
  %}

my_function() が RETURN_CODE 値 50 で戻れば、 Net.Data は次の順にエラーを処理します。

  1. ローカルな MESSAGE ブロックを、完全一致で検査する。

  2. ローカルな MESSAGE ブロックを +default で検査する。

  3. ローカルな MESSAGE ブロックを default で検査する。

  4. グローバルな MESSAGE ブロックを、完全一致で検査する。

  5. グローバルな MESSAGE ブロックを +default で検査する。

Net.Data が一致を検出した場合、 Net.Data はメッセージ・テキストを Web ブラウザーに送信し、 要求されたアクションを検査します。

continue を指定した場合は、Net.Data は、 メッセージ・テキストをプリントしてから、Net.Data マクロの処理を継続します。 たとえば、マクロが my_functions() を 5 回呼び出し、 エラー 100 が、上の例の MESSAGE ブロックの処理中に検出された場合、 プログラムからの出力は、次のようになります。

.
.
.
11 May 1997                  $245.45
13 May 1997                  $623.23
19 May 1997                  $ 83.02
return code 100 message
22 May 1997                  $ 42.67
 
Total:                       $994.37

関数の呼び出し

ユーザー定義関数および組み込み関数の両方を呼び出すには、 Net.Data 関数呼び出しステートメントを使用します。 @ 文字に続けて関数名、またはマクロ関数名を使用します。

@function_name([ argument,... ])

function_name
起動する関数またはマクロ関数の名前です。 関数は、それが組み込み関数でなければ、 Net.Data のマクロであらかじめ定義されていなければなりません。

argument
これは、変数、引用符付き文字列、変数参照、 または関数呼び出しの名前です。関数呼び出し時の引き数は、 関数またはマクロ関数仮引き数リストのパラメーターにより突き合わせられます。 各パラメーターには、関数またはマクロ関数の処理中に、 対応する引き数の値が割り当てられます。 引き数は、対応するパラメーターと同じ数および型でなければなりません。

引き数に使用する引用符付き文字列には、 変数参照および関数呼び出しを含むことができます。

例 1: テキスト・ストリング引き数による関数呼び出し

@myFunction("abc")

例 2: 変数および関数呼び出し引き数による関数呼び出し

@myFunction(myvar, @DTW_rADD("2","3"))

例 3: 変数参照および関数呼び出しを含む、 テキスト・ストリング引き数による関数呼び出し

@myFunction("abc$(myvar)def@DTW_rADD("2","3")ghi")

Net.Data 組み込み関数の呼び出し

Net.Data は、Web ページ開発を容易にするための大きな組み込み関数のセットを提供します。 これらの関数は、すでに Net.Data により定義されているので、 定義する必要はありません。他の関数と同様に呼び出すことができます。

図 20 に、 Net.Data 組み込み関数およびマクロがどのように相互作用しているかを示します。

図 20. Net.Data の組み込み関数
Net.Data の組み込み関数

組み込み関数は、その接頭部に応じて次の 3 つの方法でその結果を戻すことができます。

組み込み関数によっては、タイプを持たないものがあります。 特定の組み込み関数の型を判別するには、 Net.Data 解説書 の Net.Data 組み込み関数の章を参照してください。

以下のセクションでは、Net.Data の組み込み関数について高度な概説を提供します。 以下の関数を使用して、汎用、数学、ストリング、ワード、 あるいは表操作の各関数を実行します。 各関数とその構文および例の説明については、Net.Data 解説書 を参照してください。 これらの関数の中には、使用前に変数を設定する必要があるものや、 特定のコンテキストで使用しなければならないものがあります。 オペレーティング・システムがすべて、 個々の組み込み関数をサポートしているわけではありません。 ご使用のオペレーティング・システムがサポートしている関数を判別するには、 Net.Data 解説書 を参照してください。

汎用関数

この関数セットは、データを変更したり、システム・サービスを利用することにより、 Web ページの開発に役にたちます。 これらの関数を使用して、メール送信、HTTP Cookie の処理、 HTML エスケープ・コードの生成、およびシステムからのその他有益情報の取得を行うことができます。

たとえば、特定の条件が発生した場合に、 Net.Data がマクロの残り部分を処理せず終了するように指定するには、 DTW_EXIT 関数を使用します。

%HTML(cache_example) {
 
<html>
<head>
 <title>This is the page title</title>
</head>
 <body>
 <center>
 <h3>This is the Main Heading</h3>
 <!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!>
 <! Joe Smith sees a very short page                   !>
 <!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!>
 %IF (customer == "Joe Smith")
</body>
 </html>
 
@DTW_EXIT()
 
  %ENDIF
 
...
 
</body>
 </html>
 %}

もう 1 つ、役に立つのは、DTW_URLESCSEQ 関数です。 これは、URL では許可されていない文字をエスケープ値に置換します。 たとえば、入力変数 string1"Guys & Dolls" に等しい場合は、 DTW_URLESCSEQ は、出力変数に値 "Guys%20%26%20Dolls" を割り当てます。

有効な汎用関数のリストおよびその構文と例については、 Net.Data 解説書 の組み込み関数の章を参照してください。

数学関数

これらの関数は、数学操作を実行し、数値データの計算あるいは変更を行うことができます。 標準的な数学操作の他にも、法による除算の実行、演算結果の精度の指定、 科学表記の使用などを行うことができます。

たとえば、関数 DTW_POWER は、第 1 パラメーターの値の第 2 パラメーター乗を求め、 その結果を戻します。以下に例を示します。

@DTW_POWER("2", "-3", result)

DTW_POWER は、変数 result".125" を戻します。

有効な数学関数のリストおよびその構文と例については、 Net.Data 解説書 の組み込み関数の章を参照にしてください。

ストリング関数

これらの関数により、ストリング内の文字を操作することができます。 ストリングの大文字小文字の変更、文字の挿入あるいは削除、 別の変数へのストリング値の割り当てを行うことができます。さらに、 その他の有用な関数を実行することができます。

たとえば、DTW_ASSIGN を使用して、入力変数の値を出力変数に割り当てることができます。 この関数を使用して、マクロで変数を変更することもできます。 以下の例では、変数 RC はゼロに割り当てられます。

@DTW_ASSIGN(RC, "0")

他のストリング関数としては、ストリングを連結する DTW_CONCAT、 特定の位置にストリングを挿入する DTW_INSERT などの多くのものがあります。

有効なストリング関数のリストおよびその構文と例については、 Net.Data 解説書 の組み込み関数の章を参照してください。

ワード関数

これらの関数により、ストリング内のワードを操作することができます。 これらの関数のほとんどは、ストリング関数と同じ働きをしますが、 ワード全体に対して働きます。 たとえば、これらの関数を使用して、ストリング内のワード数のカウント、 ワードの削除、ストリングからのワードの取得などを実行することができます。

たとえば、DTW_DELW0RD を使用して、ストリングから指定した数だけワードを削除します。

@DTW_DELWORD("Now is the time", "2", "2", result)

DTW_DELWORD は、ストリング "Now time" を戻します。

他のワード関数には、ワードの文字数を戻す DTW_WORDLENGTH、 およびストリング内の文字位置を戻す DTW_WORDPOS があります。

有効なワード関数のリストおよびその構文と例については、 Net.Data 解説書 の組み込み関数の章を参照してください。

表関数

これらの関数を使用して、Net.Data の表変数のデータを使い、 レポートやフォームを生成することができます。 また、これらの関数を使用して Net.Data 表の作成、 およびその表の値の操作および検索が行えます。 表変数には、値のセット、およびこれに関連付けられた列の名前が含まれます。 これらの関数は、値のグループを関数に渡すのに都合の良い方法を提供してくれます。

たとえば、DTW_TB_APPENDROW は表に行を追加します。 以下の例では、Net.Data は表 myTable に 10 行を追加します。

@DTW_TB_APPENDROW(myTable, "10")

さらに、DTW_TB_DUMPH は、表の各行が異なる行に表示されるように、 <PRE></PRE> タグで囲んでマクロ表変数の内容を戻します。 また、DTW_TB_CHECKBOX は、マクロ表変数から、 1 つまたは複数の HTML チェック・ボックスの入力タグを戻します。

有効な表関数のリストおよびその構文と例については、 Net.Data 解説書 の組み込み関数の章を参照してください。

フラット・ファイル関数

フラット・ファイル・インターフェース (FFI) 関数を使用して、 フラット・ファイル内の保管データだけでなく、 フラット・ファイルのソース (テキスト・ファイル) のデータのオープン、 読み取り、および操作をすることができます。

たとえば、DTWF_APPEND は表変数の内容をファイルの最後に書き込み、 DTWF_DELETE はレコードをファイルから削除します。

さらに、FFI 関数では、DTWF_CLOSE および DTWF_OPEN で、 ファイルをロックすることができます。 DTWF_OPEN はファイルをロックして、 他の要求によりファイルの読み取りまたは更新を行えないようにします。 DTWF_CLOSE は、Net.Data が処理を完了するとファイルをリリースし、 他の要求によりファイルがアクセスできるようにします。


有効な FFI 関数のリストおよびその構文と例については、 Net.Data 解説書 の組み込み関数の章を参照してください。

Web レジストリー関数

Web レジストリー関数を使用することにより、 レジストリーおよびそれに含まれるエントリーを保守することができます。 Web のレジストリーとは、Net.Data により保守されるキーを持つファイルで、 エントリーの追加、検索、および削除を簡単に行えるようにしてくれます。

たとえば、DTWR_ADDENTRY はエントリーを追加して、 DTWR_DELENTRY はエントリーを削除します。 DTWR_LISTSUB は、OUT 表パラメーターにレジストリー・エントリーに関する情報を戻し、 DTWR_UPDATEENTRY は、指定したレジストリー・エントリーの既存の値を新しい値で置換します。

有効な Web レジストリー関数のリストおよびその構文と例については、 Net.Data 解説書 の組み込み関数の章を参照してください。


マクロでの Web ページの生成

Net.Data により、標準 Web ページを、 アプリケーション・ユーザーのブラウザーに簡単に提供することができます。 以下のセクションでは、マクロの HTML および REPORT ブロックについて説明し、 Net.Data のマクロにおける Web ページのフォーマット方法を示します。 これらのブロックの構文情報については、 Net.Data 解説書 の言語構成要素の章を参照してください。

HTML ブロック

Net.Data には、 Web ブラウザーに対して HTML などのテキスト表示ステートメントを生成する、 HTML ブロックが含まれます。 マクロ内には、少なくとも 1 つの HTML を指定しなくてはなりませんが、 これは必要な数だけ指定できます。 各 HTML ブロックは、ブラウザーで単一の Web ページを生成します。 Net.Data は、起動ごとに HTML ブロックを 1 つだけ処理します。 多くの Web ページから構成されるアプリケーションを作成するには、 Net.Data を複数回起動して、 リンクおよびフォームなど通常のナビゲーション手法を使用した HTML ブロックの処理を行います。

HTML や JavaScript などの任意の有効なテキスト表示ステートメントを、 HTML ブロックに記述することができます。 さらに、INCLUDE ステートメント、関数呼び出し、 および HTML ブロックの変数参照を使用することができます。 以下の例は、Net.Data のマクロにおける HTML ブロックの一般的な使い方を示しています。

%DEFINE DATABASE="MNS96"
 
%HTML(INPUT){
<H1>Hardware Query Form</H1>
<HR>
<FORM METHOD="POST" ACTION="/cgi-bin/db2www/equiplst.d2w/report">
<dl>
<dt>What hardware do you want to list?
<dd><input type="radio" name="hdware" value="MON" checked>Monitors
<dd><input type="radio" name="hdware" value="PNT">Pointing devices
<dd><input type="radio" name="hdware" value="PRT">Printers
<dd><input type="radio" name="hdware" value="SCN">Scanners
</dl>
<HR>
<input type="submit" value="Submit">
</FORM>
%}
 
%FUNCTION(DTW_SQL) myQuery() {
SELECT MODNO, COST, DESCRIP FROM EQPTABLE WHERE TYPE=$(hdware)
%REPORT{
<B>Here is the list you requested:</B><BR>
%ROW{
<HR>
$(N1): $(V1)    $(N2): $(V2)
 <P>
$(V3)
%}
%}
%}
 
%HTML(REPORT) {
@myQuery()
%}

Net.Data のマクロを、以下の例のように、HTML のリンクから起動することができます。

<a href="http://www.ibm.com/cgi-bin/db2www/equiplst.d2w/input">
  List of hardware</a>

アプリケーション・ユーザーがこのリンクをクリックすると、 Web ブラウザーは Net.Data を起動し、Net.Data はマクロを解析します。 Net.Data が起動に指定された HTML ブロック、この場合は HTML (INPUT) ブロック、 の処理を開始すると、Net.Data は、そのブロック内のテキストの処理を開始します。 Net.Data は、Net.Data のマクロ言語構成要素として認識できないものはどれも、 ブラウザーに送信して表示します。

ユーザーが選択を行い、「Submit (処理依頼)」ボタンを押すと、 Net.Data は HTML の FORM 要素の ACTION 部分を実行します。 この部分は、Net.Data のマクロの HTML(OUTPUT) ブロックへの呼び出しを指定します。 次に Net.Data は、HTML(INPUT) ブロックの場合と同様に、 HTML(OUTPUT) ブロックを処理します。

Net.Data は次に、myQuery() 関数呼び出しを処理します。 この関数呼び出しは、次に SQL FUNCTION ブロックを起動します。 SQL ステートメントの $(hdware) 変数参照を、 入力フォームで戻された値と置き換えた後、Net.Data は照会を実行します。 この時点で、Net.Data はレポート処理を再開し、 REPORT ブロックで指定されたテキスト表示ステートメントに従って照会結果を表示します。

Net.Data は REPORT ブロックの処理を完了して後、 HTML(OUTPUT) ブロックに戻り、処理を終了します。

レポート・ブロック

REPORT ブロックの言語構成要素を使用して、 FUNCTION ブロックからのデータ出力をフォーマットし、表示することができます。 この出力は、基本的には表データです。ただし、テキスト、マクロ変数参照、 および関数呼び出しの有効な組み合わせを指定することはできます。 表の名前は、オプションで REPORT ブロックで指定することができます。 SQL および ODBC 言語環境以外では、表の名前を指定しない場合は、Net.Data は、 FUNCTION パラメーター・リストの最初の出力表の表データを使用します。

REPORT ブロックは、次の 3 つのパーツを持ち、各パーツはオプションです。

例 :

%REPORT{
<H2>Query Results</H2>
<P>Select a name for details.
<TABLE BORDER=1>
  <TR>
    <TD>Name</TD>
    <TD>Location</TD></TR>
%ROW{
  <TR>
    <TD>
    <a href="/cgi-bin/db2www/name.d2w/details?name=$(V1)&location;=$(V2)">$(V1)</a>
    </TD>
    <TD>$(V2)</TD>
  </TR>
  %}
</TABLE>
%}

REPORT ブロックのガイドライン

REPORT ブロックの作成時には、以下のガイドラインを使用してください。

例 : レポートのカスタマイズ

以下の例は、特殊変数と HTML のタグを使用した、 レポート・フォーマットのカスタマイズ方法を示しています。 この例では、CustomerTbl の表から、 名前、電話番号、および FAX 番号を表示しています。

%DEFINE SET_TOTAL_ROWS="YES"
...
%FUNCTION(DTW_SQL) custlist() {
     SELECT Name, Phone, Fax FROM CustomerTbl
%REPORT{
<I>Phone Query Results:</I>
<BR>
=====================
<BR>
%ROW{
   Name: <B>$(V1)</B>
<BR>
Phone: $(V2)
<BR>
Fax: $(V3)
<BR>
------------------------------
<BR>
    %}
    Total records retrieved: $(TOTAL_ROWS)
  %}
%}

この結果作成されるレポートは、Web ブラウザーでは、次のように表示されます。

Phone Query Results:
====================
Name: Doen, David
Phone: 422-245-1293
Fax: 422-245-7383
------------------------------
Name: Ramirez, Paolo
Phone: 955-768-3489
Fax: 955-768-3974
------------------------------
Name: Wu, Jianli
Phone: 525-472-1234
Fax: 525-472-1234
------------------------------
Total records retrieved: 3

Net.Data は、以下を行い、レポートを生成しました。

  1. Phone Query Results: を、 レポートの最初に 1 回プリントする。 区切り線の付いたこのテキストは、REPORT ブロックのヘッダー部分です。

  2. 検索時に各行ごとに、変数 V1V2、 および V3 を、それぞれ Name、Phone、および Fax の値で置換する。

  3. ストリング Total records retrieved:、 および TOTAL_ROWS の値を、レポートの最後に一度プリントする。 (このテキストは、REPORT ブロックのフッター部分です。)

複数の REPORT ブロック

単一の FUNCTION または MACRO FUNCTION ブロックで複数の REPORT ブロックを指定して、 1 回の関数呼び出しで複数のレポートを生成させることができます。

一般的に、複数の REPORT ブロックは、 DTW_SQL 言語環境でストアード・プロシージャーを呼び出す関数に対して使用します。 この場合、複数の結果セットが戻ります (ストアード・プロシージャーを参照)。 ただし、複数の REPORT ブロックは、複数のレポートを生成させるために、 任意の言語環境とともに使用することができます。

複数の REPORT ブロックを使用するには、それぞれの結果セットについて、 ストアード・プロシージャーの CALL に結果セット名を配置します。 指定したレポート・ブロックの数より多い結果セットが、 ストアード・プロシージャーから戻される場合、そしてまた、 Net.Data 組み込み関数 DTW_DEFAULT_REPORT = "MULTIPLE" である場合は、 レポート・ブロックと関連がない各表に対して、デフォルトのレポートが生成されます。 レポート・ブロックが指定されていない場合、 および DTW_DEFAULT_REPORT = "YES" である場合は、 デフォルトのレポートは 1 つしか生成されません。 SQL 言語環境の場合に限り、DTW_DEFAULT_REPORT 値の YES は、 値 MULTIPLE と同等であることに注意してください。

以下の例では、複数のレポート・ブロックを使用する方法を示します。

デフォルトのレポートのフォーマットを使用して、 複数のレポートを表示させる

例 1: DTW_SQL 言語環境

%DEFINE DTW_DEFAULT_REPORT = "MULTIPLE"
%FUNCTION(dtw_sql) myStoredProc  () {
     CALL myproc (table1, table2)  %}

この例では、ストアード・プロシージャー myproc は、 2 つの結果セットを戻します。これらは、 table1 および table2 に入ります。 REPORT ブロックが指定されていないので、 デフォルトのレポートは両方の表 (最初に table1、 次に table2) について表示されます。

例 2: MACRO_FUNCTION ブロック

この例では、2 つの表が MACRO_FUNCTION ブロックに渡されます。 DTW_DEFAULT_REPORT="MULTIPLE" が指定されている場合、 Net.Data はどちらの表に対してもレポートを生成します。

%DEFINE DTW_DEFAULT_REPORT = "MULTIPLE"
%MACRO_FUNCTION multReport (INOUT tablename1, tablename2) { 
%}

この例では、2 つの表が MACRO_FUNCTION multReport に渡されます。 ここでも Net.Data は、 MACRO FUNCTION ブロック・パラメーター・リストに示されている順序で (最初に table1 に、 次に table2 について)、デフォルトのレポートを表示します。

例 3: DTW_REXX 言語環境

%DEFINE DTW_DEFAULT_REPORT = "YES"
%FUNCTION (dtw_rexx) multReport (INOUT table1, table2) {
     SAY 'Generating multiple default reports...<BR>'   
%}

この例では、2 つの表が REXX 関数 multReport に渡されます。 DTW_DEFAULT_REPORT="YES" が指定されているため、 Net.Data は最初の表にのみデフォルトのレポートを表示します。

表示処理用に REPORT ブロックを指定することによって、 複数のレポートを表示させる

例 1: 名前付き REPORT ブロック

%FUNCTION(dtw_sql) myStoredProc  () {
   CALL myproc (table1, table2)
 
   %REPORT(table2) { 
     ...    
    %ROW {  ....   %}   
     ...
   %}
   
 %REPORT (table1) {     
     ...
     %row {  ....   %} 
     ...
   %}
%}

この例では、REPORT ブロックが、 FUNCTION ブロック・パラメーター・リストに渡された両方の表に対して指定されています。 これらの表は、REPORT ブロックで指定された順序で、 最初に table2 に、次に table1 について表示されます。 REPORT ブロックで表の名前を指定することによって、 レポートが表示される順序を制御することができます。

例 2: 名前のない REPORT ブロック

%FUNCTION(dtw_sql) myStoredProc  () {
    CALL myproc   
   
%REPORT {
     ...    
    %ROW {  ....   %}  
     ...
   %} 
%REPORT {    
     ...    
    %ROW {  ....   %}     
     ...  
   %}  
%}

この例では、REPORT ブロックが、 FUNCTION ブロック・パラメーター・リストに渡された両方の表に対して指定されています。 REPORT ブロックには表の名前が指定されていないため、レポートは、 2 つの表についてストアード・プロシージャーから戻される順序で表示されます。

デフォルトのレポート、 および REPORT ブロックの組み合わせを使用して、複数のレポートを表示させる

例 : デフォルトのレポートと REPORT ブロックの組み合わせ

%DEFINE DTW_DEFAULT_REPORT = "MULTIPLE"
%FUNCTION(dtw_system) editTables (INOUT table1, table2, table3) {  
   %REPORT(table2) {    
    ...      
    %ROW {  ....   %}    
    ...   
  %}    
%}

この例では、1 つの REPORT ブロックのみが指定されています。 ブロックが table2 を指定しており、table2 は、 CALL ステートメントにリストされている 2 番目の結果セットであるため、 2 番目の結果セットがレポート表示に使用されます。 指定された REPORT ブロックが、 ストアード・プロシージャーから戻される結果セットの数より少ないため、 余分な結果セットについてはデフォルトのレポートが表示されます。 最初の結果セット table1 に対するデフォルトのレポートが最初に、 続いて 3 番目の結果セット table3 に対するデフォルトのレポートが表示されます。 出力表が 1 つ指定されていますが (table1)、 これはマクロ・ファイル中、後の処理に使用することができます。

複数の REPORT ブロックに関するガイドラインおよび制約事項

FUNCTION または MACRO_FUNCTIONブロックで、 複数の REPORT ブロックを指定する際は、以下のガイドラインおよび制約事項に従います。

ガイドライン :

制約事項 :


マクロにおける条件付き論理とループ

Net.Data により、IF および WHILE ブロックを使用して、 条件論理およびループを Net.Data のマクロに取り込むことができます。

IF および WHILE ブロックは条件リストを使用します。 これにより、1 つまたは複数の条件をテストし、 次にその条件リストの結果に基づいて、ステートメントのブロックを実行することができます。 条件リストには、 = および <+ などの論理演算子および用語が含まれ、 これらは引用符付き文字列、変数、変数参照および関数呼び出しから構成されます。 引用符付き文字列には、変数参照および関数呼び出しを含むことができます。 条件リストはネストできます。

以下のセクションでは、条件付き論理およびループを説明しています。

条件付き論理 : IF ブロック

IF ブロックを使用して、Net.Data マクロで条件付き処理を行います。 IF ブロックは、ほとんどの高級言語の IF ステートメントに類似しています。 その理由は、この IF ブロックは、1 つ以上の条件をテストし、 次に条件テストの結果に基づき、ステートメントのブロックを実行することができるからです。

IF ブロックは、マクロ内のほとんどどこにでも指定することができ、 それらをネストすることができます。 IF ブロックの構文は、Net.Data 解説書 の言語構成要素の章に示されています。

IF ブロックの規則 : IF ブロック構文の規則は、 マクロ内のブロックの位置によって決まります。 IF ブロックの実行可能なステートメント・ブロックに許される要素は、 IF ブロック自身の位置に依存します。

IF ブロックのストリング比較

Net.Data は、IF ブロック条件リストを、条件を構成している項の内容に基づき、 2 つの方法のうちのいずれか 1 つで処理します。 デフォルトのアクションは、すべての項をストリングとして処理し、 条件で指定されたストリング比較を実行します。 ただし、比較が整数を表す 2 つのストリングで行われる場合、比較は数値となります。 Net.Data は、 ストリングが数字のみ (オプションで前に '+' または '-' 文字) を含む場合、 ストリングが数値であると想定します。 ストリングは、'+' あるいは '-'以外の非数字文字を含むことができません。 Net.Data は、整数以外の数字の数値比較はサポートしません。

有効な整数ストリングの例 :
+1234567890
-47
000812
92000

無効な整数ストリングの例 :
-  20     (ブランク文字を含んでいる)
234,000   (コンマを含んでいる)
57.987    (小数点を含んでいる)

Net.Data は、IF 条件を、そのブロックを実行したときに評価します。 これは Net.Data によって最初に読み取られるときとは異なる場合があります。 たとえば、IF ブロックを REPORT ブロックに指定すると、Net.Data は、 REPORT ブロックを含む FUNCTION ブロック定義を読み取るときに、 IF ブロックに関連付けられた条件リストを評価しません。これを行うのは、 関数を呼び出して、それを実行するときなのです。 これは、IF ブロックの条件リストの部分、 および実行されるステートメントのブロックの両方に対してもあてはまります。

IF ブロックの例 : 他のブロック内に IF ブロックを含むマクロ

%{ This macro is called from another macro, passing the operating system
   and version variables in the form data.
%}
 
%IF (platform == "AS400")
  %IF (version == "V3R2")
     %INCLUDE "as400v3r2_def.hti"
  %ELIF (version == "V3R7")
     %INCLUDE "as400v3r7_def.hti"
  %ELIF (version == "V4R1")
     %INCLUDE "as400v4r1_def.hti"
  %ENDIF
%ELSE
     %INCLUDE "default_def.hti"
  %ENDIF
%MACRO_FUNCTION numericCompare(IN term1, term2, OUT result) {
  %IF (term1 < term2)
    @dtw_assign(result, "-1")
  %ELIF (term1 > term2)
    @dtw_assign(result, "1")
%ELSE
    @dtw_assign(result, "0")
  %ENDIF
%}
  
%HTML(report){
  %WHILE (a < "10") {
    outer while loop #$(a)<BR>
    %IF (@dtw_rdivrem(a,"2") == "0")
      this is an even number loop<BR>
  %ENDIF
    @DTW_ADD(a, "1", a)
  %}
%}

ループ構成体 : WHILE ブロック

WHILE ブロックを使用して、Net.Data のマクロでループを実行します。 IF ブロックと同様、WHILE ブロックにより、1 つ以上の条件をテストし、 次に、条件テストの結果に基づいてステートメントのブロックを実行することができます。 IF ブロックと異なり、ステートメントのブロックは、条件テスト結果に基づき、 何回でも実行することができます。

WHILE ブロックを HTML ブロック、REPORT ブロック、ROW ブロック、 MACRO_FUNCTION ブロック、および IF ブロック内で指定し、それらをネストすることができます。 WHILE ブロックの構文は、Net.Data 解説書 の言語構成要素の章に示されています。

Net.Data は、WHILE を、IF ブロックを処理するのと全く同じ方法で処理しますが、 ブロックを実行するごとに条件を再評価します。 そして、どの条件付きループ構成要素の場合も同じですが、 条件のコード化に誤りがある場合は、処理は無限ループに陥ることがあります。

例 : WHILE ブロックを持つマクロ

%DEFINE loopCounter = "1"


%HTML(build_table) {
%WHILE (loopCounter <= "100") {
%{ generate table tag and column headings %}
%IF (loopCounter == "1")
<TABLE BORDER>
<TR>
<TH>Item #
<TH>Description
%ENDIF

%{ generate individual rows %}
<TR>
<TD>$(loopCounter)
<TD>@getDescription(loopCounter)

%{ generate end table tag %}
%IF (loopCounter == "100")
%ENDIF

%{ increment loop counter %}
@DTW_ADD(loopCounter, "1", loopCounter)
%}
%}


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]