-
Notifications
You must be signed in to change notification settings - Fork 60
[IMP] formulas: add the SUBTOTAL function #6774
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
29f0eec
to
43c8aed
Compare
Yeah!🎉 |
43c8aed
to
e42c127
Compare
src/plugins/ui_core_views/cell_evaluation/compilation_parameters.ts
Outdated
Show resolved
Hide resolved
src/plugins/ui_core_views/cell_evaluation/compilation_parameters.ts
Outdated
Show resolved
Hide resolved
@@ -35962,6 +36293,11 @@ exports[`Test XLSX export formulas Multi-Sheets exportable functions 1`] = ` | |||
>25 | |||
</t> | |||
</si> | |||
<si> | |||
<t> | |||
=ROW(A234) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you know where this comes from ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using ROW and COLUMN for references that do not exist on the sheet no longer works.
The test has been changed so that it continues to work on an existing reference.
"Returns a subtotal for a vertical range of cells using a specified aggregation function." | ||
), | ||
args: [ | ||
arg("function_code (number)", _t("The function to use in subtotal aggregation.")), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add what are the possible codes ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to do in another commit for all formulas that accept static parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in a TOFIXUP commit
const bottom = top + ref[0].length - 1; | ||
|
||
for (let row = top; row <= bottom; row++) { | ||
if (this.getters.isRowFiltered(sheetId, row)) continue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now, all commands related to filters and hidden headers need to invalidate the evaluation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in the commit "TOFIXUP"
01b8dde
to
5d69db4
Compare
Why this commit ? We would like to introduce the SUBTOTAL formula: This formula has the particularity of taking meta arguments as input, and based on certain criteria, returning the value related to the passed reference. Compared to other formulas using meta arguments, using the values belonging to the cells of the meta arguments is a new behavior. So, for this function to be viable, two things must be done: - compute the values of the passed meta references (which was not done until now) - compute all the values of the cells belonging to the matrix when a range is passed as a meta reference This last point (computing all the cell values when a meta range is passed) implies differentiating between simple meta arguments and matrix meta arguments in the code. Hence the main purpose of this commit. Two other implications of this commit: - This commit enables vectorization for meta arguments. - We revised the way arguments were defined in meta functions, resulting in a complete redefinition for certain functions, such as COLUMNS and ROWS, which no longer use meta arguments. This change involved redefining the error type for references whose sheetname doesn't exist. This also promotes consistency. Task: 4873384
2e9751b
to
b63b9c1
Compare
src/functions/module_math.ts
Outdated
import { tokenColors } from "../components/composer/composer/abstract_composer_store"; | ||
import { splitReference, toZone } from "../helpers"; | ||
import { insertTokenAfterLeftParenthesis } from "../helpers/pivot/pivot_composer_helpers"; | ||
import { autoCompleteProviders } from "../registries/auto_completes"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/functions/module_math.ts
Outdated
|
||
for (let col = left; col <= right; col++) { | ||
const cell = this.getters.getCell({ sheetId, col, row }); | ||
if (!cell || !cell.isFormula || !cell.content || !cell.content.includes("SUBTOTAL")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cell.content
is expensive for formulas because it builds the entire formula string every time.
Check cell.compiledFormula.tokens
instead
src/functions/module_math.ts
Outdated
return functionRegistry | ||
.get(subtotalFunctionAggregateByCode[code]) | ||
.compute.apply(this, [[evaluatedCellToKeep]]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return functionRegistry | |
.get(subtotalFunctionAggregateByCode[code]) | |
.compute.apply(this, [[evaluatedCellToKeep]]); | |
return this[subtotalFunctionAggregateByCode[code]].apply(this, [[evaluatedCellToKeep]]); |
src/functions/module_math.ts
Outdated
const subtotalFunctionCodes = Object.keys(subtotalFunctionAggregateByCode); | ||
if (subtotalFunctionCodes.includes(tokenAtCursor.value)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this only checks 1-9 but not the 10x versions.
src/functions/module_math.ts
Outdated
return; | ||
} | ||
|
||
const proposals: any[] = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const proposals: any[] = []; | |
const proposals: AutoCompleteProposal[] = []; |
src/functions/module_math.ts
Outdated
(fnName: string) => _t("%s (accept hidden cells)", fnName), | ||
(fnName: string) => _t(`%s (doesn't accept hidden cells)`, fnName), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(fnName: string) => _t("%s (accept hidden cells)", fnName), | |
(fnName: string) => _t(`%s (doesn't accept hidden cells)`, fnName), | |
(fnName: string) => _t("%s (include manually-hidden rows)", fnName), | |
(fnName: string) => _t(`%s (exclude manually-hidden rows)`, fnName), |
src/functions/module_math.ts
Outdated
for (let i = 0; i < subtotalFunctionAggregateDescriptions.length; i++) { | ||
for (const functionCode of subtotalFunctionCodes) { | ||
const str = `${i === 1 ? Number(functionCode) + 100 : functionCode}`; | ||
proposals.push({ | ||
text: str, | ||
description: subtotalFunctionAggregateDescriptions[i]( | ||
subtotalFunctionAggregateByCode[functionCode] | ||
), | ||
htmlContent: [{ value: str, color: tokenColors.NUMBER }], | ||
fuzzySearchKey: str, | ||
alwaysExpanded: true, | ||
}); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like that would be a lot easier to read IMO, with a small helper function codeToProposal
for (const code of subtotalFunctionCodes) {
proposals.push(codeToProposal(code, _t("%s (accept hidden cells)", subtotalFunctionAggregateByCode[code])));
}
for (const code of subtotalFunctionCodes.map((c) => `${Number(c) + 100}`)) {
proposals.push(codeToProposal(code, _t("%s (doesn't accept hidden cells)", subtotalFunctionAggregateByCode[code])));
}
@LucasLefevre your last review will be taken into account in #6929 |
b63b9c1
to
45b5db5
Compare
Task: 4873384
45b5db5
to
825beb1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
robodoo r+ rebase-ff
Merge method set to rebase and fast-forward. |
Why this commit ? We would like to introduce the SUBTOTAL formula: This formula has the particularity of taking meta arguments as input, and based on certain criteria, returning the value related to the passed reference. Compared to other formulas using meta arguments, using the values belonging to the cells of the meta arguments is a new behavior. So, for this function to be viable, two things must be done: - compute the values of the passed meta references (which was not done until now) - compute all the values of the cells belonging to the matrix when a range is passed as a meta reference This last point (computing all the cell values when a meta range is passed) implies differentiating between simple meta arguments and matrix meta arguments in the code. Hence the main purpose of this commit. Two other implications of this commit: - This commit enables vectorization for meta arguments. - We revised the way arguments were defined in meta functions, resulting in a complete redefinition for certain functions, such as COLUMNS and ROWS, which no longer use meta arguments. This change involved redefining the error type for references whose sheetname doesn't exist. This also promotes consistency. Task: 4873384 Part-of: #6774 Signed-off-by: Lucas Lefèvre (lul) <[email protected]>
closes #6774 Task: 4873384 Signed-off-by: Lucas Lefèvre (lul) <[email protected]>
Task: 4873384