コンテンツにスキップ

$p.execProcess

概要

指定したプロセスを実行するメソッドです。

制限事項

  1. このメソッドは編集画面でのみ実行可能です。一覧画面での「一括処理」では実行しません。

構文

JavaScript
$p.execProcess(ボタン要素);

各パラメータの説明

パラメータ名 説明
ボタン要素 実行したいプロセスを実行するボタンをHTML要素で指定

使用例

下図のようなプロセスが設定されている場合を例とします。

使用例の前提となるプロセスの設定

  1. 実行種別が「追加したボタン」
    実行したいプロセスのIDを元にプロセスボタンを指定します。

    JavaScript
    // プロセスID:3のプロセスを実行
    $p.execProcess($('#Process_3'));
    
  2. 実行種別が「作成または更新」
    実行したいプロセスの画面種別が「新規」の場合は「#CreateCommand」、「編集」の場合は「#UpdateCommand」と指定します。

    JavaScript
    // プロセスID:2のプロセスを実行
    $p.execProcess($('#UpdateCommand'));
    
  3. プロセスの詳細設定-「OnClick」に直接記述
    「$(this)」と指定します。
    下図は独自実装のスクリプト(myFunc関数)を実行後にプロセスを実行する例です。

    プロセスの詳細設定の「OnClick」に記述した例

プロセスの実行条件

本メソッドを使用する場合は対象のボタンがHTML要素上に存在していることが条件となります。したがって以下ケースの場合はスクリプトを実行してもプロセス処理は実行しません。

  1. プロセスの条件を満たさないボタンを指定した場合
  2. 実行種別が「作成または更新」のプロセスに対して「 $p.execProcess($('#Process_1'))」のようにプロセスボタン要素を指定した場合
  3. サーバスクリプトelements.DisplayTypeで該当ボタンを「1:無し」にした場合(2:無効、3:非表示の場合はプロセス処理実行します)

サンプルコード

Note

コード内の【 ... 】は適宜修正してください。

1. 資産番号の読み取り1回でプロセス「返却」を実行する

貸出機器台帳の一覧画面に「返却受付」の入力欄を表示します。入力欄に資産番号を入力してEnterを押すと、台帳を資産番号の完全一致・状況「貸出中」で検索し、1件に絞れたらその編集画面を開いて、$p.execProcessでプロセス「返却」を自動で実行します。返却日のセットや状況の変更はプロセスの設定に任せ、実行後はプロセスの「一覧画面に戻る」で入力欄に戻るので、次の機器を続けて受け付けられます。

バーコードリーダーで資産番号を読み取ると、読み取った値と末尾のEnterがキーボード入力として送られるため、手で入力してEnterを押したときと同じ動きをします。

実務での使いどころ

機器や備品の貸出管理では、返却の受付が一度に何件も発生します。標準の操作では「資産番号で検索 → レコードを開く → 返却ボタンを押す」と、1件ごとに3手順以上かかります。プロセスを実行するきっかけは「追加したボタン」と「作成または更新」のみで、入力をきっかけに自動で実行する設定はありません。

このサンプルでは、資産番号の入力(読み取り)1回で返却まで済みます。一覧画面に戻ると入力欄にフォーカスが当たり、直前に受け付けた資産番号と結果が表示されるので、手を止めずに次の機器を受け付けられます。

項目名・プロセスのボタンID・状況の値を定数にしているため、講演会の来場受付、書類の受領確認、入庫検品など「読み取り1回で状況を進める」業務にも転用できます。

事前準備

1:記録テーブル(例:貸出機器台帳)に以下の項目を有効化してください。

項目コード 内容
タイトル(Title) 機器名
分類A(ClassA) 資産番号(台帳の中で重複させない)
状況(Status) 選択肢に「100,在庫」「200,貸出中」「900,廃棄」を設定
分類B(ClassB) 借用者。選択肢一覧に[[Users]]を設定
日付A(DateA) 貸出日
日付B(DateB) 返却予定日
日付C(DateC) 返却日

2:「テーブルの管理 > プロセス」タブで、プロセスを2つ登録します。

プロセス 現在の状況 変更後の状況 設定
貸出 在庫 貸出中 実行種別「追加したボタン」。入力検証で借用者・返却予定日を必須にし、データの変更で貸出日に当日をセット
返却 貸出中 在庫 実行種別「追加したボタン」。データの変更で返却日に当日をセット。状態変更後の動作は「一覧画面に戻る」。確認メッセージは設定しない

