Skip to content
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

[FIX] functions: cast to matrix #4186

Open
wants to merge 5 commits into
base: saas-17.1
Choose a base branch
from

Conversation

LucasLefevre
Copy link
Collaborator

@LucasLefevre LucasLefevre commented May 8, 2024

=SUMIF(CHOOSECOLS(A1,-1),A2) crashes

This problem actually hides three sub-problems:

  • 1st problem: Conditional functions like SUMIF using the "visitMatchingRanges" helper did not handle simple arguments correctly. This issue has been fixed, allowing conditional functions to functionally handle errors in a way that is more similar to Excel.

  • 2nd problem: The functions CHOOSECOLS and CHOOSEROWS did not take negative indices into account. This is now possible.

  • 3rd problem: Formulas typed as returning only ranges can actually return simple values. This phenomenon occurs precisely when an error is thrown: it is returned as a simple value. Normally, this type of error is handled during compilation.

Concerning the 3rd problem:

Two ways to solve the problem have been proposed here:

  • The first solution could have been to encapsulate the error in an array when it is a function returning a range. By doing this, we ensure that the function typing is correct and we keep the handling of this type of error during compilation.

  • The second solution would be to say that we cannot determine in advance what the result of a sub-function will be (simple value/error vs array). Thus, the argument check would be done at runtime.

The first solution is good, but its implementation might cause comprehension issues for the user. Indeed, it seems strange that for functions rejecting only ranges as input, depending on the return type of the sub-formula (simple vs range), the formula may crash or not for the same error.

Let's take the following example to illustrate this problem:

Suppose the case of SUMIF which only accepts ranges as parameters. Consider the functions ABS, which naturally returns a simple value, and TRANSPOSE, which naturally returns a range.

= SUMIF(ABS(), 42)
= SUMIF(TRANSPOSE(), 42)

In these two examples, no arguments were given to ABS and TRANSPOSE. Both sub-functions will respectively return an error. With the first solution, only the first case will throw, whereas in the second case, both will throw.

We therefore choose to go with the second solution, despite its implications, to ensure better consistency and understanding for the user.

Task: 3918882

Description:

description of this task, what is implemented and why it is implemented that way.

Task: : 3918882

review checklist

  • feature is organized in plugin, or UI components
  • support of duplicate sheet (deep copy)
  • in model/core: ranges are Range object, and can be adapted (adaptRanges)
  • in model/UI: ranges are strings (to show the user)
  • undo-able commands (uses this.history.update)
  • multiuser-able commands (has inverse commands and transformations where needed)
  • new/updated/removed commands are documented
  • exportable in excel
  • translations (_t("qmsdf %s", abc))
  • unit tested
  • clean commented code
  • track breaking changes
  • doc is rebuild (npm run doc)
  • status is correct in Odoo

@robodoo
Copy link
Collaborator

robodoo commented May 8, 2024

setCellContent(model, "A1", "=SUMIF(CHOOSECOLS(A2,-1),A2)");
expect(getEvaluatedCell(model, "A1").value).toBe("#ERROR"); // @compatibility: should be 0
expect(getCellError(model, "A1")).toBe(
"Function SUMIF expects criteria_range to have the same dimension"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this error makes sense on several levels:

  1. "to have the same dimension" .... as what? -> should be addressed somewhere else.
  2. Shouldn't we raise the error encapsulated in the args that we go through? In this specific case, we have converted the error arg into an array in the first process step but in the follwing loop, we process the variable args which is not a matrix. Not sure what should be the expected result

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I wanted to check with @laa-odoo

@laa-odoo
Copy link
Collaborator

@LucasLefevre are you okay to fixup the suggestion ?

@laa-odoo laa-odoo force-pushed the saas-17.1-visit-simple-arg-lul branch 3 times, most recently from fc43e50 to 6126507 Compare May 24, 2024 12:21
…ctions

Conditional functions like SUMIF using the "visitMatchingRanges"
helper did not handle simple arguments correctly. This issue has
been fixed, allowing conditional functions to functionally
handle errors in a way that is more similar to Excel.

Task: 3918882
@laa-odoo laa-odoo force-pushed the saas-17.1-visit-simple-arg-lul branch from 6126507 to db08fcd Compare May 24, 2024 15:03
Change the CHOOSECOLS and the CHOOSEROWS formulas to search
ranges with negative indexs

Task: 3918882
Formulas typed as "returning only ranges" can actually
return simple values instead of a matrix. This phenomenon
occurs precisely when an error is thrown: it is always
returned as a simple value.

Normally, this type of error is handled during
compilation. But with what is said above this is not
the case...

Two ways to solve the problem have been proposed here:

The first solution could have been to encapsulate
the throing error in an matrix when it is a function
returning a range. By doing this, we ensure that the
function typing is correct and we keep the handling
of this type of error during compilation.

The second solution would be to say that we cannot
determine in advance what the result of a sub-function
will be (simple error vs array). Thus, the argument
check would be done at runtime.

The first solution is good, but its implementation might
cause comprehension issues for the user. Indeed, it
seems strange that for functions rejecting only ranges
as input, depending on the return type of the sub-formula
(simple vs range), the formula may crash or not for
a same error.

Let's take the following example to illustrate this
problem: Suppose the case of 'SUMIF' which only accepts
ranges as parameters. Consider the functions 'ABS', which
naturally returns a simple value, and 'TRANSPOSE', which
naturally returns a range.

- SUMIF(ABS(), 42)
- SUMIF(TRANSPOSE(), 42)

In these two examples, no arguments were given to 'ABS'
and 'TRANSPOSE'. Both sub-functions will respectively
return an error. With the first solution, only the first
case will throw, whereas in the second case, both will
throw.

We therefore choose to go with the second solution,
despite its implications, to ensure better consistency
and understanding for the user.

Task: 3918882
@laa-odoo laa-odoo force-pushed the saas-17.1-visit-simple-arg-lul branch from db08fcd to ce19c77 Compare May 24, 2024 15:06
@rrahir
Copy link
Collaborator

rrahir commented May 27, 2024

the ref should be done in master

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants