Advanced Formulas

Chapter 10: Advanced Formulas

Learning Objectives

  1. Write nested logical formulas with IFS, SWITCH and NOT alongside IF, AND and OR.
  2. Find conditional maximums and minimums with MAXIFS and MINIFS.
  3. Name values inside a formula with LET.
  4. Look up data in rows with HLOOKUP.
  5. Filter data with FILTER and sort it with SORTBY.
  6. Find the day of the week with WEEKDAY and add working days with WORKDAY.

Introduction to Excel taught you most of the functions on MO-211. Lessons 2–5 covered IF, AND and OR, the conditional aggregate functions (SUMIF, COUNTIFS and the rest), XLOOKUP, VLOOKUP, INDEX and MATCH, NOW and TODAY, and PMT and NPER. This chapter adds the functions those lessons didn't cover, and it focuses on the skill MO-211 cares about most: nesting functions inside each other to answer a question in one formula.

10.1 IFS, SWITCH and nested logic

10.1.1 A quick review of nesting

A nested function is a function used as an argument to another function. You've already written formulas like these:

=IF(AND(B2>=90, C2="Yes"), "Honors", "Standard")
=IF(B2>=90, "A", IF(B2>=80, "B", IF(B2>=70, "C", "F")))

The second formula works, but each extra grade adds another IF and another closing parenthesis. IFS and SWITCH do the same job with flatter formulas.

10.1.2 IFS

IFS(test1, value1, [test2, value2], …) checks each test in order and returns the value paired with the first test that's TRUE.

=IFS(B2>=90, "A", B2>=80, "B", B2>=70, "C", B2>=60, "D", TRUE, "F")

Two things to remember:

10.1.3 SWITCH

SWITCH(expression, value1, result1, [value2, result2], …, [default]) compares one expression with a list of exact values and returns the result for the one that matches. A final unpaired argument is the default, returned when nothing matches.

=SWITCH(C2, "N", "North", "S", "South", "E", "East", "W", "West", "Unknown")
=SWITCH(WEEKDAY(A2), 1, "Weekend", 7, "Weekend", "Weekday")

Use SWITCH when you're matching one value against a list of exact options. Use IFS when each test is a different comparison, like ranges of scores. Without a default, SWITCH returns #N/A when nothing matches.

10.1.4 NOT

NOT(logical) reverses TRUE and FALSE. It's most useful inside AND or OR, to say "and this is not the case":

=IF(AND(D2>=3, NOT(E2="Probation")), "Eligible", "Not eligible")
=IF(NOT(ISBLANK(F2)), "Submitted", "Missing")

NOT(E2="Probation") means the same as E2<>"Probation". Either is fine unless a task asks for NOT.

10.1.5 Putting it together

MO-211 tasks often combine several functions. Read the task and break it into parts:

"In G2, enter a formula that returns Bonus if the employee's sales are over 50,000 and they are not in the Training group, Review if their sales are under 20,000, and None otherwise."

  1. The first condition has two parts joined by and, one of them negative: AND(E2>50000, NOT(F2="Training")).
  2. There are three outcomes, so use IFS (or nested IFs).
  3. "Otherwise" means a final TRUE test.
=IFS(AND(E2>50000, NOT(F2="Training")), "Bonus", E2<20000, "Review", TRUE, "None")

Build long formulas a piece at a time. Type the inner part, such as the AND, in a spare cell to check that it returns TRUE and FALSE where you expect, then copy it into the full formula and delete the spare cell. The exam grades only the cell the task names.

The Perform data analysis objectives also ask you to "forecast data by using AND, IF and NPER" and to calculate with PMT. Those functions are in Lessons 2 and 3 of Introduction to Excel. On the exam they appear in nested formulas, such as =IF(NPER(B3/12, -B4, B2)<=60, "Within 5 years", "Longer").

10.2 MAXIFS and MINIFS

Lesson 4 of Introduction to Excel covered SUMIFS, COUNTIFS and AVERAGEIFS. MAXIFS and MINIFS work the same way, but they return the largest or smallest value that meets the criteria:

