ExpressionScript - presentation/ja

=はじめに=

LimeSurveyでは、新しいExpressionScript（EM）モジュールを使用して、より複雑な分岐、評価、検証、および文言調整がサポートされています. LimeSurveyがサーバー内で行う置換、条件、評価の管理方法を置き換えることができます. また、ランタイムデータベースの読み込みのほとんどが不要になるため、処理速度が大幅に向上します. EMはDr. Thomas White（TMSWhite）が開発しました.

主な定義

 * 1) 式:  中括弧で囲まれたもの
 * 2) *開く中括弧の直後または閉じる中括弧の直前に空白がない
 * 3) *式の内容はEMが評価するため、数式、関数、複雑な文字列と日付処理を含めることができます.
 * 4) 文言調整: "パイピング"とも呼ばれますが、これは条件付きでテキストを変更するプロセスです.
 * 5) *すべての'置換フィールド'、参加者データ、回答データにアクセスできます.
 * 6) *質問、回答、およびそのプロパティにも簡単にアクセスできます.
 * 7) 出現条件式:  質問を表示するかを制御する新しい質問属性
 * 8) *出現条件式がある場合、その出現条件が真と評価された場合にのみ質問が表示されます.
 * 9) *内部では、すべてのarray_filterコマンドとarray_filter_excludeコマンドがサブ質問レベルの出現条件になります.
 * 10) SGQA:  LimeSurvey <= 1.91+で変数の命名に使われているものです.
 * 11) *Survey（アンケート）-Group（グループ）-Question（質問）-Answer（回答）の略です.
 * 12) *SGQA変数は123X5X382X971のようなもので、サブ質問の接尾辞がつくことがあります.
 * 13) *これらの変数はベースとなるS/Q/G/Aデータベースコードに固有のもので、変更する必要があることが良くあります.
 * 14) 式質問タイプ:  データベースに計算やレポートを保存する新しい質問タイプ
 * 15) *これはテキストを表示する質問のようなものですが、"この質問をいつも隠す"を設定しても、その内容はデータベースに保存されます.
 * 16) 質問コード:  EMでの使用が推奨される変数名
 * 17) *これは質問の目的を示すわかりやすい名前にすることができ、複雑なロジックを読みやすくなります.
 * 18) *質問コードは数字で始めることはできないので、質問番号を質問コードにするときは、単に"q1"、"q1a"、"g1q2"のようにしてください.
 * 19) *現在のところ、データをSPSSまたはRにエクスポートすると、これが変数名になります. したがって、統計分析を行う場合は、ユニークにしなければなりません.

EMを使わなければならないのか？
短い答えは"いいえ"ですが、作成するアンケートがどれだけ複雑かによって変わります.

例えば、条件エディターでは、アンケートの質問に適用できるいくつかの基本的な式を扱います. ただし、条件エディタには制限があります. EMが使用されているのはこのためです. EMがカスタマイズの可能性を広げています.

条件と出現条件式の両方を使えるか？
はい. 質問によって条件エディターを使用することも、出現条件式を使用することもできます.

条件と式の両方を同じ質問で設定することはできません. 条件が設定されると、出現条件のフィールドに書き込まれた式は使われません. さらに、出現条件式フィールドは手動では編集できません.

しかし、質問内で式と条件の両方を使用する方法があります. 上で述べたように、条件式は出現条件式のフィールドを置き換えます. 完了したら、新しく作成された式を確認し、テキストエディターにコピーします. 条件エディターで作成した条件を削除し、残りの式と一緒にテキストエディターにコピーした条件ベースの式を追加して質問を編集します.

条件と関連のどちらを選ぶべきか？
各々の長所と短所のリストを以下に示します.

=はじめに=

式マネージャーを始める最善の方法は以下のとおりです.
 * http://www.limesurvey.org/en/download からLimeSurveyの最新の安定版をインストールしてください.
 * サンプルアンケートをインポートして確認します.
 * 使用例と使用法やステップバイステップの例を読んでください.
 * EMに関するドキュメント（このページ）を読んでください.
 * 分離された式の単体テスト（上級）
 * すべてのEM関数と演算子、PHPとJavaScriptの結果の使用例を表示します.
 * PHPとJavaScriptのバージョンで異なる結果を生成する関数はほとんどありません. このページの内容を踏まえ、EMロジックを適切に計画することができます.

=用語=

