Skip to main content

I am trying to set up an employee scheduling table. The table has links to my events table and to my employee table. The events have a "Start date" and "end date". Is there a way to create new records in the scheduling table pulled from events in the events table for each date in the start to end range? Ideally it would have all the event info in each day of the range. Employees are scheduled for full days so i wont need times, i would just like the ability to be able to add employees to each day of the event. Thank you for any help!

Hey Mike - I wrote a script to do this since I couldn't figure out a way to do this using the native automation tools. I created a formula field in the events table called "Duration" that outputs a number that represents the amount of days for the event. The script is set to run when a record is created. I set up a simple form to intake the event name, start date and end date. The "Duration" field is instantly calculated, which is referenced in the script hence why I made the trigger for when a record is created rather than when a form is submitted.

 

let inputConfig = input.config();

// Create an array to store the individual date values

const dateRecords = [];

//Loop to create date records

for (let i = 0; i < inputConfig.eventDuration; i++) {

// Calculate the date for each day of the event.

const currentDate = new Date (inputConfig.eventStart);
currentDate.setDate(currentDate.getDate() + i);

// Create a new record in the "Event Dates" table.

const newDateRecord = await base.getTable('Event Dates').createRecordAsync({
'Day': currentDate.toISOString().slice(0, 10), // Format the date as YYYY-MM-DD.
});
dateRecords.push(newDateRecord);
}

output.set("dateRecords", dateRecords);

Other Notes:

The table where the records are being created is called "Event Days". In Event Days, the primary field is called "Day" with a linked field to our other table called "Event"

 


Hey Mike - I wrote a script to do this since I couldn't figure out a way to do this using the native automation tools. I created a formula field in the events table called "Duration" that outputs a number that represents the amount of days for the event. The script is set to run when a record is created. I set up a simple form to intake the event name, start date and end date. The "Duration" field is instantly calculated, which is referenced in the script hence why I made the trigger for when a record is created rather than when a form is submitted.

 

let inputConfig = input.config();

// Create an array to store the individual date values

const dateRecords = [];

//Loop to create date records

for (let i = 0; i < inputConfig.eventDuration; i++) {

// Calculate the date for each day of the event.

const currentDate = new Date (inputConfig.eventStart);
currentDate.setDate(currentDate.getDate() + i);

// Create a new record in the "Event Dates" table.

const newDateRecord = await base.getTable('Event Dates').createRecordAsync({
'Day': currentDate.toISOString().slice(0, 10), // Format the date as YYYY-MM-DD.
});
dateRecords.push(newDateRecord);
}

output.set("dateRecords", dateRecords);

Other Notes:

The table where the records are being created is called "Event Days". In Event Days, the primary field is called "Day" with a linked field to our other table called "Event"

 


Thank you for your reply! I will try this, it seems like it could work for me!


Hey Mike - I wrote a script to do this since I couldn't figure out a way to do this using the native automation tools. I created a formula field in the events table called "Duration" that outputs a number that represents the amount of days for the event. The script is set to run when a record is created. I set up a simple form to intake the event name, start date and end date. The "Duration" field is instantly calculated, which is referenced in the script hence why I made the trigger for when a record is created rather than when a form is submitted.

 

let inputConfig = input.config();

// Create an array to store the individual date values

const dateRecords = [];

//Loop to create date records

for (let i = 0; i < inputConfig.eventDuration; i++) {

// Calculate the date for each day of the event.

const currentDate = new Date (inputConfig.eventStart);
currentDate.setDate(currentDate.getDate() + i);

// Create a new record in the "Event Dates" table.

const newDateRecord = await base.getTable('Event Dates').createRecordAsync({
'Day': currentDate.toISOString().slice(0, 10), // Format the date as YYYY-MM-DD.
});
dateRecords.push(newDateRecord);
}

output.set("dateRecords", dateRecords);

Other Notes:

The table where the records are being created is called "Event Days". In Event Days, the primary field is called "Day" with a linked field to our other table called "Event"

 


Hey @salvadaor is what you put into the input.config the list of records that have a Duration calculated on the "Event Dates" table? I'm trying to replicate a similar solution for myself but instead of an employee schedule, I'm creating a Program Schedule that is always 56 days. I've already created fields for 'Start Date' and 'End Date' and a 'Duration' formula field. 


I think I want to do the same thing, and I tried to use Copilot to write the script but keep getting “Invalid Arguements” errors. Essentially, it is a PTO calendar (other things, but they all function the same). I want to put in “PTO: Bob” on “Activity Date” and then have it automated to repeat the Activity (called “Headline or Topic”) each calendar day until another field called “End date.”  Currently, if you are gone a week, you have to duplicate the “Headline or Topic” 5 times (I know that title doesn’t make sense, but it is coming from a group base).

Copilot also suggested adding a column in the grid view of “Processed” to eliminate duplicates.

 

 

Here is the script:

let table = base.getTable("Table 1");

// Get the triggering record
let inputConfig = input.config();
let recordId = inputConfig.recordId;
let record = await table.selectRecordAsync(recordId);

if (!record) {
    throw new Error("Record not found.");
}

let name = record.getCellValue("🔄 Headline or Topic");
let startDate = new Date(record.getCellValue("Activity Date"));
let endDate = new Date(record.getCellValue("End date"));

