Help

Re: Modify "Create multiple records" script so it can be included in an automation

Solved
Jump to Solution
3427 2
cancel
Showing results for 
Search instead for 
Did you mean: 
Ann_Yeom
6 - Interface Innovator
6 - Interface Innovator

Hi,

I've been trying to modify the Airtable script (Create records from multiple select) pasted below into an automation as an action. I was thinking removing the input commands and replacing the table/field location to my specific fields would work but having more trouble than I thought. 

Any one able to help me out? I'm looking to modify the script below so I can include it in an automation.

The tables and fields would stay constant.

 

 

 

// Script settings
let s = input.config({
    title: ' Create records from multiple select field options',
    description: 'Creates 1 record in another table for each option in a multiple select field in the source table, and links the new records back to the source record.',
    items: [
        // Source table select
        input.config.table('tableSource', {
            label: ' Table with existing records'
        }),
        // Source table: Multiple select field with deliverables
        input.config.field('delivField', {
            parentTable: 'tableSource',
            label: ' Multiple select field with names of records to create',
        }),
        // Destination table select
        input.config.table('tableDest', {
            label: ' Table to create new records in'
        }),
        // Destination table: Name or title field
        input.config.field('destinationField', {
            parentTable: 'tableDest',
            label: ' Deliverable name or title field in destination table',
        }),
        // Destination table: Linked record field (back to the Source table record)
        input.config.field('projField', {
            parentTable: 'tableDest',
            label: ' Linked record field (links to table with existing records)',
        }),
    ]
});
// You can use a button field that points to this script to run it for specific records,
// or you can run the script directly, in which case the following prompts the user to pick a record
let r = await input.recordAsync('Pick a record', s.tableSource);
while (!r) {
    output.text('You must select a record.');
    r = await input.recordAsync('Pick a record', s.tableSource);
}

// Gets the desired # of records to create, and deliverable names, based on the fields chosen in the script settings
let recToCreate = s.delivField.options?.choices.length;
let deliverables = r.getCellValue(s.delivField.name);

// Variables to store the applicable deliverable names and length (total records to create)
let delivNames = [];
let length = 0;

