mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-08-30 12:07:56 +00:00
Implement missing BAHTTEXT function
This commit is contained in:
@@ -525,7 +525,7 @@ Excel Function | PhpSpreadsheet Function
|
||||
-------------------------|--------------------------------------
|
||||
ARRAYTOTEXT | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Text::fromArray
|
||||
ASC | **Not yet Implemented**
|
||||
BAHTTEXT | **Not yet Implemented**
|
||||
BAHTTEXT | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Thai::getBahtText
|
||||
CHAR | \PhpOffice\PhpSpreadsheet\Calculation\TextData\CharacterConvert::character
|
||||
CLEAN | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Trim::nonPrintable
|
||||
CODE | \PhpOffice\PhpSpreadsheet\Calculation\TextData\CharacterConvert::code
|
||||
|
||||
@@ -43,7 +43,7 @@ AVERAGEIFS | STATISTICAL | Statistical\Conditional::AVER
|
||||
|
||||
Excel Function | Category | PhpSpreadsheet Function
|
||||
-------------------------|-----------------------|--------------------------------------
|
||||
BAHTTEXT | TEXT_AND_DATA | **Not yet Implemented**
|
||||
BAHTTEXT | TEXT_AND_DATA | TextData\Thai::getBahtText
|
||||
BASE | MATH_AND_TRIG | MathTrig\Base::evaluate
|
||||
BESSELI | ENGINEERING | Engineering\BesselI::BESSELI
|
||||
BESSELJ | ENGINEERING | Engineering\BesselJ::BESSELJ
|
||||
|
||||
@@ -39,7 +39,7 @@ AVERAGEIFS | CATEGORY_STATISTICAL | \PhpOffice\PhpSpread
|
||||
|
||||
Excel Function | Category | PhpSpreadsheet Function
|
||||
-------------------------|--------------------------------|--------------------------------------
|
||||
BAHTTEXT | CATEGORY_TEXT_AND_DATA | **Not yet Implemented**
|
||||
BAHTTEXT | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Thai::getBahtText
|
||||
BASE | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Base::evaluate
|
||||
BESSELI | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering\BesselI::BESSELI
|
||||
BESSELJ | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering\BesselJ::BESSELJ
|
||||
|
||||
@@ -149,7 +149,7 @@ class FunctionArray extends CalculationBase
|
||||
],
|
||||
'BAHTTEXT' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [Functions::class, 'DUMMY'],
|
||||
'functionCall' => [TextData\Thai::class, 'getBahtText'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'BASE' => [
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
|
||||
class Thai
|
||||
{
|
||||
use ArrayEnabled;
|
||||
|
||||
private const THAI_DIGITS = [
|
||||
0 => 'ศูนย์',
|
||||
1 => 'หนึ่ง',
|
||||
2 => 'สอง',
|
||||
3 => 'สาม',
|
||||
4 => 'สี่',
|
||||
5 => 'ห้า',
|
||||
6 => 'หก',
|
||||
7 => 'เจ็ด',
|
||||
8 => 'แปด',
|
||||
9 => 'เก้า',
|
||||
];
|
||||
|
||||
private const THAI_UNITS = [
|
||||
1 => 'สิบ',
|
||||
2 => 'ร้อย',
|
||||
3 => 'พัน',
|
||||
4 => 'หมื่น',
|
||||
5 => 'แสน',
|
||||
6 => 'ล้าน',
|
||||
];
|
||||
|
||||
private const THAI_COMPOUND_ONE = 'เอ็ด';
|
||||
private const THAI_COMPOUND_TWO = 'ยี่';
|
||||
private const THAI_INTEGER = 'ถ้วน';
|
||||
private const THAI_MINUS = 'ลบ';
|
||||
private const THAI_BAHT = 'บาท';
|
||||
private const THAI_SATANG = 'สตางค์';
|
||||
|
||||
/**
|
||||
* BAHTTEXT.
|
||||
*
|
||||
* @param mixed $number The number or array of numbers to convert
|
||||
*
|
||||
* @return array<mixed>|string If an array of values is passed as the argument, then the returned result will also be an array with the same dimensions
|
||||
*/
|
||||
public static function getBahtText(mixed $number): array|string
|
||||
{
|
||||
if (is_array($number)) {
|
||||
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $number);
|
||||
}
|
||||
|
||||
if (is_string($number) && preg_match('/^-?\d+$/', $number)) {
|
||||
$isNegative = str_starts_with($number, '-');
|
||||
$baht = ltrim($number, '-0') ?: '0';
|
||||
$satang = '00';
|
||||
} elseif (is_bool($number) || is_numeric($number)) {
|
||||
$number += 0;
|
||||
$isNegative = $number < 0;
|
||||
[$baht, $satang] = explode('.', number_format(abs($number), 2, '.', ''));
|
||||
} else {
|
||||
return ExcelError::VALUE();
|
||||
}
|
||||
|
||||
$hasWhole = $baht !== '0';
|
||||
$hasFraction = $satang !== '00';
|
||||
|
||||
if (!$hasWhole && !$hasFraction) {
|
||||
return self::THAI_DIGITS[0] . self::THAI_BAHT . self::THAI_INTEGER;
|
||||
}
|
||||
|
||||
$text = $isNegative
|
||||
? self::THAI_MINUS
|
||||
: '';
|
||||
|
||||
if ($hasWhole) {
|
||||
$text .= self::convertLarge($baht) . self::THAI_BAHT;
|
||||
}
|
||||
|
||||
$text .= $hasFraction
|
||||
? self::convertBlock($satang) . self::THAI_SATANG
|
||||
: self::THAI_INTEGER;
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
private static function convertLarge(string $digits): string
|
||||
{
|
||||
$length = strlen($digits) % 6 ?: 6;
|
||||
|
||||
$chunks = [
|
||||
substr($digits, 0, $length),
|
||||
...str_split(substr($digits, $length), 6),
|
||||
];
|
||||
|
||||
return implode(
|
||||
self::THAI_UNITS[6],
|
||||
array_map(self::convertBlock(...), $chunks)
|
||||
);
|
||||
}
|
||||
|
||||
private static function convertBlock(string $block): string
|
||||
{
|
||||
$out = '';
|
||||
$length = strlen($block);
|
||||
$i = 0;
|
||||
|
||||
// Hundreds and higher powers
|
||||
for ($power = $length - 1; $power >= 2; --$power) {
|
||||
$digit = $block[$i++];
|
||||
if ($digit !== '0') {
|
||||
$out .= self::THAI_DIGITS[$digit] . self::THAI_UNITS[$power];
|
||||
}
|
||||
}
|
||||
|
||||
// Tens
|
||||
$ten = $length > 1 ? $block[$i++] : '0';
|
||||
if ($ten !== '0') {
|
||||
$out .= match ($ten) {
|
||||
'1' => '',
|
||||
'2' => self::THAI_COMPOUND_TWO,
|
||||
default => self::THAI_DIGITS[$ten],
|
||||
} . self::THAI_UNITS[1];
|
||||
}
|
||||
|
||||
// Ones
|
||||
$one = $block[$i] ?? '0';
|
||||
if ($one !== '0') {
|
||||
$out .= $ten !== '0' && $one === '1'
|
||||
? self::THAI_COMPOUND_ONE
|
||||
: self::THAI_DIGITS[$one];
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class BahtTest extends TestCase
|
||||
{
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('providerBAHTTEXT')]
|
||||
public function testBAHTTEXT(mixed $expectedResult, bool|string|float|int $number): void
|
||||
{
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
|
||||
if (is_bool($number)) {
|
||||
$formulaValue = $number ? 'TRUE' : 'FALSE';
|
||||
} elseif (is_string($number)) {
|
||||
$formulaValue = '"' . $number . '"';
|
||||
} else {
|
||||
$formulaValue = (string) $number;
|
||||
}
|
||||
|
||||
$sheet->getCell('A1')->setValue('=BAHTTEXT(' . $formulaValue . ')');
|
||||
$result = $sheet->getCell('A1')->getCalculatedValue();
|
||||
|
||||
self::assertSame($expectedResult, $result);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
public static function providerBAHTTEXT(): array
|
||||
{
|
||||
return require 'tests/data/Calculation/TextData/BAHTTEXT.php';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
[
|
||||
'ศูนย์บาทถ้วน',
|
||||
0,
|
||||
],
|
||||
[
|
||||
'หนึ่งบาทถ้วน',
|
||||
1,
|
||||
],
|
||||
[
|
||||
'สองบาทถ้วน',
|
||||
2,
|
||||
],
|
||||
[
|
||||
'สิบบาทถ้วน',
|
||||
10,
|
||||
],
|
||||
[
|
||||
'สิบเอ็ดบาทถ้วน',
|
||||
11,
|
||||
],
|
||||
[
|
||||
'ยี่สิบเอ็ดบาทถ้วน',
|
||||
21,
|
||||
],
|
||||
[
|
||||
'สี่สิบสองบาทถ้วน',
|
||||
42,
|
||||
],
|
||||
[
|
||||
'หนึ่งร้อยบาทถ้วน',
|
||||
100,
|
||||
],
|
||||
[
|
||||
'หนึ่งพันบาทถ้วน',
|
||||
1000,
|
||||
],
|
||||
[
|
||||
'หนึ่งพันแปดร้อยแปดสิบเจ็ดบาทถ้วน',
|
||||
1887,
|
||||
],
|
||||
[
|
||||
'ห้าสิบสตางค์',
|
||||
0.50,
|
||||
],
|
||||
[
|
||||
'หนึ่งบาทยี่สิบห้าสตางค์',
|
||||
1.25,
|
||||
],
|
||||
[
|
||||
'หนึ่งร้อยยี่สิบสามบาทสี่สิบห้าสตางค์',
|
||||
123.45,
|
||||
],
|
||||
[
|
||||
'หนึ่งพันสองร้อยสามสิบสี่บาทห้าสิบหกสตางค์',
|
||||
1234.56,
|
||||
],
|
||||
[
|
||||
'ลบหนึ่งบาทถ้วน',
|
||||
-1,
|
||||
],
|
||||
[
|
||||
'ลบสี่สิบสามบาทถ้วน',
|
||||
-42.999,
|
||||
],
|
||||
[
|
||||
'ลบเก้าสิบเก้าบาทถ้วน',
|
||||
-99,
|
||||
],
|
||||
[
|
||||
'ลบหนึ่งร้อยยี่สิบสามบาทสี่สิบห้าสตางค์',
|
||||
-123.45,
|
||||
],
|
||||
[
|
||||
'ลบหนึ่งร้อยยี่สิบสามบาทสี่สิบห้าสตางค์',
|
||||
'-123.452',
|
||||
],
|
||||
[
|
||||
'เก้าร้อยแปดสิบเจ็ดล้านหกแสนห้าหมื่นสี่พันสามร้อยยี่สิบเอ็ดล้านเก้าแสนแปดหมื่นเจ็ดพันหกร้อยห้าสิบสี่ล้านสามแสนสองหมื่นหนึ่งพันเก้าร้อยแปดสิบเจ็ดล้านหกแสนห้าหมื่นสี่พันสามร้อยยี่สิบเอ็ดบาทถ้วน',
|
||||
'987654321987654321987654321',
|
||||
],
|
||||
[
|
||||
'หนึ่งบาทถ้วน',
|
||||
true,
|
||||
],
|
||||
[
|
||||
'ศูนย์บาทถ้วน',
|
||||
false,
|
||||
],
|
||||
[
|
||||
'#VALUE!',
|
||||
'ABC',
|
||||
],
|
||||
];
|
||||
Reference in New Issue
Block a user