登録後、「返却」プロセスのボタンID(Process_1のように、登録した順に番号が付きます)を控えておき、サンプルコードのRETURN_PROCESS_IDに指定してください。

3:スクリプトを登録します。

3-1:「テーブルの管理 > スクリプト」タブで「新規作成」を選択する。
 3-2:タイトル: 任意の名前(例:返却受付)
 3-3:スクリプト: 下記サンプルコードを貼り付け
 3-4:出力先:「一覧」と「編集」の両方にチェック

4:動作を確かめます。

4-1:「貸出」プロセスで、資産番号を入れたレコードを貸出中にする。
 4-2:一覧画面を開き、「返却受付」の入力欄に4-1の資産番号を入力してEnterを押す。
 4-3:そのレコードの編集画面が開いてプロセス「返却」が実行され、一覧画面に戻る。入力欄の横に「返却を受け付けました。」と表示される。

JavaScript
/**
 * ================================================================
 * サンプル  資産番号の読み取り1回でプロセス「返却」を実行する
 * ================================================================
 *
 * 【概要】
 *   貸出機器台帳の一覧画面に「返却受付」の入力欄を表示します。資産番号を入力して
 *   Enter を押す(バーコードリーダーで読み取ると、読み取った値と末尾の Enter が
 *   キーボード入力として送られるので同じ動きになります)と、台帳を資産番号の
 *   完全一致・状況「貸出中」で検索し、1件に絞れたらその編集画面を開いて
 *   $p.execProcess でプロセス「返却」を自動実行します。
 *   返却日のセットや状況の変更はプロセスの設定に任せ、プロセスの「一覧画面に戻る」
 *   で入力欄に戻るので、次の機器を続けて受け付けられます。
 *
 * 【なぜ標準機能では実現できないか】
 *   プロセスを実行するきっかけは「追加したボタン」と「作成または更新」だけで、
 *   入力をきっかけに自動で実行する設定はありません。標準の操作では
 *   「検索 → 行を開く → 返却ボタン」の手順が必要ですが、本サンプルでは
 *   資産番号の入力(読み取り)1回にまとめます。
 *
 * 【実装上の注意】
 *   ・on_editor_load の時点では、プロセスの実行に必要な $p.formValidate が
 *     まだ定義されていないことがあり、そのまま $p.execProcess を呼ぶと
 *     「$p.formValidate is not a function」になります。関数になるまで少し待って
 *     から実行します。
 *   ・プロセスの成功メッセージは、一覧へ戻ると表示されません。一覧へ戻ったら、
 *     直前に受け付けた資産番号と結果をスクリプト側で表示します。
 *   ・編集画面を普通に開いたときは何もしません。一覧で受け付けたレコードIDと
 *     時刻を sessionStorage に残し、一致かつ期限内のときだけ実行します。
 *     残した値は読んだらすぐ消すので、入力検証エラーなどで編集画面を開き直しても
 *     再実行されません。
 *
 * 【使い方】
 *   スクリプトの出力先は「一覧」と「編集」にチェックしてください。
 *   プロセス「返却」は、現在の状況「貸出中」→ 変更後の状況「在庫」、
 *   状態変更後の動作「一覧画面に戻る」で設定し、確認メッセージは設定しません。
 *   RETURN_PROCESS_ID には、設定したプロセスのボタンID(Process_1 など)を
 *   指定してください。
 * ================================================================
 */

// ===== 設定 =====
// 資産番号の項目
const ASSET_NO_COLUMN = 'ClassA';
// 状況「貸出中」の値
const LENT_STATUS = 200;
// プロセス「返却」のボタンID
const RETURN_PROCESS_ID = 'Process_1';
// 一覧で受け付けてから、編集画面で自動実行するまでの有効期限(ミリ秒)
const AUTO_EXEC_EXPIRE_MS = 30000;
// $p.formValidate が使えるようになるまで待つ間隔と上限(ミリ秒)
const WAIT_INTERVAL_MS = 50;
const WAIT_LIMIT_MS = 5000;
// 一覧の読み込み直後はフォーカスが外れるため、少し遅らせて当てる(ミリ秒)
const FOCUS_DELAY_MS = 500;

