Skip to content

Commit b2f48f5

Browse files
committed
[IMP] functions: added TAKE functions
Task: 5231138
1 parent 1345a4a commit b2f48f5

File tree

2 files changed

+202
-2
lines changed

2 files changed

+202
-2
lines changed

packages/o-spreadsheet-engine/src/functions/module_lookup.ts

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { getPivotTooBigErrorMessage } from "../components/translations_terms";
22
import { PIVOT_MAX_NUMBER_OF_CELLS } from "../constants";
33
import { getFullReference, splitReference } from "../helpers/";
4-
import { toXC } from "../helpers/coordinates";
4+
import { toCartesian, toXC } from "../helpers/coordinates";
55
import { range } from "../helpers/misc";
66
import {
77
addAlignFormatToPivotHeader,
@@ -11,7 +11,7 @@ import { toZone } from "../helpers/zones";
1111
import { _t } from "../translation";
1212
import { CellErrorType, EvaluationError, InvalidReferenceError } from "../types/errors";
1313
import { AddFunctionDescription } from "../types/functions";
14-
import { Arg, FunctionResultObject, Matrix, Maybe, Zone } from "../types/misc";
14+
import { Arg, FunctionResultObject, Matrix, Maybe, UID, Zone } from "../types/misc";
1515
import { arg } from "./arguments";
1616
import { expectNumberGreaterThanOrEqualToOne } from "./helper_assert";
1717
import {
@@ -1222,3 +1222,76 @@ export const ARRAYTOTEXT = {
12221222
},
12231223
isExported: true,
12241224
} satisfies AddFunctionDescription;
1225+
1226+
// -----------------------------------------------------------------------------
1227+
// FORMULATEXT
1228+
// -----------------------------------------------------------------------------
1229+
1230+
export const FORMULATEXT = {
1231+
description: _t("Returns a formula as a string."),
1232+
args: [arg("cell_reference (meta)", _t("A reference to a cell."))],
1233+
compute: function (cellReference: { value: string }) {
1234+
const { sheetName, xc } = splitReference(cellReference.value);
1235+
const { col, row } = toCartesian(xc);
1236+
let sheetId: UID;
1237+
if (sheetName) {
1238+
//@ts-ignore
1239+
sheetId = this.getters.getSheetIdByName(sheetName);
1240+
} else {
1241+
sheetId = this.getters.getActiveSheetId();
1242+
}
1243+
const result = this.getters.getCell({ sheetId, col, row });
1244+
return result?.content || "";
1245+
},
1246+
isExported: true,
1247+
} satisfies AddFunctionDescription;
1248+
1249+
// -----------------------------------------------------------------------------
1250+
// TAKE
1251+
// -----------------------------------------------------------------------------
1252+
1253+
export const TAKE = {
1254+
description: _t(
1255+
"Returns a specified number of contiguous rows or columns from the start or end of an array."
1256+
),
1257+
args: [
1258+
arg("array (range)", _t("The array from which to take rows or columns.")),
1259+
arg(
1260+
"rows (number)",
1261+
_t("The number of rows to take. A negative value takes from the end of the array.")
1262+
),
1263+
arg(
1264+
"columns (number, optional)",
1265+
_t("The number of columns to take. A negative value takes from the end of the array.")
1266+
),
1267+
],
1268+
compute: function (
1269+
array: Matrix<{ value: string }>,
1270+
rows: Maybe<FunctionResultObject>,
1271+
columns: Maybe<FunctionResultObject>
1272+
) {
1273+
let _rows = toNumber(rows, this.locale);
1274+
let _columns = toNumber(columns, this.locale);
1275+
let result = array;
1276+
if (Math.abs(_columns) >= array.length || _columns === 0) {
1277+
_columns = array.length;
1278+
}
1279+
if (Math.abs(_rows) >= array[0].length) {
1280+
_rows = array[0].length;
1281+
}
1282+
if (_columns >= 0) {
1283+
result = result.slice(0, _columns);
1284+
} else {
1285+
result = result.slice(result.length + _columns, result.length);
1286+
}
1287+
for (let i = 0; i < result.length; i++) {
1288+
if (_rows >= 0) {
1289+
result[i] = result[i].slice(0, _rows);
1290+
} else {
1291+
result[i] = result[i].slice(result[i].length + _rows, result[i].length);
1292+
}
1293+
}
1294+
return result;
1295+
},
1296+
isExported: true,
1297+
} satisfies AddFunctionDescription;

tests/functions/module_lookup.test.ts

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2085,3 +2085,130 @@ describe("ARRAYTOTEXT formula", () => {
20852085
expect(evaluateCell("D5", grid)).toBe("A1,,A2,B2");
20862086
});
20872087
});
2088+
2089+
describe("TAKE formula", () => {
2090+
test("correct for one row", () => {
2091+
//prettier-ignore
2092+
const grid = {
2093+
A1: "A1", B1: "B1",
2094+
A2: "A2", B2: "B2",
2095+
D5: "=TAKE(A1:B2,1)", E5: "",
2096+
};
2097+
//prettier-ignore
2098+
const result = {
2099+
A1: "A1", B1: "B1",
2100+
A2: "A2", B2: "B2",
2101+
D5: "A1", E5: "B1",
2102+
};
2103+
expect(evaluateGrid(grid)).toEqual(result);
2104+
});
2105+
test("correct for -1 column", () => {
2106+
//prettier-ignore
2107+
const grid = {
2108+
A1: "A1", B1: "B1",
2109+
A2: "A2", B2: "B2",
2110+
D5: "=TAKE(A1:B2,2,-1)",
2111+
D6: ""
2112+
};
2113+
//prettier-ignore
2114+
const result = {
2115+
A1: "A1", B1: "B1",
2116+
A2: "A2", B2: "B2",
2117+
D5: "B1",
2118+
D6: "B2"
2119+
};
2120+
expect(evaluateGrid(grid)).toEqual(result);
2121+
});
2122+
test("correct for -1 row", () => {
2123+
//prettier-ignore
2124+
const grid = {
2125+
A1: "A1", B1: "B1",
2126+
A2: "A2", B2: "B2",
2127+
D5: "=TAKE(A1:B2,-1)", E5: "",
2128+
};
2129+
//prettier-ignore
2130+
const result = {
2131+
A1: "A1", B1: "B1",
2132+
A2: "A2", B2: "B2",
2133+
D5: "A2", E5: "B2",
2134+
};
2135+
expect(evaluateGrid(grid)).toEqual(result);
2136+
});
2137+
test("all rows if too much rows to take", () => {
2138+
//prettier-ignore
2139+
const grid = {
2140+
A1: "A1", B1: "B1",
2141+
A2: "A2", B2: "B2",
2142+
D5: "=TAKE(A1:B2,3)", E5: "",
2143+
D6: "", E6: ""
2144+
};
2145+
//prettier-ignore
2146+
const result = {
2147+
A1: "A1", B1: "B1",
2148+
A2: "A2", B2: "B2",
2149+
D5: "A1", E5: "B1",
2150+
D6: "A2", E6: "B2",
2151+
};
2152+
expect(evaluateGrid(grid)).toEqual(result);
2153+
});
2154+
test("all columns if too much columns to take", () => {
2155+
//prettier-ignore
2156+
const grid = {
2157+
A1: "A1", B1: "B1",
2158+
A2: "A2", B2: "B2",
2159+
D5: "=TAKE(A1:B2,2,3)", E5: "",
2160+
D6: "", E6: ""
2161+
};
2162+
const result = {
2163+
A1: "A1",
2164+
B1: "B1",
2165+
A2: "A2",
2166+
B2: "B2",
2167+
D5: "A1",
2168+
E5: "B1",
2169+
D6: "A2",
2170+
E6: "B2",
2171+
};
2172+
expect(evaluateGrid(grid)).toEqual(result);
2173+
});
2174+
test("all rows if too much rows to take in negative", () => {
2175+
//prettier-ignore
2176+
const grid = {
2177+
A1: "A1", B1: "B1",
2178+
A2: "A2", B2: "B2",
2179+
D5: "=TAKE(A1:B2,-3)", E5: "",
2180+
D6: "", E6: ""
2181+
};
2182+
const result = {
2183+
A1: "A1",
2184+
B1: "B1",
2185+
A2: "A2",
2186+
B2: "B2",
2187+
D5: "A1",
2188+
E5: "B1",
2189+
D6: "A2",
2190+
E6: "B2",
2191+
};
2192+
expect(evaluateGrid(grid)).toEqual(result);
2193+
});
2194+
test("all columns if too much columns to take in negative", () => {
2195+
//prettier-ignore
2196+
const grid = {
2197+
A1: "A1", B1: "B1",
2198+
A2: "A2", B2: "B2",
2199+
D5: "=TAKE(A1:B2,2,-3)", E5: "",
2200+
D6: "", E6: ""
2201+
};
2202+
const result = {
2203+
A1: "A1",
2204+
B1: "B1",
2205+
A2: "A2",
2206+
B2: "B2",
2207+
D5: "A1",
2208+
E5: "B1",
2209+
D6: "A2",
2210+
E6: "B2",
2211+
};
2212+
expect(evaluateGrid(grid)).toEqual(result);
2213+
});
2214+
});

0 commit comments

Comments
 (0)