スポンサーリンク

【pleasanter】サーバースクリプト入門:modelと実行タイミングを理解する

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

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

1.はじめに

スクリプト はチョットかけるようになったのですが、サーバースクリプト はより敷居が高いような気がしていました。
ちょっとトライしようと思っても、「modelって何?」「この条件はいつ実行されるんだ?」と、疑問だらけで。。。エラーになってテーブルが開かなくなり、「会社のプリザンター壊しちゃった?Σ(゚д゚lll)ガーン」と青くなったのを覚えています。

ですが、あきらめずにトライし続けたところ、いつの間にか書けるようになり、さらに「スクリプトより簡単なのでは?」と感じ始め、最近はもっぱらサーバースクリプトばかり使用しています。

が、リーデックスさんの記事を読み、サーバースクリプト一辺倒でもだめなのね、調子に乗りすぎました、と反省したところです。
↓この記事は大変参考になりました。ありがとうございました。
サーバスクリプト?スクリプト? どちらでも実装できるときに考えたい判断基準

あらためて、サーバースクリプトについて一度きちんと整理してみようと再勉強してみました。

サーバースクリプトは、
プリザンターのサーバー側の処理の“途中”に割り込んで、独自の処理を差し込める仕組み。

ということを理解すると、意外とシンプルかも!と思いました。
この記事では、その理解の道のりをまとめてみます。

2.サーバースクリプトとは

(1)そもそもサーバースクリプトって何?

概要
サーバスクリプトを使用するとサーバサイドでJavaScriptを実行し、条件分岐、計算、文字列処理、レコードの操作、メールやチャットへの通知、動的なアクセス制御等を行うことが可能です。JavaScriptの実行エンジンはMicrosoft社の ClearScript を使用しています。

制限事項
1.外部のスクリプトを読み込む事はできません。
2.ローカルディスク等、ローカルリソースにアクセスする事はできません。
3.サーバスクリプト内のDateTimeの値はUTCに変換されます。

引用元:https://pleasanter.org/ja/manual/server-script

サーバースクリプトは、「プリザンターのサーバーで動くjavaScript」。つまり、[サーバースクリプト]タブで書いたコードが、プリザンターのサーバー側で実行されるものです。

サーバースクリプトは、
プリザンターのサーバー側の処理の“途中”に割り込んで、独自の処理を差し込める仕組み。
または、
プリザンター内部の処理フローに自前のコードを “フック” できる。
と考えると、理解しやすいように思います。

下の図は「サーバースクリプト」タブでコードを入力する画面です。
画面イメージの下部に「条件」とあります。ここでチェックを入れて指定した「タイミング」で実行されます。

プリザンターの内部の処理の途中に差し込ませるために、処理を実行させる「条件」で、『この時にコードを実行してね』というタイミングを指定する、というものですね。
後述4の「コードが実行されるタイミング」のところでもっと詳しく書きます。

サーバースクリプトイメージ

スクリプトと条件の間にある 無効, 関数化, TryCatch については、ここでは触れませんので公式マニュアルをご参照ください。
開発者向け機能:サーバスクリプト:TryCatch
開発者向け機能:サーバスクリプト:関数化

(2)スクリプトとの違い

スクリプトとの比較(ざっくりです)

比較項目スクリプトサーバースクリプト
実行場所クライアント(ブラウザ)サーバ
実行タイミングユーザー操作時サーバー処理時
影響範囲ユーザーのブラウザ画面サーバー上のデータ全体に適用可能
デバック比較的簡単ちょっと難しい

「スクリプト」はブラウザ側(ユーザーが見ているChrome、Edge等の画面側)で動くもの。
対して、「サーバースクリプト」はサーバー側(プリザンター本体側)で動くもの。

スクリプトは プリザンターの “外” で動き、
サーバースクリプトはプリザンターの ”中” で動く。

「はじめに」でも触れましたが、どちらで書くかの判断はリーデックスさんの以下の記事が大変参考になります。
サーバスクリプト?スクリプト? どちらでも実装できるときに考えたい判断基準