これらの単語は、EMの機能を記述するために一般的に使用されます.
 * 出現条件に基づく分岐 - 質問が出現条件を満たす場合は質問し、満たさない場合は質問しません（非表示となり、データベース内ではNULLとして格納されます）. 質問エディターパネルと質問グループエディターパネルに出現条件フィールドがあります. 後者では、各質問に同じ条件をコピーしたり、グループと質問レベルの条件付きロジックを組み合わせたりせずに、一連の条件をグループ全体に適用するために使用されます.
 * 文言調整 - どの質問を表示すべきか決めたら、文言調整（パイピングとも呼ぶ）でどのように質問するかを指定します. これは簡単な置換（例: {TOKEN:FIRSTNAME}）だけでなく、回答者が回答した性別、数に基づいて、動詞や名詞を変化させることもできます. また、アンケート回答者が回答したか（またはどのように回答したか）に基づいて、アンケート回答者に送信するメッセージを変更することもできます.
 * 式 - EMでは、式という新しい質問タイプを追加され、式の結果が格納されます. 式はページ内で非表示であっても結果が計算され、データベースに書き込まれます. したがって、非表示のまま行うスコア計算、複雑な式に基づくナビゲーション、評価、データベース内に作成・格納されるレポートに使用されます.

出現条件とカスケードされた出現条件
すべての質問タイプで、質問が表示されるかどうかを制御する出現条件オプション が追加されました. EMは、アンケートに登場する順に出現条件式を処理します. 式が真（または式がない - 古い形式のアンケート向け）の場合、質問が表示されます. 出現条件式が偽の場合、質問は非表示になり、その値はデータベースでNULLになります. グループに出現条件を満たす質問がない場合、グループ全体がスキップされます.

さらに、式に含まれる変数のいずれかの出現条件が偽の場合、式は常に偽と評価されます. これにより出現条件の入れ子が可能になり、各々の質問に対して非常に長い出現条件の式を書く必要がなくなります.

たとえば、5つの質問Q1〜Q5があり、Q1が答えられたらQ2、Q2に答えられたらQ3などを表示したいとします. 出現条件の式は次のようになります.

グループレベルの出現条件
ExpressionScriptはグループレベルの関連性もサポートしています. これにより、ループの実装が容易になります. 最大10のエンティティ（製品や家族など）から情報を収集したい場合、（家族の人数を答えさせたり、長いリストから好きな製品を選択させたりして）繰り返しが必要なエンティティの数を最初に判断します. エンティティの数がわかったら、10こある繰り返し用グループごとに{count >= 1}, {count >=2}, ... {count >= 10}のようにグループレベルの出現条件を設定します. 各々のグループ内では、質問レベルの条件付きロジック（例：各々のエンティティの性別や年齢に基づく質問）を作成できます. 質問とグループレベルの出現条件の式は、表示すべきかを決定するためにAND演算されます.

例を確認するには、次のアンケートをインポートします. [[Media:EM survey - Cohabs.zip|国勢調査の例]]

以下のスクリーンショットでは、回答者が少なくとももう1人の同居者と一緒に住んでいる場合、グループPerson 1が表示されている（出現条件を満たしている）ことがわかります.



文言調整／パイプ
中括弧内のものはすべて式として扱われるようになりました（後述する例外が1つあります）. 式はすべてのLimeReplacementFields、すべての変数（いくつかのエイリアスを介して）、すべての一般的な演算子（数学、論理、比較）、数多くの関数（クライアント側でも動的に機能する）にアクセスします.

これらの式を使用すると、次のようなことができます.
 * 1) 先行する質問への回答に基づいて文言調整されたメッセージを回答者に表示する
 * 2) 評価を作成し、その結果に基づいて評価結果を表示する（条件付きで分岐、またはメッセージを表示する）（評価モジュール自体は使用しない）
 * 3) 質問、回答、およびレポート内の動詞、名詞を変化させる
 * 4) アンケートの最後で、"回答を表示する"ページの前に回答の要約を表示する

式
式と呼ばれる新しい質問タイプがあります. これは、表示されている値をデータベースに格納することを除き、テキスト表示質問タイプと似ています. したがって、式の質問テキストに評価計算が含まれている場合、パブリックまたはプライベート統計情報内に表示できる変数の値がデータベースに格納されます.

=構文=

中カッコ内に含まれるものはすべて式と見なされます（ただし、先頭または末尾に空白がないことが必要です. これは、式マネージャーが埋め込みJavaScriptを処理しないようにするためです）.

開く括弧の後、閉じる括弧の前に空白がない限り、式は複数の行にまたがっても構いません. 特に次のような入れ子のif構文が見やすくなります.