if (deliverables) {
    // Creates record names from 'deliverables' multiple select field, if any
    for (let item of deliverables) {
        delivNames.push({
            'Name': item.name
        })
    }
    length = delivNames.length

    // Preview records to create, prompt user to confirm creation
    output.markdown('### Create ' + length + ' records for **' + r.name + '**?');

    output.table(delivNames);
    await input.buttonsAsync('', [{ label: 'Create records', value: 'Create records', variant: 'primary' }]);

    // Create records
    let dToCreate = [];

    for (let i = 0; i < length; i++) {
        let name = delivNames[i].Name

        dToCreate.push({
            fields: {
                [s.destinationField.id]: name,
                [s.projField.id]: [{ id: r.id }]
            }
        })

    };

    // Batches the creation
    while (dToCreate.length > 0) {
        await s.tableDest.createRecordsAsync(dToCreate.slice(0, 50));
        dToCreate = dToCreate.slice(50);

 

 

 

1 Solution

Accepted Solutions

So, that's exactly what I thought. Except formula primary field in table 2, but that doesn't matter. I did test runs with checkbox

Alexey_Gusev_0-1680022505338.png

Input variables

Alexey_Gusev_1-1680022687863.png

result looks similar, just double check that table2 and field names in code match existing names

Alexey_Gusev_2-1680022872704.png

 

See Solution in Thread

6 Replies 6
Alexey_Gusev
13 - Mars
13 - Mars

Hi,

Could you please describe what this script doing and how it suppose to be triggered in your case?
From description at the beginning of script it does the same thing, as if you copy-paste the value of a multiselect field to the linked field of the same record.


Anyway, suppose you need to create records in 'table2' from value of multiselect field (list of options), one record for each in field 'Name' and link all them to 'parent' record.

Pass value as 'list', and record id as ID.
this script will create the needful

const {ID,list} = input.config();
const crt=list.map(x=>({fields:{'Name':x,'Link':[{'id':ID}]}}))
await base.getTable('table2').createRecordsAsync(crt.splice(0,50))

Huh... that's an interesting script. I've always seen it, but I've never actually used it or taken a look at the code itself.

It's not worth your time to refactor that script, and it appears more complicated than it actually is.
Here's a quick look at how I would think of approaching this.

Here's the multi-select field I'm starting with, as well as the field options:

Ben_Young1_0-1679980113112.png

Ben_Young1_1-1679980131872.png

 

Here's my "target" table where I want to create my new records:

Ben_Young1_2-1679980193737.png

Super simple. Just a single field.
And here's the script itself:

// The table that contains the existing multi-select field.
const sourceTable = base.getTable("tableId");
// The table where we are writing the new records to.
const targetTable = base.getTable("tableId");

// Returns an array of each multiple select option from the specified field.
const fieldOptions = sourceTable
    .getField("fieldId")
    .options
    .choices
    .map(choice => choice.name.trim())

// Returns an array of record objects to create.
let recordsToCreate = fieldOptions.map(option => ({
    fields: {
        // Map the fields/values for the records you want to create here.
        "fieldId": option
    }
}));


if (recordsToCreate) {
    while (recordsToCreate.length > 50) {
        await targetTable.createRecordsAsync(recordsToCreate.slice(0, 50));
        recordsToCreate = recordsToCreate.slice(50);
    }
    await targetTable.createRecordsAsync(recordsToCreate);
}

Here's the result:

Ben_Young1_3-1679980269856.png

Another interesting little feature we can write in is a filter that will make sure that we only create records for each option that doesn't already exist in the table.

So if I add five new options to the field:

Ben_Young1_4-1679980390238.png

I can change the script to something like this:

// The table that contains the existing multi-select field.
const sourceTable = base.getTable("tableId");
// The table where we are writing the new records to.
const targetTable = base.getTable("tableId");

// Returns an array of each multiple select option from the specified field.
const fieldOptions = sourceTable
    .getField("fieldId")
    .options
    .choices
    .map(choice => choice.name.trim())

const uniqueOptions = fieldOptions
// Insert the id of the field in your target table that contains the name of the existing options.
    .filter(option => existingRecords.findIndex(record => record.getCellValueAsString("fieldId") === option) === -1)


// Returns an array of record objects to create.
let recordsToCreate = fieldOptions.map(option => ({
    fields: {
        // Map the fields/values for the records you want to create here.
        "fieldId": option
    }
}));


if (recordsToCreate) {
    while (recordsToCreate.length > 50) {
        await targetTable.createRecordsAsync(recordsToCreate.slice(0, 50));
        recordsToCreate = recordsToCreate.slice(50);
    }
    await targetTable.createRecordsAsync(recordsToCreate);
}

This was fun. Let me know if you're having trouble with something or if you want to add additional functionality or complexity to this.

Hi @Alexey_Gusev , 

Sure. The automation trigger, is when a record enters a view and the action is to run a script.

The script I was trying to modify... looks at the source table's multi-select field, its values for each row and creates a record in another table for each multi-select option selected, and links the new records back to the source record.

Here is the input fields and description of the extension I was trying to modify

Capture.JPG

So, I'm trying to accomplish this...
When an initiative enters this view 

1.JPG

Trigger a script that will create a record in Table 2 for each "Project" selected for an "Initiative" in Table 1 and link back to Table 1. Note the primary field in Table 2 is a formula field.

2.JPG

Hope that is clearer. Thanks!

Thanks Ben!! 
One question, how do we add to the script to link the new records created in the "Target table" back to the "Source table"? 

So, that's exactly what I thought. Except formula primary field in table 2, but that doesn't matter. I did test runs with checkbox

Alexey_Gusev_0-1680022505338.png

Input variables

Alexey_Gusev_1-1680022687863.png

result looks similar, just double check that table2 and field names in code match existing names

Alexey_Gusev_2-1680022872704.png

 

Works great! Thank you @Alexey_Gusev  😊

Thank you @Ben_Young1 as well!