MAXIFS(max_range, criteria_range1, criteria1, [criteria_range2, criteria2], …)
MINIFS(min_range, criteria_range1, criteria1, [criteria_range2, criteria2], …)

Like SUMIFS, the range being measured comes first, followed by pairs of criteria ranges and criteria. For a table Sales with the columns Region, Rep, Product and Amount:

=MAXIFS(Sales[Amount], Sales[Region], "West")
=MINIFS(Sales[Amount], Sales[Region], "West", Sales[Product], "Kayak")
=MAXIFS(Sales[Amount], Sales[Region], H2, Sales[Amount], "<"&H3)

Criteria work the same as in the other -IFS functions:

If no rows match, MAXIFS and MINIFS return 0, not an error.

The order of arguments is the most common mistake. SUMIF and AVERAGEIF put the range being totaled last, but SUMIFS, AVERAGEIFS, MAXIFS and MINIFS put it first. Excel shows each argument's name in a tooltip as you type, so check it.

10.3 LET

LET(name1, value1, [name2, value2], …, calculation) gives names to values or calculations inside a formula, then uses the names in a final calculation. It makes long formulas shorter and easier to read, and it calculates each named part only once.

Without LET, a formula might repeat the same calculation:

=IF(SUM(B2:D2)*1.08>500, SUM(B2:D2)*1.08*0.9, SUM(B2:D2)*1.08)

With LET, you name it once:

=LET(total, SUM(B2:D2)*1.08, IF(total>500, total*0.9, total))

Read it as: "Let total be SUM(B2:D2)×1.08. Then, if total is over 500, return total×0.9; otherwise return total."

You can define several names. Each name can use the ones before it:

=LET(subtotal, B2*C2, tax, subtotal*$H$1, subtotal + tax)

Rules for names:

Tasks may say "use a function that assigns a name to the calculation result." That means LET. Make sure your formula uses each name in the final calculation.

10.4 HLOOKUP

HLOOKUP is the horizontal version of VLOOKUP. VLOOKUP searches down the first column of a range and returns a value from another column. HLOOKUP searches across the first row and returns a value from another row.

HLOOKUP(lookup_value, table_array, row_index_num, [range_lookup])
Argument Meaning
lookup_value The value to find in the first row.
table_array The range to search. Its first row holds the values to search.
row_index_num Which row of the range to return from: 1 is the first row, 2 the second, and so on.
range_lookup FALSE for an exact match. TRUE (the default) for the closest match below, which needs the first row sorted in ascending order.

Suppose B1:M1 holds month names (Jan to Dec), row 2 holds sales, row 3 holds costs and row 4 holds staff counts:

=HLOOKUP("Apr", B1:M4, 3, FALSE)      April's costs
=HLOOKUP(P2, $B$1:$M$4, 2, FALSE)     sales for the month in P2

XLOOKUP (Lesson 4) searches rows or columns, defaults to an exact match and doesn't need a row number. In your own work, prefer XLOOKUP: =XLOOKUP("Apr", B1:M1, B3:M3). MO-211 still lists HLOOKUP, though, so a task may require it. Tasks that require a particular function say so, for example "use a function that searches horizontally."

10.5 FILTER and SORTBY

FILTER and SORTBY are dynamic array functions, like SORT and UNIQUE (chapter 5). They return a whole range of results that spills from one cell.

10.5.1 FILTER

FILTER(array, include, [if_empty]) returns the rows (or columns) of array where include is TRUE.

Argument Meaning
array The data to return, such as a whole table or some of its columns.
include A condition that's TRUE or FALSE for each row, the same height as array.
if_empty What to return when no rows match, such as "None". Without it, FILTER returns #CALC! when nothing matches.
=FILTER(Sales, Sales[Region]="West")
=FILTER(Sales[[Rep]:[Amount]], Sales[Amount]>=1000, "No sales over 1,000")
=FILTER(Sales, Sales[Region]=H1, "None")

To combine conditions, put each one in parentheses:

=FILTER(Sales, (Sales[Region]="West")*(Sales[Amount]>1000))
=FILTER(Sales, (Sales[Product]="Kayak")+(Sales[Product]="Canoe"))

