Lookup and reference functions

DROP

Matches all 17 recorded answers

Recorded: 17 workbook cells. How we measure this · See the Rust code

Local names in 40 languages
LanguageName in Excel
ArabicDROP
BulgarianDROP
CzechZAHODIT
DanishUDELAD
GermanDROP
GreekDROP
English (Australia)DROP
English (United Kingdom)DROP
English (United States)DROP
SpanishEXCLUIR
EstonianDROP
FinnishDROP
FrenchEXCLURE
HebrewDROP
CroatianDROP
HungarianELTÁVOLÍT
IndonesianDROP
ItalianDROP
JapaneseDROP
KoreanDROP
LithuanianDROP
LatvianDROP
NorwegianDROP
DutchWEGLATEN
PolishPOMIŃ
Portuguese (Brazil)DROP
Portuguese (Portugal)EXCLUIR
RomanianDROP
RussianСБРОСИТЬ
SlovakDROP
SlovenianDROP
Serbian (Latin)DROP
SwedishUTESLUT
ThaiDROP
TurkishBIRAK
UkrainianDROP
VietnameseDROP
Chinese (Simplified)DROP
Chinese (Hong Kong)DROP
Chinese (Traditional)DROP

Names from Microsoft's support site.

What it does

DROP(array, rows, [columns])

DROP(array, rows, [columns]) removes a contiguous band from the edge of an array and returns what is left. The sign of each count chooses the edge:

  • rows positive — remove that many rows from the top;
  • rows negative — remove that many rows from the bottom;
  • columns positive — remove that many columns from the left;
  • columns negative — remove that many columns from the right.

Both axes are trimmed in the same call when both arguments are given; the result is the rectangular remainder. Zero removes nothing on that axis, and omitting columns leaves the column axis untouched.

DROP is the exact complement of TAKE: for a non-negative n, TAKE keeps the band DROP removes. Because both use the sign convention for the edge, the pair covers all four "first/last n rows/columns" operations between them without a mode argument.

Arguments

ArgumentMeaning
arrayThe array or range to trim. Required.
rowsNumber of rows to remove; positive from the top, negative from the bottom. Required.
columnsNumber of columns to remove; positive from the left, negative from the right. Optional.

The argument most often misused is rows with the wrong sign: "drop the last row" is -1, not 1, and the mistake is silent — it returns a plausible array of the right shape from the wrong end.

Try it

Input cells (optional)

Example: {"B2": 3, "B3": 4}. A1 holds the formula. Other cells need values before a formula can read them.

Enter a formula, then calculate.

Runs locally in your browser with OneCalc. Its answer may differ from Excel. Use English function names and commas between arguments.

Quirks

Result and edge cases

Return kind: Array. The result spills; spilling is host-side adaptation, not function semantics (the call pipeline).

  • References are resolved first. array is prepared under ValuesOnlyPreAdapter, so the result carries values, not reference structure.
  • Dropping everything. If rows is at least the array's height (or columns at least its width), nothing remains. There is no empty array in the published value model (value universe), so this case has to become an error rather than an empty result — see below.
  • Fractional counts. Whether 2.7 truncates or errors is not established here.

Errors

Microsoft's page for DROP documents #VALUE! for an invalid argument and #CALC! for the case where the result would be an empty array. #CALC! is the calculation engine's "cannot produce a value" code, and the empty-array case is one of the two canonical producers of it listed in the value universe — the other being the uncalled lambda.

That pairing is the thing to remember about DROP: over-dropping does not give you nothing, it gives you #CALC!. Formulas that compute a drop count from data must either guarantee the count is smaller than the extent or wrap the call in IFERROR.

An error value supplied as an argument propagates under the universal rule in coercion and lifting.

How to implement

Notes for implementers

  • The empty result is the whole design problem. Every implementation needs a decision point where "the remainder has zero rows or zero columns" becomes #CALC! rather than an ill-formed array. Getting this wrong produces an array with a zero dimension that then corrupts whatever consumes it, and the failure surfaces far from the cause.
  • Sign handling before bounds checking. Convert the signed count into a (start, length) pair first, then range-check. Mixing the two produces off-by-ones at exactly n = height.
  • Both axes in one pass. Trimming rows then columns and trimming columns then rows must give the same rectangle — they do, for a rectangular remainder — but an implementation that materializes an intermediate array between the two steps doubles its memory traffic on large ranges for no benefit.
  • The lift positions are declared, not incidental. by_index_scalar_array_lift(positions=1|2) means the dispatch layer, not the kernel, broadcasts those arguments. An implementation that handles arrays inside its own kernel for those positions will diverge from the declared pipeline even where the results agree.
  • The module is shared with the rest of the dynamic-array reshapers, so the shape-and-bounds discipline is common code.

Rust code

Show the CalcFunc source of this function

Quoted from the public repository DnaCalc/DnaCalc, crates calc-func and calc-fml, at commit 9e1884369a67. Comments are the source's own. A kernel shared with other functions appears once, on its module page.

DROP · 7 lines · calc-func/src/catalogue/arrays.rs on GitHub
7 drop_fn "DROP" (2, 3) [R "array", V "rows", V "columns"] |s, a, sv| {
    source_error(a)?;
    match sub_area(s, a, false)? {
        Some(reference) => Ok(reference),
        None => run(s, a, sv, k::eval_drop_prepared),
    }
}
eval_drop_prepared · 24 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHub
pub fn eval_drop_prepared(args: &[CalcValue]) -> Result<CalcValue, DynamicArrayReshapeEvalError> {
    let array = materialize_array_arg(&args[0]);
    let row_count = match args.get(1) {
        Some(arg) if matches!(arg.core_ref(), CoreRef::Missing) && args.get(2).is_some() => 0,
        Some(arg) => parse_integer(arg)?,
        None => return Err(DynamicArrayReshapeEvalError::InvalidCount),
    };
    let col_count = if let Some(arg) = args.get(2) {
        parse_integer(arg)?
    } else {
        0
    };
    let (row_start, row_end) = drop_span(array.shape().rows, row_count)?;
    let (col_start, col_end) = drop_span(array.shape().cols, col_count)?;
    let rows = row_end - row_start;
    let cols = col_end - col_start;
    let mut cells = Vec::with_capacity(rows * cols);
    for row in row_start..row_end {
        for col in col_start..col_end {
            cells.push(array.get(row, col).expect("validated slice").clone());
        }
    }
    build_array(rows, cols, cells)
}

Kernels shared with other functions

Argument and result plumbing

No implementation has been published with a Handbook test suite for this function.

Version differences

No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.

Alternatives

Relationships

  • TAKE is the complement: DROP(a, n) and TAKE(a, n) partition the array's rows. Which one reads better depends on whether you are naming what you keep or what you discard.
  • CHOOSEROWS / CHOOSECOLS handle non-contiguous selections. If the selection is "everything except the first row", DROP says it in one argument where CHOOSEROWS would need an index vector.
  • FILTER removes rows by predicate rather than by position, and returns #CALC! on an empty result for the same structural reason — unless its if_empty argument is supplied. DROP has no if_empty.
  • EXPAND is the growing counterpart to this shrinking one.

Named variants

No named variants are recorded yet.

Suggest a correction or contribute an implementation · For agents