「画面に関してはスクリプト」「データに関してはサーバースクリプト」 とざっくりとした基準をもつと、考えやすいかなと思います。

計算や、DB更新、他のテーブルの値の取得は サーバースクリプトに軍配が上がります。
なぜなら「プリザンターの『中』」で動くから。

プリザンターの『外』で動くスクリプトは、DBに直接のアクセスはできないため、APIを介さないといけないので、コードが複雑になりがちです。(外から直接DBにアクセスできたらセキュリティ崩壊😨。APIは外からDBにアクセスするための『関所』みたいな感じ)

(3)ここが推し!サーバースクリプト

スクリプト、サーバースクリプト、どちらでも実装できる場合がありますが、以下に、私のサーバースクリプトの推しポイントを挙げます。

■ 他テーブルの値の参照、更新が簡単

スクリプトでこれをやろうとすると、APIを利用することになります。コードが長くなりがちだし、APIの非同期処理が初心者には難しいので他のテーブルの操作に関連するところはサーバースクリプトが簡単便利!と思います。

■ グループの操作 で使いやすい

Groupについても、他テーブルと同じように、スクリプトよりサーバースクリプトのほうが簡単に扱える、と思います。
特に、groups.get でグループ情報をゲットして、group.GetMembers でグループメンバーを取得とか、group.ContainsUser でユーザーがグループ内にいるかどうかを確認したり、をよく利用します。

■ スクリプトより 記述が簡単

たとえば、分類Aの値を取得、変更するとき
スクリプトだと
let val = $p.getControl(‘ClassA’).val(); //取得
$p.set($p.getControl(‘ClassA’), ‘100’); //変更

サーバースクリプトだと
let val = model.ClassA; //取得
model.ClassA = ‘100’;  //変更

ね!なんかすっきり簡単!だと思いませんか?

■ レコードを保存したいときの実装が簡単

スクリプトだと、値を変更、までは良いのですが、サーバー側のDBのレコードの値そのものを更新する処理を書くのは大変。

サーバースクリプトの場合、条件を「更新前」等のレコード更新前に実行される条件を指定し、レコードの値を変更するコードを書けば、レコード更新の前にコードが実行され、変更された値でDBに保存されるので、なんからくちん。
後述しますが、私はプロセスボタンクリック時に連動してサーバースクリプトを実行させる、というのがお気に入りです。

■ view.Filters で 柔軟なアクセス制御ができる

サーバースクリプトの関数 view.Filters を利用してアクセス制御をかけることをよくやります。
基本的にテーブルの管理のサイトのアクセス制御を利用するのですが、制御を複雑に設定する必要がある場合、動的な制御としたい場合などに使用しています。

3.model ってなんだ?

サーバースクリプトでは model.ClassA のように書くことで簡単にレコードの項目の値を取得、変更することができます。
でも、model ってなに???というのが私はずっと気になってしかたがなかった。

きっとこんな感じか、と以下のように自分を納得させています。(正確な解説ではないですよ)

**************************************

サーバー側で現在処理対象になっている「レコードのデータオブジェクト」をmodelと表現している。

・現在の値
・これから保存しようとする値
・ポストバックで送られてきた値
等を保持している。

画面からサーバーに送られてきたレコード。
サーバーが今、扱っているレコード。
= これを “オブジェクト“ としてあれこれ操作できるようにしている。

この model の段階では「まだDBに保存されていない」というところが一つのポイント。(更新前の場合)
つまり、model.ClassA = 100; と書いた時点ではまだDBの値が変更されたわけではなく、「更新」処理が行われて初めて分類AのDBの値が 100 になる。

**************************************

ふんわりとそんな感じ?と思っておけばいいかな?と。
model はDBのデータ と、勘違いしやすいですが、
model は
「DBのデータそのものというわけではなく、サーバーが今扱っているデータ」
「保存前に一時的にあれやこれやできるようにするためのデータ」
と考えると解釈しやすいかと思います。

以下、想像のイメージ図 (あくまでも想像ですよ!)

4.コードが実行されるタイミング

さて、ここが肝心

