# How to Make a Call Sheet in Google Sheets (With Formulas)

Source: https://storiara.com/blog/how-to-make-a-call-sheet-in-google-sheets
Last updated: 2026-09-14
Author: Spencer Kaufman, Storiara

> Keep the data on separate tabs (Schedule, Cast, Crew, Locations, Days) and make the call sheet a print tab driven by one cell: the shoot day number. FILTER pulls that day's scenes, XLOOKUP fills in names and calls, pages are stored as eighths and converted for display, and cast pickup times are subtracted from on-set times. Paste values into a dated copy before you send it.

A call sheet typed from scratch every night works fine for a two-day short. By day four of anything longer, the 2nd AD is retyping the same crew list, re-adding pages on a phone calculator, and copying cast numbers that were already on the schedule. A linked spreadsheet stops that. You change one cell (the shoot day) and the scenes, cast, locations, and page total fill in.

This guide builds that spreadsheet for BRINE, a made-up five-day short. If you'd rather start from a finished layout without formulas, download the [call sheet template](https://storiara.com/templates/call-sheet) as XLSX and open it in Sheets.

## The tab layout

Keep data and presentation apart. Every fact lives in exactly one place, and the call sheet tab only reads.

| Tab | One row per | Columns |
|---|---|---|
| Schedule | Scene per day | A Day, B Order, C Sc., D Set and description, E D/N, F Cast, G Pages (display), H Loc #, I Eighths |
| Cast | Performer | A #, B Character, C Performer, D Phone, E HMU minutes, F Drive minutes |
| Crew | Crew member | A Dept, B Position, C Name, D Phone, E Offset minutes from crew call |
| Locations | Location | A Loc #, B Name, C Address, D Parking and base camp, E Nearest ER |
| Days | Shoot day | A Day, B Date, C Crew call, D Shooting call, E Lunch, F Sunrise, G Sunset, H Weather |
| DOOD | Performer | A #, then one column per shoot day holding SW, W, WF, H |
| Times | Performer per day | A Key (day-cast#), B Day, C Cast #, D Dismissed (date and time) |
| CallSheet | Printed page | Formulas only |

Cast numbers on the Schedule tab are typed as text like `1, 2`, the way they appear on a stripboard. Times on the Days tab are entered as times (7:00 AM), and the Dismissed column on Times holds a full date and time (11/6/2026 7:10 PM) because rest periods cross midnight.

## Step 1: store pages as eighths

A page count like 1 3/8 is hard to add in a spreadsheet: depending on how it was typed, Sheets may hold it as text or convert it into something you didn't intend. Store the length in column I as a whole number of eighths, and let column G display it.

In `Schedule!G2`, then filled down:

```
=IF(I2="","",IF(I2<8, I2&"/8", INT(I2/8)&IF(MOD(I2,8)=0,""," "&MOD(I2,8)&"/8")))
```

An 11 displays as `1 3/8`, a 16 as `2`, and a 6 as `6/8`. The formula doesn't reduce 4/8 to 1/2, which is correct for production paperwork. Nobody writes half pages on a call sheet. If you're unsure how to measure a scene in the first place, see [page eighths](https://storiara.com/glossary/page-eighths).

Here is Day 2 of BRINE on the Schedule tab:

| Day | Order | Sc. | Set and description | D/N | Cast | Pages | Loc # | Eighths |
|---|---|---|---|---|---|---|---|---|
| 2 | 1 | 5 | INT. BAIT SHOP. Cal asks Mae for the boat keys. | D | 1, 2 | 1 4/8 | 1 | 12 |
| 2 | 2 | 7 | INT. BAIT SHOP - BACK ROOM. Mae hides the ledger. | D | 2 | 1 1/8 | 1 | 9 |
| 2 | 3 | 6 | EXT. BAIT SHOP - DOCK. The deputy pulls up. | D | 1, 2, 4 | 3/8 | 1 | 3 |
| 2 | 4 | 12 | EXT. DOCK. Cal lies to Deputy Soto. | D | 1, 4 | 2 5/8 | 1 | 21 |

## Step 2: the day selector and header

On the CallSheet tab, cell `B3` holds the shoot day. Add a dropdown with Data, then Data validation, pointing at `Days!A2:A`, so nobody types a day that doesn't exist.

```
B4  Date           =XLOOKUP($B$3, Days!A2:A, Days!B2:B, "Not scheduled")
B5  Crew call      =XLOOKUP($B$3, Days!A2:A, Days!C2:C)
B6  Shooting call  =XLOOKUP($B$3, Days!A2:A, Days!D2:D)
B7  Lunch          =XLOOKUP($B$3, Days!A2:A, Days!E2:E)
B8  Sunrise        =XLOOKUP($B$3, Days!A2:A, Days!F2:F)
B9  Sunset         =XLOOKUP($B$3, Days!A2:A, Days!G2:G)
```

Format B5 through B9 as times. Sheets has no sunrise function, so get the times for each location and date from the [sunrise and sunset planner](https://storiara.com/tools/sunrise-sunset-planner) and paste them into the Days tab during prep.

## Step 3: pull the day's scenes

In `A12` on the CallSheet tab:

```
=IFERROR(SORT(FILTER(Schedule!B2:H, Schedule!A2:A=$B$3), 1, TRUE), "No scenes scheduled")
```

FILTER returns every Schedule row whose day matches B3, SORT puts them in shooting order by the Order column, and IFERROR covers days with nothing scheduled (FILTER returns #N/A when no rows match). Leave enough empty rows below A12 for your longest day. If the spill runs into something typed below it, you get a #REF! error.

The page total goes in the row under the scene block. First the sum in eighths, in a helper cell such as `J11`:

```
=SUM(FILTER(Schedule!I2:I, Schedule!A2:A=$B$3))
```

Then the display version beside the word TOTAL, using the same conversion as Step 1 pointed at J11. For Day 2 that's 12 + 9 + 3 + 21 = 45 eighths. 45 divided by 8 is 5 with 5 left over, so the sheet prints 5 5/8. That number should match Day 2 on your [one-line schedule](https://storiara.com/templates/one-line-schedule).

## Step 4: build the cast list from the scenes

The cast for the day is whoever appears in any of its scenes, listed once. One formula in `A22` does it:

```
=SORT(UNIQUE(TRANSPOSE(SPLIT(TEXTJOIN(",", TRUE, FILTER(Schedule!F2:F, Schedule!A2:A=$B$3)), ", "))))
```

Read it from the inside out. FILTER gets the cast cells for the day (`1, 2`, `2`, `1, 2, 4`, `1, 4`). TEXTJOIN glues them into one string. SPLIT breaks that string on commas and spaces. By default SPLIT treats each character in the delimiter separately and drops the empty pieces, so both `1, 2` and `1,2` work. TRANSPOSE turns the row into a column, UNIQUE removes repeats, and SORT orders them. Day 2 returns 1, 2, 4.

Each row beside it looks up the rest. In row 22, filled down:

```
B22  Character  =IF($A22="","",XLOOKUP($A22, Cast!$A$2:$A, Cast!$B$2:$B))
C22  Performer  =IF($A22="","",XLOOKUP($A22, Cast!$A$2:$A, Cast!$C$2:$C))
D22  Status     =IF($A22="","",INDEX(DOOD!$B$2:$Z, MATCH($A22, DOOD!$A$2:$A, 0), MATCH($B$3, DOOD!$B$1:$Z$1, 0)))
F22  On set     (typed by the 2nd AD after talking to the 1st AD)
E22  MU/WD call =IF(F22="","",F22-XLOOKUP($A22, Cast!$A$2:$A, Cast!$E$2:$E)/1440)
G22  Pickup     =IF(F22="","",E22-XLOOKUP($A22, Cast!$A$2:$A, Cast!$F$2:$F)/1440)
```

Sheets stores a time as a fraction of a day, and a day has 1,440 minutes, so dividing minutes by 1440 lets you subtract them from a time. Ruth Adair (Mae) is on set at 8:00 AM with 60 minutes of hair and makeup and a 40-minute drive: makeup call 7:00 AM, pickup 6:20 AM. The status column reads from the DOOD tab, so it stays in step with the [day out of days](https://storiara.com/templates/day-out-of-days) rather than whatever was on yesterday's sheet.

Keep the on-set column typed by hand. It's a judgment call about the shooting order, and a formula that guesses it will be wrong on exactly the days that matter.

## Step 5: check each actor's rest

Add one more column. The Times tab key is the day and cast number joined, like `1-2` for Day 1, performer 2.

```
H22  Rest check
=IF(E22="","",IF($B$4+E22 < XLOOKUP(($B$3-1)&"-"&$A22, Times!$A$2:$A, Times!$D$2:$D, 0)+0.5, "CHECK REST", "OK"))
```

`$B$4+E22` is today's date plus the makeup call, a full date and time. The XLOOKUP finds the performer's dismissal on the previous shoot day, and `+0.5` adds 12 hours, the SAG-AFTRA theatrical daily rest in the studio zone. When the performer didn't work yesterday, the lookup returns 0 and the check passes. Change 0.5 to match your agreement (10 hours is 10/24).

On BRINE, Mae was dismissed at 7:10 PM on Day 1, so her earliest call on Day 2 is 7:10 AM, and her 7:00 AM makeup call flags CHECK REST. The fix the 2nd AD chose was to move Scene 12 to the top of the order, since it's Cal and the deputy only, and put Mae on set at 9:15 AM. The formulas recalculated her makeup call to 8:15 AM and her pickup to 7:35 AM. For the reasoning behind choices like that, read [how to set call times](https://storiara.com/blog/how-to-set-call-times), and for a quick check outside the spreadsheet use the [turnaround calculator](https://storiara.com/tools/turnaround-calculator).

## Step 6: crew calls and locations

Each crew member has an offset in minutes from general crew call on the Crew tab: -30 for camera, -45 for hair and makeup, 0 for most departments. On the CallSheet tab, list the crew with `=FILTER(Crew!A2:C, Crew!C2:C<>"")` in `A40`, then in `D40`, filled down:

```
=IF(C40="","",$B$5+XLOOKUP(C40, Crew!$C$2:$C, Crew!$E$2:$E, 0)/1440)
```

With a 7:00 AM crew call, an offset of -45 gives 6:15 AM. Change crew call on the Days tab and every department call moves with it. Offsets that change day to day (a rigging crew on a pre-light) are easier to overwrite by hand on the final copy than to model.

For locations, show every location used by the day's scenes:

```
=FILTER(Locations!A2:E, ISNUMBER(MATCH(Locations!A2:A, FILTER(Schedule!H2:H, Schedule!A2:A=$B$3), 0)))
```

The nearest ER column comes along with it. Somebody still has to call that hospital before the first day at each location.

## Step 7: the advance schedule

The next two shoot days, pulled the same way as the scenes:

```
=IFERROR(SORT(FILTER(Schedule!A2:H, Schedule!A2:A>$B$3, Schedule!A2:A<=$B$3+2), 1, TRUE, 2, TRUE), "")
```

Label the block TENTATIVE. [Advance call sheets](https://storiara.com/blog/advance-call-sheets) explains why.

## Sharing it without breaking it

If the coordinator keeps the master crew list in a separate production file, pull it into the Crew tab with `=IMPORTRANGE("spreadsheet URL", "Crew!A2:E")`. The first time, Sheets asks you to allow access between the two files.

Then protect the formulas. Under Data, Protect sheets and ranges, lock the CallSheet tab so only the 2nd AD and 1st AD can edit it. One PA typing over the cast formula in row 22 is enough to send an actor the wrong pickup.

The biggest problem with a linked sheet is also its best feature: it always shows current data. Change the schedule on Wednesday and the Day 2 call sheet you sent on Monday changes too, which makes it useless as a record. When a day's sheet is final:

1. Right-click the CallSheet tab and duplicate it.
2. Select all on the copy, copy, and paste values only.
3. Rename it with the day and date, like `D2 SAT 11-7 SENT`.
4. Download that tab as a PDF (File, then Download, then PDF) with the print settings on current sheet and fit to width, and send the PDF or the snapshot.

That snapshot is what the [daily production report](https://storiara.com/templates/daily-production-report) gets compared against at wrap.

## Where the spreadsheet runs out

The formulas above handle one location per scene, one call per crew member per day, and one dismissal per performer. Company moves, split calls, a second unit, and background with multiple report times all mean manual overrides, and every override is something the next person to open the file won't know about. Shows that outgrow this usually do it around the second week. The [Google Sheets comparison](https://storiara.com/compare/google-sheets) looks at where the line tends to fall.

## Moving the same data into Storiara

Storiara doesn't connect to Google Sheets, but its Cast & Crew and Locations pages import CSV and XLSX files, so the Cast, Crew, and Locations tabs above can be downloaded as CSV and brought in. From there, call sheets are built per shoot day from the Storiara schedule, and each one can be printed, shared as a link, or emailed now or at a scheduled time.

## Frequently asked questions

### Is there a free call sheet template for Google Sheets?

Yes. Download the XLSX version of the Storiara call sheet template and open it in Google Sheets, or build the linked version described here so the call sheet fills itself from your schedule tab.

### How do I add up page eighths in Google Sheets?

Store each scene's length as a whole number of eighths (1 3/8 is 11), SUM those numbers, and convert the total for display with INT for whole pages and MOD for the remaining eighths. Adding text like 1 3/8 directly doesn't work.

### Why did my old call sheet change after I edited the schedule?

Because a formula-driven call sheet always shows the current data. Once a sheet is final, copy the tab and paste values only into a dated tab or a PDF, so the version you sent stays the version on file.

### Can Google Sheets calculate call times automatically?

It can do the subtraction. Enter each actor's on-set time, keep their hair and makeup duration and drive time in minutes on the Cast tab, and subtract minutes divided by 1440 to get makeup call and pickup. Someone still has to decide the on-set times.

### What does FILTER return when a day has no scenes?

It returns #N/A. Wrap the formula in IFERROR with a message such as 'No scenes scheduled' so the printed sheet doesn't show an error.

## Sources

- [Google Docs Editors Help: FILTER function](https://support.google.com/docs/answer/3093197?hl=en)
- [Google Docs Editors Help: XLOOKUP function](https://support.google.com/docs/answer/12405947?hl=en)
- [Google Docs Editors Help: SPLIT function](https://support.google.com/docs/answer/3094136?hl=en)
- [Google Docs Editors Help: TEXTJOIN](https://support.google.com/docs/answer/7013992?hl=en)
- [Google Docs Editors Help: IMPORTRANGE](https://support.google.com/docs/answer/3093340?hl=en)
- [Google Docs Editors Help: Protect, hide, and edit sheets](https://support.google.com/docs/answer/1218656?hl=en)
