PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.10.8
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.10.8
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 3.10.4 All 148 releases
visualizer / vendor / phpoffice / phpspreadsheet / src / PhpSpreadsheet / Calculation / Database.php

Database.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.10.8, at vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Database.php

633 lines 30.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace PhpOffice\PhpSpreadsheet\Calculation;
4
5 class Database
6 {
7 /**
8 * fieldExtract.
9 *
10 * Extracts the column ID to use for the data field.
11 *
12 * @param mixed[] $database The range of cells that makes up the list or database.
13 * A database is a list of related data in which rows of related
14 * information are records, and columns of data are fields. The
15 * first row of the list contains labels for each column.
16 * @param mixed $field Indicates which column is used in the function. Enter the
17 * column label enclosed between double quotation marks, such as
18 * "Age" or "Yield," or a number (without quotation marks) that
19 * represents the position of the column within the list: 1 for
20 * the first column, 2 for the second column, and so on.
21 *
22 * @return null|string
23 */
24 private static function fieldExtract($database, $field)
25 {
26 $field = strtoupper(Functions::flattenSingleValue($field));
27 $fieldNames = array_map('strtoupper', array_shift($database));
28
29 if (is_numeric($field)) {
30 $keys = array_keys($fieldNames);
31
32 return $keys[$field - 1];
33 }
34 $key = array_search($field, $fieldNames);
35
36 return ($key) ? $key : null;
37 }
38
39 /**
40 * filter.
41 *
42 * Parses the selection criteria, extracts the database rows that match those criteria, and
43 * returns that subset of rows.
44 *
45 * @param mixed[] $database The range of cells that makes up the list or database.
46 * A database is a list of related data in which rows of related
47 * information are records, and columns of data are fields. The
48 * first row of the list contains labels for each column.
49 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
50 * You can use any range for the criteria argument, as long as it
51 * includes at least one column label and at least one cell below
52 * the column label in which you specify a condition for the
53 * column.
54 *
55 * @return array of mixed
56 */
57 private static function filter($database, $criteria)
58 {
59 $fieldNames = array_shift($database);
60 $criteriaNames = array_shift($criteria);
61
62 // Convert the criteria into a set of AND/OR conditions with [:placeholders]
63 $testConditions = $testValues = [];
64 $testConditionsCount = 0;
65 foreach ($criteriaNames as $key => $criteriaName) {
66 $testCondition = [];
67 $testConditionCount = 0;
68 foreach ($criteria as $row => $criterion) {
69 if ($criterion[$key] > '') {
70 $testCondition[] = '[:' . $criteriaName . ']' . Functions::ifCondition($criterion[$key]);
71 ++$testConditionCount;
72 }
73 }
74 if ($testConditionCount > 1) {
75 $testConditions[] = 'OR(' . implode(',', $testCondition) . ')';
76 ++$testConditionsCount;
77 } elseif ($testConditionCount == 1) {
78 $testConditions[] = $testCondition[0];
79 ++$testConditionsCount;
80 }
81 }
82
83 if ($testConditionsCount > 1) {
84 $testConditionSet = 'AND(' . implode(',', $testConditions) . ')';
85 } elseif ($testConditionsCount == 1) {
86 $testConditionSet = $testConditions[0];
87 }
88
89 // Loop through each row of the database
90 foreach ($database as $dataRow => $dataValues) {
91 // Substitute actual values from the database row for our [:placeholders]
92 $testConditionList = $testConditionSet;
93 foreach ($criteriaNames as $key => $criteriaName) {
94 $k = array_search($criteriaName, $fieldNames);
95 if (isset($dataValues[$k])) {
96 $dataValue = $dataValues[$k];
97 $dataValue = (is_string($dataValue)) ? Calculation::wrapResult(strtoupper($dataValue)) : $dataValue;
98 $testConditionList = str_replace('[:' . $criteriaName . ']', $dataValue, $testConditionList);
99 }
100 }
101 // evaluate the criteria against the row data
102 $result = Calculation::getInstance()->_calculateFormulaValue('=' . $testConditionList);
103 // If the row failed to meet the criteria, remove it from the database
104 if (!$result) {
105 unset($database[$dataRow]);
106 }
107 }
108
109 return $database;
110 }
111
112 private static function getFilteredColumn($database, $field, $criteria)
113 {
114 // reduce the database to a set of rows that match all the criteria
115 $database = self::filter($database, $criteria);
116 // extract an array of values for the requested column
117 $colData = [];
118 foreach ($database as $row) {
119 $colData[] = $row[$field];
120 }
121
122 return $colData;
123 }
124
125 /**
126 * DAVERAGE.
127 *
128 * Averages the values in a column of a list or database that match conditions you specify.
129 *
130 * Excel Function:
131 * DAVERAGE(database,field,criteria)
132 *
133 * @category Database Functions
134 *
135 * @param mixed[] $database The range of cells that makes up the list or database.
136 * A database is a list of related data in which rows of related
137 * information are records, and columns of data are fields. The
138 * first row of the list contains labels for each column.
139 * @param int|string $field Indicates which column is used in the function. Enter the
140 * column label enclosed between double quotation marks, such as
141 * "Age" or "Yield," or a number (without quotation marks) that
142 * represents the position of the column within the list: 1 for
143 * the first column, 2 for the second column, and so on.
144 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
145 * You can use any range for the criteria argument, as long as it
146 * includes at least one column label and at least one cell below
147 * the column label in which you specify a condition for the
148 * column.
149 *
150 * @return float
151 */
152 public static function DAVERAGE($database, $field, $criteria)
153 {
154 $field = self::fieldExtract($database, $field);
155 if ($field === null) {
156 return null;
157 }
158
159 // Return
160 return Statistical::AVERAGE(
161 self::getFilteredColumn($database, $field, $criteria)
162 );
163 }
164
165 /**
166 * DCOUNT.
167 *
168 * Counts the cells that contain numbers in a column of a list or database that match conditions
169 * that you specify.
170 *
171 * Excel Function:
172 * DCOUNT(database,[field],criteria)
173 *
174 * Excel Function:
175 * DAVERAGE(database,field,criteria)
176 *
177 * @category Database Functions
178 *
179 * @param mixed[] $database The range of cells that makes up the list or database.
180 * A database is a list of related data in which rows of related
181 * information are records, and columns of data are fields. The
182 * first row of the list contains labels for each column.
183 * @param int|string $field Indicates which column is used in the function. Enter the
184 * column label enclosed between double quotation marks, such as
185 * "Age" or "Yield," or a number (without quotation marks) that
186 * represents the position of the column within the list: 1 for
187 * the first column, 2 for the second column, and so on.
188 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
189 * You can use any range for the criteria argument, as long as it
190 * includes at least one column label and at least one cell below
191 * the column label in which you specify a condition for the
192 * column.
193 *
194 * @return int
195 *
196 * @TODO The field argument is optional. If field is omitted, DCOUNT counts all records in the
197 * database that match the criteria.
198 */
199 public static function DCOUNT($database, $field, $criteria)
200 {
201 $field = self::fieldExtract($database, $field);
202 if ($field === null) {
203 return null;
204 }
205
206 // Return
207 return Statistical::COUNT(
208 self::getFilteredColumn($database, $field, $criteria)
209 );
210 }
211
212 /**
213 * DCOUNTA.
214 *
215 * Counts the nonblank cells in a column of a list or database that match conditions that you specify.
216 *
217 * Excel Function:
218 * DCOUNTA(database,[field],criteria)
219 *
220 * @category Database Functions
221 *
222 * @param mixed[] $database The range of cells that makes up the list or database.
223 * A database is a list of related data in which rows of related
224 * information are records, and columns of data are fields. The
225 * first row of the list contains labels for each column.
226 * @param int|string $field Indicates which column is used in the function. Enter the
227 * column label enclosed between double quotation marks, such as
228 * "Age" or "Yield," or a number (without quotation marks) that
229 * represents the position of the column within the list: 1 for
230 * the first column, 2 for the second column, and so on.
231 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
232 * You can use any range for the criteria argument, as long as it
233 * includes at least one column label and at least one cell below
234 * the column label in which you specify a condition for the
235 * column.
236 *
237 * @return int
238 *
239 * @TODO The field argument is optional. If field is omitted, DCOUNTA counts all records in the
240 * database that match the criteria.
241 */
242 public static function DCOUNTA($database, $field, $criteria)
243 {
244 $field = self::fieldExtract($database, $field);
245 if ($field === null) {
246 return null;
247 }
248
249 // reduce the database to a set of rows that match all the criteria
250 $database = self::filter($database, $criteria);
251 // extract an array of values for the requested column
252 $colData = [];
253 foreach ($database as $row) {
254 $colData[] = $row[$field];
255 }
256
257 // Return
258 return Statistical::COUNTA(
259 self::getFilteredColumn($database, $field, $criteria)
260 );
261 }
262
263 /**
264 * DGET.
265 *
266 * Extracts a single value from a column of a list or database that matches conditions that you
267 * specify.
268 *
269 * Excel Function:
270 * DGET(database,field,criteria)
271 *
272 * @category Database Functions
273 *
274 * @param mixed[] $database The range of cells that makes up the list or database.
275 * A database is a list of related data in which rows of related
276 * information are records, and columns of data are fields. The
277 * first row of the list contains labels for each column.
278 * @param int|string $field Indicates which column is used in the function. Enter the
279 * column label enclosed between double quotation marks, such as
280 * "Age" or "Yield," or a number (without quotation marks) that
281 * represents the position of the column within the list: 1 for
282 * the first column, 2 for the second column, and so on.
283 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
284 * You can use any range for the criteria argument, as long as it
285 * includes at least one column label and at least one cell below
286 * the column label in which you specify a condition for the
287 * column.
288 *
289 * @return mixed
290 */
291 public static function DGET($database, $field, $criteria)
292 {
293 $field = self::fieldExtract($database, $field);
294 if ($field === null) {
295 return null;
296 }
297
298 // Return
299 $colData = self::getFilteredColumn($database, $field, $criteria);
300 if (count($colData) > 1) {
301 return Functions::NAN();
302 }
303
304 return $colData[0];
305 }
306
307 /**
308 * DMAX.
309 *
310 * Returns the largest number in a column of a list or database that matches conditions you that
311 * specify.
312 *
313 * Excel Function:
314 * DMAX(database,field,criteria)
315 *
316 * @category Database Functions
317 *
318 * @param mixed[] $database The range of cells that makes up the list or database.
319 * A database is a list of related data in which rows of related
320 * information are records, and columns of data are fields. The
321 * first row of the list contains labels for each column.
322 * @param int|string $field Indicates which column is used in the function. Enter the
323 * column label enclosed between double quotation marks, such as
324 * "Age" or "Yield," or a number (without quotation marks) that
325 * represents the position of the column within the list: 1 for
326 * the first column, 2 for the second column, and so on.
327 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
328 * You can use any range for the criteria argument, as long as it
329 * includes at least one column label and at least one cell below
330 * the column label in which you specify a condition for the
331 * column.
332 *
333 * @return float
334 */
335 public static function DMAX($database, $field, $criteria)
336 {
337 $field = self::fieldExtract($database, $field);
338 if ($field === null) {
339 return null;
340 }
341
342 // Return
343 return Statistical::MAX(
344 self::getFilteredColumn($database, $field, $criteria)
345 );
346 }
347
348 /**
349 * DMIN.
350 *
351 * Returns the smallest number in a column of a list or database that matches conditions you that
352 * specify.
353 *
354 * Excel Function:
355 * DMIN(database,field,criteria)
356 *
357 * @category Database Functions
358 *
359 * @param mixed[] $database The range of cells that makes up the list or database.
360 * A database is a list of related data in which rows of related
361 * information are records, and columns of data are fields. The
362 * first row of the list contains labels for each column.
363 * @param int|string $field Indicates which column is used in the function. Enter the
364 * column label enclosed between double quotation marks, such as
365 * "Age" or "Yield," or a number (without quotation marks) that
366 * represents the position of the column within the list: 1 for
367 * the first column, 2 for the second column, and so on.
368 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
369 * You can use any range for the criteria argument, as long as it
370 * includes at least one column label and at least one cell below
371 * the column label in which you specify a condition for the
372 * column.
373 *
374 * @return float
375 */
376 public static function DMIN($database, $field, $criteria)
377 {
378 $field = self::fieldExtract($database, $field);
379 if ($field === null) {
380 return null;
381 }
382
383 // Return
384 return Statistical::MIN(
385 self::getFilteredColumn($database, $field, $criteria)
386 );
387 }
388
389 /**
390 * DPRODUCT.
391 *
392 * Multiplies the values in a column of a list or database that match conditions that you specify.
393 *
394 * Excel Function:
395 * DPRODUCT(database,field,criteria)
396 *
397 * @category Database Functions
398 *
399 * @param mixed[] $database The range of cells that makes up the list or database.
400 * A database is a list of related data in which rows of related
401 * information are records, and columns of data are fields. The
402 * first row of the list contains labels for each column.
403 * @param int|string $field Indicates which column is used in the function. Enter the
404 * column label enclosed between double quotation marks, such as
405 * "Age" or "Yield," or a number (without quotation marks) that
406 * represents the position of the column within the list: 1 for
407 * the first column, 2 for the second column, and so on.
408 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
409 * You can use any range for the criteria argument, as long as it
410 * includes at least one column label and at least one cell below
411 * the column label in which you specify a condition for the
412 * column.
413 *
414 * @return float
415 */
416 public static function DPRODUCT($database, $field, $criteria)
417 {
418 $field = self::fieldExtract($database, $field);
419 if ($field === null) {
420 return null;
421 }
422
423 // Return
424 return MathTrig::PRODUCT(
425 self::getFilteredColumn($database, $field, $criteria)
426 );
427 }
428
429 /**
430 * DSTDEV.
431 *
432 * Estimates the standard deviation of a population based on a sample by using the numbers in a
433 * column of a list or database that match conditions that you specify.
434 *
435 * Excel Function:
436 * DSTDEV(database,field,criteria)
437 *
438 * @category Database Functions
439 *
440 * @param mixed[] $database The range of cells that makes up the list or database.
441 * A database is a list of related data in which rows of related
442 * information are records, and columns of data are fields. The
443 * first row of the list contains labels for each column.
444 * @param int|string $field Indicates which column is used in the function. Enter the
445 * column label enclosed between double quotation marks, such as
446 * "Age" or "Yield," or a number (without quotation marks) that
447 * represents the position of the column within the list: 1 for
448 * the first column, 2 for the second column, and so on.
449 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
450 * You can use any range for the criteria argument, as long as it
451 * includes at least one column label and at least one cell below
452 * the column label in which you specify a condition for the
453 * column.
454 *
455 * @return float
456 */
457 public static function DSTDEV($database, $field, $criteria)
458 {
459 $field = self::fieldExtract($database, $field);
460 if ($field === null) {
461 return null;
462 }
463
464 // Return
465 return Statistical::STDEV(
466 self::getFilteredColumn($database, $field, $criteria)
467 );
468 }
469
470 /**
471 * DSTDEVP.
472 *
473 * Calculates the standard deviation of a population based on the entire population by using the
474 * numbers in a column of a list or database that match conditions that you specify.
475 *
476 * Excel Function:
477 * DSTDEVP(database,field,criteria)
478 *
479 * @category Database Functions
480 *
481 * @param mixed[] $database The range of cells that makes up the list or database.
482 * A database is a list of related data in which rows of related
483 * information are records, and columns of data are fields. The
484 * first row of the list contains labels for each column.
485 * @param int|string $field Indicates which column is used in the function. Enter the
486 * column label enclosed between double quotation marks, such as
487 * "Age" or "Yield," or a number (without quotation marks) that
488 * represents the position of the column within the list: 1 for
489 * the first column, 2 for the second column, and so on.
490 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
491 * You can use any range for the criteria argument, as long as it
492 * includes at least one column label and at least one cell below
493 * the column label in which you specify a condition for the
494 * column.
495 *
496 * @return float
497 */
498 public static function DSTDEVP($database, $field, $criteria)
499 {
500 $field = self::fieldExtract($database, $field);
501 if ($field === null) {
502 return null;
503 }
504
505 // Return
506 return Statistical::STDEVP(
507 self::getFilteredColumn($database, $field, $criteria)
508 );
509 }
510
511 /**
512 * DSUM.
513 *
514 * Adds the numbers in a column of a list or database that match conditions that you specify.
515 *
516 * Excel Function:
517 * DSUM(database,field,criteria)
518 *
519 * @category Database Functions
520 *
521 * @param mixed[] $database The range of cells that makes up the list or database.
522 * A database is a list of related data in which rows of related
523 * information are records, and columns of data are fields. The
524 * first row of the list contains labels for each column.
525 * @param int|string $field Indicates which column is used in the function. Enter the
526 * column label enclosed between double quotation marks, such as
527 * "Age" or "Yield," or a number (without quotation marks) that
528 * represents the position of the column within the list: 1 for
529 * the first column, 2 for the second column, and so on.
530 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
531 * You can use any range for the criteria argument, as long as it
532 * includes at least one column label and at least one cell below
533 * the column label in which you specify a condition for the
534 * column.
535 *
536 * @return float
537 */
538 public static function DSUM($database, $field, $criteria)
539 {
540 $field = self::fieldExtract($database, $field);
541 if ($field === null) {
542 return null;
543 }
544
545 // Return
546 return MathTrig::SUM(
547 self::getFilteredColumn($database, $field, $criteria)
548 );
549 }
550
551 /**
552 * DVAR.
553 *
554 * Estimates the variance of a population based on a sample by using the numbers in a column
555 * of a list or database that match conditions that you specify.
556 *
557 * Excel Function:
558 * DVAR(database,field,criteria)
559 *
560 * @category Database Functions
561 *
562 * @param mixed[] $database The range of cells that makes up the list or database.
563 * A database is a list of related data in which rows of related
564 * information are records, and columns of data are fields. The
565 * first row of the list contains labels for each column.
566 * @param int|string $field Indicates which column is used in the function. Enter the
567 * column label enclosed between double quotation marks, such as
568 * "Age" or "Yield," or a number (without quotation marks) that
569 * represents the position of the column within the list: 1 for
570 * the first column, 2 for the second column, and so on.
571 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
572 * You can use any range for the criteria argument, as long as it
573 * includes at least one column label and at least one cell below
574 * the column label in which you specify a condition for the
575 * column.
576 *
577 * @return float
578 */
579 public static function DVAR($database, $field, $criteria)
580 {
581 $field = self::fieldExtract($database, $field);
582 if ($field === null) {
583 return null;
584 }
585
586 // Return
587 return Statistical::VARFunc(
588 self::getFilteredColumn($database, $field, $criteria)
589 );
590 }
591
592 /**
593 * DVARP.
594 *
595 * Calculates the variance of a population based on the entire population by using the numbers
596 * in a column of a list or database that match conditions that you specify.
597 *
598 * Excel Function:
599 * DVARP(database,field,criteria)
600 *
601 * @category Database Functions
602 *
603 * @param mixed[] $database The range of cells that makes up the list or database.
604 * A database is a list of related data in which rows of related
605 * information are records, and columns of data are fields. The
606 * first row of the list contains labels for each column.
607 * @param int|string $field Indicates which column is used in the function. Enter the
608 * column label enclosed between double quotation marks, such as
609 * "Age" or "Yield," or a number (without quotation marks) that
610 * represents the position of the column within the list: 1 for
611 * the first column, 2 for the second column, and so on.
612 * @param mixed[] $criteria The range of cells that contains the conditions you specify.
613 * You can use any range for the criteria argument, as long as it
614 * includes at least one column label and at least one cell below
615 * the column label in which you specify a condition for the
616 * column.
617 *
618 * @return float
619 */
620 public static function DVARP($database, $field, $criteria)
621 {
622 $field = self::fieldExtract($database, $field);
623 if ($field === null) {
624 return null;
625 }
626
627 // Return
628 return Statistical::VARP(
629 self::getFilteredColumn($database, $field, $criteria)
630 );
631 }
632 }
633