

スクリプトタスクでは、テーブル型データ項目の読み書きができます。テーブル型は文字型や数値型と操作方法が大きく異なるため、この記事では基本的な操作方法をサンプルコードとともに解説します。
各データ型のメソッド詳細については、リファレンス「R2301: スクリプトタスクでのデータ取得/更新」を参照してください。
テーブル型が他のデータ型と異なる点
文字型や数値型は engine.findDataByVarName() で取得した値をそのまま engine.setDataByVarName() で書き戻せますが、テーブル型の更新では、空の場合に新しいテーブルを作成する都合上、データ定義オブジェクトを経由する手順をおすすめします(後述)。
セル単位のアクセスは、列のデータ型に応じた型で行うのが基本です。文字型の列は String、数値型の列は BigDecimal、選択型は ItemView、日付型は AddableDate として読み書きできます。通常のデータ項目と同じ感覚で扱えます。
セルを すべて文字列として扱う 補助 API(get() / put())もあります。CSV ライクな処理など、型を気にせず文字列として扱いたい場合に便利です。記事の終盤で紹介します。
テーブル型を「参照」するには
engine.findDataByVarName() でテーブルを取得すると、ScriptListArray オブジェクトが返されます。行数は size()、各セルの値は getObject(行番号, 列の指定) で取得できます。
列の指定には列番号(0 始まり)またはフィールド名が使えます。
const table = engine.findDataByVarName("q_order_items"); // テーブル型
// テーブルが空の場合は null になる
if (table === null) {
throw new Error("明細が入力されていません");
}
const rowCount = table.size(); // 行数
for (let i = 0; i < rowCount; i++) {
const itemName = table.getObject(i, "item_name"); // 文字型列 → String
const quantity = table.getObject(i, "quantity"); // 数値型列 → BigDecimal
const unitPrice = table.getObject(i, 2); // 列番号でも指定可(0 始まり)
// 必須でない列は、セル単位で未入力(null)の場合がある
if (quantity === null || unitPrice === null) {
continue; // この行はスキップ、など
}
}2 段階の null チェック
テーブル全体の未入力(table === null)と、行内の個別セルの未入力(getObject() が null)は別物です。table が非 null でも、行の中に値が入っていない列は null になります。必須でない列を使う場合は、行内でも null チェックを入れてください。
なお get()(文字列 API)の場合、空セルは null ではなく 空文字 "" が返ります。
テーブル型を「更新」するには
テーブル型の更新では、空の場合に新しい ScriptListArray を作る必要があるため、データ定義オブジェクトを取得しておくと一貫して書けます。
// データ定義を取得してからテーブルを取得する
const def = engine.findDataDefinitionByVarName("q_order_items");
let table = engine.findData(def);
// テーブルが空の場合は新規作成する
if (table === null) {
table = def.createListArray();
}
// --- ここで行の操作を行う(後述)---
// 最後に書き戻す
engine.setData(def, table);書き戻しは engine.setData(def, table) でも engine.setDataByVarName("q_order_items", table) でも構いません。ただし空の場合に def.createListArray() を呼ぶ必要があるため、結局 def を取得することになります。
行を追加する
table.addRow() で末尾に新しい行を追加し、row.setObject(フィールド名, 値) でセルに値を入れます。値は 列のデータ型に応じたオブジェクトを渡します。
const def = engine.findDataDefinitionByVarName("q_order_items");
let table = engine.findData(def);
if (table === null) {
table = def.createListArray();
}
// 末尾に行を追加
const row = table.addRow();
row.setObject("item_name", "ボールペン"); // 文字型 → String
row.setObject("quantity", new java.math.BigDecimal(10)); // 数値型 → BigDecimal
row.setObject("unit_price", new java.math.BigDecimal("120"));
// 追加直後の各セルは空文字なので、値を入れなくてもエラーにはならない
engine.setData(def, table);setObject() は値と列のデータ型が合っているかチェックします。例えば数値型の列に数値として解釈できない文字列を渡したり、選択型の列に BigDecimal を渡すとエラーになります。
既存の行を変更する
table.getRow(行番号) で行オブジェクトを取得し、setObject() で値を書き換えます。
const def = engine.findDataDefinitionByVarName("q_order_items");
let table = engine.findData(def);
if (table === null || table.size() < 2) {
throw new Error("2 行目が存在しません");
}
// 2行目(インデックス 1)の単価を変更する
const row = table.getRow(1);
row.setObject("unit_price", new java.math.BigDecimal("150"));
engine.setData(def, table);行を削除する
table.removeRow(行番号) で指定した行を削除します。行番号は 0 始まりです。
const def = engine.findDataDefinitionByVarName("q_order_items");
let table = engine.findData(def);
if (table === null || table.size() < 2) {
throw new Error("2 行目が存在しません");
}
table.removeRow(1); // 2行目を削除
engine.setData(def, table);条件に合致する行だけを削除する場合の注意
前方ループでインデックスを進めながら removeRow(i) を呼ぶと、削除のたびに後続行が前に詰まるため、次の行が読み飛ばされます。後方から走査するのが安全です。
// 単価が 0 の行をすべて削除する例
for (let i = table.size() - 1; i >= 0; i--) {
const unitPrice = table.getObject(i, "unit_price");
if (unitPrice !== null && unitPrice.signum() === 0) {
table.removeRow(i);
}
}なお、テーブルを丸ごとクリアしたい場合は、行を 1 つずつ消すのではなく engine.setDataByVarName("q_order_items", null) で null を上書きするだけで済みます。
補足:文字列として扱うget()/put()
getObject() / setObject() の代わりに、セルをすべて文字列として扱う API もあります。
| メソッド | 戻り値 / 受け取る値 |
|---|---|
table.get(行番号, 列の指定) | 列のデータ型を問わず、常に String |
row.put(フィールド名, 値) | 値は String のみ |
const table = engine.findDataByVarName("q_order_items");
for (let i = 0; i < table.size(); i++) {
const quantity = table.get(i, "quantity"); // 数値型でも String で返る
const unitPrice = table.get(i, "unit_price"); // 同上
// 数値計算するには BigDecimal への変換が必要
const subTotal = new java.math.BigDecimal(quantity).multiply(new java.math.BigDecimal(unitPrice));
}CSV ライクな出力など、すべて文字列のままで処理したい場合に向きます。数値計算や日付計算をしたい場合は getObject() / setObject() を使うほうが簡潔です。
実践例:明細の合計金額を計算して文字型に書き込む
注文明細テーブル(q_order_items)の数量・単価から合計金額を計算し、合計金額フィールド(文字型)に書き込む例です。数値列の値は getObject() で BigDecimal として直接取得できます。
const table = engine.findDataByVarName("q_order_items");
if (table === null || table.size() === 0) {
throw new Error("明細が入力されていません");
}
let total = new java.math.BigDecimal(0);
for (let i = 0; i < table.size(); i++) {
const quantity = table.getObject(i, "quantity"); // BigDecimal
const unitPrice = table.getObject(i, "unit_price"); // BigDecimal
// 数量・単価のいずれかが未入力の行はエラーにする(仕様に応じて continue でスキップしてもよい)
if (quantity === null || unitPrice === null) {
throw new Error((i + 1) + " 行目の数量または単価が未入力です");
}
total = total.add(quantity.multiply(unitPrice));
}
// 合計を桁区切り付きで文字型に書き込む
const formatter = new java.text.DecimalFormat("#,##0");
engine.setDataByVarName("q_total_amount", formatter.format(total) + " 円");関連リファレンス
- R2301: スクリプトタスクでのデータ取得/更新 — テーブル型を含む全データ型のメソッドとサンプルコードの一覧
- スクリプトタスクでデータ項目の値を参照・更新する — テーブル型以外のデータ型の操作方法



