About Subrecords
When working with records in SuiteScript, you'll often deal with various field types. You may see fields with a data type of summary. The only way to fill these fields is by saving a subrecord to them. To work with these fields, you need to know how to script with subrecords.
Saving subrecords to summary fields can be more complicated than setting values for other field types. However, subrecords are similar to records. So if you know how to work with records, you already know a great deal about working with subrecords. This topic summarizes the similarities and differences.
Note that subrecords don't work with the Advanced Employee Permissions feature. For more information, see Before Enabling the Advanced Employee Permissions Feature.
Subrecords
Subrecords are a way to store data in NetSuite.
Like records, subrecords are classified by type. Common subrecord types include address, inventory detail, and order schedule.
Each subrecord type has its own purpose and set of fields. For example:
-
An address subrecord holds an address with fields like city, state, and zip.
-
An order schedule subrecord is for purchase schedules, with fields like startdate and enddate.
-
An inventory detail subrecord stores data like serial numbers for inventory items, with a sublist to hold this data.
At the same time, subrecords differ from records in some ways. For example, while records can exist independently, a subrecord exists solely to hold information about a specific record. You can only work with subrecords in the context of their parent record.
In the UI, you usually open a subrecord by clicking an icon on the parent record. This opens the subrecord form in a new window. For example, the following illustration shows, at left, a purchase order with one line in its Items sublist. If you click the icon, it opens a window showing the inventory detail subrecord.

