Thảo luận Về chuyển đổi số thành chữ

malemkhoang

Rìu Sắt
Cuối năm, lại phải làm mấy chứng từ thanh toán. Chợt nhận ra cái vụ “Viết bằng chữ…” kia thật mệt mỏi quá chừng, vntools, Acchelper…, Phạm Văn Trung/Phạm Trung (Bình Dương), Nguyễn Tiến Thùy (Hải Phòng), tươi hơn thì có của Nguyễn Thanh Hải (Tiền Giang)…cập nhật tháng 11-2017; trực tuyến thì có bambu ngố: tienich.bambu.vn, khongbiet.vn…; đều bị giới hạn không 12 chữ số thì 15 chữ số, chị Gu gồ thì được 18 chữ số; cũng chẳng cần tham vọng lớn quá làm gì.

Kimkhadotcom thì lý luận rằng: Chúng ta có thể nhận thấy rằng các chữ số thường được chia ra thành nhiều block (tỷ, triệu, nghìn, đơn vị), và người ta sẽ thêm một hậu tố ở sau mỗi block. Mỗi block đó có cách đọc hoàn toàn giống nhau (trăm, chục, đơn vị). Như vậy, cách đọc số là tách số ra thành nhiều block, rồi gọi hàm đọc từng block sau đó thêm hậu tố vào là xong. Nhưng cũng chỉ được 15 chữ số.

