Eliminate need for use of money_format() function; various fixes to HLOOKUP, VLOOKUP and DOLLAR functions + unit tests

This commit is contained in:
Mark Baker 2013-06-15 12:15:03 +01:00
parent 83bd690633
commit 4d92e77d00
6 changed files with 37 additions and 101 deletions

View File

@ -689,100 +689,6 @@ if (!function_exists('atanh')) {
} // function atanh() } // function atanh()
} }
if (!function_exists('money_format')) {
function money_format($format, $number) {
$regex = array( '/%((?:[\^!\-]|\+|\(|\=.)*)([0-9]+)?(?:#([0-9]+))?',
'(?:\.([0-9]+))?([in%])/'
);
$regex = implode('', $regex);
if (setlocale(LC_MONETARY, null) == '') {
setlocale(LC_MONETARY, '');
}
$locale = localeconv();
$number = floatval($number);
if (!preg_match($regex, $format, $fmatch)) {
trigger_error("No format specified or invalid format", E_USER_WARNING);
return $number;
}
$flags = array( 'fillchar' => preg_match('/\=(.)/', $fmatch[1], $match) ? $match[1] : ' ',
'nogroup' => preg_match('/\^/', $fmatch[1]) > 0,
'usesignal' => preg_match('/\+|\(/', $fmatch[1], $match) ? $match[0] : '+',
'nosimbol' => preg_match('/\!/', $fmatch[1]) > 0,
'isleft' => preg_match('/\-/', $fmatch[1]) > 0
);
$width = trim($fmatch[2]) ? (int)$fmatch[2] : 0;
$left = trim($fmatch[3]) ? (int)$fmatch[3] : 0;
$right = trim($fmatch[4]) ? (int)$fmatch[4] : $locale['int_frac_digits'];
$conversion = $fmatch[5];
$positive = true;
if ($number < 0) {
$positive = false;
$number *= -1;
}
$letter = $positive ? 'p' : 'n';
$prefix = $suffix = $cprefix = $csuffix = $signal = '';
if (!$positive) {
$signal = $locale['negative_sign'];
switch (true) {
case $locale['n_sign_posn'] == 0 || $flags['usesignal'] == '(':
$prefix = '(';
$suffix = ')';
break;
case $locale['n_sign_posn'] == 1:
$prefix = $signal;
break;
case $locale['n_sign_posn'] == 2:
$suffix = $signal;
break;
case $locale['n_sign_posn'] == 3:
$cprefix = $signal;
break;
case $locale['n_sign_posn'] == 4:
$csuffix = $signal;
break;
}
}
if (!$flags['nosimbol']) {
$currency = $cprefix;
$currency .= ($conversion == 'i' ? $locale['int_curr_symbol'] : $locale['currency_symbol']);
$currency .= $csuffix;
$currency = iconv('ISO-8859-1','UTF-8',$currency);
} else {
$currency = '';
}
$space = $locale["{$letter}_sep_by_space"] ? ' ' : '';
if (!isset($locale['mon_decimal_point']) || empty($locale['mon_decimal_point'])) {
$locale['mon_decimal_point'] = (!isset($locale['decimal_point']) || empty($locale['decimal_point'])) ?
$locale['decimal_point'] :
'.';
}
$number = number_format($number, $right, $locale['mon_decimal_point'], $flags['nogroup'] ? '' : $locale['mon_thousands_sep'] );
$number = explode($locale['mon_decimal_point'], $number);
$n = strlen($prefix) + strlen($currency);
if ($left > 0 && $left > $n) {
if ($flags['isleft']) {
$number[0] .= str_repeat($flags['fillchar'], $left - $n);
} else {
$number[0] = str_repeat($flags['fillchar'], $left - $n) . $number[0];
}
}
$number = implode($locale['mon_decimal_point'], $number);
if ($locale["{$letter}_cs_precedes"]) {
$number = $prefix . $currency . $space . $number . $suffix;
} else {
$number = $prefix . $number . $space . $currency . $suffix;
}
if ($width > 0) {
$number = str_pad($number, $width, $flags['fillchar'], $flags['isleft'] ? STR_PAD_RIGHT : STR_PAD_LEFT);
}
$format = str_replace($fmatch[0], $number, $format);
return $format;
} // function money_format()
}
// //
// Strangely, PHP doesn't have a mb_str_replace multibyte function // Strangely, PHP doesn't have a mb_str_replace multibyte function