// sessionStorage のキー
const TARGET_KEY = 'returnByBarcode.target'; // 自動実行する対象
const RESULT_KEY = 'returnByBarcode.result'; // 一覧へ戻ったときに表示する結果

// 入力欄と結果表示の要素ID
const INPUT_ID = 'ReturnByBarcodeInput';
const RESULT_ID = 'ReturnByBarcodeResult';

// ===== 共通 =====
// sessionStorage から読み、読んだらすぐ消す
function takeFromSession(key) {
    const value = sessionStorage.getItem(key);
    sessionStorage.removeItem(key);
    return value ? JSON.parse(value) : null;
}

// 前後の空白を除き、全角の英数字・記号を半角に直す
function normalizeAssetNo(value) {
    return value
        .trim()
        .replace(/[!-~]/g, (c) => String.fromCharCode(c.charCodeAt(0) - 0xfee0));
}

// ===== 一覧画面 =====
// 入力欄の横に結果を表示する。プロセスの成功メッセージは一覧では見えないため、
// 標準のメッセージ欄ではなく、この入力欄の横に独自に表示する
function showResult(text, isError) {
    $('#' + RESULT_ID)
        .text(text)
        .css('color', isError ? '#c00000' : '#006400');
}

// 入力欄をクリアしてフォーカスを当てる(次の読み取りに備える)
function resetInput() {
    $('#' + INPUT_ID).val('').trigger('focus');
}

// 資産番号で「貸出中」のレコードを検索し、1件なら編集画面へ移る
function acceptReturn(assetNo) {
    $p.apiGet({
        id: $p.siteId(),
        data: {
            View: {
                // 分類項目は配列形式+ExactMatchMultiple で完全一致にする
                // (A-000 で A-0001 が見つかる、といった取り違えを防ぐ)
                ColumnFilterHash: {
                    [ASSET_NO_COLUMN]: JSON.stringify([assetNo]),
                    Status: JSON.stringify([String(LENT_STATUS)]),
                },
                ColumnFilterSearchTypes: {
                    [ASSET_NO_COLUMN]: 'ExactMatchMultiple',
                },
            },
        },
        done: function (data) {
            const records = data.Response.Data || [];
            if (records.length !== 1) {
                // 0件・複数件のときは画面を移らず、次の読み取りに備える
                showResult(
                    records.length === 0
                        ? `${assetNo}:貸出中の機器が見つかりません。`
                        : `${assetNo}:該当する機器が複数あります(${records.length}件)。台帳を確認してください。`,
                    true
                );
                resetInput();
                return;
            }
            const recordId = records[0].ResultId || records[0].IssueId;
            sessionStorage.setItem(
                TARGET_KEY,
                JSON.stringify({ id: recordId, assetNo: assetNo, time: Date.now() })
            );
            location.href = $('#ApplicationPath').val() + 'items/' + recordId + '/edit';
        },
        fail: function () {
            showResult(`${assetNo}:検索に失敗しました。`, true);
            resetInput();
        },
    });
}

// 直前に受け付けた結果を表示する。状況が「貸出中」から変わっていれば返却済みとする
function showLastResult() {
    const last = takeFromSession(RESULT_KEY);
    if (!last || Date.now() - last.time > AUTO_EXEC_EXPIRE_MS) {
        return;
    }
    $p.apiGet({
        id: last.id,
        data: {},
        done: function (data) {
            const record = (data.Response.Data || [])[0];
            if (record && Number(record.Status) !== LENT_STATUS) {
                showResult(`${last.assetNo}:返却を受け付けました。`, false);
            } else {
                showResult(`${last.assetNo}:返却できませんでした。台帳を確認してください。`, true);
            }
        },
        fail: function () {
            showResult(`${last.assetNo}:結果を確認できませんでした。台帳を確認してください。`, true);
        },
    });
}