Tổng hợp mấy cái thứ đó lại, thì mình cũng đọc được 18 chữ số như chị mu gồ… à nhầm… Gu gồ. Tuy nhiên, mình dùng AutoIT cho nó có hơi hướng nguồn mở một tí, code đây:
;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include <Array.au3>
#include <File.au3>
#include <MsgBoxConstants.au3>
#include <String.au3>
#include "FileConstants.au3"
#include "StringConstants.au3"
;=============================
Local $chia9
Local $lop[6]
Local $llop[3]
Local $solieu
Local $sl
Local $slg
Local $sl9
Local $chia3
Local $du
Local $tg = ""
Local $tb = " (kết quả có trong ClipBoard)"
;///////////////// BEGIN \\\\\\\\\\\\\\\\\\\\\
;nhập số
$solieu = Inputbox("ĐỌC SỐ - CHỮ", "Nhập số:")
;chuyển sang dạng chuỗi
$sl = String($solieu)
;quá lớn
If StringLen($sl) > 18 then
MsgBox($MB_SYSTEMMODAL, "ĐỔI SỐ THÀNH CHỮ", $solieu & " > 18 chữ số." & @CRLF & "Nhiều tiền thế, sao mà ăn hết được.")
Exit
Endif
;tách 9 số, đọc Max 18 số như chị Gu gồ
If StringLen($sl) > 12 then
$du = Mod(StringLen($sl), 9)
If $du > 0 then
$sl = _StringRepeat("\", (9 - $du)) & $sl
Endif
$chia9 = StringLen($sl) / 9
;$llop[0] = $chia9
$sl9 = $sl
For $i = 1 to $chia9
$llop[$i] = StringLeft($sl9, 9)
$sl9 = StringTrimLeft($sl9, 9)
$llop[$i] = StringReplace($llop[$i], "\", "")
Next
;_ArrayDisplay($llop, "2D display")
;dùng hàm đọc 9 số
For $i = 1 to $chia9
$tg = $llop[$i]
$llop[$i] = doc9($tg, $i)
Next
$slg = $slg & $llop[1] & $llop[2] & " đồng."
$slg = StringStripWS($slg, $STR_STRIPLEADING + $STR_STRIPTRAILING + $STR_STRIPSPACES)
ClipPut($slg)
MsgBox($MB_SYSTEMMODAL, "Thành tiền", "SỐ: " & $solieu & $tb & ", đọc là:" & @CRLF & $slg)
Exit
Endif
;tách cụm 3 số, đọc Max 12 số (dưới nghìn tỷ)
$du = Mod(StringLen($sl), 3)
Select
Case $du = 1
$sl = "\\" & $sl
Case $du = 2
$sl = "\" & $sl
EndSelect
$chia3 = StringLen($sl) / 3
;$lop[0] = $chia3
;Vòng lặp tách cụm 3 số từ phải sang trái
For $i = 1 to $chia3
$lop[$i] = StringRight($sl, 3)
$sl = StringTrimRight($sl, 3)
$lop[$i] = StringReplace($lop[$i], "\", "")
Next
;_ArrayDisplay($lop, "2D display")
For $i = 1 to $chia3
$tg = $lop[$i]
$lop[$i] = doclop($tg, $i)
Next
;ghép kết quả cuối cùng
For $i = $chia3 to 1 Step -1
$slg = $slg & $lop[$i]
Next
$slg = StringStripWS($slg, $STR_STRIPLEADING + $STR_STRIPTRAILING + $STR_STRIPSPACES) & " đồng."
ClipPut($slg)
MsgBox($MB_SYSTEMMODAL, "Thành tiền", "SỐ: " & $solieu & $tb & ", đọc là:" & @CRLF & $slg)
;////////////////// END \\\\\\\\\\\\\\\
Func danhvan($X)
;đánh vần từng con số
Select
Case $X = 0
Return "không"
Case $X = 1
Return "một"
Case $X = 2
Return "hai"
Case $X = 3
Return "ba"
Case $X = 4
Return "bốn"
Case $X = 5
Return "năm"
Case $X = 6
Return "sáu"
Case $X = 7
Return "bảy"
Case $X = 8
Return "tám"
Case $X = 9
Return "chín"
EndSelect
EndFunc
;///////////////////////////////////////////
Func doccum($cum)
;Đọc 3 số
;$cum chứa từ 1 đến 3 chữ số
Local $du
Local $hang[4]
Local $slcum
Local $k = ""
$slcum = $cum
$du = Mod(StringLen($cum), 3)
Select
Case $du = 1
$slcum = "\\" & $slcum
Case $du = 2
$slcum = "\" & $slcum
EndSelect
;
For $i = 1 to 3
$hang[$i] = StringLeft($slcum, 1)
$slcum = StringTrimLeft($slcum, 1)
$hang[$i] = StringReplace($hang[$i], "\", "")
Next
;trăm
If $hang[1] <> "" then
If $hang[1] = 0 AND $hang[2] = 0 AND $hang[3] = 0 then
$k = $k & ""
Else
$k = $k & danhvan($hang[1]) & " trăm "
Endif
Endif
;chục
If $hang[2] <> "" then
Select
Case $hang[2] = 0
If ($hang[3] > 0) then
$k = $k & "linh "
Endif
Case $hang[2] = 1
$k = $k & "mười"
Case $hang[2] > 1
$k = $k & danhvan($hang[2]) & " mươi "
EndSelect
Endif
;đơn vị
Select
Case $hang[3] = 0
If ($hang[1] = "") AND ($hang[2] = "") then
$k = $k & "không"
Endif
Case $hang[3] = 1
If $hang[2] > 1 then
$k = $k & " mốt"
Else
$k = $k & " " & danhvan($hang[3])
Endif
Case $hang[3] = 5
If $hang[2] > 0 then
$k = $k & " lăm "
Else
$k = $k & " " & danhvan($hang[3])
Endif
Case Else
$k = $k & danhvan($hang[3])
EndSelect
Return $k
EndFunc
;////////////////////////////////////////////
Func doclop($cum, $class)
;đọc đúng lớp tương ứng, lớp có 3 chữ số
Local $kq = ""
Select
Case $class = 1
If $cum <> "000" then
$kq = $kq & doccum($cum) & ""
Endif
Case $class = 2
If $cum <> "000" then
$kq = $kq & doccum($cum) & " nghìn "
Endif
Case $class = 3
If $cum <> "000" then
$kq = $kq & doccum($cum) & " triệu "
Endif
Case $class = 4
$kq = $kq & doccum($cum) & " tỷ, "
EndSelect
Return $kq
Endfunc
;///////////////////////////////////////////
Func doc9($s9, $lan)
Local $d9
Local $sl9
Local $chia39
Local $lop9[6]
Local $tg9
Local $slg9
$sl9 = $s9
$d9 = Mod(StringLen($sl9), 3)
Select
Case $d9 = 1
$sl9 = "\\" & $sl9
Case $d9 = 2
$sl9 = "\" & $sl9
EndSelect
$chia39 = StringLen($sl9) / 3
;$lop9[0] = $chia39
;Vòng lặp tách cụm 3 số từ phải sang trái
For $i = 1 to $chia39
$lop9[$i] = StringRight($sl9, 3)
$sl9 = StringTrimRight($sl9, 3)
$lop9[$i] = StringReplace($lop9[$i], "\", "")
Next
;đọc xong lưu luôn vào phần tử mảng tương ứng
For $i = 1 to $chia39
$tg9 = $lop9[$i]
$lop9[$i] = doclop($tg9, $i)
Next
;ghép kết quả cuối cùng
For $i = $chia39 to 1 Step -1
$slg9 = $slg9 & $lop9[$i]
Next
If $lan = 1 then
$slg9 = $slg9 & " tỷ, "
Endif
Return $slg9
Endfunc
;\\\\\\\\\\\\ XONG ////////////
Bonus:
Ai dùng tiện ích Excel của Nguyễn Thanh Hải thì dùng mã sau đây:
"001001ax"
đăng ký mà dùng dài dài nha.
 
Tin công nghệ
Liên Hệ và Hợp Tác

Top