📝 記事概要
NetSuiteでは、データを一括更新する手段として CSVインポート や ワークフロー がありますが、動的な更新が必要な場合は SuiteScript が最適です。本記事では、SuiteScript 1.0 & 2.0 で一括更新する方法を解説します。
🚀 SuiteScriptでの一括更新のポイント
✔ 特定条件のデータを柔軟に更新
✔ スケジュール実行で自動化可能
✔ 大量データ処理ならMap/Reduceを活用
📌 SuiteScript 1.0 でのスケジュールスクリプト
function scheduled_UpdateInvoices(type) {
// 「請求書(invoice)」レコードを検索(ステータスが「Open」のもの)
var results = nlapiSearchRecord('invoice', null,
[new nlobjSearchFilter('status', null, 'anyof', 'Open')],
[new nlobjSearchColumn('internalid')]
);
// 検索結果が存在する場合
if (results) {
for (var i = 0; i < results.length; i++) {
// 検索結果の 内部IDを取得し、ステータスを「全額適用済」に更新
nlapiSubmitField('invoice', results[i].getId(), 'status', 'PaidInFull');
}
}
}
✅ ポイント
nlapiSearchRecord() でデータ取得(条件:請求書のステータスが「Open」)nlapiSubmitField() でステータスを「PaidInFull」に一括更新- 最大1000件までのレコード を処理可能(1回の検索で取得できる最大件数)
📌 SuiteScript 2.0 でのスケジュールスクリプト
define(['N/record', 'N/search'], function(record, search) {
function execute(context) {
// 「請求書(invoice)」レコードを検索(ステータスが「Open」のもの)
var invoiceSearch = search.create({
type: search.Type.INVOICE, // レコードタイプを「INVOICE」に指定
filters: [['status', 'anyof', 'Open']], // フィルター条件(ステータスが「Open」)
columns: ['internalid'] // 取得するフィールド(internalid)
}).run().getRange({ start: 0, end: 1000 }); // 取得範囲(最大1000件)
// 検索結果を1件ずつ処理
invoiceSearch.forEach(function(result) {
// 内部IDを取得し、ステータスを「全額適用済」に更新
record.submitFields({
type: record.Type.INVOICE, // 更新対象レコード(請求書)
id: result.getValue('internalid'), // レコードID
values: { status: 'PaidInFull' } // 更新するフィールド値
});
});
}
return { execute: execute };
});
✅ ポイント
search.create() でデータ取得(請求書のステータスが「Open」)record.submitFields() でステータスを「PaidInFull」に更新- 1000件以上の処理なら Map/Reduce を検討(スケジュールスクリプトでは1000件制限あり)
🚀 方法 2:Map/Reduceスクリプトで超大量データを更新
スケジュールスクリプトでは1000件ずつの処理が限界 ですが、Map/Reduce を使えば 10万件以上 のレコードも処理できます
/**
* @NApiVersion 2.x
* @NScriptType MapReduceScript
*/
define(['N/record', 'N/search'], function(record, search) {
// ステップ 1: 検索フェーズ(対象データを取得)
function getInputData() {
return search.create({
type: search.Type.INVOICE, // 対象レコード(請求書)
filters: [['status', 'anyof', 'Open']], // フィルター(未払いの請求書)
columns: ['internalid'] // 取得フィールド(内部ID)
});
}
// ステップ 2: マップフェーズ(データを処理)
function map(context) {
var id = JSON.parse(context.value).id; // 請求書ID取得
record.submitFields({
type: record.Type.INVOICE,
id: id,
values: { status: 'PaidInFull' } // ステータスを変更
});
}
// ステップ 3: 結果をまとめる(今回は不要)
function reduce(context) {}
// ステップ 4: 後処理(ログ記録など)
function summarize(summary) {
log.audit('処理完了', '正常終了');
}
return {
getInputData: getInputData,
map: map,
reduce: reduce,
summarize: summarize
};
});
✅ ポイント
getInputData() で検索したレコードをバッチ処理map() でレコードを1つずつ更新(並列処理で高速化)
📌 SuiteScriptでの一括更新の注意点
❌ NG
🚫 record.load() のループ処理は負荷が高い(パフォーマンスが低下)
🚫 1000件以上の処理をスケジュールスクリプトで行うと 制限に引っかかる
🚫 ユーザーインターフェース上で実行すると タイムアウトのリスクがある
✅ ベストプラクティス
✔ search.create() で対象データを 最小限に絞る
✔ スケジュール実行 で負荷分散(Map/Reduceを検討)
✔ エラーハンドリング を適切に実装(ネットワークエラー時のリカバリ)
🎯 まとめ
SuiteScriptを活用すれば、大量データの一括更新を 自動化 & 効率化 できます。
用途に応じて スケジュールスクリプト や Map/Reduce を活用しましょう!
💡 「他にもこんな処理を自動化したい!」 というリクエストがあれば、ぜひコメントで教えてください! 🚀