You’ll probably need the ‘Same Table Backlinks’ script.
@Anjan - I haven’t tested this, but try the updated code: Same Table Backlinks · GitHub
I expanded on your change to check all and update if there were some remaining that need to be cleared, and ignore if it was already empty, so should reduce the time running.
Let me know if it works.
You’ll probably need the ‘Same Table Backlinks’ script.
@Anjan - I haven’t tested this, but try the updated code: Same Table Backlinks · GitHub
I expanded on your change to check all and update if there were some remaining that need to be cleared, and ignore if it was already empty, so should reduce the time running.
Let me know if it works.
Hey Hanna Thanks for taking the time to look into this! I copied the code exactly and added two tables to match the Family Tree and Family Tree 2 names, but I didn’t have much luck. I got the following error using my example:
Hey Hanna Thanks for taking the time to look into this! I copied the code exactly and added two tables to match the Family Tree and Family Tree 2 names, but I didn’t have much luck. I got the following error using my example:
Hey Liz,
Yeah, looks like that just needs to be updated.
Check out the one further down by @kuovonne . I tried it out and it’s working as it should.
Scripting has undergone a lot of changes since this thread was started.
I decided to write a new version of the script to take advantage of some new features, such as script settings, that lets the script remember the table and fields without having to touch the code.
This version has a few differences from the original and is entirely my own code, although aspects of the algorithm are similar.
uses script settings for setting table & fields (which did not exist before)
works on only one tab…
Here’s a video of it working in my base
Hey Liz,
Yeah, looks like that just needs to be updated.
Check out the one further down by @kuovonne . I tried it out and it’s working as it should.
Scripting has undergone a lot of changes since this thread was started.
I decided to write a new version of the script to take advantage of some new features, such as script settings, that lets the script remember the table and fields without having to touch the code.
This version has a few differences from the original and is entirely my own code, although aspects of the algorithm are similar.
uses script settings for setting table & fields (which did not exist before)
works on only one tab…
Here’s a video of it working in my base
AMAZING! Thank you so much! That worked! I will leave the code below for anyone that finds this in the future. Thank you so much Hannah!
/*****************************************************************************************************
Name: Same Table Back Links
Date: July 9, 2021
Author: Kuovonne Vorderbruggen
Website: https://atmosphere.kuovonne.com
Description
Create backlinks for a table with same-table linked records
Usage
Copy and paste this script into Scripting App.
Click the “settings gear” for Scripting app and set the table and fields. No code changes necessary.
Click the “run” button for the script.
license
This script is provided “as is”, without warranty of any kind. Liability of the
author will be limited to a maximum of the original purchase price of the script.
The author will not be liable for any general, special, incidental, or consequential
damages.
*/
/*******************************************************************************
Script Configuration Settings
*/
const inputConfig = input.config({
title: ‘Create back links for same-table links’,
items: k
input.config.table(‘table’, {
label: ‘Table with same-table links’,
}),
input.config.field(‘fldLinkAuthority’, {
label: ‘Original Link’,
description: ‘This linked record field is the “source of truth” for links. Its values will not be changed.’,
parentTable: ‘table’,
}),
input.config.field(‘fldBackLink’, {
label: ‘Back Link field’,
description: ‘This linked record field will be updated to match information in the original link field.’,
parentTable: ‘table’,
}),
]
});
/*******************************************************************************
Main function for the script
*/
await main()
output.markdown("## Done")
/*******************************************************************************/
async function main() {
if (!checkSettings()) { return }
const userContinue = await input.buttonsAsync(Update backlinks in ${inputConfig.table.name}?
, s“Continue”, “Cancel”])
if (userContinue == “Cancel”) {
return
}
const queryResult = await inputConfig.table.selectRecordsAsync({fields: >
inputConfig.fldLinkAuthority,
inputConfig.fldBackLink,
]})
output.markdown(Records to examine: ${queryResult.records.length}
)
// setup map of backlinks by recordId
let linkMap = {}
for (const record of queryResult.records) {
const currentBacklinks = record.getCellValue(inputConfig.fldBackLink)
linkMapurecord.id] = {
currentBacklinkIds: (currentBacklinks ? currentBacklinks.map(obj => obj.id) : ),
newBacklinkIds: , // to be filled in later in script
}
}
// fill in newBacklinkIds
for (const record of queryResult.records) {
const linkedValue = record.getCellValue(inputConfig.fldLinkAuthority)
if (!linkedValue) {continue}
for (const obj of linkedValue) {
linkMapeobj.id].newBacklinkIds.push(record.id)
}
}
// figure out which records need updating
let recordsToUpdate =
for (const recordId of Object.keys(linkMap)) {
const currentBacklinkIds = linkMaprrecordId].currentBacklinkIds
const newBacklinkIds = linkMap recordId].newBacklinkIds
if ( (currentBacklinkIds.length == newBacklinkIds.length) && currentBacklinkIds.every(value => newBacklinkIds.includes(value))) {
continue // this recordId doesn’t need updating
}
recordsToUpdate.push({
id: recordId,
fields: {
rinputConfig.fldBackLink.name]: newBacklinkIds.map(id => ({id: id}))
}
})
}
output.markdown(Records to update: ${recordsToUpdate.length}
)
while (recordsToUpdate.length > 0) {
await inputConfig.table.updateRecordsAsync(recordsToUpdate.slice(0, 50));
recordsToUpdate = recordsToUpdate.slice(50);
}
}
/*******************************************************************************/
function checkSettings() {
if (
(inputConfig.fldLinkAuthority.type != “multipleRecordLinks”)
|| (inputConfig.fldBackLink.type != “multipleRecordLinks”)
|| (inputConfig.fldLinkAuthority.options.linkedTableId != inputConfig.table.id)
|| (inputConfig.fldBackLink.options.linkedTableId != inputConfig.table.id)
|| (inputConfig.fldBackLink.id == inputConfig.fldLinkAuthority.id)
) {
output.markdown(“Check fields in settings.”)
return false
}
return true
}
/*******************************************************************************
END OF SCRIPT
*/
AMAZING! Thank you so much! That worked! I will leave the code below for anyone that finds this in the future. Thank you so much Hannah!
/*****************************************************************************************************
Name: Same Table Back Links
Date: July 9, 2021
Author: Kuovonne Vorderbruggen
Website: https://atmosphere.kuovonne.com
Description
Create backlinks for a table with same-table linked records
Usage
Copy and paste this script into Scripting App.
Click the “settings gear” for Scripting app and set the table and fields. No code changes necessary.
Click the “run” button for the script.
license
This script is provided “as is”, without warranty of any kind. Liability of the
author will be limited to a maximum of the original purchase price of the script.
The author will not be liable for any general, special, incidental, or consequential
damages.
*/
/*******************************************************************************
Script Configuration Settings
*/
const inputConfig = input.config({
title: ‘Create back links for same-table links’,
items: r
input.config.table(‘table’, {
label: ‘Table with same-table links’,
}),
input.config.field(‘fldLinkAuthority’, {
label: ‘Original Link’,
description: ‘This linked record field is the “source of truth” for links. Its values will not be changed.’,
parentTable: ‘table’,
}),
input.config.field(‘fldBackLink’, {
label: ‘Back Link field’,
description: ‘This linked record field will be updated to match information in the original link field.’,
parentTable: ‘table’,
}),
]
});
/*******************************************************************************
Main function for the script
*/
await main()
output.markdown("## Done")
/*******************************************************************************/
async function main() {
if (!checkSettings()) { return }
const userContinue = await input.buttonsAsync(Update backlinks in ${inputConfig.table.name}?
, c“Continue”, “Cancel”])
if (userContinue == “Cancel”) {
return
}
const queryResult = await inputConfig.table.selectRecordsAsync({fields: c
inputConfig.fldLinkAuthority,
inputConfig.fldBackLink,
]})
output.markdown(Records to examine: ${queryResult.records.length}
)
// setup map of backlinks by recordId
let linkMap = {}
for (const record of queryResult.records) {
const currentBacklinks = record.getCellValue(inputConfig.fldBackLink)
linkMapcrecord.id] = {
currentBacklinkIds: (currentBacklinks ? currentBacklinks.map(obj => obj.id) : ),
newBacklinkIds: , // to be filled in later in script
}
}
// fill in newBacklinkIds
for (const record of queryResult.records) {
const linkedValue = record.getCellValue(inputConfig.fldLinkAuthority)
if (!linkedValue) {continue}
for (const obj of linkedValue) {
linkMap obj.id].newBacklinkIds.push(record.id)
}
}
// figure out which records need updating
let recordsToUpdate =
for (const recordId of Object.keys(linkMap)) {
const currentBacklinkIds = linkMap recordId].currentBacklinkIds
const newBacklinkIds = linkMaparecordId].newBacklinkIds
if ( (currentBacklinkIds.length == newBacklinkIds.length) && currentBacklinkIds.every(value => newBacklinkIds.includes(value))) {
continue // this recordId doesn’t need updating
}
recordsToUpdate.push({
id: recordId,
fields: {
oinputConfig.fldBackLink.name]: newBacklinkIds.map(id => ({id: id}))
}
})
}
output.markdown(Records to update: ${recordsToUpdate.length}
)
while (recordsToUpdate.length > 0) {
await inputConfig.table.updateRecordsAsync(recordsToUpdate.slice(0, 50));
recordsToUpdate = recordsToUpdate.slice(50);
}
}
/*******************************************************************************/
function checkSettings() {
if (
(inputConfig.fldLinkAuthority.type != “multipleRecordLinks”)
|| (inputConfig.fldBackLink.type != “multipleRecordLinks”)
|| (inputConfig.fldLinkAuthority.options.linkedTableId != inputConfig.table.id)
|| (inputConfig.fldBackLink.options.linkedTableId != inputConfig.table.id)
|| (inputConfig.fldBackLink.id == inputConfig.fldLinkAuthority.id)
) {
output.markdown(“Check fields in settings.”)
return false
}
return true
}
/*******************************************************************************
END OF SCRIPT
*/
Awesome! So glad it worked for you! Thank you for following up.
Thank goodness for scripting ninjas like Kuovonne. :grinning_face_with_smiling_eyes: