Help

πŸ†˜ Complicated formula help please

3582 29
cancel
Showing results forΒ 
Search instead forΒ 
Did you mean:Β 
RnJ
8 - Airtable Astronomer
8 - Airtable Astronomer

I have a scheduling base for Volunteers helping at Non-Profits. I am wondering if it is possible accomplish these with a formula?

I have attached a generic base to give you an idea of what i am looking for. I have entered the answers into the fields as an Example via text.

#1. Volunteering with -
If multiple volunteers are on the (same date, same location, same start time, same stop time), I would like column " :raising_hand_man: Volunteering with :raising_hand_man: " to show the names of each volunteer on the same detail.

#2. Double Booked -
If a volunteer is signed up for multiple details the same day I would like a column β€œ :eyes: Double Booked/Overlapping Shifts :eyes: ”, if they are double booked or have overlapping shifts.

#3. Relieving/Relieved by -
I would like two columns " :handshake: Relieving Volunteer :handshake: " & " :handshake: Relieved By Volunteer :handshake: " to list the names of those volunteers if applicable (ie. If one shift ends and another one starts. Shift one is 8:00am-10:00am, shift two is 10:00am-2:00pm, shift three is 2:00pm-4:00pm, etc.)

Thanks for any help you can provide!

29 Replies 29
RnJ
8 - Airtable Astronomer
8 - Airtable Astronomer

Awesome thanks Kamille! I am just starting to dig into learning to script :slightly_smiling_face:

P.S. Do you also do custom scripting for hire? If so, I may need to hire you for some other upcoming challenges I run into.

Thanks again

The answer 9/10 is no. Sometimes if there’s a fun use case within my capability I’ll consider it, but most times I do not. There are several highly talented consultants lurking in the forum that you can consider however.

RnJ
8 - Airtable Astronomer
8 - Airtable Astronomer

Well I do appreciate all the help, I just feel bad asking a ton of questions with really no compensation :slightly_smiling_face: They need some sort of tip button in the forum for the people so dedicated to help others :slightly_smiling_face:

RnJ
8 - Airtable Astronomer
8 - Airtable Astronomer

@Kamille_Parks Sorry, another question if you get time.

Would it be hard to add these to the original script?

For Double Booked/Overlapping Shifts:
If shift date & hours are the same display β€œDouble Booked” & If shift date & hours only overlap display β€œOverlap” otherwise β€œNo”

For Volunteering,:
If same shift does not have a volunteer assigned yet display β€œTBD” in place of Volunteer Name.
*this could be accomplished using a formula field IF(volunteer="",TBD,volunteer) but think would make sense to have in the script instead?

For Relieving Volunteer & Relieved By Volunteer:
Same idea - If same shift does not have a volunteer assigned yet display β€œTBD” in place of Volunteer Name.

Thanks again

For TBD you could replace the part of the script inside .updateRecordAsync() using this format:

'Name of Field': value ? value : 'TBD'

Replace value with whatever the script currently has there.

As for editing the double booking part: Yes its possible, no I don’t want to do it.

RnJ
8 - Airtable Astronomer
8 - Airtable Astronomer

I have been fine tuning this script for my needs and thought I would post the updates in case it can benefit anyone else.

@Kamille_Parks - Thanks again for getting me going on this. It has been fun to learn how scripting works and look forward to learning more.

This is the first time I have ever worked with scripting, so my modifications may have not been the best way, but they seem to work :slightly_smiling_face:

Changes Made:

  1. For Double Booked/Overlapping Shifts: If shift date & hours are the same display β€œDouble Booked” & If shift date & hours only overlap display β€œOverlap” otherwise β€œNo”

  2. For Volunteering: If same shift does not have a volunteer assigned yet display β€œTBD” in place of Volunteer Name. I also created another field so I could separate the volunteers assigned to same location/same hours & volunteers assigned to same location/overlapping hours.

  3. For Relieving Volunteer & Relieved By Volunteer: Same idea - If same shift does not have a volunteer assigned yet display β€œTBD” in place of Volunteer Name.

Code:

const scheduleT = base.getTable('Schedule')

const scheduleQ = await scheduleT.selectRecordsAsync()

const scheduleR = scheduleQ.records

const trigger = await input.recordAsync('Which schedule record do you want to gather info about?', scheduleT)

const triggerValues = {

    id: trigger.id,

    volunteer: trigger.getCellValueAsString('Volunteer'),

    start: new Date(trigger.getCellValue('Start')),

    stop: new Date(trigger.getCellValue('Stop')),

    location: trigger.getCellValue('Location'),

}

const shiftRecords = scheduleR.map(x => {return (

    {

        id: x.id,

        volunteer: x.getCellValueAsString('Volunteer') ? x.getCellValueAsString('Volunteer'):'TBD',

        start: new Date(x.getCellValue('Start')),

        stop: new Date(x.getCellValue('Stop')),

        location: x.getCellValue('Location'),

    }

)})

const sameShiftRecordsexact = shiftRecords.filter(x => {

    return (

        ((triggerValues.start <= x.start && triggerValues.stop >= x.stop)) && 

        (x.location == triggerValues.location) 

    )

})

const sameShiftRecordsoverlap = shiftRecords.filter(x => {

    return (

        ((triggerValues.start > x.start && triggerValues.start < x.stop) || x.start > triggerValues.start && x.start < triggerValues.stop) && 

        (x.location == triggerValues.location) 

    )

})

const isDoubleBooked = (shiftRecords.filter(x => {

    return (

        (x.id !== triggerValues.id) && 

        (x.volunteer == triggerValues.volunteer) &&

        ((triggerValues.start <= x.start && triggerValues.stop >= x.stop))

    )

}).length > 0) ? '🚫 Double Booked' :

(shiftRecords.filter(x => {

    return (

        (x.id !== triggerValues.id) && 

        (x.volunteer == triggerValues.volunteer) &&

        ((triggerValues.start > x.start && triggerValues.start < x.stop) || x.start > triggerValues.start && x.start < triggerValues.stop)

    )

}).length > 0) ? '⚠ Overlap':

'βœ… No'

const prevShiftRecords = shiftRecords.filter(x => {

    return (x.stop.toISOString() == triggerValues.start.toISOString()&& 

        (x.location == triggerValues.location)) 

})

const nextShiftRecords = shiftRecords.filter(x => {

    return (x.start.toISOString() == triggerValues.stop.toISOString()&& 

        (x.location == triggerValues.location)) 

})

output.table({

    ['Volunteer']: triggerValues.volunteer,

    ['Start']: triggerValues.start,

    ['Stop']: triggerValues.stop,

    ['Volnteering (same shift)']: Array(...(sameShiftRecordsexact.map(x => x.volunteer))).join(', '),

    ['Volnteering (overlapping shift)']: Array(...(sameShiftRecordsoverlap.map(x => x.volunteer))).join(', '),

    ['Double Booked?']: isDoubleBooked,

    ['Relieving']: Array(...(prevShiftRecords.map(x => x.volunteer))).join(', '),

    ['Relieved By']: Array(...(nextShiftRecords.map(x => x.volunteer))).join(', '),

})

await scheduleT.updateRecordAsync(triggerValues.id, {

    'EXAMPLE πŸ™‹β€β™‚οΈVolunteering (exact shifts) πŸ™‹β€β™‚οΈ': Array(...(sameShiftRecordsexact.map(x => x.volunteer))).join(', '),

    'EXAMPLE πŸ™‹β€β™‚οΈVolunteering with (overlapping shifts) πŸ™‹β€β™‚οΈ': Array(...(sameShiftRecordsoverlap.map(x => x.volunteer))).join(', '),

    'EXAMPLE πŸ‘€ Double Booked/Overlapping Shifts πŸ‘€': isDoubleBooked.toString(),

    'EXAMPLE 🀝Relieving Volunteer🀝': Array(...(prevShiftRecords.map(x => x.volunteer))).join(', '),

    'EXAMPLE 🀝Relieved By Volunteer🀝': Array(...(nextShiftRecords.map(x => x.volunteer))).join(', ')

})
RnJ
8 - Airtable Astronomer
8 - Airtable Astronomer

Ok, I just found a little hiccup in the code and am having a tough time finding a solution.

For my β€œsameShiftRecordsexact” it is pulling in data if the chosen shift is within another shift and not just exactly the same.

I thought this part

    ((triggerValues.start <= x.start && triggerValues.stop >= x.stop)) && 

would just need

==

instead of

<=

but that didn’t work :frowning: Any help is greatly appreciated :slightly_smiling_face:

Did you set both <= and >= to ==?

RnJ
8 - Airtable Astronomer
8 - Airtable Astronomer

Yeah, when I change them both to == it is not recognizing anything for the β€œsameShiftRecordsExact”.

((triggerValues.start == x.start && triggerValues.stop == x.stop)) &&

RnJ
8 - Airtable Astronomer
8 - Airtable Astronomer

Disregard. I finally figured it out :slightly_smiling_face: Had to change this block of code to with the β€œtoISOString”

Thanks again.

const sameShiftRecordsExact = shiftRecords.filter(x => {

return (x.start.toISOString() == triggerValues.start.toISOString()&&

    (x.stop.toISOString() == triggerValues.stop.toISOString()&&

    (x.location == triggerValues.location))

)

})