View File

@ -735,7 +735,11 @@ class PHPExcel_Calculation_LookupRef {
return PHPExcel_Calculation_Functions::NA(); return PHPExcel_Calculation_Functions::NA();
} else { } else {
// otherwise return the appropriate value // otherwise return the appropriate value
return $lookup_array[$rowNumber][$returnColumn]; $result = $lookup_array[$rowNumber][$returnColumn];
if ((is_numeric($lookup_value) && is_numeric($result)) ||
(!is_numeric($lookup_value) && !is_numeric($result))) {
return $result;
}
} }
} }
@ -798,7 +802,8 @@ class PHPExcel_Calculation_LookupRef {
return PHPExcel_Calculation_Functions::NA(); return PHPExcel_Calculation_Functions::NA();
} else { } else {
// otherwise return the appropriate value // otherwise return the appropriate value
return $lookup_array[$returnColumn][$rowNumber]; $result = $lookup_array[$returnColumn][$rowNumber];
return $result;
} }
} }

View File

@ -208,16 +208,17 @@ class PHPExcel_Calculation_TextData {
} }
$decimals = floor($decimals); $decimals = floor($decimals);
$mask = '$#,##0';
if ($decimals > 0) { if ($decimals > 0) {
return money_format('%.'.$decimals.'n',$value); $mask .= '.' . str_repeat('0',$decimals);
} else { } else {
$round = pow(10,abs($decimals)); $round = pow(10,abs($decimals));
if ($value < 0) { $round = 0-$round; } if ($value < 0) { $round = 0-$round; }
$value = PHPExcel_Calculation_MathTrig::MROUND($value,$round); $value = PHPExcel_Calculation_MathTrig::MROUND($value, $round);
// The implementation of money_format used if the standard PHP function is not available can't handle decimal places of 0,
// so we display to 1 dp and chop off that character and the decimal separator using substr
return substr(money_format('%.1n',$value),0,-2);
} }
return PHPExcel_Style_NumberFormat::toFormattedString($value, $mask);
} // function DOLLAR() } // function DOLLAR()

View File

@ -31,4 +31,20 @@ class LookupRefTest extends PHPUnit_Framework_TestCase
return new testDataFileIterator('rawTestData/Calculation/LookupRef/HLOOKUP.data'); return new testDataFileIterator('rawTestData/Calculation/LookupRef/HLOOKUP.data');
} }
/**
* @dataProvider providerVLOOKUP
*/
public function testVLOOKUP()
{
$args = func_get_args();
$expectedResult = array_pop($args);
$result = call_user_func_array(array('PHPExcel_Calculation_LookupRef','VLOOKUP'),$args);
$this->assertEquals($expectedResult, $result);
}
public function providerVLOOKUP()
{
return new testDataFileIterator('rawTestData/Calculation/LookupRef/VLOOKUP.data');
}
} }

View File

@ -12,6 +12,9 @@ class NumberFormatTest extends PHPUnit_Framework_TestCase
define('PHPEXCEL_ROOT', APPLICATION_PATH . '/'); define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');
} }
require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
PHPExcel_Shared_String::setDecimalSeparator('.');
PHPExcel_Shared_String::setThousandsSeparator(',');
} }
/** /**

View File

@ -0,0 +1,5 @@
1, {"Density"|"Viscosity"|"Temperature";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0}, 2, FALSE, 2.17
1, {"Density"|"Viscosity"|"Temperature";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0}, 3, TRUE, 100
.7, {"Density"|"Viscosity"|"Temperature";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0}, 3, FALSE, "#N/A"
0.1, {"Density"|"Viscosity"|"Temperature";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0}, 2, TRUE, "#N/A"
2, {"Density"|"Viscosity"|"Temperature";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0}, 2, TRUE, 1.71