Initial Implementation of the new Excel TEXTBEFORE() and TEXTAFTER() functions
This commit is contained in:
parent
db57af0c7f
commit
88bfa98291
|
|
@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
|||
|
||||
### Added
|
||||
|
||||
- Nothing
|
||||
- Implementation of the `TEXTBEFORE()` and `TEXTAFTER()` Excel Functions
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
|||
|
|
@ -2490,13 +2490,13 @@ class Calculation
|
|||
],
|
||||
'TEXTAFTER' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [Functions::class, 'DUMMY'],
|
||||
'argumentCount' => '2-4',
|
||||
'functionCall' => [TextData\Extract::class, 'after'],
|
||||
'argumentCount' => '2-6',
|
||||
],
|
||||
'TEXTBEFORE' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [Functions::class, 'DUMMY'],
|
||||
'argumentCount' => '2-4',
|
||||
'functionCall' => [TextData\Extract::class, 'before'],
|
||||
'argumentCount' => '2-6',
|
||||
],
|
||||
'TEXTJOIN' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
|||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
||||
|
||||
class Extract
|
||||
{
|
||||
|
|
@ -95,4 +98,157 @@ class Extract
|
|||
|
||||
return mb_substr($value ?? '', mb_strlen($value ?? '', 'UTF-8') - $chars, $chars, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* TEXTBEFORE.
|
||||
*
|
||||
* @param mixed $text the text that you're searching
|
||||
* Or can be an array of values
|
||||
* @param ?string $delimiter the text that marks the point before which you want to extract
|
||||
* @param mixed $instance The instance of the delimiter after which you want to extract the text.
|
||||
* By default, this is the first instance (1).
|
||||
* A negative value means start searching from the end of the text string.
|
||||
* Or can be an array of values
|
||||
* @param mixed $matchMode Determines whether the match is case-sensitive or not.
|
||||
* 0 - Case-sensitive
|
||||
* 1 - Case-insensitive
|
||||
* Or can be an array of values
|
||||
* @param mixed $matchEnd Treats the end of text as a delimiter.
|
||||
* 0 - Don't match the delimiter against the end of the text.
|
||||
* 1 - Match the delimiter against the end of the text.
|
||||
* Or can be an array of values
|
||||
* @param mixed $ifNotFound value to return if no match is found
|
||||
* The default is a #N/A Error
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return mixed|mixed[] the string extracted from text before the delimiter; or the $ifNotFound value
|
||||
* If an array of values is passed for any of the arguments, then the returned result
|
||||
* will also be an array with matching dimensions
|
||||
*/
|
||||
public static function before($text, $delimiter, $instance = 1, $matchMode = 0, $matchEnd = 0, $ifNotFound = '#N/A')
|
||||
{
|
||||
if (is_array($text) || is_array($instance) || is_array($matchMode) || is_array($matchEnd) || is_array($ifNotFound)) {
|
||||
return self::evaluateArrayArgumentsIgnore([self::class, __FUNCTION__], 1, $text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound);
|
||||
}
|
||||
|
||||
$text = Helpers::extractString($text ?? '');
|
||||
$delimiter = Helpers::extractString(Functions::flattenSingleValue($delimiter ?? ''));
|
||||
$instance = (int) $instance;
|
||||
$matchMode = (int) $matchMode;
|
||||
$matchEnd = (int) $matchEnd;
|
||||
|
||||
$split = self::validateTextBeforeAfter($text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound);
|
||||
if (is_array($split) === false) {
|
||||
return $split;
|
||||
}
|
||||
if ($delimiter === '') {
|
||||
return ($instance > 0) ? '' : $text;
|
||||
}
|
||||
|
||||
// Adjustment for a match as the first element of the split
|
||||
$flags = self::matchFlags($matchMode);
|
||||
$adjust = preg_match('/^' . preg_quote($delimiter) . "\$/{$flags}", $split[0]);
|
||||
$oddReverseAdjustment = count($split) % 2;
|
||||
|
||||
$split = ($instance < 0)
|
||||
? array_slice($split, 0, max(count($split) - (abs($instance) * 2 - 1) - $adjust - $oddReverseAdjustment, 0))
|
||||
: array_slice($split, 0, $instance * 2 - 1 - $adjust);
|
||||
|
||||
return implode('', $split);
|
||||
}
|
||||
|
||||
/**
|
||||
* TEXTAFTER.
|
||||
*
|
||||
* @param mixed $text the text that you're searching
|
||||
* @param ?string $delimiter the text that marks the point before which you want to extract
|
||||
* @param mixed $instance The instance of the delimiter after which you want to extract the text.
|
||||
* By default, this is the first instance (1).
|
||||
* A negative value means start searching from the end of the text string.
|
||||
* Or can be an array of values
|
||||
* @param mixed $matchMode Determines whether the match is case-sensitive or not.
|
||||
* 0 - Case-sensitive
|
||||
* 1 - Case-insensitive
|
||||
* Or can be an array of values
|
||||
* @param mixed $matchEnd Treats the end of text as a delimiter.
|
||||
* 0 - Don't match the delimiter against the end of the text.
|
||||
* 1 - Match the delimiter against the end of the text.
|
||||
* Or can be an array of values
|
||||
* @param mixed $ifNotFound value to return if no match is found
|
||||
* The default is a #N/A Error
|
||||
* Or can be an array of values
|
||||
*
|
||||
* @return mixed|mixed[] the string extracted from text before the delimiter; or the $ifNotFound value
|
||||
* If an array of values is passed for any of the arguments, then the returned result
|
||||
* will also be an array with matching dimensions
|
||||
*/
|
||||
public static function after($text, $delimiter, $instance = 1, $matchMode = 0, $matchEnd = 0, $ifNotFound = '#N/A')
|
||||
{
|
||||
if (is_array($text) || is_array($instance) || is_array($matchMode) || is_array($matchEnd) || is_array($ifNotFound)) {
|
||||
return self::evaluateArrayArgumentsIgnore([self::class, __FUNCTION__], 1, $text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound);
|
||||
}
|
||||
|
||||
$text = Helpers::extractString($text ?? '');
|
||||
$delimiter = Helpers::extractString(Functions::flattenSingleValue($delimiter ?? ''));
|
||||
$instance = (int) $instance;
|
||||
$matchMode = (int) $matchMode;
|
||||
$matchEnd = (int) $matchEnd;
|
||||
|
||||
$split = self::validateTextBeforeAfter($text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound);
|
||||
if (is_array($split) === false) {
|
||||
return $split;
|
||||
}
|
||||
if ($delimiter === '') {
|
||||
return ($instance < 0) ? '' : $text;
|
||||
}
|
||||
|
||||
// Adjustment for a match as the first element of the split
|
||||
$flags = self::matchFlags($matchMode);
|
||||
$adjust = preg_match('/^' . preg_quote($delimiter) . "\$/{$flags}", $split[0]);
|
||||
$oddReverseAdjustment = count($split) % 2;
|
||||
|
||||
$split = ($instance < 0)
|
||||
? array_slice($split, count($split) - (abs($instance + 1) * 2) - $adjust - $oddReverseAdjustment)
|
||||
: array_slice($split, $instance * 2 - $adjust);
|
||||
|
||||
return implode('', $split);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $matchMode
|
||||
* @param int $matchEnd
|
||||
* @param mixed $ifNotFound
|
||||
*
|
||||
* @return string|string[]
|
||||
*/
|
||||
private static function validateTextBeforeAfter(string $text, string $delimiter, int $instance, $matchMode, $matchEnd, $ifNotFound)
|
||||
{
|
||||
$flags = self::matchFlags($matchMode);
|
||||
|
||||
if (preg_match('/' . preg_quote($delimiter) . "/{$flags}", $text) === 0 && $matchEnd === 0) {
|
||||
return $ifNotFound;
|
||||
}
|
||||
|
||||
$split = preg_split('/(' . preg_quote($delimiter) . ")/{$flags}", $text, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
|
||||
if ($split === false) {
|
||||
return ExcelError::NA();
|
||||
}
|
||||
|
||||
if ($instance === 0 || abs($instance) > StringHelper::countCharacters($text)) {
|
||||
return ExcelError::VALUE();
|
||||
}
|
||||
|
||||
if ($matchEnd === 0 && (abs($instance) > floor(count($split) / 2))) {
|
||||
return ExcelError::NA();
|
||||
} elseif ($matchEnd !== 0 && (abs($instance) - 1 > ceil(count($split) / 2))) {
|
||||
return ExcelError::NA();
|
||||
}
|
||||
|
||||
return $split;
|
||||
}
|
||||
|
||||
private static function matchFlags(int $matchMode): string
|
||||
{
|
||||
return ($matchMode === 0) ? 'mu' : 'miu';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,6 +144,8 @@ class Xlfn
|
|||
. '|call'
|
||||
. '|let'
|
||||
. '|register[.]id'
|
||||
. '|textafter'
|
||||
. '|textbefore'
|
||||
. '|valuetotext'
|
||||
. ')(?=\\s*[(])/i';
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
|
||||
class TextAfterTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerTEXTAFTER
|
||||
*/
|
||||
public function testTextAfter(string $expectedResult, array $arguments): void
|
||||
{
|
||||
$text = $arguments[0];
|
||||
$delimiter = $arguments[1];
|
||||
|
||||
$args = 'A1, A2';
|
||||
$args .= (isset($arguments[2])) ? ", {$arguments[2]}" : ',';
|
||||
$args .= (isset($arguments[3])) ? ", {$arguments[3]}" : ',';
|
||||
$args .= (isset($arguments[4])) ? ", {$arguments[4]}" : ',';
|
||||
|
||||
$worksheet = $this->getSheet();
|
||||
$worksheet->getCell('A1')->setValue($text);
|
||||
$worksheet->getCell('A2')->setValue($delimiter);
|
||||
$worksheet->getCell('B1')->setValue("=TEXTAFTER({$args})");
|
||||
|
||||
$result = $worksheet->getCell('B1')->getCalculatedValue();
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerTEXTAFTER(): array
|
||||
{
|
||||
return require 'tests/data/Calculation/TextData/TEXTAFTER.php';
|
||||
}
|
||||
|
||||
public function testTextAfterWithArray(): void
|
||||
{
|
||||
$calculation = Calculation::getInstance();
|
||||
|
||||
$text = "Red Riding Hood's red riding hood";
|
||||
$delimiter = 'red';
|
||||
|
||||
$args = "\"{$text}\", \"{$delimiter}\", 1, {0;1}";
|
||||
|
||||
$formula = "=TEXTAFTER({$args})";
|
||||
$result = $calculation->_calculateFormulaValue($formula);
|
||||
self::assertEquals([[' riding hood'], [" Riding Hood's red riding hood"]], $result);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
|
||||
|
||||
class TextBeforeTest extends AllSetupTeardown
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerTEXTBEFORE
|
||||
*/
|
||||
public function testTextBefore(string $expectedResult, array $arguments): void
|
||||
{
|
||||
$text = $arguments[0];
|
||||
$delimiter = $arguments[1];
|
||||
|
||||
$args = 'A1, A2';
|
||||
$args .= (isset($arguments[2])) ? ", {$arguments[2]}" : ',';
|
||||
$args .= (isset($arguments[3])) ? ", {$arguments[3]}" : ',';
|
||||
$args .= (isset($arguments[4])) ? ", {$arguments[4]}" : ',';
|
||||
|
||||
$worksheet = $this->getSheet();
|
||||
$worksheet->getCell('A1')->setValue($text);
|
||||
$worksheet->getCell('A2')->setValue($delimiter);
|
||||
$worksheet->getCell('B1')->setValue("=TEXTBEFORE({$args})");
|
||||
|
||||
$result = $worksheet->getCell('B1')->getCalculatedValue();
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function providerTEXTBEFORE(): array
|
||||
{
|
||||
return require 'tests/data/Calculation/TextData/TEXTBEFORE.php';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
<?php
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
return [
|
||||
'END Case-sensitive Offset 1' => [
|
||||
"'s red hood",
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset 2' => [
|
||||
'',
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
2,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset -1' => [
|
||||
'',
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
-1,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset -2' => [
|
||||
"'s red hood",
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
-2,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset 3' => [
|
||||
ExcelError::NA(),
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
3,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset -3' => [
|
||||
ExcelError::NA(),
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
-3,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset 3 with end' => [
|
||||
'',
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
3,
|
||||
0,
|
||||
1,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset -3 with end' => [
|
||||
"Red riding hood's red hood",
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
-3,
|
||||
0,
|
||||
1,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive - No Match' => [
|
||||
ExcelError::NA(),
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'HOOD',
|
||||
],
|
||||
],
|
||||
'END Case-insensitive Offset 1' => [
|
||||
"'s red hood",
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'HOOD',
|
||||
1,
|
||||
1,
|
||||
],
|
||||
],
|
||||
'END Case-insensitive Offset 2' => [
|
||||
'',
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'HOOD',
|
||||
2,
|
||||
1,
|
||||
],
|
||||
],
|
||||
'END Offset 0' => [
|
||||
ExcelError::VALUE(),
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
0,
|
||||
],
|
||||
],
|
||||
'Empty match positive' => [
|
||||
"Red riding hood's red hood",
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'',
|
||||
],
|
||||
],
|
||||
'Empty match negative' => [
|
||||
'',
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'',
|
||||
-1,
|
||||
],
|
||||
],
|
||||
'START Case-sensitive Offset 1' => [
|
||||
' riding hood',
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
'red',
|
||||
],
|
||||
],
|
||||
'START Case-insensitive Offset 1' => [
|
||||
" Riding Hood's red riding hood",
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
'red',
|
||||
1,
|
||||
1,
|
||||
],
|
||||
],
|
||||
'START Case-sensitive Offset -2' => [
|
||||
"Red Riding Hood's red riding hood",
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
'red',
|
||||
-2,
|
||||
0,
|
||||
1,
|
||||
],
|
||||
],
|
||||
'START Case-insensitive Offset -2' => [
|
||||
" Riding Hood's red riding hood",
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
'red',
|
||||
-2,
|
||||
1,
|
||||
1,
|
||||
],
|
||||
],
|
||||
[
|
||||
' riding hood',
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
'red',
|
||||
1,
|
||||
0,
|
||||
],
|
||||
],
|
||||
[
|
||||
" Riding Hood's red riding hood",
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
'red',
|
||||
1,
|
||||
1,
|
||||
],
|
||||
],
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
'red',
|
||||
-2,
|
||||
0,
|
||||
1,
|
||||
],
|
||||
],
|
||||
[
|
||||
" Riding Hood's red riding hood",
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
'red',
|
||||
-2,
|
||||
1,
|
||||
1,
|
||||
],
|
||||
],
|
||||
[
|
||||
ExcelError::NA(),
|
||||
[
|
||||
'Socrates',
|
||||
' ',
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
],
|
||||
[
|
||||
'',
|
||||
[
|
||||
'Socrates',
|
||||
' ',
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
<?php
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
return [
|
||||
'END Case-sensitive Offset 1' => [
|
||||
'Red riding ',
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset 2' => [
|
||||
"Red riding hood's red ",
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
2,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset -1' => [
|
||||
"Red riding hood's red ",
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
-1,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset -2' => [
|
||||
'Red riding ',
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
-2,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset 3' => [
|
||||
ExcelError::NA(),
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
3,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset -3' => [
|
||||
ExcelError::NA(),
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
-3,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset 3 with end' => [
|
||||
"Red riding hood's red hood",
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
3,
|
||||
0,
|
||||
1,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive Offset -3 with end' => [
|
||||
'',
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
-3,
|
||||
0,
|
||||
1,
|
||||
],
|
||||
],
|
||||
'END Case-sensitive - No Match' => [
|
||||
ExcelError::NA(),
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'HOOD',
|
||||
],
|
||||
],
|
||||
'END Case-insensitive Offset 1' => [
|
||||
'Red riding ',
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'HOOD',
|
||||
1,
|
||||
1,
|
||||
],
|
||||
],
|
||||
'END Case-insensitive Offset 2' => [
|
||||
"Red riding hood's red ",
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'HOOD',
|
||||
2,
|
||||
1,
|
||||
],
|
||||
],
|
||||
'END Offset 0' => [
|
||||
ExcelError::VALUE(),
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'hood',
|
||||
0,
|
||||
],
|
||||
],
|
||||
'Empty match positive' => [
|
||||
'',
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'',
|
||||
],
|
||||
],
|
||||
'Empty match negative' => [
|
||||
"Red riding hood's red hood",
|
||||
[
|
||||
"Red riding hood's red hood",
|
||||
'',
|
||||
-1,
|
||||
],
|
||||
],
|
||||
'START Case-sensitive Offset 1' => [
|
||||
"Red Riding Hood's ",
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
'red',
|
||||
],
|
||||
],
|
||||
'START Case-insensitive Offset 1' => [
|
||||
'',
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
'red',
|
||||
1,
|
||||
1,
|
||||
],
|
||||
],
|
||||
'START Case-sensitive Offset -2' => [
|
||||
'',
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
'red',
|
||||
-2,
|
||||
0,
|
||||
1,
|
||||
],
|
||||
],
|
||||
'START Case-insensitive Offset -2' => [
|
||||
'',
|
||||
[
|
||||
"Red Riding Hood's red riding hood",
|
||||
'red',
|
||||
-2,
|
||||
1,
|
||||
1,
|
||||
],
|
||||
],
|
||||
[
|
||||
ExcelError::NA(),
|
||||
[
|
||||
'ABACADAEA',
|
||||
'A',
|
||||
6,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
],
|
||||
[
|
||||
'ABACADAEA',
|
||||
[
|
||||
'ABACADAEA',
|
||||
'A',
|
||||
6,
|
||||
0,
|
||||
1,
|
||||
],
|
||||
],
|
||||
[
|
||||
ExcelError::NA(),
|
||||
[
|
||||
'Socrates',
|
||||
' ',
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
],
|
||||
[
|
||||
'Socrates',
|
||||
[
|
||||
'Socrates',
|
||||
' ',
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
],
|
||||
],
|
||||
[
|
||||
'Immanuel',
|
||||
[
|
||||
'Immanuel Kant',
|
||||
' ',
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
],
|
||||
],
|
||||
];
|
||||
Loading…
Reference in New Issue