if (!startDate || !endDate) {
    throw new Error("Activity or End Date is missing.");
}

startDate.setHours(0, 0, 0, 0);
endDate.setHours(0, 0, 0, 0);

if (endDate < startDate) {
    throw new Error("End date is before start date.");
}

let currentDate = new Date(startDate);
let recordsToCreate = t];

while (currentDate <= endDate) {
    recordsToCreate.push({
        fields: {
            "🔄 Headline or Topic": name + " (Copy)",
            "Activity Date": new Date(currentDate),
            "End date": new Date(currentDate)
        }
    });
    currentDate.setDate(currentDate.getDate() + 1);
}

// Create records in batches of 50
while (recordsToCreate.length > 0) {
    await table.createRecordsAsync(recordsToCreate.slice(0, 50));
    recordsToCreate = recordsToCreate.slice(50);
}

// Optional: mark the original record as processed
await table.updateRecordAsync(recordId, {
    "Processed": true
});
 

 

Here is the error

 


I think I am trying to do something similar, but keep getting a TypeError: Invalid arguments passed to table.selectRecordAsync(recordId, options):

Trying to create a PTO calendar where you don’t have to create a new Activity Date for each day you are out, but can just copy event each day until input “End date”. I freely admit I am both new to Airtable, as well as a complete uninformed (not even novice) on Script writing for automations.

 

 

This is my base, where the “Headline or Topic” needs to be repeated each day from “Activity Date” to “End date.”  I tried to use Copilot (aka, ChatGPT) to write the script, and it seemed to know what I was asking for, and gave me the following, but keep getting errors. My son thinks it is a input string error, but I have not idea.

 

let table = base.getTable("Table 1");

// Get the triggering record
let inputConfig = input.config();
let recordId = inputConfig.recordId;
let record = await table.selectRecordAsync(recordId);

if (!record) {
    throw new Error("Record not found.");
}

let name = record.getCellValue("🔄 Headline or Topic");
let startDate = new Date(record.getCellValue("Activity Date"));
let endDate = new Date(record.getCellValue("End date"));

if (!startDate || !endDate) {
    throw new Error("Activity or End Date is missing.");
}

startDate.setHours(0, 0, 0, 0);
endDate.setHours(0, 0, 0, 0);

if (endDate < startDate) {
    throw new Error("End date is before start date.");
}

let currentDate = new Date(startDate);
let recordsToCreate = e];

while (currentDate <= endDate) {
    recordsToCreate.push({
        fields: {
            "🔄 Headline or Topic": name + " (Copy)",
            "Activity Date": new Date(currentDate),
            "End date": new Date(currentDate)
        }
    });
    currentDate.setDate(currentDate.getDate() + 1);
}

// Create records in batches of 50
while (recordsToCreate.length > 0) {
    await table.createRecordsAsync(recordsToCreate.slice(0, 50));
    recordsToCreate = recordsToCreate.slice(50);
}

// Optional: mark the original record as processed
await table.updateRecordAsync(recordId, {
    "Processed": true
});

 


Hm could you provide a screenshot of your automation action?  If it helps, this is how a working bit looks just for the selectRecord bit

let inputConfig = input.config();
let recordId = inputConfig.recordId;
let table = base.getTable('New table')
let record = await table.selectRecordAsync(recordId)

console.log(record)

 


You mean this? 

 

It does say “Table already assigned” (line 1 let table - base.getTabel(“Table 1”);

 

The rest looks the same except “Console.log” … but still getting same error (back from line 6)

 


Ah yeah I think the issue is that you haven’t set up your ‘recordId’ variable

This is how it should look:

 


Well, not sure if it is better or worse, but it is now duplicating the activity, but it doesn’t STOP (I had to kill the automations). It is triggering the “Processed” to be checked, but i am guessing it isn’t rechecking that?

Or maybe it creates a copy, but then changes the second entry to “PTO: Test (Copy)” … and then “PTO: Test (Copy) (Copy)” etc.

 


It is also not duplicating all the fields. We have several fields that are also used for identification/filtering that should be duplicated. I want the entire record as first put in just duplicated each day, exactly the same, until the “End date”

 


The first post was apparently never approved, but the update kind of worked. It kept repeating itself. It is supposed to insert a “Check” mark under Processed, and then when it finds that, NOT make a duplicate. Instead, it just kept duplicating (until I jumped in and turned the script off - not sure it would have ever ended otherwise).  It also kept recreating the name, so “PTO: Test 3” became, then “PTO: Test 3 (copy)”, then “PTO: Test 3 (copy) (copy)”  etc etc.


Hmm, if I were you I’d try to generate a script that would output an array of dates instead, and then use that array in a Repeating Group action with a Create Record step

 

That way the script becomes a lot simpler (only outputs dates), and you can use Airtable’s automation UI how you want the fields updated instead of fiddling with a script, does that make sense?


Yes, you can achieve this by using an automation or script that loops through each event in your events table and creates a new record in the scheduling table for each date in the event’s start-to-end range. Each record would include the event details and the specific date. 


@TheTimeSavingCo and ​@ManleyKovacek  -- I think what you are saying is the good way to go, but admit I am such a novice at this, I have no idea how to do it (I literally just asked Copilot to create the script for me … and it got me some of the way there, but with enough errrors that it didn’t help to much. So much for AI taking over the world).