From 280620a753fc098567fdc6ed24675abb44f3f3de Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 30 Aug 2014 00:12:31 +0100 Subject: [PATCH] Implement Excel VALUE() function, locale-warts and all --- Classes/PHPExcel/Calculation.php | 2 +- Classes/PHPExcel/Calculation/TextData.php | 45 ++++++++++++++++++- Documentation/FunctionListByCategory.txt | 2 +- Documentation/FunctionListByName.txt | 2 +- .../PHPExcel/Calculation/TextDataTest.php | 20 +++++++++ .../Calculation/TextData/VALUE.data | 10 +++++ 6 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 unitTests/rawTestData/Calculation/TextData/VALUE.data diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index c159012b..4de70eb2 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -1628,7 +1628,7 @@ class PHPExcel_Calculation { 'argumentCount' => '2' ), 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, - 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'functionCall' => 'PHPExcel_Calculation_TextData::VALUE', 'argumentCount' => '1' ), 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, diff --git a/Classes/PHPExcel/Calculation/TextData.php b/Classes/PHPExcel/Calculation/TextData.php index 73a0d0cd..7a52d2e7 100644 --- a/Classes/PHPExcel/Calculation/TextData.php +++ b/Classes/PHPExcel/Calculation/TextData.php @@ -104,7 +104,7 @@ class PHPExcel_Calculation_TextData { } if (is_string($stringValue) || is_numeric($stringValue)) { - return str_replace(self::$_invalidChars,'',trim($stringValue,"\x00..\x1F")); + return str_replace(self::$_invalidChars, '', trim($stringValue, "\x00..\x1F")); } return NULL; } // function TRIMNONPRINTABLE() @@ -587,4 +587,45 @@ class PHPExcel_Calculation_TextData { return (string) PHPExcel_Style_NumberFormat::toFormattedString($value,$format); } // function TEXTFORMAT() -} // class PHPExcel_Calculation_TextData + /** + * VALUE + * + * @param mixed $value Value to check + * @return boolean + */ + public static function VALUE($value = '') { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (!is_numeric($value)) { + $numberValue = str_replace( + PHPExcel_Shared_String::getThousandsSeparator(), + '', + trim($value, " \t\n\r\0\x0B" . PHPExcel_Shared_String::getCurrencyCode()) + ); + if (is_numeric($numberValue)) { + return (float) $numberValue; + } + + $dateSetting = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + + if (strpos($value, ':') !== false) { + $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($value); + if ($timeValue !== PHPExcel_Calculation_Functions::VALUE()) { + PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); + return $timeValue; + } + } + $dateValue = PHPExcel_Calculation_DateTime::DATEVALUE($value); + if ($dateValue !== PHPExcel_Calculation_Functions::VALUE()) { + PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); + return $dateValue; + } + PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); + + return PHPExcel_Calculation_Functions::VALUE(); + } + return (float) $value; + } + +} diff --git a/Documentation/FunctionListByCategory.txt b/Documentation/FunctionListByCategory.txt index 1c3ec5c2..b23d9a11 100644 --- a/Documentation/FunctionListByCategory.txt +++ b/Documentation/FunctionListByCategory.txt @@ -374,4 +374,4 @@ CATEGORY_TEXT_AND_DATA TEXT PHPExcel_Calculation_TextData::TEXTFORMAT TRIM PHPExcel_Calculation_TextData::TRIMSPACES UPPER PHPExcel_Calculation_TextData::UPPERCASE - VALUE *** Not yet Implemented + VALUE PHPExcel_Calculation_TextData::VALUE diff --git a/Documentation/FunctionListByName.txt b/Documentation/FunctionListByName.txt index 02e2f063..45a9daf7 100644 --- a/Documentation/FunctionListByName.txt +++ b/Documentation/FunctionListByName.txt @@ -355,7 +355,7 @@ TYPE CATEGORY_INFORMATION PHPExcel_Calculation_Fun UPPER CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::UPPERCASE USDOLLAR CATEGORY_FINANCIAL *** Not yet Implemented -VALUE CATEGORY_TEXT_AND_DATA *** Not yet Implemented +VALUE CATEGORY_TEXT_AND_DATA PHPExcel_Calculation_TextData::VALUE VAR CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARFunc VARA CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARA VARP CATEGORY_STATISTICAL PHPExcel_Calculation_Statistical::VARP diff --git a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php index 717e8fef..ea7882b6 100644 --- a/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php +++ b/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php @@ -340,4 +340,24 @@ class TextDataTest extends PHPUnit_Framework_TestCase return new testDataFileIterator('rawTestData/Calculation/TextData/TEXT.data'); } + /** + * @dataProvider providerVALUE + */ + public function testVALUE() + { + call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),'.'); + call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),' '); + call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),'$'); + + $args = func_get_args(); + $expectedResult = array_pop($args); + $result = call_user_func_array(array('PHPExcel_Calculation_TextData','VALUE'),$args); + $this->assertEquals($expectedResult, $result, NULL, 1E-8); + } + + public function providerVALUE() + { + return new testDataFileIterator('rawTestData/Calculation/TextData/VALUE.data'); + } + } diff --git a/unitTests/rawTestData/Calculation/TextData/VALUE.data b/unitTests/rawTestData/Calculation/TextData/VALUE.data new file mode 100644 index 00000000..505c2915 --- /dev/null +++ b/unitTests/rawTestData/Calculation/TextData/VALUE.data @@ -0,0 +1,10 @@ +"1000", "1000" +"1 000", "1000" +"$1 000", "1000" +"£1 000", "#VALUE!" +"1.1", "1.1" +"1 000.1", "1000.1" +"13 Monkeys", "#VALUE!" +"1-Jan-2014", "41640" +"12:34:56", "0.524259259259259" +"2:46 AM", "0.11527777777778"