コードは書いた、が、条件は何を指定すればよいのかわからない。。。というのが、躓きポイントでした。

「1.サーバースクリプトとは」を振り返ってみましょう。

サーバースクリプトは、
プリザンターのサーバー側の処理の“途中”に割り込んで、独自の処理を差し込める仕組み。

「条件」は、
プリザンターの内部の処理の途中に差し込ませるために、『この時(この「条件」の時)にコードを実行してね』というタイミングを指定するもの。

と、考えるとなんとなく見えてくるような気がします。

(1)サーバースクリプトが実行されるタイミングと「条件」の関係

サーバースクリプトの「条件」は、
サーバー処理のどのタイミングでスクリプトを実行するかを指定するものです。
主な条件を、処理の流れ順に整理してみました(ざっくりです)。

条件実行されるタイミングサーバーの処理の中での位置どんな時に使う?(例)
計算式の前サーバーで計算式が実行される前ポストバック後、計算処理の前計算式で使う値を事前に変更する
計算式の後サーバーで計算式が実行された後計算処理の直後計算結果をもとに別の項目を更新する
作成前/更新前/削除前レコード保存・削除する直前DBに保存する前入力値のチェック(保存せず返却することもできる)
データの値の変更(変更した値で保存される)
作成後/更新後/削除後レコードの保存・削除が完了した後DB保存後、レスポンス返却前更新後のデータに基づいて、他のテーブルの更新
ログ記録 等
画面表示の前画面を表示する直前ブラウザに返却する画面(html)を作る前ユーザーごとの表示の変更
項目の読取専用化
ボタンの表示・非表示
等々
行表示の前一覧画面で1行表示するごと一覧画面の1レコード描画の前条件に応じた色変更
表示内容の調整
※1行ごとに実行されるので、重くなることがあるので注意

(2)タイミングのイメージを図解してみた

繰り返しになりますが。

サーバースクリプトは、
プリザンターのサーバー側処理の“途中”に割り込んで、独自の処理を差し込める仕組み

これを念頭に置いて考えると、理解がしやすいように思います。

以下、計算処理有の場合の更新ボタンクリック時はこんな感じかしら、の図

サーバースクリプトの実行タイミングのイメージ

違ってたら、ご指摘ください!

(3)躓きポイント

私が躓いたポイントは、たくさんありますが、代表的な二つについて。

① 画面表示の前っていったいいつなの?

一言でいうと、

「サーバーが画面のHTMLを作る直前」に実行される処理です。

編集画面や一覧画面など、ブラウザに表示するためのHTMLをサーバー側で生成する直前に実行されます。
名前だけ見るとブラウザ側で実行されるような印象がありますが、実際にはサーバー上で動く処理です。

少し分かりにくいのは、「いつ実行されるのか」が直感的に想像しにくいところです。

「画面表示の前」は、画面を表示するためのHTMLが生成されるタイミングで実行されます。

例えば次のような場合です。

  • 編集画面を開いたとき
  • 更新ボタンを押して画面が再表示されるとき
  • 計算のための自動ポストバックで画面が再表示されるとき
  • 一覧画面に戻ったとき

このように、「画面の(再)表示」が発生する場合に実行されます。

逆に言うと、HTMLの生成が行われない処理では実行されません。

つまり、

『画面表示の前』=「画面を作る(HTML生成)直前のタイミング」

と考えると理解しやすいです。

② 画面表示の前と行表示の前って何が違うの?

大きな違いは、実行される回数と対象

「行表示の前」は、一覧画面にのみ関係する処理です。

一覧画面の表示では、次のような処理が行われています。

  • まず、画面全体のHTMLが作られる
  • 次に、一覧テーブルの中にレコードが1行ずつ入れられる

このときの実行タイミングは次のようになります。

画面表示の前
→ 画面全体を作る前に 1回だけ実行

行表示の前
→ 一覧の各レコードを表示する前に レコード数分実行

例えば100件のレコードを表示する場合は
画面表示の前 :1回
行表示の前  :100回
実行されることになります。

つまり、

画面表示の前
→ 画面全体に対する処理

