SubTotalTest.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <?php
  2. namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
  3. class SubTotalTest extends AllSetupTeardown
  4. {
  5. /**
  6. * @dataProvider providerSUBTOTAL
  7. *
  8. * @param mixed $expectedResult
  9. * @param mixed $type expect an integer
  10. */
  11. public function testSubtotal($expectedResult, $type): void
  12. {
  13. $this->mightHaveException($expectedResult);
  14. $sheet = $this->getSheet();
  15. $sheet->fromArray([[0], [1], [1], [2], [3], [5], [8], [13], [21], [34], [55], [89]], null, 'A1', true);
  16. $maxCol = $sheet->getHighestColumn();
  17. $maxRow = $sheet->getHighestRow();
  18. $sheet->getCell('D2')->setValue("=SUBTOTAL($type, A1:$maxCol$maxRow)");
  19. $result = $sheet->getCell('D2')->getCalculatedValue();
  20. self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
  21. }
  22. public function providerSUBTOTAL(): array
  23. {
  24. return require 'tests/data/Calculation/MathTrig/SUBTOTAL.php';
  25. }
  26. /**
  27. * @dataProvider providerSUBTOTAL
  28. *
  29. * @param mixed $expectedResult
  30. * @param mixed $type expect an integer
  31. */
  32. public function testSubtotalColumnHidden($expectedResult, $type): void
  33. {
  34. // Hidden columns don't affect calculation, only hidden rows
  35. $this->mightHaveException($expectedResult);
  36. $sheet = $this->getSheet();
  37. $sheet->fromArray([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89], null, 'A1', true);
  38. $maxCol = $sheet->getHighestColumn();
  39. $maxRow = $sheet->getHighestRow();
  40. $hiddenColumns = [
  41. 'A' => false,
  42. 'B' => true,
  43. 'C' => false,
  44. 'D' => true,
  45. 'E' => false,
  46. 'F' => false,
  47. 'G' => false,
  48. 'H' => true,
  49. 'I' => false,
  50. 'J' => true,
  51. 'K' => true,
  52. 'L' => false,
  53. ];
  54. foreach ($hiddenColumns as $col => $hidden) {
  55. $columnDimension = $sheet->getColumnDimension($col);
  56. $columnDimension->setVisible($hidden);
  57. }
  58. $sheet->getCell('D2')->setValue("=SUBTOTAL($type, A1:$maxCol$maxRow)");
  59. $result = $sheet->getCell('D2')->getCalculatedValue();
  60. self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
  61. }
  62. /**
  63. * @dataProvider providerSUBTOTALHIDDEN
  64. *
  65. * @param mixed $expectedResult
  66. * @param mixed $type expect an integer
  67. */
  68. public function testSubtotalRowHidden($expectedResult, $type): void
  69. {
  70. $this->mightHaveException($expectedResult);
  71. $sheet = $this->getSheet();
  72. $sheet->fromArray([[0], [1], [1], [2], [3], [5], [8], [13], [21], [34], [55], [89]], null, 'A1', true);
  73. $maxCol = $sheet->getHighestColumn();
  74. $maxRow = $sheet->getHighestRow();
  75. $visibleRows = [
  76. '1' => false,
  77. '2' => true,
  78. '3' => false,
  79. '4' => true,
  80. '5' => false,
  81. '6' => false,
  82. '7' => false,
  83. '8' => true,
  84. '9' => false,
  85. '10' => true,
  86. '11' => true,
  87. '12' => false,
  88. ];
  89. foreach ($visibleRows as $row => $visible) {
  90. $rowDimension = $sheet->getRowDimension((int) $row);
  91. $rowDimension->setVisible($visible);
  92. }
  93. $sheet->getCell('D2')->setValue("=SUBTOTAL($type, A1:$maxCol$maxRow)");
  94. $result = $sheet->getCell('D2')->getCalculatedValue();
  95. self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
  96. }
  97. public function providerSUBTOTALHIDDEN(): array
  98. {
  99. return require 'tests/data/Calculation/MathTrig/SUBTOTALHIDDEN.php';
  100. }
  101. public function testSubtotalNested(): void
  102. {
  103. $sheet = $this->getSheet();
  104. $sheet->fromArray(
  105. [
  106. [123],
  107. [234],
  108. ['=SUBTOTAL(1,A1:A2)'],
  109. ['=ROMAN(SUBTOTAL(1, A1:A2))'],
  110. ['This is text containing "=" and "SUBTOTAL("'],
  111. ['=AGGREGATE(1, 0, A1:A2)'],
  112. ['=SUM(2, 3)'],
  113. ],
  114. null,
  115. 'A1',
  116. true
  117. );
  118. $maxCol = $sheet->getHighestColumn();
  119. $maxRow = $sheet->getHighestRow();
  120. $sheet->getCell('H1')->setValue("=SUBTOTAL(9, A1:$maxCol$maxRow)");
  121. self::assertEquals(362, $sheet->getCell('H1')->getCalculatedValue());
  122. }
  123. public function testRefError(): void
  124. {
  125. $sheet = $this->getSheet();
  126. $sheet->getCell('A1')->setValue('=SUBTOTAL(9, #REF!)');
  127. self::assertEquals('#REF!', $sheet->getCell('A1')->getCalculatedValue());
  128. }
  129. public function testSecondaryRefError(): void
  130. {
  131. $sheet = $this->getSheet();
  132. $sheet->getCell('A1')->setValue('=SUBTOTAL(9, B1:B9,#REF!,C1:C9)');
  133. self::assertEquals('#REF!', $sheet->getCell('A1')->getCalculatedValue());
  134. }
  135. public function testNonStringSingleCellRefError(): void
  136. {
  137. $sheet = $this->getSheet();
  138. $sheet->getCell('A1')->setValue('=SUBTOTAL(9, 1, C1, Sheet99!A11)');
  139. self::assertEquals('#REF!', $sheet->getCell('A1')->getCalculatedValue());
  140. }
  141. public function testNonStringCellRangeRefError(): void
  142. {
  143. $sheet = $this->getSheet();
  144. $sheet->getCell('A1')->setValue('=SUBTOTAL(9, Sheet99!A1)');
  145. self::assertEquals('#REF!', $sheet->getCell('A1')->getCalculatedValue());
  146. }
  147. }