スポンサーリンク

【pleasanter】計算式(拡張)活用サンプル②~入力チェックに利用する~

プリザンター
スポンサーリンク
※当サイトは広告を含みます

※おことわり
2025年2月時点の情報です。プリザンターのバージョンは 1.4.9.1 です。Google Chrome でやっています。
javascript,html,cssともに初心者です。調べながら、やってみながら、きっとこうすればいいんだ!という感じで書いていますので、間違っている、または効率的な書き方ではない可能性が大いにあります。間違ってるよ!とか、こうしたほうがいいよ!ということがありましたら、コメント等で教えていただけると大変ありがたいです。

1.はじめに

Excel関数好きにはプリザンターの計算式(拡張)がうれしい。なぜかというと、Excelの関数とほとんど使い方が同じなので、調べなくても関数名で使い方の予測がつき、さささっとよどみなくできちゃう。スクリプトだと、いちいち調べてコピペっているので。。。

前回は、リマインダーで利用する計算式(拡張)サンプルをやってみました。
【pleasanter】計算式(拡張)活用サンプル①~リマインダーの日付として利用する~

今回は、計算式(拡張)を入力チェックに利用する、というのをやってみました。
基本的な使い方等は以下の記事、または公式マニュアル。関数の一覧などは公式マニュアルをご参照ください。
【pleasanter】計算式(規定・拡張)についてまとめてみた

公式マニュアル
テーブルの管理:計算式(既定)
テーブルの管理:計算式(拡張)
計算式(拡張)の関数一覧
計算式(拡張)の関数で使用する論理式

計算式の構文等の詳しい説明は割愛していますので、公式マニュアルをご参照ください。

以下、基本的に「計算式」タブで「計算方法」は[拡張]を利用、「エラーを出力する」はオフ、「表示名を使用しない」はオフ でやっています。

2.複雑な入力チェックに使用する

項目の組み合わせで入力制限を設定したいときとかに、計算式(拡張)にチェック結果を反映させて、その値を入力チェックに利用する。

(1)やりたいこと

例① 以下の条件が満たされていない場合、「作成」「更新」ができない。

条件
分類Aで「100,取得済」が選択されている場合、説明Aに文字列が入力されていること。
分類Aで「200,未取得」が選択されている場合、説明Bに文字列が入力されていること。
※分類Aで「900,対象外」が選択されている場合、説明A・説明Bとも未入力でOK。

(2)計算式とスクリプトでやってみる

エディタの設定

分類A:選択肢 100,取得済/200,未取得/900,対象外
    入力必須
    自動ポストバック=ON

日付A:自動ポストバック=ON

説明A:自動ポストバック=ON

チェックA:表示名「入力チェック」

計算式(拡張)

使用した関数:$IFS, $AND, $NOT, $ISBLANK, $LEN, $TRIM

条件を満たした場合、チェックAがオンとなり、それ以外はオフとなるように計算式(拡張)を設定します。対象(出力先)は「入力チェック(チェックA)」を指定します。

$IFS($AND(分類A == 100, $NOT($ISBLANK(日付A))), 1, $AND(分類A == 200, $LEN($TRIM(説明A))>0), 1, 分類A == 900, 1, "true", 0)

計算式の説明

$IFS は、条件を複数書いていくことができ、頭から順番に判定し、最初にtrueとなった条件の後の処理を返してくれます。

$IFS(条件1, 条件1がtrueの場合の処理, 条件2, 条件2がtrueの場合の処理, … , “true”, どの条件にも当てはまらなかった場合の処理)

case式 みたいな、if elseif … みたいな感じ。最後にどの条件にも当てはまらなかった場合(elseみたいな部分)は “true” として問答無用で true にしています。