式マネージャは、次の構文をサポートしています.
 * 標準的な数学演算子（例: +,-,*,/,!）
 * 標準的な比較演算子（例: <,<=,==,!=,>,>=, およびこれらと同じ意味を持つlt, le, eq, ne, gt, ge）
 * かっこ（入れ子の式をグループ化できます）
 * 条件演算子（例: &&, | | およびこれらと同じ意味を持つand, or）
 * シングルまたはダブルクオートで囲まれた文字列（別のクオート記号で囲まれた文字列を含めることができます）
 * コンマ演算子（式のリストを持ち、最終結果を返します）
 * 代入演算子（=）
 * 定義済み変数（質問、質問属性、回答を参照する） - 例: SGQAコード
 * 定義済み関数（80以上あり、簡単に追加できます）

演算子
EM構文は、通常の演算子の優先順位に従います.

番号と文字列の不一致およびアルファベット／数字の比較に関する注意
次の用語は、EMの機能を記述するためによく使用されます.

たとえば、Q0.NAOKが数値質問で値が9である場合、 はtrueとなります. これは、演算子 が、これを数値の比較ではなく、文字列の比較とみなすためです.

整数値を確実に比較するには、 を使用します. Q0.NAOKが数値でない（空または文字列）場合は、intval(Q0.NAOK) === 0となります. 文字列値を比較する（"A" < "B"）場合は、直接strcmpを使用します. または

代入演算子（=）を使用する際の注意
代入演算子は、予期しない副作用を引き起こす可能性があるため、どうしても必要な場合を除いて使用しないでください. たとえば、先行する質問の値を変更すると、その質問と現在の質問との間で入れ子となった出現条件と検証ロジックが再計算されないため、内部的に一貫性のないデータになることがあります（たとえば、NULLにすべきなのに回答がある、回答すべきだがスキップされる、等）. 一般に、変数に値を割り当てる場合は、式の質問タイプを作成し、その値を設定する式を使用する必要があります. しかし、この演算子がまれに必要となるため用意されています.

この演算子について注意を促すため、構文式の中では赤いフォントで表示されています（"=="と混同しないようにするため）.



代入演算子を使用する
代入演算子を使用する主な理由は次のとおりです.
 * 既定値を設定できない質問の既定値を式を使って設定する必要がある（ユーザーインターフェイスでは回答オプションの1つを選択できるが、式を入力することができないリスト、ラジオなど）. ただし、LimeSurveyは式がその質問に対する許容可能な回答を生成できるかどうかを検証できないため、注意して使用してください.
 * 後続の回答に基づいて先行する質問への回答を強制的に変更する必要がある
 * など...

この目的のために、式マネージャーシステムを使用することができます. この目的のため、式を使用する方がよいでしょう.

例:
 * 質問への回答を小文字にする:
 * アンケートの開始時に配列質問タイプに既定の回答を設定する:
 * アンケート開始時に配列テキストの質問タイプに対する既定の回答を設定する:
 * 条件付きの回答を設定する:

= XSS セキュリティ =

XSSを有効にすると、式マネージャーシステムの一部がつかえなくなります.
 * 式でHTMLタグを開き、別の式で閉じる
 * URL内で複雑な式を使用する

例と解決策
 * はXSSでは正常に動作しないため、次のようにします.
 * は、ここでは式の質問を使います. なぜなら、完全な質問コードがOKだからです.

=変数へのアクセス=

式マネージャーでは、必要な変数に読み取り専用でアクセスできます. 互換性のため、次のものにアクセスできます.
 * TOKEN:xxx - TOKENの値（例: TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5）（匿名アンケートでないもののみ）
 * INSERTANS:SGQA - 回答の表示値（"はい"など） - {QCODE.shown}と類似
 * すべてのテンプレートで使われる{XXX}の値
 * 質問テキストでは、質問idの代わりに{QID}、質問のSGQAの代わりに{SGQ}を使います.

さらに、式マネージャーでは、質問コード（データベース内の質問テーブルの'タイトル'列）で変数を参照できます. これは、データをSPSS、R、またはSASにエクスポートするときにも使用される変数ラベルです. たとえば、名前、年齢、性別に関する質問がある場合、12345X13X22、12345X13X23’'、12345X13X24の代わりに、変数name、age、gender''で呼び出すことができます. これにより、誰もが簡単にロジックを理解し検証することができ、グループや質問の数を把握しなくても質問をシャッフルすることができます.

重要: 先行するページや質問で発生する変数を参照するのが安全です.

さらに、式マネージャーを使用すると、多くの質問プロパティにアクセスできます.