This works because TRUE counts as 1 and FALSE as 0. A product is 1 only when both conditions are 1, and a sum is 0 only when both conditions are 0.

AND and OR don't work inside FILTER's include argument. They return one TRUE or FALSE for the whole range instead of one for each row. Use * and + instead.

10.5.2 SORTBY

SORTBY(array, by_array1, [sort_order1], [by_array2, sort_order2], …) sorts array by one or more other ranges.

=SORTBY(Staff[Name], Staff[Salary], -1)
=SORTBY(Staff, Staff[Department], 1, Staff[Salary], -1)

The first formula lists names from highest salary to lowest, without showing the salaries. The second sorts the whole table by department, A to Z, and by salary from highest to lowest within each department.

SORT (chapter 5) sorts by a column number inside the array. SORTBY sorts by ranges, which has two advantages:

Each by_array must be the same height as array. Sort order is 1 for ascending (the default) or -1 for descending.

10.5.3 Combining them

Dynamic array functions nest well:

=SORTBY(FILTER(Sales, Sales[Region]="West"), FILTER(Sales[Amount], Sales[Region]="West"), -1)
=SORT(FILTER(Sales[[Rep]:[Amount]], Sales[Amount]>1000), 2, -1)

The second formula is shorter because SORT sorts by a column number of the filtered result. Use SORTBY when you need to sort by something that isn't in the result.

10.6 WEEKDAY and WORKDAY

Lesson 5 of Introduction to Excel covered dates, TODAY and NOW. MO-211 adds two functions for working with days of the week.

10.6.1 WEEKDAY

WEEKDAY(serial_number, [return_type]) returns a number for the day of the week of a date. return_type chooses the numbering:

return_type Numbering
1 or omitted Sunday = 1 through Saturday = 7
2 Monday = 1 through Sunday = 7
3 Monday = 0 through Sunday = 6

With return_type 2, weekends are 6 and 7, which makes weekend checks simple:

=IF(WEEKDAY(A2, 2)>5, "Weekend", "Weekday")

To show the day's name instead of its number, use a number format (dddd, chapter 9) or =TEXT(A2, "dddd").

10.6.2 WORKDAY

WORKDAY(start_date, days, [holidays]) returns the date that is a number of working days before or after a start date. It skips Saturdays, Sundays and any dates you list as holidays.

=WORKDAY(A2, 10)                  10 working days after A2
=WORKDAY(A2, 10, Holidays[Date])  the same, also skipping listed holidays
=WORKDAY(A2, -5)                  5 working days before A2

The start date itself isn't counted. WORKDAY returns a serial number, so format the cell as a date if it shows a number like 46213.

"Calculate the due date, 15 business days after the order date, excluding the holidays listed on the Holidays worksheet" is a WORKDAY task. Use the holiday range as the third argument, with absolute references (or a table reference) so the range doesn't shift when you copy the formula down.

10.7 Practice

Simmy assessment goes here. Exam-style tasks on IFS, SWITCH, NOT, MAXIFS, MINIFS, LET, HLOOKUP, FILTER, SORTBY, WEEKDAY and WORKDAY, with nesting. When a student misses a task, Simmy builds the AI prompt (the task as worded, what the student did, and the correct result).

Starting data. A workbook named Brightline Staffing with sheets Placements, Rates and Holidays.

Placements: a table named Placements (A1:G16):

ID Worker Client Type Start Hours Score
P-01 Ana Morales Hartwell Contract 9/1/2027 320 92
P-02 Ravi Singh Kestrel Temp 9/3/2027 80 67
P-03 Nora Walsh Hartwell Temp 9/6/2027 120 85
P-04 Ken Ito Orchard Contract 9/8/2027 400 78
P-05 Lina Haddad Kestrel Direct 9/10/2027 0 95
P-06 Luc Moreau Orchard Temp 9/13/2027 60 54
P-07 Maya Torres Hartwell Contract 9/15/2027 280 88
P-08 Liam Okafor Orchard Temp 9/17/2027 140 73
P-09 Ava Chen Kestrel Contract 9/20/2027 360 81
P-10 Noah Patel Hartwell Direct 9/22/2027 0 90
P-11 Zoe Lindqvist Orchard Contract 9/24/2027 300 69
P-12 Eli Brooks Kestrel Temp 9/27/2027 100 77
P-13 Isla Romero Hartwell Temp 9/29/2027 40 58
P-14 Owen Fitzgerald Orchard Direct 10/1/2027 0 84
P-15 Ruby Nakamura Kestrel Contract 10/4/2027 380 93