条件式のところで $AND 関数を使用し「カッコ内の条件のすべてを満たすこと」を要求しています。
最初の条件式は「分類Aが100 かつ 日付Aに日付が指定されていること」を判定しています。
二番目の条件式は「分類Aが200 かつ 説明Aに1文字以上の文字が入力されていること」を判定しています。$NOT($ISBLANK(説明A)) でもよいのですが、説明項目の入力欄でスペースキーちょいちょいと押して空白文字をいれても通ってしまうので、なにか文字を入力しないと許さん、という仕様とするため$LEN$TRIM を使用しました。しかし、文字入力無しでも改行入れれば通るということに気が付きました。。。が、まあしかだがない。

チェック項目をオンにするには 1 , true, “true” のいずれでも大丈夫でした。
オフにするには 0 , false , “false” 。
以下、分類Aが100の場合、チェックオン、そうでない場合チェックオフにする計算式。
出力先:チェック項目
$IF(分類A == 100, 1, 0)
$IF(分類A == 100, true, false)
$IF(分類A == 100, “true”, “false”)

チェックがオンでないと「作成」「更新」させない制御

・エディタの設定でやる
チェックAを「入力必須」にすると、チェックAがチェックされていない場合、「作成」「更新」ができなくなります。
また、チェックAは手で切り替えしてほしくないですよね。でも「読取専用」とすると、入力必須のチェックが働かないようです。「非表示」の場合は大丈夫。
ただし、エラーのメッセージが「入力された内容に誤りがあります」というメッセージとなり、「どこが悪いの?」とわかりにくい。

・スクリプトでやる

じゃあ、初めから全部スクリプトでやればよいのでは?というツッコミがはいるかもしれませんが。

スクリプトに以下のコードを入力します。出力先は「新規作成」「編集」。
ほぼ公式マニュアルからのコピペ。

$p.events.before_validate = function (args) { 
  //チェックAがチェックされているか,されていないか
  if ($p.getControl('CheckA').is(':checked')) {
    //チェックされている場合、trueを返す
    return true;    //trueのときは更新される
  } else {
    //チェックされていない場合、メッセージを表示し、falseを返す
    $p.setMessage('#Message', JSON.stringify({
        Css: 'alert-warning',
        Text: '「取得済」の場合は日付A、「未取得」の場合は説明Aの入力が必須です。'
    }));
    return false;    //falseのときは処理が止まり、更新されない
  }
}

チェックAは「読取専用」でも「非表示」でも大丈夫です。

