What-ifs and other schedules

A formula can read a schedule other than the one in the grid: the schedule as CPM would date it with something changed (a what-if), the baseline, or a named revision or scenario. You read any of them with IN: IN(BASELINE(), [Finish date]) is each task's baseline finish.

A what-if is a real CPM run, not an estimate. A delay doesn't travel through a schedule as simple arithmetic once calendars, constraints, progress and level-of-effort tasks are involved, so Owl doesn't add numbers up along paths. It dates a copy of the schedule with the project's own settings and calendars, and the formula reads the copy. A what-if that changes nothing reads exactly what the grid shows.

You want to knowRead
What happens if something changesA what-if: IN(WHATIF(…), …)
What the plan said when it was baselinedIN(BASELINE(), …)
What a named revision or a scenario saysIN(SCHEDULE("Rev 0 — submitted plan"), …)
What a field was at each past updateHISTORY(…): see Values over time

Ask CPM: WHATIF and IN

WHATIF names the tasks to change, then each field and its new value. IN works out an expression in it:

Formula
=IN(WHATIF(Task("BDC_001"), [Duration], [Duration] + 10d), [Finish date])

Each task's finish date if BDC_001 took ten more working days.

Compare outside IN to see the change:

Formula
=WORKDAYS([Finish date], IN(WHATIF(Task("BDC_001"), [Duration], [Duration] + 10d), [Finish date]))

How far each task would move.

Everything inside IN is read in the what-if, so a field there is the what-if's value, and names you gave outside with LET aren't visible inside it.

What a what-if can change

After the tasks, pairs of a field and its new value. The new value is worked out for each task being changed: in WHATIF(All, [Duration], [Duration] * 1.2), [Duration] is each task's own.

FieldNew value
[Duration]A duration. Before a task starts, its remaining work follows
[Remaining duration]A duration, for work in progress
[Constraint]A constraint, "Start on or after", or BLANK() for none
[Constraint date]A date, or BLANK()
[Calendar]One of the project's calendars, by name

The tasks can be one task, Task("A1000"), or a set: All, FILTER(All, All[Discipline] = "Electrical"). Several groups of tasks and changes can follow each other; where two touch the same task and field, the later one wins.

Formula
=IN(WHATIF(FILTER(All, All[Discipline] = "Electrical"), [Remaining duration], [Remaining duration] * 1.2), Task("FINISH")[Finish date])

When the project finishes if electrical work is 20% slower.

A project setting is changed with SETTING and its value:

SettingValue
"Data date"A date
"Out-of-sequence progress""Retained logic", "Progress override" or "Actual dates"
"Critical path""Longest path" or "Total float"
"Must finish by"A date, or BLANK()
Formula
=IN(WHATIF(SETTING("Must finish by"), DATE(2026, 1, 20)), [Total float])

Each task's float against a deadline: negative where the deadline can't be met.

Float to a milestone rather than to the project's end is FLOATTO, and it reads in a what-if like any other value:

Formula
=IN(WHATIF(Task("BDC_001"), [Duration], [Duration] + 5d), FLOATTO(Task("MS_SUB")))

Each task's float to MS_SUB if BDC_001 took five more working days.

One what-if, or one per row

A what-if is the same for every row unless it names the row's own tasks or a value from the row. Then each row gets a what-if of its own, with its own change:

Formula
=WORKDAYS(Project[Finish date], IN(WHATIF([Task], [Remaining duration], [Remaining duration] + 1h), Project[Finish date]))

For each task: how far the project finish moves if this task takes an hour longer. That is DCMA's critical path test.

The column's tableThe tasks a what-if per row can change
Task[Task], [Driver], or one step away: Predecessors, Successors, their driving forms, a FILTER of those
WBS nodeTasks: every task in the node, changed together
ResourceTasks: every task it's assigned to
AssignmentTask
RelationshipPredecessor or Successor

A what-if per row only re-dates what its change reaches, so it is fast. To keep it so, the editor refuses the shapes that would date a whole schedule for every row: changing Upstream or All per row, reading All inside IN, a project setting that differs by row, and a what-if inside another. Each refusal says what to write instead.

Only the rows that take a branch are dated: IF([Critical], IN(WHATIF([Task], …), …)) runs one what-if per critical task.

The baseline

BASELINE() is the project's baseline as a schedule. Tasks line up by task code; a task that isn't in the baseline is blank there.

Formula
=WORKDAYS(IN(BASELINE(), [Finish date]), [Finish date])

How far each task has slipped against its baseline finish: positive is late.

Anything can be read in the baseline, formula columns included: IN(BASELINE(), [Budget]) is your Budget column worked out on the baseline, and IN(BASELINE(), COUNT(Successors)) reads the baseline's own logic.

Measure (on the project)
=LET(m, FILTER(Tasks, Tasks[Type] = "Milestone"),
    COUNT(FILTER(m, m[Finish date] > IN(BASELINE(), m[Finish date]))))

A measure: how many milestones finish later than baselined. A set named outside IN is read in the baseline member by member.

With no baseline set, IN(BASELINE(), …) is blank on every row, with the reason.

Revisions and scenarios

SCHEDULE("name") is another schedule of the project by its name: a named revision (from the Revisions tab) or a scenario. It reads exactly as the baseline does:

Formula
=WORKDAYS([Finish date], IN(SCHEDULE("Rev 0 — submitted plan"), [Finish date]))

How far each task has moved since Rev 0.

The name is checked when you save. A revision removed later makes the formula fail its check again, saying so.

A what-ifThe baseline, a revision, a scenario
IsThis schedule, re-dated now with a few inputs changedAnother stored schedule, read as it is
Can differ byDurations, constraints, calendars, settingsAnything: tasks added and removed, logic changed
Formula columns inside INNot read: a what-if re-dates the schedule, not its columnsRead, worked out on that schedule

Common questions

Why can't I just add the slip along the path?

You can, with a column that reads itself, and it matches CPM only while every task on the path shares a calendar and nothing else intervenes. A what-if asks CPM itself, so it is right with mixed calendars, constraints and progress.

Can I change [Finish date] in a what-if?

No: dates are what CPM works out. Change what CPM reads instead, for example a constraint: “[Finish date] can't be changed in a what-if. These can: Duration, Remaining duration, Constraint, Constraint date, Calendar”.

Can I put one what-if inside another?

No. Make both side by side and compare them outside:

Formula
=LET(a, WHATIF(Task("BDC_001"), [Duration], [Duration] + 5d),
    b, WHATIF(Task("E100"), [Duration], [Duration] + 5d),
    WORKDAYS(IN(a, [Finish date]), IN(b, [Finish date])))

Which of two delays moves each task further.

Does a what-if change my schedule?

Never. It is a copy that lives only while the formula is worked out. To try a change for real, make a scenario.