Help

Re: Batch duplication of records?

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

Hello Airtable fans,

I use Airtable to manage a very large collection of recipes. There are often times that I would like to duplicate large numbers of these recipes so that I may change them slightly. It’s become very time consuming for me to duplicate each recipe one by one and assign a new ID to them. As a work around, I create a CSV with the original recipe info, change the ID and then re-upload to create new records. Is there some other way to do this? Has Airtable ever considered a batch duplication feature?

Thanks!

Leslie

1 Solution

Accepted Solutions
Justin_Barrett
18 - Pluto
18 - Pluto

The easiest way I can think of to pull this off is with a script in the Scripting app. Add a checkbox field named “Copy”, and check that box on all records that you want to duplicate. With that, the following script could easily find those checked records, make new records that match them, and uncheck the original records. In case your checkbox field is named something besides “Copy”, change the relevant lines in the code to match your field name.

let table = base.getTable(cursor.activeTableId)
let query = await table.selectRecordsAsync()
let checked = query.records.filter(record => {return record.getCellValue("Copy") === true})

// Uncheck the current records
let uncheck = checked.map(record => {return {id: record.id, fields: {"Copy": false}}})
while (uncheck.length > 0) {
    // @ts-ignore
    await table.updateRecordsAsync(uncheck.slice(0, 50))
    uncheck = uncheck.slice(50)
}

// Make new records based on those that were checked
let newRecords = []
for (let record of checked) {
    let newRecord = {fields: {}}
    for (let field of table.fields) {
        // @ts-ignore
        if (field.isComputed || field.name === "Copy")
            continue
        let value = record.getCellValue(field.name)
        if (value === record.name)
            value += " copy"
        newRecord.fields[field.name] = value
    }
    newRecords.push(newRecord)
}

while (newRecords.length > 0) {
    await table.createRecordsAsync(newRecords.slice(0, 50))
    newRecords = newRecords.slice(50)
}

See Solution in Thread

7 Replies 7
Justin_Barrett
18 - Pluto
18 - Pluto

The easiest way I can think of to pull this off is with a script in the Scripting app. Add a checkbox field named “Copy”, and check that box on all records that you want to duplicate. With that, the following script could easily find those checked records, make new records that match them, and uncheck the original records. In case your checkbox field is named something besides “Copy”, change the relevant lines in the code to match your field name.

let table = base.getTable(cursor.activeTableId)
let query = await table.selectRecordsAsync()
let checked = query.records.filter(record => {return record.getCellValue("Copy") === true})

// Uncheck the current records
let uncheck = checked.map(record => {return {id: record.id, fields: {"Copy": false}}})
while (uncheck.length > 0) {
    // @ts-ignore
    await table.updateRecordsAsync(uncheck.slice(0, 50))
    uncheck = uncheck.slice(50)
}

// Make new records based on those that were checked
let newRecords = []
for (let record of checked) {
    let newRecord = {fields: {}}
    for (let field of table.fields) {
        // @ts-ignore
        if (field.isComputed || field.name === "Copy")
            continue
        let value = record.getCellValue(field.name)
        if (value === record.name)
            value += " copy"
        newRecord.fields[field.name] = value
    }
    newRecords.push(newRecord)
}

while (newRecords.length > 0) {
    await table.createRecordsAsync(newRecords.slice(0, 50))
    newRecords = newRecords.slice(50)
}

Hi @Justin_Barrett

Should the last “copy” be capitalized, with no space in front of it? It just seemed the odd one out.

Mary

It’s different on purpose. The line before it checks to see if the content came from the record’s primary field. If so, it adds " copy" to that value, so the user can distinguish between the original and the new copied version. With a specific example like this, I always test code before posting it, so you can guarantee that it works as intended.

Leslie_Engel
6 - Interface Innovator
6 - Interface Innovator

Thank you @Justin_Barrett for this! I have not experimented with scripts yet but did view the webinar on scripting recently. I will try this out and see how it goes!

Tried this out this morning @Justin_Barrett and it worked like a charm. Thanks again!

It raised another question for me. Is there a way (via a script) to then mark the duplicated IDs as “new” or something like that so I am able to easily find them?

The script above already appends " copy" to the end of the primary field value to distinguish each duplicate record from the original. So if the original primary field contains “Baked Alaska”, then the copy of that record will read “Baked Alaska copy” (as long as the primary field isn’t a formula; if it’s a formula, then it will likely have the same name as the original).

If that’s not sufficient, then what would you prefer? I don’t suggest making a new field that only serves to mark new duplicate records. You’ll already have to edit the record to change its name, so maybe adding a colorful emoji to the " copy" addition would work. Maybe change " copy" to " :warning: COPY" in the code.

Leslie_Engel
6 - Interface Innovator
6 - Interface Innovator

Interesting! I’m not seeing “copy” at the end of the primary field, which is a number (not a formula though). That would be sufficient for me, but maybe I will attempt the copy + emoji in the code and see what happens.