To access this same subrecord from a script, start by loading the purchase order. Then you would use the Record.getSublistSubrecord(options) method to open the subrecord. For example:
...
// Load the purchase order.
var rec = record.load({
type: record.Type.PURCHASE_ORDER,
id: 7,
isDynamic: false
});
// Retrieve the subrecord. For sublistId, use the ID of the relevant sublist on
// the purchase order record type. For fieldId, use the ID of the summary field
// on the sublist that holds the subrecord.
var subrec = rec.getSublistSubrecord({
sublistId: 'item',
line: 0,
fieldId: 'inventorydetail'
});
...
For a full script example, see Creating an Inventory Detail Subrecord Example.
Subrecord Scripting Overview
Use the following guidelines when scripting with subrecords:
When Subrecords Are Read-Only
You can use subrecords in both client and server scripts. But subrecords are read-only if you retrieve their parent records in these ways:
-
Through the context object provided to a client script, or through currentRecord.get().
-
Through the context object provided to a beforeLoad user event script.
For more details, see Supported Deployments for Subrecord Scripting.
Look Up Details About the Summary Field
To work with a subrecord, you need to know about the summary field that contains it. You'll also need to know if the summary field is on the parent record's body or on a sublist. You need both pieces of information to instantiate the subrecord. If it's a sublist field, you'll also need the sublist ID.
If you are not sure where the field is situated, you can review the record in the UI. You can also check the reference page for the record in the SuiteScript Records Browser. On the reference page for each record type, the Fields table lists all of the record type’s body fields. The tables listed under the heading Sublists show sublist fields. For more details, see Finding Details About Parent Record Types.
Look Up the Subrecord’s Field and Sublist IDs
Like records, all subrecords have required and optional fields. You need the field IDs to set values for these fields. For sublist fields, you'll also need the sublist ID. You can find this info in the SuiteScript Records Browser. The browser lists subrecord types alongside record types. For each subrecord type, a reference page includes the IDs for all of the elements on the subrecord, including a sublist, if one exists, and all of the subrecord’s fields. For more details, see Finding Details About Subrecord Types.
Additionally, if you have the Show Internal IDs preference enabled, you can use the UI to find the IDs for subrecord body fields. To view a field’s ID, click its label. This will open a popup with the ID. For help enabling this preference, see Setting the Internal ID Preference.
Use Record Methods to Get and Set Values
Scripting with subrecords is similar to scripting with records in many ways.
For example, when your script instantiates a subrecord, the system returns one of the same objects that it uses to represent records. These objects include record.Record and currentRecord.CurrentRecord.
You can use many of the same methods for subrecords as you do for records. For example:
-
In server scripts, use Record.setValue(options) to set values on record or subrecord body fields.
-
In a client script, use CurrentRecord.getValue(options) to retrieve the value stored in either a record or subrecord body field.
Some record methods and properties don't work with subrecords. These exceptions are noted in the property descriptions in the N/record Module and N/currentRecord Module topics.
Do Not Explicitly Save a Subrecord
After you have created or updated a subrecord, you do not explicitly save it. Rather, after you have set all required fields on the subrecord, you simply save the parent record. Saving the parent record also saves the subrecord.
Creating an Inventory Detail Subrecord Example
Here's an example of how to create a subrecord.
This example creates a purchase order with one inventory item in its sublist. The example also creates an inventory detail subrecord to store a lot number for the item.
Before using this example in your NetSuite account, do the following:
-
Make sure the Advanced Bin / Numbered Inventory Management feature is enabled, at Setup > Company > Enable Features, on the Items & Inventory subtab.
-
Verify that you have at least one vendor, one location, and one lot-numbered inventory item defined in your system. Make a note of each record’s internal ID.
-
Where noted in the script example comments, replace the hardcoded IDs with valid values from your NetSuite account.
This example uses standard mode, but you can also use dynamic mode. For more details about both approaches, see Using SuiteScript 2.x to Create a Subrecord in a Sublist Field.
For help deploying a user event script, see SuiteScript 2.x Entry Point Script Creation and Deployment.
/**
* @NApiVersion 2.x
* @NScriptType UserEventScript
*/
define(['N/record'], function(record){
function myAfterSubmit(context){
// Create the purchase order.
var rec = record.create({
type: record.Type.PURCHASE_ORDER,
isDynamic: false
});
// Set body fields on the purchase order. Replace both of these
// hardcoded values with valid values from your NetSuite account.
rec.setValue({
fieldId: 'entity',
value: '2'
});
rec.setValue({
fieldId: 'location',
value: '2'
});
// Insert a line in the item sublist.
rec.insertLine({
sublistId: 'item',
line: 0
});
// Set the required fields on the line. Replace the hardcoded value
// for the item field with a valid value from your NetSuite account.
rec.setSublistValue({
sublistId: 'item',
fieldId: 'item',
line: 0,
value: '7'
});
rec.setSublistValue({
sublistId: 'item',
fieldId: 'quantity',
line: 0,
value: 1
});
// Instantiate the subrecord. To use this method, you must
// provide the ID of the sublist, the number of the line you want
// to interact with, and the ID of the summary field.
var subrec = rec.getSublistSubrecord({
sublistId: 'item',
line: 0,
fieldId: 'inventorydetail'
});
// Insert a line in the subrecord's inventory assignment sublist.
subrec.insertLine({
sublistId: 'inventoryassignment',
line: 0
});
subrec.setSublistValue({
sublistId: 'inventoryassignment',
fieldId: 'quantity',
line: 0,
value: 1
});
// Set the lot number for the item. Although this value is
// hardcoded, you do not have to change it, because it doesn't
// reference a record in your account. For this example,
// the value can be any string.
subrec.setSublistValue({
sublistId: 'inventoryassignment',
fieldId: 'receiptinventorynumber',
line: 0,
value: '01234'
});
// Save the record. Note that the subrecord object does
// not have to be explicitly saved.
try {
var recId = rec.save();
log.debug({
title: 'Record created successfully',
details: 'Id: ' + recId
});
} catch (e) {
log.error({
title: e.name,
details: e.message
});
}
}
}
return {
afterSubmit: myAfterSubmit
};
});
For additional script samples, see Scripting Subrecords that Occur on Sublist Lines and Scripting Subrecords that Occur in Body Fields.