用PHPExcel读取包含命名范围的公式结果

问题描述 投票:3回答:1

我正在一个项目中,我需要导出电子表格,手动填充它,然后再次将其重新导入系统。我正在使用PHPExcel来完成所有艰苦的工作。

电子表格基本上是一组需要回答的问题。 (You can download an example of the spreadsheet here)。每个问题的答案都在Data Validation List中,该数据来自另一个使用命名范围的工作表(答案)。问题和答案都带有唯一的ID,因此我可以轻松地将结果读回数据库。

问题ID存储在B列中,并在创建电子表格时插入。但是,答案ID是通过查找(在C列中)完成的,因为答案ID会根据所选答案而变化。每组答案都有两个命名范围,分别是列表中的答案和一个查找范围。这些命名的范围分别标记为Answers_questionID和Answers_lookup_questionID。 C列中用于获取查找值的公式为:

=INDEX(answers_lookup_1, MATCH(E6, answers_1, 0),2)

我使用INDEX和MATCH而不是VLOOKUP,因为我不想按字母顺序对数据进行排序。

这在电子表格中都可以正常工作,就是当我尝试重新阅读该文件时,我遇到了问题。当我尝试读回值时,要么得到0(它们都应为正整数),要么得到#REF!

这是我读回数据时正在做的事情:

$objPHPExcel = new PHPExcel();

// Set a read filter so that we can restrict what we're loading in
class MyReadFilter implements PHPExcel_Reader_IReadFilter {
    private $_iStartRow = 0;
    private $_iEndRow = 0;
    private $_aColumns = array();

    public function __construct($iStartRow, $iEndRow, $aColumns) {
        $this->_iStartRow   = $iStartRow;
        $this->_iEndRow     = $iEndRow;
        $this->_aColumns    = $aColumns;
    }

    public function readCell($iCol, $iRow, $sWorksheetName = '') {
        if ($iRow >= $this->_iStartRow && $iRow <= $this->_iEndRow) {
            if (in_array($iCol, $this->_aColumns)) {
                return true;
            }
        }
        return false;
    }
}

$objFilterSubset = new MyReadFilter(5, 500, range('B', 'L'));

// Which type of reader do we need.
if (!extension_loaded('zip')) dl('php_zip.dll');
$objReader = new PHPExcel_Reader_Excel2007();

// Set the read filter so we don't get EVERYTHING
$objReader->setReadFilter($objFilterSubset);

// Load the actual data
$objPHPExcel = $objReader->load($sFilename);

// Store the data in an array
$aSheetNames = $objPHPExcel->getSheetNames();

foreach ($aSheetNames as $iSheetNum => $sSheetName) {
    $objPHPExcel->setActiveSheetIndex($iSheetNum);
    $aSheetData[$sSheetName] = $objPHPExcel->getActiveSheet()->toArray(null,true,true,false);
}

所以我得到了一个很好的大数组,其中包含所有数据,只有C列是错误的。

  • 我的公式在excel中工作似乎没有什么问题。
  • 我尝试了更简单的公式版本,它们可以将多个单元格加在一起。
  • 阅读时都有两张纸。
  • 所有命名范围在阅读时都已设置好。
  • 我正在使用1.7.4版,但我已经尝试了所有版本至1.7.9(1.8.0甚至没有在电子表格中读取)。

[马克·贝克(Mark Ba​​ker)要求我运行一个公式测试,该测试可以在here中找到,如果有人可以理解,它可以进行以下调试。

Formula Value is =INDEX(answers_lookup_1, MATCH(E6, answers_1, 0),2)
Expected Value is 7 Parser Stack :-

Array (
[0] => Array
    (
        [type] => Value
        [value] => answers_lookup_1
        [reference] =>
    )

[1] => Array
    (
        [type] => Cell Reference
        [value] => E6
        [reference] => E6
    )

[2] => Array
    (
        [type] => Value
        [value] => answers_1
        [reference] => 
    )

[3] => Array
    (
        [type] => Value
        [value] => 0
        [reference] => 
    )

[4] => Array
    (
        [type] => Operand Count for Function MATCH()
        [value] => 3
        [reference] => 
    )

[5] => Array
    (
        [type] => Function
        [value] => MATCH(
        [reference] => 
    )

[6] => Array
    (
        [type] => Value
        [value] => 2
        [reference] => 
    )

[7] => Array
    (
        [type] => Operand Count for Function INDEX()
        [value] => 3
        [reference] => 
    )

[8] => Array
    (
        [type] => Function
        [value] => INDEX(
        [reference] => 
    )

)

Calculated Value is 0

Evaluation Log:
Array
(
    [0] => Questions!C6 -> Evaluating Named Range answers_lookup_1
    [1] => Questions!C6 -> Evaluation Result for named range A4:B6 is a matrix with a value of { , ; , 7; , 8 }
    [2] => Questions!C6 -> Evaluating Cell E6 in current worksheet
    [3] => Questions!C6 -> Evaluation Result for cell Questions!E6 is a string with a value of Yes
    [4] => Questions!C6 -> Evaluating Named Range answers_1
    [5] => Questions!C6 -> Evaluation Result for named range A4:A6 is a matrix with a value of { ; ;  }
    [6] => Questions!C6 -> Evaluating Function MATCH() with 3 arguments
    [7] => Questions!C6 -> Evaluating MATCH( Yes, { ; ;  }, 0 )
    [8] => Questions!C6 -> Evaluation Result for MATCH() function call is a #N/A error
    [9] => Questions!C6 -> Evaluating Function INDEX() with 3 arguments
    [10] => Questions!C6 -> Evaluating INDEX( { , ; , 7; , 8 }, #N/A, 2 )
    [11] => Questions!C6 -> Evaluation Result for INDEX() function call is a null value
)

我已经尝试了公式的多种变体以及读取数据的方式。我遍历了数据并使用getCalculatedValue()而不是toArray(),但仍然得到相同的结果。

我只能认为这可能是Functions.phpINDEX函数内的一个错误,并且在使用命名范围读取该公式时不能正确解释该公式。如果我将传递的数组输出到INDEX(),结果为:

INDEX: Array
(
    [12] => Array
    (
        [A] =>
        [B] => 6
    )
    [13] => Array
    (
        [A] =>
        [B] => 7
    )
    [14] => Array
    (
        [A] =>
        [B] => 8
    )
)

这是正确的值(尽管我不确定是否应该像在电子表格中一样填充A列),即是,否和不适用...

如果您已经走了这么远,谢谢,希望您能为我提供帮助或指出正确的方向。

非常感谢,

亚当

php phpexcel phpexcelreader
1个回答
0
投票

类似函数INDEX不能将单元格引用作为第二个参数处理

@@ -604,10 +604,13 @@ class PHPExcel_Calculation_LookupRef
         }

         if (!is_array($arrayValues)) {
             return PHPExcel_Calculation_Functions::REF();
         }
+        
+        $lrow = PHPExcel_Calculation_Functions::flattenSingleValue($rowNum); 
+        $rowNum = $lrow;

         $rowKeys = array_keys($arrayValues);
         $columnKeys = @array_keys($arrayValues[$rowKeys[0]]);

         if ($columnNum > count($columnKeys)) {
© www.soinside.com 2019 - 2024. All rights reserved.