スプレッドシートをエクスポートし、手動で入力してから、システムに再度インポートする必要があるプロジェクトに取り組んでいます。私はPHPExcelを使用してすべてのハードワークを行っています。
スプレッドシートは基本的に、回答が必要な一連の質問です。(スプレッドシートの例をここからダウンロードできます)。各質問への回答は、名前付き範囲を使用して別のシート (回答) から取得されたデータ検証リストにあります。質問と回答の両方に一意の ID が付いているので、結果を簡単にデータベースに読み込むことができます。
questionID は列 B に格納され、スプレッドシートの作成時に挿入されます。ただし、answerID は、選択された回答に応じて変化するため、ルックアップ (列 C) を介して行われます。回答の各セットには、リスト内の回答用とルックアップ用の 2 つの名前付き範囲があります。これらの名前付き範囲には、answers_questionID およびanswers_lookup_questionID というラベルが付けられています。ルックアップ値を取得するために列 C で使用される式は次のとおりです。
=INDEX(answers_lookup_1, MATCH(E6, answers_1, 0),2)
データをアルファベット順に並べ替えたくないので、VLOOKUP の代わりに INDEX と MATCH を使用しています。
これはすべてスプレッドシートで正常に機能します。問題があるのは、スプレッドシートを読み戻そうとしたときです。値を読み戻そうとすると、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で機能するため、私の数式に問題はないようです。
- 数式のより単純なバージョンを試してみましたが、それらは機能します。つまり、複数のセルを合計します。
- 両方のシートは、読み取り時に存在します。
- すべての名前付き範囲は、読み取り時に適切に設定されています。
- v 1.7.4 を使用していますが、1.7.9 までのすべてのバージョンを試しました (1.8.0 はスプレッドシートを読み取れません)。
Mark Baker は、式のテストを実行するように私に依頼しました。
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
)
数式の複数のバリエーションとデータの読み取り方法を試しました。データをループし、toArray() の代わりに getCalculatedValue() を使用しましたが、同じ結果が得られました。
これは、 Functions.phpのINDEX関数内のバグである可能性があり、名前付き範囲を使用して読み込まれたときに式が正しく解釈されていないとしか思えません。渡された配列を INDEX() に出力すると、結果は次のようになります。
INDEX: Array
(
[12] => Array
(
[A] =>
[B] => 6
)
[13] => Array
(
[A] =>
[B] => 7
)
[14] => Array
(
[A] =>
[B] => 8
)
)
これは正しい値です (ただし、スプレッドシートにあるように A 列に入力する必要があるかどうかはわかりません)、つまり、はい、いいえ、および N/A...
あなたがここまで来たら、ありがとう、うまくいけば、あなたは私を正しい方向に導くか、助けてくれるでしょう.
とても有難い、
アダム。