Oct 15, 2020 11:21 AM
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
Solved! Go to Solution.
Oct 15, 2020 05:48 PM
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)
}
Oct 15, 2020 05:48 PM
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)
}
Oct 15, 2020 06:06 PM
Should the last “copy” be capitalized, with no space in front of it? It just seemed the odd one out.
Mary
Oct 15, 2020 06:44 PM
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.
Oct 19, 2020 03:07 PM
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!
Oct 20, 2020 07:38 AM
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?
Oct 20, 2020 08:05 AM
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.
Oct 20, 2020 08:16 AM
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.