简体   繁体   English

PHPExcel不评估公式

[英]PHPExcel doesn't evaluate formula

I'm trying to evaluate the following formular in my XSLX workbook with PHPExcel 1.7.9 : =IF($H$7=1,$F$13,$H$227*$J$227) 我正在尝试使用PHPExcel 1.7.9在我的XSLX工作簿中评估以下公式: =IF($H$7=1,$F$13,$H$227*$J$227)

Before I have to update some cells in the workbook and then I use this line to calculate the value: 在我必须更新工作簿中的某些单元格然后我使用此行来计算值之前:

$sheet->getCell('L228')->getCalculatedValue();

However, PHPExcel seems not to update the cell which contains the formula correctly. 但是,PHPExcel似乎不会正确更新包含公式的单元格。 It throws out some notice messages like the following but doesn't update the cell's calculated value: 它会抛出一些通知消息,如下所示但不更新单元格的计算值:

Notice: Undefined offset: 2 in D:\\my-path\\hkc\\Classes\\PHPExcel\\Calculation.php on line 2852 注意:未定义的偏移量:第2852行的D:\\ my-path \\ hkc \\ Classes \\ PHPExcel \\ Calculation.php中的2

There's no exception and it seems that getCalculatedValue() returns the old cached value calculated by MS Excel. 没有例外,似乎getCalculatedValue()返回由MS Excel计算的旧缓存值。 As pointed out below, I've activated debug logging of the calculation engine but it seems to be empty: 如下所述,我已经激活了计算引擎的调试日志记录,但它似乎是空的:

PHPExcel_CalcEngine_Logger Object
(
    [_writeDebugLog:PHPExcel_CalcEngine_Logger:private] => 
    [_echoDebugLog:PHPExcel_CalcEngine_Logger:private] => 
    [_debugLog:PHPExcel_CalcEngine_Logger:private] => Array
        (
        )

    [_cellStack:PHPExcel_CalcEngine_Logger:private] => PHPExcel_CalcEngine_CyclicReferenceStack Object
        (
            [_stack:PHPExcel_CalcEngine_CyclicReferenceStack:private] => Array
                (
                )

        )

)

I've tried the following steps to solve the problem: 我已经尝试了以下步骤来解决问题:

  1. Deactivate calculation cache: PHPExcel_Calculation::getInstance()->setCalculationCacheEnabled(FALSE); 取消激活计算缓存: PHPExcel_Calculation::getInstance()->setCalculationCacheEnabled(FALSE);
  2. Activate debug mode of calculation engine: This is described in How to handle exception with PhpExcel? 激活计算引擎的调试模式: 如何使用PhpExcel处理异常中描述了这一点。 and especially http://phpexcel.codeplex.com/discussions/233047 特别是http://phpexcel.codeplex.com/discussions/233047
    However, I had to modify the code of the referenced pages slightly - maybe something has changed in PHPExcel 1.7.9? 但是,我不得不稍微修改引用页面的代码 - 也许在PHPExcel 1.7.9中有些变化?
    Activate debug: PHPExcel_Calculation::getInstance()->writeDebugLog = true; 激活调试: PHPExcel_Calculation::getInstance()->writeDebugLog = true;
    Get debug log: print_r(PHPExcel_Calculation::getInstance()->getDebugLog()); 获取调试日志: print_r(PHPExcel_Calculation::getInstance()->getDebugLog());

I don't get it why the actual log of the engine is empty? 我不明白为什么引擎的实际日志是空的? Either the engine stops working before it writes out any entries or something is wrong with my debugging configuration? 引擎在写出任何条目之前是否停止工作或者我的调试配置有问题?

However, the I've tried to evaluate the same formula with Java and Apache POI - it worked! 但是,我试图用Java和Apache POI评估相同的公式 - 它有效! Unfortunately I've to use PHP for the current project. 不幸的是我要将PHP用于当前项目。

Please help me! 请帮我! Maybe somebody knows what's wrong with the formula evaluation or at least can give me some hints how to activate debugging properly? 也许有人知道公式评估有什么问题,或者至少可以给我一些提示如何正确激活调试?

Thanks! 谢谢!

Not an answer yet, but too long to be written a comment: 还不是答案,但写评论的时间太长了:

PHPExcel 1.7.9 modified the calculation engine from a singleton to a multiton (required to avoid clashes when working with multiple workbooks concurrently). PHPExcel 1.7.9将计算引擎从单例修改为多重(同时处理多个工作簿时需要避免冲突)。 As such, each workbook runs its own instance of the calc engine, and when making calls to 因此,每个工作簿都会运行自己的calc引擎实例,并在调用时运行

PHPExcel_Calculation::getInstance()

you now have to specify which instance you need to access. 您现在必须指定需要访问的实例。 Each PHPExcel instance has an ID value, maintained in the PHPExcel object that it is used for this purpose, and you need to pass the PHPExcel object itself to the getInstance() method. 每个PHPExcel实例都有一个ID值,在PHPExcel对象中维护,用于此目的,您需要将PHPExcel对象本身传递给getInstance()方法。 So, if your PHPExcel workbook is $objPHPExcel, you'd need to use 因此,如果您的PHPExcel工作簿是$ objPHPExcel,则需要使用

PHPExcel_Calculation::getInstance($objPHPExcel)

to reference the correct calc engine instance when flushing the cache, or enabling the logger, or reading the log. 在刷新缓存,启用记录器或读取日志时引用正确的calc引擎实例。

re. 回覆。 the specifics of your error: Do any of the cells referenced by your IF formula cell reference other formulae containing CUBE functions or the SUMIFS function? 错误的细节:IF公式单元格引用的任何单元格是否引用包含CUBE函数或SUMIFS函数的其他公式? Those are the only functions that I'm aware of that might trigger this particular error 这些是我所知道的唯一可能触发此特定错误的函数

EDIT 编辑

Example of refactoring a SUMIFS() function 重构SUMIFS()函数的示例

=SUMIFS(A2:A3, B2:B3, E1, C2:C3, F1)

which sums A2:A3 if B2:B3 meets the E1 criteria, and C2:C3 meets the F1 criteria. 总和A2:A3如果B2:B3符合E1标准,C2:C3符合F1标准。

This can be refactored as 这可以重构为

=SUMPRODUCT(A2:A3 * (B2:B3=E1) * (C2:C3=F1))

I've refactored a few SUMIFS to SUMPRODUCT and it seems to work. 我已经为SUMPRODUCT重构了一些SUMIFS,它似乎有效。 I'm currently looking for an approach to do the refactoring by automated means as there are more than 50 SUMIFS formulae in the sheet. 我目前正在寻找一种通过自动化方法进行重构的方法,因为工作表中有超过50个SUMIFS公式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM