作为GPT综合症的一种表现,我们今朝来探究下GPT会不会抢了我们SuiteScript的编程饭碗,以及如何与之相处。以下内容来自我个人的实践总结。
我们假设一个功能场景:
为了让用户能够在报价单上实现“一键多行”功能,也就是在报价中可以通过“一键多行”按钮,一次添加多行。其中数据源来自一个自定义记录,我们把它称为“数据模板”。通过用户自己维护数据源,在报价时可以把数据源中的记录,通过点个按钮,一次性的导入当前的行上去。在报价单上放个超链接,可以打开那个数据模板。
设想中的界面如下所示:
结合chatGPT,就是OpenAI的3.5版本,我们开始了GPT辅助编程的实践。
Prompt & chatGPT
Prompt:
使用NetSuite suitescript Client脚本,搜索一个自定义记录中匹配的Item数据,将结果插入当前的estimate的行中。请给出具体代码。
chatGPT:
以下是一个示例代码,用于搜索一个自定义记录中匹配的Item数据,并将结果插入当前的estimate的行中:
```javascript
/**
* @NApiVersion 2.x
* @NScriptType ClientScript
* @NModuleScope SameAccount
*/
define(['N/search', 'N/record'], function (search, record) {
function addCustomRecordItemsToEstimate() {
// 获取当前estimate的ID
var estimateId = record.getCurrentRecord().id;
// 定义自定义记录的ID
var customRecordId = 123;
// 创建一个查询自定义记录的搜索
var customRecordSearch = search.create({
type: 'customrecord_' + customRecordId,
filters: [
['isinactive', 'is', 'F']
],
columns: [
'name',
'custrecord_item',
'custrecord_quantity'
]
});
// 运行搜索并处理结果
customRecordSearch.run().each(function (result) {
// 获取自定义记录中的Item和Quantity字段
var item = result.getValue('custrecord_item');
var quantity = result.getValue('custrecord_quantity');
// 创建一个新的estimate行
var line = record.getCurrentRecord().selectNewLine({
sublistId: 'item'
});
// 设置行上的Item和Quantity字段
record.getCurrentRecord().setCurrentSublistValue({
sublistId: 'item',
fieldId: 'item',
value: item
});
record.getCurrentRecord().setCurrentSublistValue({
sublistId: 'item',
fieldId: 'quantity',
value: quantity
});
// 保存新行并继续处理下一个结果
record.getCurrentRecord().commitLine({
sublistId: 'item'
});
return true;
});
}
return {
pageInit: function (context) {
addCustomRecordItemsToEstimate();
}
};
});
```
Prompt:
NetSuite Userevent Script,在estimate的Item list的位置添加一个Button,名字叫做“一键导入”。当用户点击时,执行前面所说的Client Script。请给出详细代码。
chatGPT:
下面是一个可能的NetSuite UserEvent Script:
```javascript
/**
* @NApiVersion 2.x
* @NScriptType UserEventScript
* @NModuleScope SameAccount
*/
define(['N/ui/serverWidget', 'N/url'], function (serverWidget, url) {
function beforeLoad(context) {
if (context.type === context.UserEventType.VIEW) {
var form = context.form;
var sublist = form.getSublist({ id: 'item' });
sublist.addButton({
id: 'custpage_import_button',
label: '一键导入',
functionName: 'addCustomRecordItemsToEstimate'
});
var scriptUrl = url.resolveScript({
scriptId: 'customscript_my_client_script',
deploymentId: 'customdeploy_my_client_script',
returnExternalUrl: false
});
form.clientScriptModulePath = scriptUrl;
}
}
return {
beforeLoad: beforeLoad
};
});
```
这个UserEvent Script会在estimate页面加载前执行,将一个名为“一键导入”的按钮添加到Item sublist中。当用户点击这个按钮时,会执行名为“importEstimateItems”的客户端脚本。同时,这个UserEvent Script也会将客户端脚本的URL添加到estimate表单中,以便客户端脚本能够被正确加载和执行。
Prompt:
NetSuite Userevent Script,请刚才的Button旁边,添加一个超链接。这个链接可以打开某个自定义记录的界面。
chatGPT:
下面是一个可能的NetSuite UserEvent Script:
```javascript
/**
* @NApiVersion 2.x
* @NScriptType UserEventScript
* @NModuleScope SameAccount
*/
define(['N/ui/serverWidget', 'N/url'], function (serverWidget, url) {
function beforeLoad(context) {
if (context.type === context.UserEventType.VIEW) {
var form = context.form;
var sublist = form.getSublist({ id: 'item' });
sublist.addButton({
id: 'custpage_import_button',
label: '一键导入',
functionName: 'importEstimateItems'
});
// 添加自定义记录链接
var linkUrl = url.resolveRecord({
recordType: 'customrecord_my_custom_record',
isEditMode: true
});
var link = '<a href=\ + linkUrl + '\打开自定义记录</a>';
sublist.addField({
id: 'custpage_custom_record_link',
label: '自定义记录',
type: serverWidget.FieldType.INLINEHTML
}).defaultValue = link;
// 添加客户端脚本链接
var scriptUrl = url.resolveScript({
scriptId: 'customscript_my_client_script',
deploymentId: 'customdeploy_my_client_script',
returnExternalUrl: false
});
form.clientScriptModulePath = scriptUrl;
}
}
return {
beforeLoad: beforeLoad
};
});
```
这个UserEvent Script会在estimate页面加载前执行,将一个名为“一键导入”的按钮添加到Item sublist中,并在这个按钮旁边添加一个超链接,用于打开自定义记录的界面。注意,这里的自定义记录类型为`customrecord_my_custom_record`,应该替换为实际的自定义记录类型。
同时,这个UserEvent Script也会将客户端脚本的URL添加到estimate表单中,以便客户端脚本能够被正确加载和执行。
请注意,这个UserEvent Script中的代码与之前的回答中的代码是相同的,只是添加了一个新的字段来显示自定义记录链接。
分析与心得
代码问题:
- 我的意图是进行增加行,但是chatGPT给出context.UserEventType.VIEW的代码建议。
- chatGPT把Record和CurrentRecord两个类搞错了,导致了类方法调用失败。
- 在Client Script中未建立Page Init函数。
- 在Item Tab中添加serverWidget.FieldType.INLINEHTML的建议失败,系统不允许。
- 在一直无法正确的添加多行的情况下,chatGPT给出了提示了两个重要提示:一是有可能是因为必填字段没有赋值导致的,二是通过网页调试工具来检查错误来源。这最终帮助了我们发现了错误来源。
心得:
- 代码建议出现错误的概率很高,需要有代码经验的人才能驾驭。
- 代码建议的框架是完整的,特别在注释习惯上好过人工。在解决了关键问题的错误后,能够帮助提升效率。
- 虽然NetSuite用户手册给出了代码Samples,但是chatGPT并没有采用之 。如果能将chatGPT作为问答入口,将NetSuite的Sample Codes作为知识库,则较好。
- chatGPT在解决JS相关的通用语法的问答上准确度高。例如,“netsuite脚本中,如何表示在本级目录?”
- 不同的Prompt,会带来回答的差异。所以应该从Prompt Engineering的角度来做问题优化。
- 采用chatGPT来实现功能的骨干,然后人工去概念性错误,细节调整。这是有效的配合模式。
- 在ERP顾问领域,可以有效赋能独立实施顾问和甲方系统管理员,来实现轻量级开发。这将深刻的改变这两类人的工作状态。让顾问更加专注在业务流程的创新上,方便的进行概念验证。
- 由于涉及SuiteScript的代码,有概念性错误,可以判断chatGPT在SuiteScript上的语料库还不是很充沛,训练不足。如果能够建立私有化的GPT,用NetSuite的专用脚本数据去训练,应该可以有很大改善。
结合GPT的代码模式
基于上述的实践,我们初步总结出如下的最佳实践:
以上是我们结合GPT进行NetSuite代码的实践。基本结论是还是得有编程基础以及NetSuite SuiteScript的底子,否则效率无法提升。NetSuite开发的小伙伴可以暂时松一口气了。