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

Calculation engine executes statements on every branches #788

Closed
frantzmiccoli opened this issue Nov 26, 2018 · 11 comments
Closed

Calculation engine executes statements on every branches #788

frantzmiccoli opened this issue Nov 26, 2018 · 11 comments
Assignees

Comments

@frantzmiccoli
Copy link
Contributor

This is:

- [ ] a bug report
- [x] a feature request
- [x] **not** a usage question (ask them on https://stackoverflow.com/questions/tagged/phpspreadsheet or https://gitter.im/PHPOffice/PhpSpreadsheet)

To be honest I am not sure whether it is a feature request or a bug report.

What is the expected behavior?

If we take the example of an IF statement like IF(A1="YES";B12;C12) we could expect that A1 contains the value YES we should only resolve the value in the cell B12.

What is the current behavior?

Currently B12 is resolved and reutrned correctly, though C12 is evaluated too which causes extra, not required, computation

What are the steps to reproduce?

  1. Using 1.5.1 and the following file: repro.xlsx

  2. Alter the Calculation::calculateCellValue method to just log the name of the resolved cell. Like:

public function calculateCellValue(Cell $pCell = null, $resetLog = true)
    {
        var_dump($pCell->getCoordinate());
     ...
  1. Run the following test case:
<?php
class RandomTest extends \PHPUnit\Framework\TestCase {

    public function testIdentifiedProblem() {
        $path = 'model/excel/repro.xlsx';
        $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($path);

        $targetSheetName = 'Sheet1';

        $spreadsheet->setActiveSheetIndexByName($targetSheetName);

        $cell = 'B2';
        $value = 'YES';

        $spreadsheet->getActiveSheet()->setCellValue($cell, $value);

        $targetCell = 'B13';
        $targetValue = $spreadsheet->getActiveSheet()->getCell($targetCell)
            ->getCalculatedValue(true);
        $expectedValue = 8;
        $this->assertEquals($expectedValue, $targetValue);
    }

}

4. Observe that both `D11` and `B11` are processed.

Which versions of PhpSpreadsheet and PHP are affected?

PHP 7.2.3-1ubuntu1 (cli) (built: Mar 14 2018 22:03:58) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.3-1ubuntu1, Copyright (c) 1999-2018, by Zend Technologies

PhpSpreadsheet 1.5.1
@MarkBaker
Copy link
Member

This is most definitely not a bug report, a bug report would be when the calculation engine returns an incorrect result for a formula (eg if C12 was returned in your example rather than B12).

PHPSPreadsheet uses a simplistic stack-based parser for the calculation engine, which evaluates all the data necessary for a function (all the arguments) onto the stack before executing the function itself. For most functions, this is more efficient than alternative approaches, because the arguments for most functions are pre-determined and required; and it is only a few functions like the IF() functions where it isn't efficient.

I have done some prototyping work on alternative approaches to evaluating formulae and that would make the calculation engine more manageable, it is a non-trivial piece of work, although it would have other benefits such as better handling for errors, the ability to handle array formulae (even 3d arrays), and support for row and column references (not simply cell and range references). However, this is still very much an experimental prototype, and will take a lot of time and effort before it's stable enough to start integrating into PHPSpreadsheet itself.

@frantzmiccoli frantzmiccoli changed the title Calculation engine executes conditional statements on every branches Calculation engine executes statements on every branches Nov 30, 2018
frantzmiccoli added a commit to frantzmiccoli/PhpSpreadsheet that referenced this issue Dec 14, 2018
@frantzmiccoli
Copy link
Contributor Author

@MarkBaker I have implemented something keeping the stack based parser and tagging tokens to enable pruning. #818

frantzmiccoli added a commit to frantzmiccoli/PhpSpreadsheet that referenced this issue Jan 7, 2019
@stale
Copy link

stale bot commented Feb 12, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If this is still an issue for you, please try to help by debugging it further and sharing your results.
Thank you for your contributions.

@stale stale bot added the stale label Feb 12, 2019
@frantzmiccoli
Copy link
Contributor Author

Not stale! ;)

@stale stale bot removed the stale label Feb 13, 2019
@stale
Copy link

stale bot commented Apr 14, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If this is still an issue for you, please try to help by debugging it further and sharing your results.
Thank you for your contributions.

@stale stale bot added the stale label Apr 14, 2019
@frantzmiccoli
Copy link
Contributor Author

Nope, mean bot! Not stale!

@stale stale bot removed the stale label Apr 14, 2019
@MarkBaker MarkBaker self-assigned this Apr 15, 2019
@stale
Copy link

stale bot commented Jun 14, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If this is still an issue for you, please try to help by debugging it further and sharing your results.
Thank you for your contributions.

@stale stale bot added the stale label Jun 14, 2019
@frantzmiccoli
Copy link
Contributor Author

Not stale

@stale stale bot removed the stale label Jun 18, 2019
@stale
Copy link

stale bot commented Aug 17, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If this is still an issue for you, please try to help by debugging it further and sharing your results.
Thank you for your contributions.

@stale stale bot added the stale label Aug 17, 2019
@frantzmiccoli
Copy link
Contributor Author

Not stale, pending review dear bot!

@stale stale bot removed the stale label Aug 20, 2019
@frantzmiccoli
Copy link
Contributor Author

Resolved through 0b387e7

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

No branches or pull requests

2 participants