** แก้ไข 12/5/2014 ปรับปรุงไฟล์รูปภาพ **( ดาวน์โหลดซอร์สโค้ดได้ที่ https://github.com/noomdev/ThaiBaht )
การเขียน Function เพื่อเปลี่ยนจากตัวเลขเป็นตัวอักษร นั้น ถือว่าเป็นเรื่องสุดคลาสสิกที่โปรแกรมเมอร์ทุกคนต้องสามารถ “เขียนได้” ข้อสอบเข้าทำงานของบริษัทต่างๆ ก็มีให้เขียนโปรแกรมแปลงตัวเลขเป็นตัวอักษรทั้งนั้น ดังนั้นจะเป็นการดีไหมที่โปรแกรมทุกคนควรเขียน Function เหล่านี้เอง และทำความเข้าใจ Logic ของโปรแกรมให้ถ่องแท้และปรับแต่งให้ดีสุด ให้โปรแกรมมีขนาดเล็ก และทำงานได้อย่างถูกต้องตามต้องการ ในบทความนี้ผมได้เขียน Function ชื่อ ThaiBaht ขึ้นมา ซึ่งเป็น Function ที่แปลงจากตัวเลขเป็นตัวอักษร เช่น 10 เป็น สิบ, 121 เป็น หนึ่งร้อยยี่สิบเอ็ด, 150.25 เป็น หนึ่งร้อยห้าสิบบาทยี่สิบห้าสตางค์ ตาม Code Listing ด้านล่างนี้
Listing 1 : Function ThaiBaht
Public Shared Function ThaiBaht(ByVal pAmount As Double) As String
If pAmount = 0 Then
Return "ศูนย์บาทถ้วน"
End If
Dim _integerValue As String ' จำนวนเต็ม
Dim _decimalValue As String ' ทศนิยม
Dim _integerTranslatedText As String ' จำนวนเต็ม ภาษาไทย
Dim _decimalTranslatedText As String ' ทศนิยมภาษาไทย
_integerValue = Format(pAmount, "####.00") ' จัด Format ค่าเงินเป็นตัวเลข 2 หลัก
_decimalValue = Mid(_integerValue, Len(_integerValue) - 1, 2) ' ทศนิยม
_integerValue = Mid(_integerValue, 1, Len(_integerValue) - 3) ' จำนวนเต็ม
' แปลง จำนวนเต็ม เป็น ภาษาไทย
_integerTranslatedText = NumberToText(CDbl(_integerValue))
' แปลง ทศนิยม เป็น ภาษาไทย
If CDbl(_decimalValue) = 0 Then
_decimalTranslatedText = NumberToText(CDbl(_decimalValue))
Else
_decimalTranslatedText = ""
End If
' ถ้าไม่มีทศนิม
If _decimalTranslatedText.Trim = "" Then
_integerTranslatedText += "บาทถ้วน"
Else
_integerTranslatedText += "บาท" & _decimalTranslatedText & "สตางค์"
End If
Return _integerTranslatedText
End Function
Listing 2 : Function NumberToText
Private Shared Function NumberToText(ByVal pAmount As Double) As String
' ตัวอักษร
Dim _numberText() As String = {"", "หนึ่ง", "สอง", "สาม", "สี่", "ห้า", "หก", "เจ็ด", "แปด", "เก้า", "สิบ"}
' หลัก หน่วย สิบ ร้อย พัน ...
Dim _digit() As String = {"", "สิบ", "ร้อย", "พัน", "หมื่น", "แสน", "ล้าน"}
Dim _value As String, _aWord As String, _text As String
Dim _numberTranslatedText As String = ""
Dim _length, _digitPosition As Integer
_value = pAmount.ToString
_length = Len(_value) ' ขนาดของ ข้อมูลที่ต้องการแปลง เช่น 122200 มีขนาด เท่ากับ 6
For i As Integer = 0 To _length - 1 ' วนลูป เริ่มจาก 0 จนถึง (ขนาด - 1)
' ตำแหน่งของ หลัก (digit) ของตัวเลข
' เช่น
' ตำแหน่งหลักที่0 (หลักหน่วย)
' ตำแหน่งหลักที่1 (หลักสิบ)
' ตำแหน่งหลักที่2 (หลักร้อย)
' ถ้าเป็นข้อมูล i = 7 ตำแหน่งหลักจะเท่ากับ 1 (หลักสิบ)
' ถ้าเป็นข้อมูล i = 9 ตำแหน่งหลักจะเท่ากับ 3 (หลักพัน)
' ถ้าเป็นข้อมูล i = 13 ตำแหน่งหลักจะเท่ากับ 1 (หลักสิบ)
_digitPosition = i - (6 * ((i - 1) \ 6))
_aWord = Mid(_value, Len(_value) - i, 1)
_text = ""
Select Case _digitPosition
Case 0 ' หลักหน่วย
If _aWord = "1" And _length > 1 Then
' ถ้าเป็นเลข 1 และมีขนาดมากกว่า 1 ให้มีค่าเท่ากับ "เอ็ด"
_text = "เอ็ด"
ElseIf _aWord <> "0" Then
' ถ้าไม่ใช่เลข 0 ให้หา ตัวอักษร ใน _numberText()
_text = _numberText(CInt(_aWord))
End If
Case 1 ' หลักสิบ
If _aWord = "1" Then
' ถ้าเป็นเลข 1 ไม่ต้องมี ตัวอักษร อื่นอีก นอกจากคำว่า "สิบ"
'_numberTranslatedText = "สิบ" + _numberTranslatedText
_text = _digit(_digitPosition)
ElseIf _aWord = "2" Then
' ถ้าเป็นเลข 2 ให้ตัวอักษรคือ "ยี่สิบ"
_text = "ยี่" + _digit(_digitPosition)
ElseIf _aWord <> "0" Then
' ถ้าไม่ใช่เลข 0 ให้หา ตัวอักษร ใน _numberText() และหาหลัก(digit) ใน _digit()
_text = _numberText(CInt(_aWord)) + _digit(_digitPosition)
End If
Case 2, 3, 4, 5 ' หลักร้อย ถึง แสน
If _aWord <> "0" Then
_text = _numberText(CInt(_aWord)) + _digit(_digitPosition)
End If
Case 6 ' หลักล้าน
If _aWord = "0" Then
_text = "ล้าน"
ElseIf _aWord = "1" And _length - 1 > i Then
_text = "เอ็ดล้าน"
Else
_text = _numberText(CInt(_aWord)) + _digit(_digitPosition)
End If
End Select
_numberTranslatedText = _text + _numberTranslatedText
Next
Return _numberTranslatedText
End Function
อธิบาย
Function ThaiBaht เป็น function หลักในการทำงาน โดยมีหน้าที่จัดรูปแบบจำนวนเงินที่ส่งเข้ามาซึ่งมี data type เป็น double โดยทำการเปลี่ยนเป็น string ที่มีทศนิยม 2 หลัก และทำการแยกข้อมูล ตัวเลขจำนวนเต็ม กับ ตัวเลขทศนิยม ออกจากกัน จากนั้นจึงส่งข้อมูล ตัวเลขจำนวนเต็ม และ ตัวเลขทศนิยม ไปยัง function NumberToText ทีละตัว แล้วนำข้อความตัวอักษรมารวมกัน (concat) อีกครั้งก่อน return ตัวอักษรกลับไปทั้งหมด
ทดลองใช้งาน
1.สร้าง class ชื่อ sample.vb ใน Visual Basic .NET 2005 โดยมี function ทั้ง 2 ข้างต้น
2.สร้าง Form1 ให้มีหน้าตาตามรูป
3.เขียน code ดังนี้
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show(Sample.ThaiBaht(TextBox1.Text))
End Sub
4.ลอง run และทดสอบผลลัพธ์
ลองนำไปประยุกต์และปรับปรุงได้ตามความเหมาะสมนะครับ
-- NooM --
16 comments:
ขอบคุณครับ
มีประโยชน์กับผมมากเลย
เขียนได้ดีครับ
เดียวจะลองเอาไปใช้ มีอะไรผิดพลาดจะแจ้งให้ทราบนะครับ
thk a lot
แปลงข้อมลจากตัวเลขเป็นตัวอักษร ได้แล้ว แต่การนำมาใช้ คือ กรอกตัวเลขลงText ให้อีกText เป็นตัวอักษรได้ แต่ตอนบันทึกข้อมูล มันขึ้น Error ว่า Conversion from string "" to type 'Double' is not valid.
จะแก้ error ยังไงค่ะ
ขอบคุณค่ะ
ขอโทษครับทีตอบช้าไป
Error ที่บอกมากนั้นเกิดจากมันส่งค่าว่าง "" ไปแปลงเป็น Double ครับ ซึ่งมันแปลงไม่ได้ครับ
คุณควรตรวจสอบค่าก่อนว่าหากเป็น "" ให้กำหนดเป็น "0.00" ก่อนก็ได้ครับ
คุณหน่องกอง
ยินดีน้อมรับข้อผิดพลาดครับ
;-)
พี่ค่ะ พอดีทำโปรเจ็คเกี่ยวกับ กองทุนหมู่บ้าน
มันต้องฝากเงิน แต่พอดีมีปัญหา ว่ามันฝากซ้ำเลขที่สมาชิกเดิมไม่ได้ ทำไงดี
คือต้องเก็บทุกครั้งที่ฝาก
ขอบคุณค่ะ
คุณ 111
แล้วทำไมจึงฝากซ้ำเลขสมาชิกเดิมไม่ได้ล่ะครับ
ขอบพระคุณมากครับ
ขอบคุณมาก
ผมไม่เข้าใจตรง
_digitPosition = i - (6 * ((i - 1) \ 6)) อะครับ ผมลองคิดแล้วยังไงออกมาก็เท่ากับ 1 ตลอดอะครับ หรือผมเข้าใจอะไรผิดหรือป่าวครับ
เครื่องหมาย \ เป็นการหารเอาผลลัพธ์จำนวนเต็มเท่านั้น ดังนั้น
ถ้า i = 1
i - (6 * ((i - 1) \ 6))
= 1 - (6 * ((1 - 1) \ 6))
= 1 - (6 * 0)
= 1 - 0
= 1
ถ้า i = 7
i - (6 * ((i - 1) \ 6))
= 7 - (6 * ((7 - 1) \ 6))
= 7 - (6 * ((6) \ 6))
= 7 - (6 * 1)
= 1
ถ้า i = 3
i - (6 * ((i - 1) \ 6))
= 3 - (6 * ((3 - 1) \ 6))
= 3 - (6 * ((2) \ 6))
= 3 - (6 * 0)
= 3
ถ้า i = 8
i - (6 * ((i - 1) \ 6))
= 8 - (6 * ((8 - 1) \ 6))
= 8 - (6 * ((7) \ 6))
= 8 - (6 * 1)
= 2
thankyou naka
very good
ขอบคุณมากเลยนะครับ
ยังคิดอยู่เลยว่าถ้าต้องทำ function แบบนี้เอง
จะรอดมั้ยนะ (แต่ดูแล้วไม่น่ารอด ^,^)
ขอบคุณอีกครั้งครับ
ขอบคุณมาก ๆ จากใจจริงครับสำหรับความรู้ที่แบ่งปัน
วันใดที่ผมเขียนโปรแกรมเก่ง ผมจะนึกถึงบุญคุณผู้เขียนบทความดีๆแบบนี้ให้อ่าน
ขอบคุณจากใจจริงครับ
สวัสดีคับผม ผมมีเรื่องปรึกษาเกี่ยวกับ โปรแกรมแปลง ตัวเลขเป็นตัวอักษร ในVB ที่พี่เคยทำไว้อ่ะคับ http://noomdev.blogspot.com/2007/08/function-visual-basic.html ผมอยากจะสอบถามว่าพี่ใช้แกรมม่าอะไรในการเขียนอ่ะคับ โปรแกรมของพี่เป็นแนวทางให้ผมได้พัฒนาต่อเป็นโปรเจคของวิชา compiler อ่ะคับ รบกวนด้วยนะคับ ขอขอบพระคุณล่วงหน้าคับผม
Post a Comment