行表示の前
→ 一覧の1行(1レコード)ごとの処理

と考えると分かりやすいです。

5.エラー時の対応

サーバースクリプトは、通常のスクリプトに比べてエラー時の原因が分かりにくく、デバッグが少し難しいと感じました。
エラーが発生したときの画面の見方と、TryCatchによる基本的な対応方法について書きます。

エラーの詳細は、サイト管理のログから確認できるのだと思います。が、私は会社では権限がなく見れず、たぶん見てもわからないのでここでは割愛します。

(1)エラー画面

エラーとなったとき、以下の画面になります。最初に見たときは「プリザンター壊しちゃった?」と青くなりました。でも大丈夫!落ち着いて、画面下部の「テーブルの管理」ボタンをクリックして、テーブルの管理画面に戻り、サーバースクリプトを修正することができます。
最初はドキッとしましたが、エラーを出しまくっているうちに、見慣れました。。。

(2)TryCatch

TryCatchでコードを囲むことにより、Tryの後の{}内のコードを実行し、エラーとなった場合Catchの{}に流れるようにすることができます。

try {
  columns.ClassB.AddChoiceHash(100, 'test1');
  columns.ClassB.AddChoiceHash(200, 'test2');
  columns.ClassB.AddChoiceHash(300, 'test3');
} catch(e) {
   context.Log(e.stack);
}

また、サーバースクリプト設定の画面下部の「TryCatch」にチェックを入れることで、スクリプト記述内でTryCatch文として返還されます。開発者向け機能:サーバスクリプト:TryCatch

ただし、綴り間違いなどの構文エラーの場合、TryCatchしていても(1)のエラー画面になってしまいます。

6.デバック方法

初心者は書いてはみたけどちゃんと期待した通りの動きをするのだろうか?と不安になるので、コンソールにちょいちょい出力しながらやってみたりします。(皆さんそうですか?)
ここで変数に何が入ったか出力して確認してみようとか、この処理が走ったか確認したいから目印になにかコンソールに出力するようにしておこうとか。

スクリプトでは console.log(‘出力したい文字’);
と書くことで、開発者画面のコンソールに出力されます。

サーバースクリプトでは context.Log(‘出力したい文字’);
と書くことで、開発者画面のコンソールに出力できます。

開発者向け機能:サーバスクリプト:context.Log

しかし!私が困ったのは、「作成前」「作成後」「削除前」「削除後」等ではコンソールに出力されても、一瞬で消えてしまうんです。

上記の処理では、処理後に画面がリダイレクトされる(新しいものに完全に切り替わる)ので、コンソールが初期化されてしまうんです。

そのようなときの対応として、以下の2つをやってみたりしました。
①ログのように別テーブルに出力する
②一時的に説明項目などに出力し確認する

①の例:削除したレコードのIDとタイトルをログテーブルに出力(ログテーブルは別に用意しておく)

//「条件」は[削除後]
context.Log("削除後の処理が実行されました。");    //これはちらっと表示されるが消える
//ログテーブルに出力
let siteId = 9366;    //ログテーブルのサイトID
let item = items.NewResult();    //アイテムオブジェクトを作成
//作成したアイテムのタイトルを作成(現在のレコードIDとタイトル)
item.Title = "【削除されました】ID:" + model.ResultId + " タイトル:" + model.Title ;
//ログテーブルに上記で作成したアイテムの内容でレコードを新規作成する
items.Create(siteId, item);

②の例:作成前び処理が実行されたことを、作成したレコードの説明Aに出力

//「条件」は [作成前}
context.Log("作成前の処理が実行されました");    //これはコンソールにちらっと見えて消える
model.DescriptionA = "作成前の処理が実行されました";  //新規作成したレコードの説明Aに出力される

7.プロセスと組み合わせてコードを実行するサンプル

サーバースクリプトが『この場合の時だけ動いてほしい』ということはありますよね!
if 文 で状況が〇〇の時だけ、とか条件分岐をしたりして、実装することができます。