HTMLエディターの問題
HTMLエディターを使用すると、一部の文字がHTML実体に置き換えられます.
 * & → &amp;amp;
 * < → &amp;lt;
 * > → &amp;gt;

HTMLエディターを使用する場合は、次のものを使用する必要があります.
 * & に対しては and
 * < に対してはlt
 * <= に対してはle
 * > に対してはgt
 * >= に対してはge

式の中のHTML表現を消去することをお勧めします. LimeSurvey HTMLエディターを使用する場合は、エディターの左上にある"ソース"ボタンをクリックして、式に関連しないすべての文字を削除します（例： 、 など）.

=Qcode変数の命名=

Qcodeを構成する方法（およびいくつかのプロパティにアクセスする方法）の質問タイプ別の詳細は次のとおりです. 一般に、Qcodeは次のように構成されます.

QuestionCode. '_' . SubQuestionID. '_' . ScaleId

commentとotherの場合、対応する質問コードはそれぞれQuestionCode_comment、QuestionCode_otherです.

=NAOKの利用=

NAOK --> "Not Applicable"（該当なし、NA）は問題ない（OK）

NAOKは、すべてまたは一部の変数が出現条件を満たさないということです. "Not Applicable"（該当なし、NA）は問題ない（OK）.

例: count(Q1_SQ1,Q1_SQ2,Q1_SQ3,Q1_SQ4) は、Q1のサブ質問の一つがフィルターされている場合、常に空文字となります. このような質問で、チェックされたサブ質問の数をカウントするには、count(Q1_SQ1.NAOK,Q1_SQ2.NAOK,Q1_SQ3.NAOK,Q1_SQ4.NAOK)とします. サブ質問が隠されている場合、式マネージャーは空文字を返します.

NAOKがない場合、1つの質問または1つのサブ質問が非表示になっている場合、式マネージャーは常に空の文字列を返します（falseを返すのと同じです）.

.shownは常にNAOKの仕組み（非表示の時は空文字）を使っていますが、回答のコードが必要な場合は、質問コードの後に.NAOKを付加するとよいでしょう. それが必要で、内容を理解している場合は別です.

詳細は、入れ子条件の上書きの項にあります.

=予約変数 "this"、"self"、"that"=

回答されたサブ質問の数を数えたり、スコアを合計するなど、質問の全体を評価したい場合がよくあります. また、質問の特定の行や列（行や列の合計を取得してデータベースに格納するなど）を処理したい場合もあります. 以下の予約変数により、そのプロセスを簡単に実現できます.

変数"This"
"this"変数は、"質問全体の検証式と"サブ質問の検証式"のオプションで排他的に使用されます（後者はGUIからは使えません）. 該当の質問内の各セルの変数名に展開されます. したがって、各エントリが3より大きいかどうかを確認する場合は、"サブ質問の検証式"を(this > 3)に設定します.

変数"Self"
"self"と"that"変数はより強力で、式を処理する前に展開されるマクロとして機能します. "self"変数の構文は次のとおりです.
 * self
 * self.suffix
 * self.sub-selector
 * self.sub-selector.suffix


 * 1) suffixは、通常のqcode接尾辞のいずれかです（例: NAOK、value、shown）.


 * 1) サブセレクターは次のようなものがあります.
 * comments - コメントとなるサブ質問のみ（コメント付き複数選択、コメント付きリストなど）
 * nocomments - コメントのないサブ質問のみ
 * sq_X - Xは行か列の識別子. パターンXと一致するサブ質問のみが選択されます. 検索は完全なコード識別子で行われ、sq_XはnX、X、Xnといったサブ質問にマッチしますが（例えば、sq_1を使用する場合はサブ質問a1、1a、1、11または001がマッチします）. 二元スケール質問タイプではサブ質問はQCODE_SQCODE_1とQCODE_SQCODE_1になり、順位付け質問タイプではサブ質問コードがQCODE_1,QCODE_2 ....となります.

例:
 * 質問に対して何らかの回答があったか？ -> {count(self.NAOK)>0}
 * この質問の評価点数は？ -> {sum(self.value)}

行と列の合計を取得することもできます. 列A-Eと行1-5の数字の配列があるとします.
 * 総合計は？ -> {sum(self.NAOK)}
 * 列Bの合計は？ -> {sum(self.sq_B.NAOK)}
 * 行3の合計は？ -> {sum(self.sq_3.NAOK)}

変数"That"
"that"は"self"に似ていますが、他の質問を参照することができます. 構文は次のとおりです.
 * that.qname
 * that.qname.suffix
 * that.qname.sub-selector
 * that.qname.sub-selector.suffix

