Commit Graph

543 Commits

Author SHA1 Message Date
oleibman b05dc31850
MathTrig - Change Names of funcWhatever to evaluate (#2008)
* MathTrig - Change Names of funcWhatever to evaluate

Per discussions while MathTrig was being broken up, this would help standardize the code. That idea was adopted partway through the breakup. This PR applies that standardization to the earlier efforts. A similar effort is required for DateTime; that will come later. This PR replaces #2006.

The only 2 remaining funcWhatevers in MathTrig are both in SUM, which required two different methods depending on whether or not string parameters were to be ignored. It seems appropriate to leave those method names non-standardized in order to require a decision about which is to be used if they are invoked internally.

3 Phpstan grandfathered errors were eliminated as part of this change, and its baseline has changed accordingly.

Co-authored-by: Mark Baker <mark@lange.demon.co.uk>
2021-04-20 22:43:29 +02:00
oleibman c79a9a8e21
Improved Support for INDIRECT, ROW, and COLUMN Functions (#2004)
* Improved Support for INDIRECT, ROW, and COLUMN Functions

This should address issues #1913 and #1993. INDIRECT had heretofore not supported an optional parameter intended to support addresses in R1C1 format which was introduced with Excel 2010. It also had not supported the use of defined names as an argument. This PR is a replacement for #1995, which is currently in draft status and which I will close in a day or two.

The ROW and COLUMN functions also should support defined names. I have added that, and test cases, with the latest push. ROWS and COLUMNS already supported it correctly, but there had been no test cases. Because ROW and COLUMN can return arrays, and PhpSpreadsheet does not support dynamic arrays, I left the existing direct-call tests unchanged to demonstrate those capabilities.

The unit tests for INDIRECT had used mocking, and were sorely lacking (tested only error conditions). They have been replaced with normal, and hopefully adequate, tests. This includes testing globally defined names, as well as locally defined names, both in and out of scope.

The test case in 1913 was too complicated for me to add as a unit test. The main impediments to it are now removed, and its complex situation will, I hope, be corrected with this fix.

INDIRECT can also support a reference of the form Sheetname!localName when localName on its own would be out of scope. That functionality is added. It is also added, in theory, for ROW and COLUMN, however such a construction is rejected by the Calculation engine before passing control to ROW or COLUMN. It might be possible to change the engine to allow this, and I may want to look into that later, but it seems much too risky, and not nearly useful enough, to attempt to address that as part of this change.

Several unusual test cases (leading equals sign, not-quite-as-expected name definition in file, complex indirection involving concatenation and a dropdown list) were suggested by @MarkBaker and are included in this request.
2021-04-20 22:16:21 +02:00
oleibman aeccdb35e2
XLSX Reader and Empty Fill Tag (#2011)
Openpyxl can generate the xml tag `<patternFill/>`, possibly even as a default style. Excel has no problem with this, treating it as "fill none", but PhpSpreadsheet has a glitch because it treats it as "fill solid white". So, when PhpSpreadsheet loads and saves such a file, the result at first appears as if gridlines are disabled; in fact, the gridlines are merely invisible behind the cells with their solid white fill. This PR makes PhpSpreadsheet behave the same as Excel in this circumstance.

Co-authored-by: Mark Baker <mark@lange.demon.co.uk>
2021-04-20 17:20:59 +02:00
Mark Baker 6282035c96
Extract Property and Style readers from the XML Reader into separate classes (#2009)
* Extract Property and Style readers from the XML Reader into separate classes
2021-04-20 15:27:44 +02:00
Tiago Fernandes 11f8a02194
Merge branch 'master' into issue-907-absolute-path-in-Target 2021-04-19 14:32:20 +01:00
Tiago Fernandes 559c0761df Remove unnecessary changes. Added test 2021-04-19 11:25:48 +01:00
Mark Baker f49a951bea
Tag deprecations for MathTrig, and eliminate calls to the deprecated methods (#2005)
* Tag deprecations for MathTrig, and eliminate calls to the deprecated methods
2021-04-18 12:19:53 +02:00
Mark Baker ddd07ee504
Use validation classes rather than traits for Statistical functions, … (#1999)
* Use validation classes rather than traits for Statistical functions, and some verification of nullable arguments
* Eliminate more of the issues resolved in phpstan baseline
2021-04-13 16:56:21 +02:00
Adrien Crivelli d85eaacfa3
BREAKING `Worksheet::getCell()` cannot return null anymore
`Worksheet::getCell()` used to optionnaly return null if passed a
second argument. This second argument was removed entirely and the
method always returns a Cell (possibly creating it if needed).

This make the API more predictable and easier to do static analysis
with tools such as PHPStan.

If you relied on that second parameter, you should instead use the
`Worksheet::cellExists()` before calling `getCell()`.
2021-04-13 11:09:29 +09:00
Mark Baker a34695e0f9
Financial functions more rationalization (#1990)
* Additional unit tests and rationalisation for Financial Functions
* Providing a series of sample files for Financial functions
* Refactor the last of the existing Financial functions
* Some more unit tests with default assignments from null arguments

Co-authored-by: Adrien Crivelli <adrien.crivelli@gmail.com>
2021-04-12 22:08:58 +02:00
Adrien Crivelli 49f87de165
Reduce PHPStan error in tests 2021-04-12 11:10:23 +09:00
Adrien Crivelli f9532231d2
PHPStan Level 3 2021-04-11 16:33:53 +09:00
Akira Taniguchi da28089c3c
Merge branch 'master' into master 2021-04-06 23:56:37 +09:00
Mark Baker bc18fb7e77
more extraction of Excel Financial functions (#1989)
* More Financial function extracts, this time looking at the Periodic Cashflow functions
* Initial extract of Constant Periodic Interest and Payment functions
2021-04-06 12:45:37 +02:00
Akira Taniguchi 551bbdf30f
Update CsvOutputEncodingTest.php 2021-04-06 18:53:21 +09:00
Vivek 93d858a064
Merge branch 'master' into fix_excel_overwrite 2021-04-06 08:19:44 +05:30
Akira Taniguchi e48ffdbe77
Update CsvOutputEncodingTest.php 2021-04-06 04:44:24 +09:00
Akira Taniguchi 991616d1d9
Update CsvOutputEncodingTest.php 2021-04-06 04:39:26 +09:00
Akira Taniguchi 86f3bdd598
Update CsvOutputEncodingTest.php 2021-04-06 04:27:14 +09:00
Akira Taniguchi bfd4a659a4
Update CsvOutputEncodingTest.php 2021-04-06 04:11:46 +09:00
Akira Taniguchi 2adc44262c
Update CsvOutputEncodingTest.php 2021-04-06 03:48:08 +09:00
Akira Taniguchi 7681a1093f
Update CsvOutputEncodingTest.php 2021-04-06 03:46:10 +09:00
Akira Taniguchi 2df8e1a93f
Update CsvOutputEncodingTest.php 2021-04-06 03:07:10 +09:00
Akira Taniguchi f6bfbd0655
Create CsvOutputEncodingTest.php 2021-04-06 02:56:54 +09:00
Akira Taniguchi 2a16ce1432
Delete CsvOutputEncoding.php 2021-04-06 02:47:46 +09:00
Akira Taniguchi eef90b62df
Create CsvOutputEncoding.php 2021-04-06 02:05:08 +09:00
Vivek Kumar dd9cb259d0 Unlink temporary file 2021-04-05 22:14:50 +05:30
oleibman 95b8c4d59b
Continue MathTrig Breakup - Completion! (#1985)
* Continue MathTrig Breakup - Completion!

Continuing the process of breaking MathTrip.php up into smaller classes. This round takes care of everything that was left:
- ABS
- DEGREES
- EXP
- RADIANS
- SQRT
- SQRTPI
- SUMSQ, SUMX2MY2, SUMX2PY2, SUMXMY2

The only notable logic change was that the 3 SUMX* functions had accepted arrays of unlike length; in that condition, they now return N/A, as Excel does. There had been no tests for this condition.

All the functions in MathTrig.php are now deprecated. Except for COMBIN, the test suite executes them only from MathTrig MovedFunctionsTest. COMBIN is still directly called by some Statistics Binomial functions which have not yet had the opportunity to be re-coded for the new location.


Co-authored-by: Mark Baker <mark@lange.demon.co.uk>
2021-04-05 16:39:03 +02:00
Vivek Kumar 5e96f4292b Merge remote-tracking branch 'master' into fix_excel_overwrite 2021-04-05 12:42:43 +05:30
Vivek Kumar 59de56bb62 Move original file to temporary file 2021-04-05 12:26:44 +05:30
Adrien Crivelli d02352845c
PHPStan Level 2 2021-04-04 22:06:00 +09:00
Mark Baker 42761f90b7
Financial start refactoring cash flow functions (#1986)
* Start extracting CashFlow functions from Financial, beginning with the simple Single Rate flows
* Extracting Variable Periodic and NonPeriodic CashFlow functions from Financial
* Some more unit tests for exception cases
2021-04-04 14:44:06 +02:00
Mark Baker dd74dd7fcf
Let's start with some appeasements to phpstan, just to reduce the baseline (#1983)
* Let's start with some appeasements to phpstan, just to reduce the baseline
* Appeasements to phpstan, taking the number of reported errors down to just 61
2021-04-03 17:10:40 +02:00
Adrien Crivelli a189d933f2
Introduce PHPStan
To improve the feedback loop on code quality with a process
that can be run locally by the developers, instead of only
on Scrutinizer.
2021-04-03 16:13:21 +09:00
Mark Baker a2bb825bc5
Extract Normal and Standard Normal Distributions from the Statistical Class (#1981)
* Extract Normal and Standard Normal Distributions from the Statistical Class
* Extract ZTest from the Statistical Class, and move it to the Standard Normal Distribution class
Additional unit tests for NORMINV()
* Extract LogNormal distribution functions from Statistical
2021-04-02 20:17:03 +02:00
oleibman a4982fd9fe
Continue MathTrig Breakup - Penultimate? (#1973)
* Continue MathTrig Breakup - Penultimate?

Continuing the process of breaking MathTrip.php up into smaller classes. This round takes care of about half of what is left, so perhaps one round after this one will finish the job:
- ARABIC
- COMBIN; also implemented COMBINA
- FACTDOUBLE
- GCD (which accepts and ignores empty cells as arguments, but returns VALUE if all the arguments are that way; LCM does the same)
- LOG_BASE, LOG10, LN
- implemented MUNIT
- MOD
- POWER
- RAND, RANDBETWEEN (RANDARRAY is too complicated to implement with this ticket)

As you can see from the description, there are some functions which were combined in a single class. When not combined, I adopted PowerKiki's suggestion of using "execute" as the function name.

Co-authored-by: Mark Baker <mark@lange.demon.co.uk>
2021-04-02 14:35:34 +02:00
Mark Baker 0c403efe60
Resolution for [#Issue 1972](https://github.com/PHPOffice/PhpSpreadsheet/issues/1972) (#1978)
* Resolution for [#Issue 1972](https://github.com/PHPOffice/PhpSpreadsheet/issues/1972) where format masks with a leading and trailing quote were always treated as literal strings, even when they masks containing quoted characters.

Also resolves issue with colour name case-sensitivity
2021-04-01 13:25:05 +02:00
Mark Baker 17af13281b
Extract a few more Distribution functions from Statistical (#1975)
* Extract a few more Distribution functions from Statistical; this time EXPONDIST() and HYPGEOMDIST()

* Extract the F Distribution (although only F.DIST() is implemented so far

* Updae docblocks

* PHPCS
2021-03-31 21:45:06 +02:00
Mark Baker 029f345987
Extract Binomial Distribution functions from Statistical (#1974)
* Extract Binomial Distribution functions from Statistical
Replace the old MS algorithm for CRITBINOM() (which has now been replaced with te BINOM.INV() function) with a brute force approach - I'll look to refine it later. The MS algorithm is no longer documented, and the implementation produced erroneous results anyway

* Exract the NEGBINOMDIST() function as well; still need to add a cumulative flag to support the additional argument for the newer NEGBINOM.DIST() function
* Rationalise validation of probability arguments
2021-03-30 22:49:10 +02:00
Mark Baker 1c92b7611a
Extract Percentile-type functions from Statistics (#1966)
* Extract Percentile-type functions from Statistics (e.g. PERCENTILE(), PERCENTRANK(), QUARTILE(), and RANK())
* Unit test for PERCENTILE() with an empty (of numbers) dataset
2021-03-29 12:59:46 +02:00
Mark Baker e68978f1c7
Chi squared inverse left tailed (#1964)
* Implementation of the CHISQ.INV() method for ChiSquared distribution left-tail
2021-03-28 19:12:45 +02:00
Mark Baker e2ff14fe89
Implemented the CHISQ.DIST() Statistical function. (#1961)
* Implementation of the CHISQ.DIST() statistical function for left tail distribution
2021-03-28 16:13:00 +02:00
Mark Baker 67fec4e3fc
Implementation of the CHITEST() statistical function (#1960)
* Implementation of the CHITEST() statistical function

* A couple of additional edge case tests (rows = 1, columns = 1)
2021-03-27 22:04:05 +01:00
Mark Baker a34dd71cce
Difference in variance calculations between Excel/Gnumeric and Open/LibreOffice (#1959)
* Difference in variance calculations between Excel/Gnumeric and Open/LibreOffice
* Simplify STDEV() function logic by remembering that STDEV() is simply the square root of VAR(), so we can simply use the VAR() calculaion rather than duplicating the basic logic... and also allow for the differences between Excel/Gnumeric and Open/LibreOffice
2021-03-27 18:31:24 +01:00
Mark Baker ec2531411d
Start implementing Newton-Raphson for the inverse of Statistical Distributions (#1958)
* Start implementing Newton-Raphson for the inverse of Statistical Distributions, starting with the two-tailed Student-T
* Additional unit tests and validations
* Use the new Newton Raphson class for calculating the Inverse of ChiSquared
* Extract Weibull distribution, and provide unit tests
2021-03-27 13:29:58 +01:00
Mark Baker c699d144e2
Extract ACCRINT() and ACCRINTM() Financial functions into their own class (#1956)
* Extract ACCRINT() and ACCRINTM() Financial functions into their own class
Implement additional validations, with additional unit tests
Add support for the new calculation method argument for ACCRINT()
* Additional tests for Amortization functions
2021-03-26 22:49:16 +01:00
oleibman 9239b3deca
Continue MathTrig Breakup - Problem Children (#1954)
Continuing the process of breaking MathTrip.php up into smaller classes. This round takes care of all functions which might be an impediment to installing due to either uncovered code or "complexity":
- BASE
- FACT
- LCM
- MDETERM, MINVERSE, MMULT
- MULTINOMIAL
- PRODUCT
- QUOTIENT
- SERIESSUM
- SUM
- SUMPRODUCT

MathTrig and the members in directory MathTrig are now 100% covered. Many tests have been added, and some edge-case bugs are corrected. Some cases where PhpSpreadsheet had rejected numeric values stored as strings have been changed to accept them whenever Excel does; there had been no tests for that condition.

Boolean arguments are now accepted as arguments wherever Excel accpets them. Taking a cue from what has been done in Engineering, the parameter validation now happens in a routine which issues Exceptions for invalid values; this simplifies the code in the functions themselves. Thank you for doing that; I did not foresee how useful that was when I first looked at it.

Consistent with earlier changes of this nature, the versions in the MathTrig class remain, with a doc block indicating deprecation, and a stub call to the new routines.

All tests except for MINVERSE and MMULT are now handled in the context of a spreadsheet rather than a direct call to the calculation function which implements it. PhpSpreadsheet would need to handle dynamic arrays in order to test MINVERSE and MMULT in a spreadsheet context. Implementing that looks like it might be *very* challenging. It is not something I plan to look at, at least not in the near future.

One parsing problem turned up in the test conversion. It is in one of the SUMIF tests. It takes me to an area in Calculation where the comment says "I don't even want to know what you did to get here". It did not show up in the previous incarnation because, by using a direct call, the previous test managed to bypass the parsing. I have confirmed that this problem shows up in earlier releases of PhpSpreadsheet, so the changes in this PR did not cause it - they merely exposed it. I have left the test intact, but marked it "incomplete" for documentation purposes. I have not been able to get a handle on what's going wrong yet. I will probably open an issue on it if I can't resolve it soon. However, the test in question isn't a "real world" issue, and the error wasn't caused by this change, so I see no reason to delay this pending a resolution of the problem.

SUM had an idiosyncratic moment of its own. It had been ignoring non-numeric values, but Excel returns VALUE in that situation. So I changed it and wrote some new tests, which worked, but ... SUMIF uses several levels of indirection to get to SUM, and SUMIF *does* ignore non-numeric values, so a SUMIF test broke. SUM is a really simple function; the most practical approach seemed to be to clone it, with the string-accepting version being used by the Legacy version (which is called by SUMIF), and the non-string-accepting version being used in the Calculation Function table. That seems far easier and more practical than, for instance, adding a boolean parameter to the variable parameter list. As a follow-up, I will change SUMIF to explicitly call the appropriate new version, but I did not want to add that to this already large change.

SUM again - although it was fully covered beforehand, there was not a specific test member for it. There is now.

FACT had been coded to fail Gnumeric requests where the numeric argument has a decimal portion. However, Gnumeric does accept such an argument, and, unlike Excel and ODS, does not truncate it, but returns the result of a Gamma function call instead. This has been corrected.

When LCM included arguments which contained both 0 and a negative number, it returned 0 or NUM, whichever it found first. It is changed to always return NUM in that circumstance, as Excel does.

QUOTIENT had been documented as taking a variadic list of arguments. In fact, it takes exactly 2 - numerator and denominator - and the docblock and signature is fixed, even in the deprecated version.

The SERIESSUM docbock and signature are more accurate, even in the deprecated version. It is changed to ignore nulls, as Excel does, rather than return VALUE, and is one of the routines which previously rejected numbers in string form.

SUBTOTAL tests had used mocking for some reason. These are replaced with normal tests. And SUBTOTAL had a big surprise in store. That part of it which deals with hidden cells cares only whether the row is hidden, and doesn't care about the column's visibility.

I struggled with whether it should be SubTotal or Subtotal. I think the latter is correct, so that's how I proceeded. I don't think there are likely to be any other capitalization controversies.
2021-03-26 17:35:30 +09:00
Mark Baker c380b25d3c
Extract Poisson distribution into its own class (#1953) 2021-03-26 09:08:23 +01:00
Mark Baker f51c19c125
First steps toward refactoring Excel's Statistical Distributions (#1949)
* First steps toward refactoring Statistical Distributions into smaller classes: BETA() and GAMMA() (and related functions) to start with... they all need a lot of tidying up, and more testing; but it's a start

* Add basic datatype validations to Beta and Gamma Excel function implementations
* Switch to using a trait with the validation methods to provide easier sharing between distribution classes
* Additional unit tests for Beta and Gamma functions, including unhappy path for validations

* Extract ChiSquared functions
* Additional argument validation checks with unit tests for Chi Squared functions

* Extract Fisher

* Move MEDIAN() and MODE() to the Averages class
* Extract filters for Median and Mode for common usage
2021-03-25 20:54:55 +01:00
Mark Baker 07ad800755
New Bessel Algorithm, providing a higher degree of accuracy and precision (#1946)
* New Bessel Algorithm, providing a higher degree of precision (12 decimal places) and still matching/exceeding MS Excel's precision across the range of values
2021-03-24 13:29:54 +01:00