サポート > リポジトリ > 計算式 > 基本的な書き方
ja | en

項目IDをプレースホルダで括ることで式中に表現できます。

モデル項目詳細定義ダイアログの「詳細 > 自動計算」の欄に、計算式を記述します。

図1 計算式の記述例

Wagby がサポートしている四則演算式は次のとおりです。

演算子 説明
( ) 括弧
* 乗算
/ 徐算 (注意点...)
+ 加算
- 減算または符号反転
% 余り
自動計算項目は計算により値が一意に決まるため、登録・更新画面では読み取り専用項目となります。

式中に(同一モデル内の)項目を指定することができます。項目名の指定は「${...}」と記述します。(... の部分に英語項目名を指定します。)

${...}

以下に例を示します。

モデル項目 value1 に 1 を加算した値を求める。
${value1} + 1
モデル項目 kosuu とモデル項目 tanka の積に1.05を乗じた値を求める。
${kosuu} * ${tanka} * 1.05

条件判定式の書き方は、対象となる項目の「型」によって異なります。

数値型 文字列型 日付型 (*3)
一致 ${v1}==${v2} EXACT(${v1},${v2}) DATE(${v1})==DATE(${v2})
または
EXACT(${v1},${v2})
不一致 ${v1}!=${v2} !EXACT(${v1},${v2}) DATE(${v1})!=DATE(${v2})
または
!EXACT(${v1},${v2})
より大きい ${v1}>${v2} - DATE(${v1})>DATE(${v2})
より小さい ${v1}<${v2} - DATE(${v1})<DATE(${v2})
以上 ${v1}>=${v2} - DATE(${v1})>=DATE(${v2})
以下 ${v1}<=${v2} - DATE(${v1})<=DATE(${v2})
未設定 - ISBLANK(${v1}) ISBLANK(${v1})

標準は「値をデータベースに保存する」となっています。

図2 値をデータベースに保存するが有効な状態
  • 計算項目が「値をデータベースに保存する」となっていた場合、登録・更新時にのみ計算されます。表示時はデータベースに格納されている値がそのまま用いられます。
  • 計算項目が「値をデータベースに保存する」となっていない場合、表示のタイミングで常に最新の値で再計算されます。

自分自身を演算する場合

数値型項目に次の式を設定した場合を想定します。

Me()+1
Me は自分自身を示す特別な関数です。

このとき、データベース保存の有無により計算結果は異なります。

種別 説明
DB保存あり更新の都度、値は +1 されて保存されます。
DB保存なし初期値 0 が +1 され、常に 1 となります。

Excelでは格納できる有効桁数は15桁となっています。そのため、例えば "11000.00000000001" は強制的に "11000.00000000000" となります。しかし Wagby は Java の浮動小数点仕様に準拠しているため、Excelと動きが異なります。(上記例では、強制的に小数部をゼロとすることはありません。)そのため、小数点を含む計算では Excel と結果が異なることがあります。ここでは、計算誤差を回避するいくつかの手法をご説明します。

金額の計算(演算誤差を考慮した四則演算)

加減乗除の演算子 (+,-,*,/) ではなく、関数 ADD,SUB,MUL,DIV を用いると、演算誤差を考慮した加減乗除を行うことができます。大きな金額を扱う場合や、途中で小数を含むような計算で有効です。

例えば ${item1} + ${item2} という式は、次のように記述できます。

ROUND(VALUE(ADD(${item1},${item2})),1)

ADD,SUB,MUL,DIV関数の戻り値は、数値の文字列表現です。例えば "123.456" となります。そこでVALUE関数を適用することで、8バイト浮動小数点に戻すことができます。ROUND関数は数値を四捨五入して指定された桁数にします。詳細は、各関数の説明をお読みください。

出力フォーマットの指定

出力フォーマットを指定することができます。例えばフォーマット中に「%」文字を指定すると、計算結果が自動的に100倍されます。詳細は「数値-出力フォーマット」を参照してください。

整数型の計算結果を小数点型で表現する場合

整数型同士の計算結果を小数点で表現したい場合、計算時に(整数型を)小数点型に「型変換」する方法があります。

次の計算式のように項目名の前に「(double)」と「8バイト浮動小数点(double)型」への変換を明記します。

(double)${uriagekingaku}/(double)${yosankingaku}
この方法は Java 開発者向けです。(double などの「型」は Java 文法に準拠しています。)

演算誤差を回避する式の書き方

小数点型の演算には常に誤差が含まれることに注意してください。例えば次の式において

ROUND(${item1}*0.12+${item2}*0.34, 1)

ROUND関数に渡す計算値が 10.8499999999 となった場合、ROUND によって 10.9 ではなく 10.8 になってしまいます。