$p.events.on_grid_load = function () {
    // 一覧の描き直しで再度呼ばれても、入力欄を重ねて作らない
    if ($('#' + INPUT_ID).length === 0) {
        $('#ViewModeContainer').before(
            `<div style="margin:8px 0;">
                <label for="${INPUT_ID}" style="font-weight:bold;margin-right:8px;">返却受付</label>
                <input type="text" id="${INPUT_ID}" placeholder="資産番号を入力してEnter" autocomplete="off" style="width:240px;">
                <span id="${RESULT_ID}" style="margin-left:12px;font-weight:bold;"></span>
            </div>`
        );
        $('#' + INPUT_ID).on('keydown', function (e) {
            // 日本語入力の確定の Enter は対象にしない
            if (e.key !== 'Enter' || (e.originalEvent && e.originalEvent.isComposing)) {
                return;
            }
            e.preventDefault();
            const assetNo = normalizeAssetNo($(this).val());
            if (assetNo === '') {
                return;
            }
            acceptReturn(assetNo);
        });
    }
    showLastResult();
    setTimeout(function () {
        $('#' + INPUT_ID).trigger('focus');
    }, FOCUS_DELAY_MS);
};

// ===== 編集画面 =====
// $p.formValidate が使えるようになるまで待ってから、プロセスを実行する
function execProcessWhenReady($button, target, startedAt) {
    if (typeof $p.formValidate === 'function') {
        // 一覧へ戻ったときに結果を表示するため、受け付けた内容を残しておく
        sessionStorage.setItem(
            RESULT_KEY,
            JSON.stringify({ id: target.id, assetNo: target.assetNo, time: Date.now() })
        );
        $p.execProcess($button);
        return;
    }
    if (Date.now() - startedAt > WAIT_LIMIT_MS) {
        $p.setMessage('#Message', JSON.stringify({
            Css: 'alert-error',
            Text: '返却を自動で実行できませんでした。「返却」ボタンを押してください。',
        }));
        return;
    }
    setTimeout(function () {
        execProcessWhenReady($button, target, startedAt);
    }, WAIT_INTERVAL_MS);
}

$p.events.on_editor_load = function () {
    // 一覧で受け付けた対象を読む(読んだらすぐ消す)
    const target = takeFromSession(TARGET_KEY);
    // 普通に編集画面を開いたとき、別のレコード、期限切れのときは何もしない
    if (!target
        || String(target.id) !== String($p.id())
        || Date.now() - target.time > AUTO_EXEC_EXPIRE_MS) {
        return;
    }
    // 状況が「貸出中」でない等で、返却ボタンが画面に無いときは実行しない
    const $button = $('#' + RETURN_PROCESS_ID);
    if ($button.length === 0) {
        $p.setMessage('#Message', JSON.stringify({
            Css: 'alert-error',
            Text: `${target.assetNo}:返却できる状態ではないため、返却を実行しませんでした。`,
        }));
        return;
    }
    execProcessWhenReady($button, target, Date.now());
};

注意点

  • バーコードリーダーを使う場合は、読み取った値の末尾にEnterを送る設定にしてください(USB接続の一般的なリーダーの既定です)。日本語入力がオンのままだと全角で入力されるため、入力欄では全角の英数字・記号を半角に直してから検索しています。
  • 資産番号は、配列形式の値とExactMatchMultipleで完全一致で検索しています。分類項目を素の値で絞り込むと部分一致になることがあり、A-000でA-0001が見つかる、といった取り違えが起こります。
  • 該当する貸出中の機器が無いとき、または複数見つかったときは、画面を移らずに入力欄の横へメッセージを表示し、入力欄をクリアして次の入力を待ちます。
  • 編集画面を開いた直後($p.events.on_editor_loadの時点)は、プロセスの実行に必要な$p.formValidateがまだ定義されていないことがあり、そのまま$p.execProcessを呼ぶと「$p.formValidate is not a function」のエラーになります。このサンプルでは、関数として使えるようになるまで待ってから実行しています。
  • プロセスの成功メッセージは、「一覧画面に戻る」で一覧画面へ戻ると表示されません。このサンプルでは、一覧画面に戻ったときに対象レコードの状況を確かめ、直前に受け付けた資産番号と結果を入力欄の横に表示しています。
  • 自動で実行するのは、一覧画面で受け付けたレコードを、受け付けてから30秒以内に開いたときに限ります。受け付けた内容は読み取ったらすぐ消すため、普通に編集画面を開いたときや、入力検証のエラーなどで編集画面を開き直したときには実行されません。
  • 状況が「貸出中」でないなどで、編集画面に「返却」ボタンが表示されていないときは、プロセスを実行せずにメッセージを表示します。
  • $p.execProcessは編集画面で動くメソッドのため、一覧画面の一括処理からは実行できません。

関連情報