我有一个包含公式的Excel电子表格。我想知道根据给定的输入使用公式和计算输出的最佳方法是什么。
我的第一个倾向是将传播加载到PHPExcel对象中,并将公式中涉及的每个单元格的值设置为给定输入,然后最终读取结果。
编辑:我试图通过以下方式获取公式的计算值:
getCalculatedValue()
我在应该包含扩展的计算值的单元格上运行此方法'按原样',但是它为Excel5.php和MathTrig.php吐出未定义的偏移错误并且结果不正确:
Notice: Undefined offset: 437 in /Applications/MAMP/htdocs/bang/Classes/PHPExcel/Reader/Excel5.php on line 5679
Notice: Undefined offset: 438 in /Applications/MAMP/htdocs/bang/Classes/PHPExcel/Reader/Excel5.php on line 5679
Notice: Undefined offset: 439 in /Applications/MAMP/htdocs/bang/Classes/PHPExcel/Reader/Excel5.php on line 5679
Notice: Undefined offset: 9 in /Applications/MAMP/htdocs/bang/Classes/PHPExcel/Calculation/MathTrig.php on line 1171
PHPExcel中调试的公式和堆栈跟踪是:
Value is =SUMIF(Sheet3!A1:H530,"=212410000",Sheet3!H1:H530)
Parser Stack :-
Array
(
[0] => Array
(
[type] => Cell Reference
[value] => Sheet3!A1
[reference] => Sheet3!A1
)
[1] => Array
(
[type] => Cell Reference
[value] => Sheet3!H530
[reference] => Sheet3!H530
)
[2] => Array
(
[type] => Binary Operator
[value] => :
[reference] =>
)
[3] => Array
(
[type] => Value
[value] => "=212410000"
[reference] =>
)
[4] => Array
(
[type] => Cell Reference
[value] => Sheet3!H1
[reference] => Sheet3!H1
)
[5] => Array
(
[type] => Cell Reference
[value] => Sheet3!H530
[reference] => Sheet3!H530
)
[6] => Array
(
[type] => Binary Operator
[value] => :
[reference] =>
)
[7] => Array
(
[type] => Operand Count for Function SUMIF()
[value] => 3
[reference] =>
)
[8] => Array
(
[type] => Function
[value] => SUMIF(
[reference] =>
)
)
Excel5.php中触发错误的行是:
// offset: 1; size: 2; one-based index to definedname record
$definedNameIndex = self::_GetInt2d($formulaData, 1) - 1;
// offset: 2; size: 2; not used
$data = $this->_definedname[$definedNameIndex]['name']; // errors here
答案 0 :(得分:1)
您可以在调试模式下运行计算引擎,以获取有关其帮助诊断此类问题的更多详细信息:
$cell = 'C3';
// enable debugging
PHPExcel_Calculation::getInstance()->writeDebugLog = true;
$sheet = $objPHPExcel->getActiveSheet();
$formulaValue = $sheet->getCell($cell)->getValue();
echo '<b>'.$cell.' Value is </b>'.$formulaValue."<br />\n";
$calculate = false;
try {
$tokens = PHPExcel_Calculation::getInstance()->parseFormula($formulaValue,$sheet->getCell($cell));
echo '<b>Parser Stack :-</b><pre>';
print_r($tokens);
echo '</pre>';
$calculate = true;
} catch (Exception $e) {
echo "PARSER ERROR: ".$e->getMessage()."<br />\n";
echo '<b>Parser Stack :-</b><pre>';
print_r($tokens);
echo '</pre>';
}
if ($calculate) {
// calculate
try {
$cellValue = $sheet->getCell($cell)->getCalculatedValue();
} catch (Exception $e) {
echo "CALCULATION ENGINE ERROR: ".$e->getMessage()."<br />\n";
echo '<h3>Evaluation Log:</h3><pre>';
print_r(PHPExcel_Calculation::getInstance()->debugLog);
echo '</pre>';
}
}
修改强>
没有保证,因为我需要再测试一下,但修改Classes / PHPExcel / Calculation / MathTrig.php文件中的第1171行
此行目前为
$returnValue += $sumArgs[$key];
将其更改为
$returnValue += $sumArgs[$key % count($sumArgs)];
假设条件范围内的单元格数(Sheet3!A1:H530在您的情况下)与求和范围中的单元格数量(Sheet3!H1:H530)匹配,当标准显然不是这样的情况引用8列和530行,而求和范围仅引用单列中的530行。
编辑#2
虽然上面的编辑建议会修复错误,但它会返回错误的结果。如果您指定A1:H530作为您的标准,但仅指定H1:H530作为MS Excel中的总和值,它仅测试第一列(以匹配潜在的求和结果数)并忽略标准中的列BH。
快速修复可能是修改第1161行:
if (empty($sumArgs)) {
$sumArgs = $aArgs;
}
到
if (empty($sumArgs)) {
$sumArgs = $aArgs;
} elseif (count($aArgs) > count($sumArgs)) {
$aArgs = array_slice($aArgs,0,count($sumArgs));
}
并将第1171行(现为1173)还原为
$returnValue += $sumArgs[$key];
我仍然需要检查flattenArray是否正确命令单元格,但这将是一个更接近的修复
编辑#3
修复PHPExcel的calc引擎以处理不匹配的条件/求和数组需要更长的时间(上面的我的修复不起作用,因为PHPExcel按行展平,而这需要由列平展) - 但是作为临时修补更改您的公式只能在条件范围内使用一列
答案 1 :(得分:0)
如果你这样做,你可以:
$objWorksheet = $objPHPExcel->setActiveSheetIndex($index);
$arrExcelObject = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
代码中记录了toArray函数:
public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnColumnRef = false)
所以第二个arg表示你想从公式计算,默认情况下设置为true。