qnameは、サブ質問拡張がない質問の名前です. 質問 'q1'を作成したら、それがqnameとなります.

例:
 * 質問q1に対して何らかの回答があったか？ -> {count(that.q1.NAOK)>0}
 * q2の評価点数は？ -> {sum(that.q2.NAOK)}
 * q3の総合計は？ -> {sum(that.q3.NAOK)}
 * q4の列Cの合計は？ -> {sum(that.q4.sq_C.NAOK)}
 * q4の行2の合計は？ -> {sum(that.q4.sq_2.NAOK)}

"self"と"that"変数は、出現条件、検証、文言調整の式で使用できます.

注意すべき点は、ロジックファイルの表示機能を使用すると、"self"と"that"を展開した値が表示されることです. これにより、生成される実際の式が表示され、その結果、変数が存在することを検証できるようになります. かなり長い式になるかもしれないので、混乱しているように見えるかもしれません. しかし、質問を編集すると、"self"や"that"を使っている元の式が表示されます.

=関数へのアクセス=

式マネージャーでは、以下に示すように、数学関数、文字列関数、およびユーザー定義関数が利用できます. これらの関数にはPHPとJavaScriptに同等のものがあるので、サーバ側（PHP）とクライアント側（JavaScript）で同じように動作します. 新しい機能を追加するのは簡単です.

実装済み関数
現在、以下の関数が利用可能です.

=式マネージャーとローカル変数=

ページのJavaScriptを適切に構築するため、式マネージャーはページに設定されている変数とJavaScript IDが何であるかを知る必要があります（例: document.getElementById(x)）. また、他のページにどの変数が設定されているかも知る必要があります（これにより、必要なフィールドが存在しているか確認できます）.

条件の入れ子
いずれかの変数がfalseである場合、式全体はfalseになります. たとえば、次の表では、N/Aは変数の1つがtrueでないことを意味します.

入れ子条件の上書き
出現条件を満たした回答の合計を表示したいとします. 式 {sum(q1,q2,q3,...,qN)}を使おうとするでしょう. しかし、これは内部的にLEMif(LEManyNA("q1","q2","q3",...,"qN"),"",sum(LEMval("q1"),LEMval("q2"),LEMval("q3"),...,LEMval("qN")))に変換されます. これにより、値q1〜qNのいずれかが出現条件を満たさない場合、式は常にfalseを返します. この場合、sumはすべての質問が出現して回答されない限り"0"となります.

この問題を回避するために、各変数には".NAOK"という接尾辞（「Not Applicable」はOK）を追加することができます. このような場合、次のような現象が発生します. 変数q1.NAOKがあるとします.
 * 1) q1はLEManyNA節には追加されません
 * 2) LEMval('q1')は回答が出現条件を満たしているかを確認し、そうでない場合は "" を返します（出現条件を満たさない回答は無視されますが、式全体を無効にしません）.

したがって、合計を求める方法は、次の式となります. sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK)

.NAOK接尾辞を使用することで、いくつかの可能な経路を経て、後に共通の経路に収束するアンケートを設計することができます. 例えば、回答者が通常の範囲から外れた回答をしたとします. アンケート実施者は、有効な結果を得られない可能性があることを回答者に警告し、アンケートを継続するかどうかを尋ねることができます. 彼らが"はい"と答えると、残りの質問が表示されます. "残りの質問"の条件は、回答が正常範囲内で回答されたか、または正常範囲外で回答した場合にのみ表示される質問に対して"はい"と回答したかどうかをチェックします.

=式マネージャーはどのように条件付き文言調整を実現するか？=

ここでは、カスタマイズ（質問タイプ'expr'は式を意味します）の例を示します.

このアンケート例をダウンロードするには、次のリンクをクリックしてください. [[Media:No_of_kids_-_Micro_Tailoring.zip|子供の数のアンケート例]]

これらの質問はすべて1つのページ（たとえば同じグループ）に入れることができ、出現条件に合致する質問のみが表示されます. さらに、子供の年齢を入力すると、最後の質問のsum式がページ上で動的に更新されます.

式マネージャーは、各式を名前付き  要素で囲むことでこの機能を提供します. 値が変更されるたびに、その  要素に表示される式を再計算し、再表示します. そのようなカスタマイズされた式が同じページに数十、または数百もあっても、ページは一度の画面更新ですべて再表示されます.

=構文ハイライト=

式の入力と検証を支援するために、EMでは以下のような構文強調表示機能を提供しています.

構文ハイライトの種類と意味
=参考記事=