Rates (A1:E3): row 1 holds the types Contract, Temp, Direct in B1:D1 (A1 "Type"); row 2 "Hourly" 48, 32, 0; row 3 "Fee %" 0.10, 0.15, 0.20.

Holidays: a table named Holidays with one column, Date: 9/6/2027, 10/11/2027, 11/11/2027, 11/25/2027.

Tasks.

  1. In H2 of the Placements table, add a column named Rating that returns "Excellent" for scores of 90 or more, "Good" for 75 to 89, "Fair" for 60 to 74, and "Poor" otherwise. Use a single function without nesting IF. Expected result: H1 "Rating"; =IFS([@Score]>=90,"Excellent",[@Score]>=75,"Good",[@Score]>=60,"Fair",TRUE,"Poor"). Objective: Perform logical operations by using IFS().
  2. Add a column named Code that returns "C" for Contract, "T" for Temp and "D" for Direct, using a function that compares the type with a list of values. Expected result: I1 "Code"; =SWITCH([@Type],"Contract","C","Temp","T","Direct","D"). Objective: Perform logical operations by using SWITCH().
  3. Add a column named Review that returns "Yes" when a placement's score is below 70 and its type is not Direct, and "No" otherwise. Expected result: J1 "Review"; =IF(AND([@Score]<70,NOT([@Type]="Direct")),"Yes","No"). Yes for P-02, P-06, P-11, P-13. Objective: Perform logical operations by using AND(), NOT(), IF().
  4. In cell Q2, enter a formula that returns the highest score for Hartwell placements. In Q3, return the lowest hours for Contract placements. Expected result: Q2 =MAXIFS(Placements[Score],Placements[Client],"Hartwell") = 92; Q3 =MINIFS(Placements[Hours],Placements[Type],"Contract") = 280. Objective: MAXIFS(); MINIFS().
  5. Add a column named Pay that looks up the hourly rate for the placement's type on the Rates worksheet and multiplies it by the hours. Use a function that searches across the first row of a range. Expected result: K1 "Pay"; =HLOOKUP([@Type],Rates!$B$1:$D$3,2,FALSE)*[@Hours]. Objective: Look up data by using HLOOKUP().
  6. In cell Q5, enter a formula that multiplies the total hours of Hartwell placements by 32, then returns that amount minus 10 percent if it is more than 20,000. Assign the name amt to the amount within the formula. Expected result: Q5 =LET(amt,SUMIFS(Placements[Hours],Placements[Client],"Hartwell")*32,IF(amt>20000,amt*0.9,amt)); 760 hours × 32 = 24,320, minus 10 percent = 21,888. Objective: Perform logical operations by using LET().
  7. In cell S1, enter a formula that returns the names of the workers in Contract placements, sorted from highest score to lowest. Do not include the scores in the result. Expected result: S1 =SORTBY(FILTER(Placements[Worker],Placements[Type]="Contract"),FILTER(Placements[Score],Placements[Type]="Contract"),-1), spilling Ruby Nakamura, Ana Morales, Maya Torres, Ava Chen, Ken Ito, Zoe Lindqvist. Objective: Filter data by using FILTER(); Sort data by using SORTBY().
  8. Add a column named Ready that returns the date 10 working days after the start date, skipping the dates in the Holidays table. Expected result: L1 "Ready"; =WORKDAY([@Start],10,Holidays[Date]), formatted as a date. Objective: Calculate dates by using WORKDAY().
  9. Add a column named Start Day that returns 1 for a start on Monday through 7 for a start on Sunday. Expected result: M1 "Start Day" … =WEEKDAY([@Start],2). Objective: Calculate dates by using WEEKDAY().