ADD,SUB,MUL,DIV 関数を使うことで、このような問題を回避できますが、もう一つの簡易手法として、式を工夫してできるだけ整数演算に持ち込むことで演算誤差を極小化する方法があります。

上の式は、次のように作成することができます。

ROUND((${item1}*12+${item2}*34)/100.0, 1)
計算結果が一時的に整数の範囲を超える場合には注意が必要です。上記の例で item1 が 10 億という値をとる場合、12倍すると 120 億になりますが、これは整数型の表現できる範囲(42億)を超えるため正しい結果になりません。整数型が表現できる数値の範囲は「モデルの定義 > 」をお読みください。

"null" は "値がない" という意味で用いられます。null がセットされた項目は、表示時に空白となります。

"null" と "0" は違うものです。また、"null" と "" (空文字) も違うものです。 null は値がない、という特別な意味をもちます。
必須項目に null をセットすることはできません。

未入力項目(入力フィールドだが、何も入力していない状態)の値は、次のようになります。

数値0
それ以外null

このため式中で "0" という値の扱いは注意が必要です。入力値が "0" なのか、未入力状態なのかを区別できないためです。

例えば数値型項目 item1 に値が入力されていればそれを使い、未入力なら item2 の値を使うという式を次のように記述した場合、意図に反して item1 が未入力でも値 "0" が返されます。

IF(${item1} >= 0, ${item1}, ${item2})

項目 item1 に格納される値は常に "0" より大きいという場合、等号 (=) を除くことで意図通りの動作になります。

IF(${item1} > 0, ${item1}, ${item2})

ISEMPTY関数

ISEMPTY関数を使って項目に値が入っているかどうかを判定することができます。未入力の場合は true を返します。入力済の場合は false を返します。

数値型項目を例に説明します。

型と性質ISEMPTY関数の戻り値説明
数値型-必須false必須項目の場合、初期値0がセットされているため。
数値型-非必須:未入力true未入力の判定が可能。
数値型-非必須:入力ありfalse入力された時点でfalseになる。

計算式に三項演算子 "?:" を含めることができます。

( 式 ) ? 式が真の場合の値 : 式が偽の場合の値
書式 説明
式 ? x : y 式が真なら x を返します。式が偽なら y を返します。
x, y も式という場合もあります。

例:三項演算子を使って自動計算の結果に null を設定する

次の例は、項目 item1 の値が 0 より大きければ 1 をセットします。そうでなければ null をセットします。

${item1} > 0 ? 1 : null

ゼロで徐算することはできません。これを回避するために三項演算子を使うことができます。

( (${bunbo}!=0) ? ${bunsi}/${bunbo} : 0 )

これは項目 bunbo (ここでは整数型とします)の値が 0 なら "0" を、そうでなければ bunsi/bunbo の計算結果を格納するという意味になります。 なお、数値が等しくないという判定は「!=」を使います。

上の式において、項目 bunsi や bunbo は整数型だが、計算結果は小数点を格納する場合は、次のように(double)を項目IDの前に付与する強制的な型指定を行うことができます。

( (${bunbo}!=0) ? (double)${bunsi}/(double)${bunbo} : 0.0 )

初期値を設定するタイミングは、自動計算の「後」になります。 そのため、初期値の値を自動計算の条件判定に使うような記述を行うことはできません。

繰り返し項目は、内部では「配列」形式でデータを格納しています。 従って、配列を引数に受け取り、配列を返すような関数を使って、繰り返し項目の値を、別の繰り返し項目へセットすることができます。

例:繰り返し項目 toAddress から、メールアドレス部のみを抜き取って、同じく繰り返し項目 toEmailAddress へセットする場合、toEmailAddress へ次の式を記載します。

MAILADDRESS(${toAddress})

検索条件の初期値に式を記述するとき、対象となる項目が範囲検索に対応している場合は次のルールがあります。

範囲検索の場合、内部では上限と下限を表す二つの項目が用意され、それぞれ、元の項目名に "1jshparam" "2jshparam" が付与されます。例えば、整数型の項目 num については、num1jshparam と num2jshparam が内部で用意されます。

例:検索条件項目 item1 の初期値として、同じ検索条件項目である num の上限値に 1 を加えた値を設定する場合は次のように記述します。

${num1jshparam}+1

親子モデル関係において、子モデルの情報が親モデル側に反映されます。

例:親モデル側の項目で、子モデルの数をかぞえるための式 COUNT(${child_lp}) を用意したとき、子モデルの登録や削除時に、親モデルの該当項目も変更されます。

ブラウザに Internet Explorer 9 を利用する場合、オートコンプリート機能を用いて値を入力した後、フォーカスを移動しても自動計算項目が更新されません。これはIEの仕様で、オートコンプリートで値を入力すると(JavaScriptの)changeイベントが発生しないためです。