チェックAがチェックされているか、の部分は,
$(‘#Results_CheckA’).is(‘:checked’) //記録テーブル
$(‘#Issues_CheckA’).is(‘:checked’) //期限付きテーブル
でも大丈夫です。

公式マニュアル
開発者向け機能:スクリプト:$p.events.before_validate
開発者向け機能:スクリプト:$p.setMessage
開発者向け機能:スクリプト:$p.getControl

これまではスクリプトで項目の値チェックも書いていたりしたので、それに比べてスクリプトは短くなる。けれどもチェックAってなんだ?と計算式を見ないと、入力制御の条件がわからないのは難点。よしあしですね。

(3)計算式と項目の「入力検証」でやってみた

スクリプトを使わないチャレンジ(笑)

エディタの設定

分類A:選択肢 100,取得済/200,未取得/900,対象外
    入力必須
    自動ポストバック=ON

日付A:自動ポストバック=ON

説明A:自動ポストバック=ON

分類B:非表示=ON、自動ポストバック=ON
以下の「入力検証」を設定します。
入力内容が「OK」と完全一致しないとダメよ、という正規表現 ^OK\ をクライアント正規表現に入力します。

分類C:スタイル「ワイド」、読取専用=ON、コントロールcss=mystyle

スタイルの設定

これはやらなくてもOKです。ちょっと目立たせたかった。出力先は「新規作成」「編集」

.mystyle {
    background-color: lightpink;
}

計算式(拡張)

使用した関数:$IFS, $IF, $AND, $NOT, $ISBLANK, $LEN, $TRIM

例①をちょっと変えるだけ。入力チェックがOKであれば分類Bに「OK」の値をセット。チェックNGであれば分類Bに「NG」の値をセット。
対象(出力先)は「分類B」にします。

$IFS($AND(分類A == 100, $NOT($ISBLANK(日付A))), "OK", $AND(分類A == 200, $LEN($TRIM(説明A))>0), "OK", 分類A == 900, "OK", "true", "NG")

もうひとつ計算式。出力先は「分類C」。「分類C」を注意を促すメッセージを出力する項目としてます。
最初に $IF で分類B の値が「NG」かどうかで切り分けし、「NG」の場合の処理を $IFS で分類A の値で分岐処理しています。

対象(出力先)は「分類C」

$IF(分類B == "NG", $IFS(分類A == 100, "「取得済」の場合は日付Aを入力してください。", 分類A == 200, "「未取得」の場合は説明Aを入力してください。","true", "「取得済」の場合は日付Aを、「未取得」の場合は説明Aを入力してください。") , "")

完成イメージ

(4)番外編:状況による制御でやってみる

状況による制御でも同じことが簡単にできました。

(計算式、スクリプト、入力検証等は削除した状態で行います。)

[状況による制御] タブで2つの制御条件を設定します。

①分類Aが「取得済」の場合の制御 ⇒ 日付Aを入力必須にする

名称:取得済
状況:* (状況はなんでもいい)
全般:日付Aを選択し「入力必須」ボタンをクリックして「入力必須」にする。
条件:条件タブに切り替えて、フィルタ条件 分類A=取得済 を設定する。

②分類Aが「未取得」の場合の制御 ⇒ 説明Aを入力必須にする

名称:未取得
状況:* (状況はなんでもいい)
全般:説明Aを選択し「入力必須」ボタンをクリックして「入力必須」にする。
条件:条件タブに切り替えて、フィルタ条件 分類A=未取得 を設定する。

シンプルでいいかも(;・∀・) なんか、負けた気がする。

3.チェック項目に1つ以上のチェックがついていることを必須とする

ラジオボタンだとエディタで「入力必須」とすることで、1つ以上をオンにすることを要求することが可能。

ただし、複数選択ができない。なので、複数選択可能にしたいときはチェック項目を使う。そうすると今度はチェック項目はグループ化することはできない(と思う)ので、1つ以上チェックがついていること!とかはスクリプト書かないとチェックできなかった。

これを計算式(拡張)でやってみる。

エディタの設定

見出し:興味のある分野を1つ以上選んでください(複数可)

チェックA~E:表示名=「飲食」「サービス」「金融」「IT」「その他」、自動ポストバック=ON

説明A:表示名=その他の内容、スタイル=ワイド

分類A:表示名=チェック有無

数値A:表示名=チェック数

計算式(拡張)

使用した関数:$IF, $OR

チェックA~Eを使ったけどなにがなんだったか忘れちゃったので、カラム名で指定しています。[CheckA] 等と [ ] で囲んで指定します。

対象(出力先):チェック有無(分類A)

$IF($OR([CheckA], [CheckB], [CheckC], [CheckD], [CheckE]), "有", "無")

対象(出力先):チェック数(数値A)

[CheckA] + [CheckB]  + [CheckC]  + [CheckD]  + [CheckE] 

ちょっと補足説明

[表示名を使用しない] にチェックを入れると、[CheckA]等の表記のままとなります。
[表示名を使用しない] にチェックを入れない場合は、[CheckA] と入力した内容が表示名に自動変換されます。

チェック項目の取り扱い方ですが、そのまま分類項目に出力してみたところ、チェックオンの場合「True」、チェックオフの場合「False」 という内容になりました。

じゃあ、と思って
$IF([CheckA] == true, 1, 0)
とかやろうと思ったら、チェック項目はオンの場合 True、オフの場合 False だから、そのまま $IF のなかに入れてしまえばいいんですね。

で、どれか一つが True だったら「有」ということで、$OR( ) の中に複数のチェック項目を入れるとよいのですね。
$OR はかっこ内のどれか一つが OK! ならば True を返します。
$AND はかっこ内のすべての項目が OK! でなければ True を出してくれません。
$OR はゆるーい関所、$AND は厳しい関所、と覚えておきます。

で、以下の計算式で「チェック項目のどれか一つでもチェックがついていたら[有] 、ひとつもチェックがついていなかったら[無] 」という計算式は以下の計算式としました。
$IF($OR([CheckA], [CheckB], [CheckC], [CheckD], [CheckE]), “有”, “無”)

チェック数を出す計算式
[CheckA] + [CheckB] + [CheckC] + [CheckD] + [CheckE]

もっと良い方法があったら教えてください。。。
チェックオンが True だから、True は 1、False は 0 ということで、1か0に読み替えてくれないかなという淡い期待を込めてこの計算式にしたところ、読み替えてくれました。

最初はこうやった。
$IF([CheckA],1,0) + $IF([CheckB],1,0) + $IF([CheckC],1,0) + $IF([CheckD],1,0) + $IF([CheckE],1,0)

スクリプト

入力値チェックはスクリプトでやりました。

$p.events.before_validate = function (args) { 
  //チェックAがチェックされているか,されていないか
  if ($p.getControl('ClassA').val() !== '有') {
    //チェックが一つもない場合、メッセージを表示し、falseを返す
    $p.setMessage('#Message', JSON.stringify({
        Css: 'alert-warning',
        Text: '1つ以上チェックを付けてください'
    }));
    return false;    //falseのときは処理が止まり、更新されない
  }
  
  if ( $p.getControl('CheckE').is(':checked') && 
    $p.getControl('DescriptionA').val() == '' ) {
    //「その他」がチェックされていて、「その他の内容」欄が空欄の場合メッセージを表示しfalseを返す
    $p.setMessage('#Message', JSON.stringify({
        Css: 'alert-warning',
        Text: 'その他を選択した場合は、「その他の内容」を入力してください'
    }));
    return false;    //falseのときは処理が止まり、更新されない
  }

  //上記2つのチェックを通過した場合は、作成・更新を許可
  return true;    //trueのときは更新される
}

結果

5.おわりに

チェックの値の扱い方が、文字列や数字と違ってちょっと迷ってしまった。

チェックをオンにする時は true か 1 (オフにするときは false か 0)
分類Aが100の場合、チェックオン、そうでない場合チェックオフ
$IF(分類A == 100, true, false)

チェックがオンかオフかを判定するとき
$IF(チェックA, “チェックオン”, “チェックオフ”)
チェック項目そのものが true か false を返すから、そのまま突っ込むだけでOK!

計算式をやった後にスクリプトをちょっと書いただけでどっと疲れてしまった。計算式で遊んでばかりいないでスクリプトも精進しないといけませんね。

でも、次回も計算式(拡張)活用サンプルをやりまっす!

お読みいただきありがとうございました。

6.参考文献、記事

公式マニュアル
テーブルの管理:計算式(既定)
テーブルの管理:計算式(拡張)
計算式(拡張)の関数一覧
計算式(拡張)の関数で使用する論理式
開発者向け機能:スクリプト:$p.events.before_validate
開発者向け機能:スクリプト:$p.setMessage
開発者向け機能:スクリプト:$p.getControl

その他参考とさせていただいたサイト
基本的な正規表現の使い方

内部リンク
【pleasanter】計算式(規定・拡張)についてまとめてみた
【pleasanter】計算式(拡張)活用サンプル①~リマインダーの日付として利用する~

【pleasanter】計算式(拡張)活用サンプル②~入力チェックに利用する~
【pleasanter】計算式(拡張)活用サンプル③~タイトルを自由自在に~

もう読みましたか?プリザンターの概要、インストール方法から基本操作方法、導入事例、サンプル等役に立つ情報が満載でした!

コメント

タイトルとURLをコピーしました