そのほか、context.Action で『今行われたのはなんの処理?』が取得できるので、それにより実行を制限できたりします。
context.Action については、大塚さんのQuita記事に詳しく載っています。←いつもありがとうございます!
プリザンターのサーバスクリプトのcontext.Actionの値を見てみる

他に、「押されたプロセスのボタンに応じてサーバースクリプト処理が走る」というのを私はよく使用しています。
context.ControlId でどのボタンが押されて処理が走ったのか、というのを取得することができるのでそれを利用します。

参考とさせていただいたのは、以下の記事です。
【プリザンター】 第272回)スクリプトとサーバスクリプトを連携させる方法
プリザンターのスクリプトとサーバスクリプト

例です。

プロセス:「確認」ボタンクリック時、DB保存処理が実行され、担当者に通知が行く。
サーバースクリプト:「確認記録テーブル更新」処理が走り、別のテーブル「確認記録テーブル」に確認ボタンをクリックしたユーザーと説明Aの入力文字列を登録する。

プロセス(ID1)のボタンクリックでプロセス(ID1)に登録した処理と「更新」処理が走ります。
サーバースクリプトの「条件」を「更新前」とすることで、サーバースクリプトの処理が発火します。
「押されたボタンが目的のプロセス(ID1)のボタンである」ことを条件として、処理を実行させる。
という、流れです。
「更新」処理が走っても、トリガーがプロセス(ID1)のボタン以外の時は、「プロセス(ID1)のボタンではない」ため、サーバースクリプト自体は実行されますが、条件分岐により処理が実行されません。

//サーバースクリプトのコード。条件は [更新後]
if (context.ControlId === 'Process_1') {
  const siteId = 9366;             //更新対象テーブル
  let item = items.NewResult();    //アイテムオブジェクトを作成
  //作成したアイテムのタイトルを作成(現在のレコードIDとタイトル)
  item.Title = model.ResultId + " :" + model.Title;
  item.Owner = context.UserId;
  item.Body = model.DescriptionA;
  //確認記録テーブルに上記で作成したアイテムの内容でレコードを新規作成する
  items.Create(siteId, item);
}

8.さいごに

サーバースクリプトに少し怖いイメージを持っていましたが、処理が実行される “タイミング” を意識して整理してみると、仕組みは意外とシンプルで、むしろ書きやすい場面も多いと感じるようになりました。

ここまでやってきて感じたことは
タイミングを制する者はサーバースクリプトを制す!
です!

この記事が、私と同じように「なんとなく難しそう」「いまいち理解できない」と感じている方の、ちょっとしたヒントやきっかけになればうれしいです。

なお、SoftwareDesignの2025年5月号にプリザンターの「バックエンドのカスタマイズと独自のAPIの追加」の記事があるのですが、ここでサーバースクリプトについて触れられており、「ほー、なるほど!」と理解が深まりました。お勧めです。2025年3月~7月で短期連載です。プリザンターの生みの親である内田太志さんが執筆されているので、大変わかりやすい!お勧めです!

9.参考文献、記事

公式マニュアル
開発者向け機能:サーバスクリプト
テーブルの管理:サーバスクリプト
サーバスクリプト
開発者向け機能:サーバスクリプト:TryCatch
開発者向け機能:サーバスクリプト:関数化
開発者向け機能:サーバスクリプト:view.Filters
開発者向け機能:サーバスクリプト:context.Log
開発者向け機能:サーバスクリプト:context

参考とさせていただいた記事

サーバスクリプト?スクリプト? どちらでも実装できるときに考えたい判断基準
プリザンターのスクリプトとサーバスクリプト
【JavaScript入門】try…catchの使い方と例外処理のまとめ!
プリザンターのサーバスクリプトのcontext.Actionの値を見てみる

参考文献

SoftwareDesign 2025年5月号「バックエンドのカスタマイズと独自のAPIの追加」

こちらも絶賛おすすめ!!プリザンターの概要、インストール方法から基本操作方法、導入事例、サンプル等役に立つ情報が満載!

!– START MoshimoAffiliateEasyLink –>

スポンサーリンク
スポンサーリンク
Uncategorized
スポンサーリンク
mwkをフォローする

コメント

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