HLookupTest.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <?php
  2. namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;
  3. use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
  4. use PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
  5. use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
  6. use PhpOffice\PhpSpreadsheet\NamedRange;
  7. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  8. use PHPUnit\Framework\TestCase;
  9. class HLookupTest extends TestCase
  10. {
  11. /**
  12. * @dataProvider providerHLOOKUP
  13. *
  14. * @param mixed $expectedResult
  15. * @param mixed $lookup
  16. * @param mixed $rowIndex
  17. */
  18. public function testHLOOKUP($expectedResult, $lookup, array $values, $rowIndex, ?bool $rangeLookup = null): void
  19. {
  20. $spreadsheet = new Spreadsheet();
  21. $sheet = $spreadsheet->getActiveSheet();
  22. $maxRow = 0;
  23. $maxCol = 0;
  24. $maxColLetter = 'A';
  25. $row = 0;
  26. foreach ($values as $rowValues) {
  27. ++$row;
  28. ++$maxRow;
  29. $col = 0;
  30. if (!is_array($rowValues)) {
  31. $rowValues = [$rowValues];
  32. }
  33. foreach ($rowValues as $cellValue) {
  34. ++$col;
  35. $colLetter = Coordinate::stringFromColumnIndex($col);
  36. if ($col > $maxCol) {
  37. $maxCol = $col;
  38. $maxColLetter = $colLetter;
  39. }
  40. if ($cellValue !== null) {
  41. $sheet->getCell("$colLetter$row")->setValue($cellValue);
  42. }
  43. }
  44. }
  45. $boolArg = self::parseRangeLookup($rangeLookup);
  46. $sheet->getCell('ZZ8')->setValue($lookup);
  47. $sheet->getCell('ZZ7')->setValue($rowIndex);
  48. $sheet->getCell('ZZ1')->setValue("=HLOOKUP(ZZ8, A1:$maxColLetter$maxRow, ZZ7$boolArg)");
  49. self::assertEquals($expectedResult, $sheet->getCell('ZZ1')->getCalculatedValue());
  50. $spreadsheet->disconnectWorksheets();
  51. }
  52. private static function parseRangeLookup(?bool $rangeLookup): string
  53. {
  54. if ($rangeLookup === null) {
  55. return '';
  56. }
  57. return $rangeLookup ? ', true' : ', false';
  58. }
  59. public function providerHLOOKUP(): array
  60. {
  61. return require 'tests/data/Calculation/LookupRef/HLOOKUP.php';
  62. }
  63. public function testGrandfathered(): void
  64. {
  65. // Second parameter is supposed to be array of arrays.
  66. // Some old tests called function directly using array of strings;
  67. // ensure these work as before.
  68. $expectedResult = '#REF!';
  69. $result = LookupRef::HLOOKUP(
  70. 'Selection column',
  71. ['Selection column', 'Value to retrieve'],
  72. 5,
  73. false
  74. );
  75. self::assertSame($expectedResult, $result);
  76. $expectedResult = 'Value to retrieve';
  77. $result = LookupRef::HLOOKUP(
  78. 'Selection column',
  79. ['Selection column', 'Value to retrieve'],
  80. 2,
  81. false
  82. );
  83. self::assertSame($expectedResult, $result);
  84. }
  85. /**
  86. * @dataProvider providerHLookupNamedRange
  87. */
  88. public function testHLookupNamedRange(string $expectedResult, string $cellAddress): void
  89. {
  90. $lookupData = [
  91. ['Rating', 1, 2, 3, 4],
  92. ['Level', 'Poor', 'Average', 'Good', 'Excellent'],
  93. ];
  94. $formData = [
  95. ['Category', 'Rating', 'Level'],
  96. ['Service', 2, '=HLOOKUP(C5,Lookup_Table,2,FALSE)'],
  97. ['Quality', 3, '=HLOOKUP(C6,Lookup_Table,2,FALSE)'],
  98. ['Value', 4, '=HLOOKUP(C7,Lookup_Table,2,FALSE)'],
  99. ['Cleanliness', 3, '=HLOOKUP(C8,Lookup_Table,2,FALSE)'],
  100. ];
  101. $spreadsheet = new Spreadsheet();
  102. $worksheet = $spreadsheet->getActiveSheet();
  103. $worksheet->fromArray($lookupData, null, 'F4');
  104. $worksheet->fromArray($formData, null, 'B4');
  105. $spreadsheet->addNamedRange(new NamedRange('Lookup_Table', $worksheet, '=$G$4:$J$5'));
  106. $result = $worksheet->getCell($cellAddress)->getCalculatedValue();
  107. self::assertEquals($expectedResult, $result);
  108. }
  109. public function providerHLookupNamedRange(): array
  110. {
  111. return [
  112. ['Average', 'D5'],
  113. ['Good', 'D6'],
  114. ['Excellent', 'D7'],
  115. ['Good', 'D8'],
  116. ];
  117. }
  118. /**
  119. * @dataProvider providerHLookupArray
  120. */
  121. public function testHLookupArray(array $expectedResult, string $values, string $database, string $index): void
  122. {
  123. $calculation = Calculation::getInstance();
  124. $formula = "=HLOOKUP({$values}, {$database}, {$index}, false)";
  125. $result = $calculation->_calculateFormulaValue($formula);
  126. self::assertEquals($expectedResult, $result);
  127. }
  128. public function providerHLookupArray(): array
  129. {
  130. return [
  131. 'row vector #1' => [
  132. [[4, 9]],
  133. '{"Axles", "Bolts"}',
  134. '{"Axles", "Bearings", "Bolts"; 4, 4, 9; 5, 7, 10; 6, 8, 11}',
  135. '2',
  136. ],
  137. 'row vector #2' => [
  138. [[5, 7]],
  139. '{"Axles", "Bearings"}',
  140. '{"Axles", "Bearings", "Bolts"; 4, 4, 9; 5, 7, 10; 6, 8, 11}',
  141. '3',
  142. ],
  143. 'row/column vectors' => [
  144. [[4, 9], [5, 10]],
  145. '{"Axles", "Bolts"}',
  146. '{"Axles", "Bearings", "Bolts"; 4, 4, 9; 5, 7, 10; 6, 8, 11}',
  147. '{2; 3}',
  148. ],
  149. ];
  150. }
  151. }