Retrieving Recent Data
Subscription Tier Required
This feature requires the Premier subscription tier or higher.
Sometimes you will want to retrieve recently-submitted data records. One common reason for this is to look up data based on a Traceability value selected during an Inspection.
In this guide, you will create an Inspection which will retrieve the most recent data record after the user enters the Work Order Traceability. If data exists for that Work Order, then other Traceability Tests in the Inspection will be populated to match the values from that data.
You should be familiar with the principles of Inspection Scripting before getting started.
Prerequisites
This guide assumes that you have:
- At least one Characteristic.
- Multiple Traceability fields.
- A User with a Role containing the Retrieve and Analyze Data Records permission.
For the purpose of this guide, the Characteristic will be Length and the Traceability will be Work Order, Machine, and Shift.
Create the Inspection
To begin, create an Inspection:
- Navigate to the Inspection list.
- Press the Add button.

- Fill in the Name field with Retrieve Data.
- Press the Save button.

- Open the Inspection Settings and set Autoload First Sub-Inspection to Yes.
- If you only have one Process created in your GS account, it will automatically be set on the Inspection. If you have created more than one Process, select the desired Process in the Inspection Settings overlay.
Set Up the Sub-Inspection
In the existing Sub-Inspection, add three Traceability Tests, selecting the Traceability and setting their associated Script IDs:
- Work Order, with the Script ID
workorder. - Machine, with the Script ID
machine. - Shift, with the Script ID
shift.
Add an SPC Test and select the Length Characteristic. Set the Script ID to length.
Finally, edit the Sub-Inspection settings:
- Name the Sub-Inspection Measurements.
- Select Measurements as the Next Sub-Inspection.
- Set the Script ID to
measurements.
Script
Now that the Inspection has been set up, you can begin scripting. Create a new Inspection Script and give it a memorable name. If this interface is unfamiliar, review the Inspection Scripting Principles and Code Editor articles.
The tasks we will use scripting to accomplish are:
- Listening for changes to the Work Order Traceability.
- Retrieving the most recent data record for the entered Work Order.
- Setting the Machine and Shift Traceability Test values based on the most recent record.
Listen for Work Order Changes
In the newly created Inspection Script, get a reference to the measurements Sub-Inspection API and the workorder Traceability Test API:
const subi = gsApi.inspection.subInspection('measurements');
const workOrderTraceability = subi.traceability('workorder');
Then add a map for your Traceability IDs. While optional, defining a map for Traceability IDs helps avoid hardcoding 'magic numbers' later in the script.
Warning
Remember to replace these numbers with the actual IDs from your account!
const workOrderTraceability = subi.traceability('workorder');
const traceabilityIds = {
workOrder: 3,
machine: 1,
shift: 2,
};
Next, bind to the onFocusOut event of the Work Order Test.
onFocusOut will fire whenever the browser's focus leaves a Test, even if the Test is incomplete or has not changed. We only want to look up the previous data record when a Work Order has been entered, so add the following code to short-circuit the onFocusOut event:
workOrderTraceability.onFocusOut(async (e) => {
const newWorkOrder = (await workOrderTraceability.getProperties()).value;
if (!newWorkOrder || typeof newWorkOrder !== 'string' || !e.data.hasChanged) {
return;
}
});
Retrieve Data
Now that you have the Work Order stored in the newWorkOrder variable, you are ready to request data from GS. Because requesting data will take a non-negligible amount of time, you may want to lock the screen so the user cannot interact with the other Tests. Add the following code to lock the screen:
workOrderTraceability.onFocusOut(async (e) => {
const newWorkOrder = (await workOrderTraceability.getProperties()).value;
if (!newWorkOrder || typeof newWorkOrder !== 'string' || !e.data.hasChanged) {
return;
}
await gsApi.display.addLoading();
});
Then request the data. In this guide, we will request data from the past year for the SPC Test's Characteristic:
await gsApi.display.addLoading();
const data = await gsApi.analysis.retrieveData({
dataType: 'spc',
maxRecords: 1,
datePeriod: {
type: 'relative',
relative: 'nEndingNow',
timePeriod: 'year',
n: 1
},
standards: {
type: 'characteristic',
characteristicIds: [/** @type {GSBaseEntity} */((await subi.spc('length').getProperties()).spcCharacteristic).id]
},
filter: {
grouping: 'all',
nodes: [{
filterBy: 'trace',
entityId: traceabilityIds.workOrder,
operationId: 'textIs',
value: newWorkOrder
}]
}
});
Information
You may notice that attempting to access the spcCharacteristic.id property of the SPC Test results in an error message. This is due to the code editor not knowing that the SPC Test has a Characteristic. In order to tell the code editor that we know that spcCharacteristic is defined, we use a @type annotation. This is entirely optional, and omitting it will not prevent the code from running.
Populate Other Traceability
Using the retrieved data, you can now look up the previous Machine and Shift. Add the following code:
let previousMachine;
let previousShift;
if (data.type === 'spcData' && data.details.length && data.details[0].data.length) {
const previousTraceability = data.details[0].data[0].traceability;
previousMachine = previousTraceability.find(x => x.id === traceabilityIds.machine)?.value;
previousShift = previousTraceability.find(x => x.id === traceabilityIds.shift)?.value;
}
await subi.traceability('machine').updateProperties({
value: previousMachine ?? null
});
await subi.traceability('shift').updateProperties({
value: previousShift ?? null
});
Finally, unlock the screen at the end of the onFocusOut handler so the user can continue with the Inspection:
Test the Inspection
Save and Run the Inspection.
Enter values for the Traceability and SPC Tests, then submit the Sub-Inspection. Do this for a few combinations of Traceability values, and notice that every time you enter the value of a previously-used Work Order, the Machine and Shift are automatically populated from the most recent record.
Final Code
const subi = gsApi.inspection.subInspection('measurements');
const workOrderTraceability = subi.traceability('workorder');
const traceabilityIds = {
workOrder: 3,
machine: 1,
shift: 2,
};
workOrderTraceability.onFocusOut(async (e) => {
// If the Work Order has not been set or has not changed, exit early
const newWorkOrder = (await workOrderTraceability.getProperties()).value?.toString();
if (!newWorkOrder || !e.data.hasChanged) {
return;
}
// Lock the screen so the operator cannot interact with other controls while we're processing
await gsApi.display.addLoading();
// Retrieve data in the past year for the current characteristic and work order
const data = await gsApi.analysis.retrieveData({
dataType: 'spc',
maxRecords: 1,
datePeriod: {
type: 'relative',
relative: 'nEndingNow',
timePeriod: 'year',
n: 1
},
standards: {
type: 'characteristic',
characteristicIds: [/** @type {GSBaseEntity} */((await subi.spc('length').getProperties()).spcCharacteristic).id]
},
filter: {
grouping: 'all',
nodes: [{
filterBy: 'trace',
entityId: traceabilityIds.workOrder,
operationId: 'textIs',
value: newWorkOrder
}]
}
});
// Find the Machine and Shift in the most recent record
let previousMachine;
let previousShift;
if (data.type === 'spcData' && data.details.length && data.details[0].data.length) {
const previousTraceability = data.details[0].data[0].traceability;
previousMachine = previousTraceability.find(x => x.id === traceabilityIds.machine)?.value;
previousShift = previousTraceability.find(x => x.id === traceabilityIds.shift)?.value;
}
// Update the Traceability Tests with the most recent values, falling back to `null` if they're not defined
await subi.traceability('machine').updateProperties({
value: previousMachine ?? null
});
await subi.traceability('shift').updateProperties({
value: previousShift ?? null
});
// Unlock the screen so the operator can continue
await gsApi.display.removeLoading();
});





