SuiteScript按钮点击执行脚本异常求助:仅第二个日志运行
看起来你遇到的问题是按钮触发的脚本只执行到第二个日志就卡住了,后面的逻辑完全没跑。我帮你梳理下可能的原因和解决办法:
核心问题:客户端脚本误用服务器端API
你绑定到按钮的createTO函数是客户端脚本(通过form.setScript关联到表单,按钮点击触发的是客户端逻辑),但代码里用了几个只有服务器端脚本才能用的API,这直接导致代码执行到这里就抛出错误中断了:
nlapiGetNewRecord()用错了
这个API是给服务器端的用户事件脚本(比如beforeSubmit)设计的,用来获取待保存的新记录。在客户端脚本里,你需要用nlapiGetCurrentRecord()来获取当前页面的记录对象。
执行到PORecord = nlapiGetNewRecord();这一行时,客户端环境不支持这个函数,直接抛出错误,后面的代码自然就停了——这就是为什么你只看到runs 2的日志。其他潜在的API混用问题
原代码里的nlapiSetCurrentLineItemValue('item', 'location', 6);也是错误的:你正在创建新的调拨单记录,却调用了全局的行项目操作API,这会操作当前页面的PO记录而非新的TO记录,同样会导致逻辑异常。
具体修复步骤
1. 替换错误的记录获取API
把代码里的:
PORecord = nlapiGetNewRecord();
改成客户端兼容的写法:
PORecord = nlapiGetCurrentRecord();
2. 修正行项目操作的API调用
原代码里的全局行项目操作,要改成针对新创建的TO记录的方法调用:
// 原错误代码 // nlapiSetCurrentLineItemValue('item', 'location', 6); // 修正后:先选中行,再设置值,最后提交行 TOrecord.selectLineItem('item', 1); // 选中第一行(行号从1开始) TOrecord.setCurrentLineItemValue('item', 'location', 6); TOrecord.commitLineItem('item');
3. 新增记录保存状态判断
客户端脚本里nlapiGetRecordId()在记录未保存时会返回null,如果直接用未保存的PO创建TO会出问题,建议加个判断:
POID = nlapiGetRecordId(); POTYPE = nlapiGetRecordType(); if (!POID) { alert('请先保存采购订单再执行此操作!'); nlapiLogExecution('ERROR', 'script', 'PO未保存,无法获取记录ID'); return; }
4. 优化数组赋值逻辑(可选但更规范)
原代码用new Array()后通过索引赋值的方式可以优化为push(),避免索引混乱:
var arrayName = []; var arrayQty = []; for ( var i = 1; i <= lines ; i++ ) { arrayName.push(PORecord.getLineItemValue('item', 'item', i )); arrayQty.push(PORecord.getLineItemValue('item', 'quantity' , i)); }
5. 客户端脚本调试技巧
客户端脚本的错误不会出现在NetSuite的系统日志里,你可以打开浏览器开发者工具(按F12),切换到Console标签页,点击按钮后查看报错信息,快速定位问题点。
修复后的关键代码片段
function createTO() { alert("This function was called"); nlapiLogExecution('DEBUG', 'script', 'runs 1'); var POID ; var POType ; var PORecord; var lines; nlapiLogExecution('DEBUG', 'script', 'runs 2'); // 修正:客户端用nlapiGetCurrentRecord()获取当前记录 PORecord = nlapiGetCurrentRecord(); lines = PORecord.getLineItemCount('item'); POID = nlapiGetRecordId(); POType = nlapiGetRecordType(); // 新增:判断记录是否已保存 if (!POID) { alert('请先保存采购订单再创建调拨单!'); nlapiLogExecution('ERROR', 'script', 'PO未保存,无法获取记录ID'); return; } var arrayName = []; var arrayQty = []; // 优化数组赋值方式 for ( var i = 1; i <= lines ; i++ ) { arrayName.push(PORecord.getLineItemValue('item', 'item', i )); arrayQty.push(PORecord.getLineItemValue('item', 'quantity' , i)); } nlapiLogExecution('DEBUG', 'script', 'runs 3'); // 创建调拨单记录 var TOrecord = nlapiCreateRecord ('transferorder'); TOrecord.setFieldValue('customform',128); TOrecord.setFieldValue('subsidiary',2); TOrecord.setFieldValue('location',144); TOrecord.setFieldValue('transferlocation',145); TOrecord.setFieldValue('memo', 'PO: ' + POID ); TOrecord.setFieldValue('employee',nlapiGetContext().getUser()); // 批量设置调拨单行项目 for ( var j = 0; j < arrayName.length ; j++ ) { var lineNum = j + 1; // 调拨单行号从1开始 TOrecord.setLineItemValue("item", "item", lineNum , parseInt(arrayName[j]) ); TOrecord.setLineItemValue("item", "quantity", lineNum , parseInt(arrayQty[j])); } // 修正行项目位置设置逻辑 TOrecord.selectLineItem('item', 1); TOrecord.setCurrentLineItemValue('item', 'location', 6); TOrecord.commitLineItem('item'); var TOResult = nlapiSubmitRecord(TOrecord, true, true); var TOTranID= nlapiLookupField('transferorder', TOResult, 'tranid'); var poURL = nlapiResolveURL('RECORD', 'transferorder', TOResult); nlapiSetRedirectURL('RECORD','transferorder', TOResult); return; }
内容的提问来源于stack exchange,提问作者Brandon Reale

