Bug ของ Calc ใน OpenOffice.org 3.1.0 (BahtText)

BahtText() เป็นฟังก์ชั่นที่เพิ่มขึ้นใหม่ใน Calc .ในชุด OpenOffice.org รุ่น 3.1.0 เพื่อแสดงจำนวนเงินเป็นตัวอักษรภาษาไทย ซึ่งเป็นฟังก์ชั่นมาตรฐานในชุด MS Office ภาษาไทยอย่างไรก็ตาม จากการทดลองใช้งานพบว่ายังมี Bug อยู่ โดยเมื่อจำนวนเงินมีค่าตั้งแต่ 1,000,000,000,000.00 (หนึ่งล้านล้านบาทถ้วน) ขึ้นไป จนถึง 9,999,999,999,999.97 (เก้าล้านเก้าแสนเก้าหมื่นเก้าพันเก้าร้อยเก้าสิบเก้าล้านเก้าแสนเก้าหมื่นเก้าพันเก้าร้อยเก้าสิบเก้าบาทเก้าสิบเจ็สตางค์-เฮ้อ เหนื่อย :-| ) จะมีสตางต์เพิ่มขึ้นมาอีก 1 สตางค์ดังภาพOpenOffice 3.1.0 Calc Bug BahtText()และถ้าจำนวนเงิน 9,999,999,999,999.98 ถึง 9,999,999,999,999.99 บาท จะถูกปัดขึ้นเป็น สิบล้านส้านบาทถ้วนซึ่งการใช้งานทั่วไปคงไม่มีผลกระทบมากนัก เพราะจำนวนเงินค่อนข้างสูง แต่อย่างไรก็ตาม มันก็อยู่ในช่วงกว้างพอสมควร และควรต้องได้รับการแก้ไขการแก้ไขปัญหานี้เราต้องเขียน OpenOffice Basic Macro ดังต่อไปนี้  เพื่อสร้างฟังก์ชั่นที่ใช้ทดแทน โดยเรียกใช้แบบเดียวกัน แต่เปลี่ยนชื่อเป็น ThBahtText(Number) เช่น ThBahtText(125.25) หรือ ThBahtText(a1) โดยมีความแม่นยำถึง 999,999,999,999,999.00 บาท

'-----------------------------
' Function: ThBahtText
' Purpose: converts a number to a string that spells out the number in Thai
'-----------------------------
Function ThBahtText(InputCurrency As Double) As String
    Dim InputCal as Double
    Dim DecimalNum, FractionNum, DecNumBackup as Double
    Dim SatangText,ResultText, NegText as String
    Dim FractionLng as Long
    Dim DLoopCount as Integer
    InputCal = InputCurrency
    DecNumBackup = 0
    DLoopCount = 0
    ThBahtText = ""
    NegText = ""
    ResultText = ""
    SatangText = ""
    if InputCurrency = 0.00 then
        ThBahtText = "ศูนย์บาทถ้วน"
    else
        if InputCurrency < 0.00 then
            NegText = "ลบ"
            InputCal = Abs(InputCal)
        end if
        ' To be create ThBahtText String
        ' Extract Decimal and Fractional Part
        FractionNum = InputCal - Int(InputCal)
        DecimalNum = InputCal - FractionNum
'        MsgBox "FractionNum = " + FractionNum + Chr(13) + "DecimalNum = " + DecimalNum + Chr(13) + "InputCal = " + InputCal
        ' Round down to 2 decimal point
        FractionLng = CLng(CDbl(FractionNum) * 100)
        ' Generate Satang Text or 0(Zero) Satang (ถ้วน)
        if FractionLng = 0 then
            SatangText = "ถ้วน"
        else
            SatangText = ThaiSpellNumber(FractionLng) + "สตางค์"
        end if
        ' Reset for reusing of variable
        FractionNum = 0.0
        FractionLng = CLng(FractionNum)
        DecNumBackup = DecimalNum
        DLoopCount = 0
        do while DecimalNum >= (10^6)     ' Over 6 digit (6 Million)
            ' 10 Million or more
            DLoopCount = DLoopCount + 1
            DecimalNum = CDbl(DecimalNum) / (10^6)
            FractionNum = DecimalNum - Fix(DecimalNum)
            DecimalNum = DecimalNum - FractionNum
            FractionLng = CLng(FractionNum * (10^6))
'            MsgBox "FractionNum = " + FractionNum + Chr(13) + "FractionLng = " + FractionLng + Chr(13) + "DecimalNum = " + DecimalNum
            if FractionLng = 0 then
                ' Skip word "ศูนย์"
                ResultText = "ล้าน" + ResultText
            else
'                if FractionLng = 1 then
                    ' Change to word "หนึ่ง"
'                    ResultText = "ล้าน" + "เอ็ด" + ResultText
'                else
                    ResultText = "ล้าน" + ThaiSpellNumber(FractionLng) + ResultText
'                endif
            end if
'            MsgBox "ResultText = " + ResultText
        loop
        if DloopCount = 0 then
            ResultText = ResultText + ThaiSpellNumber(DecimalNum)
        else
            ResultText = ThaiSpellNumber(CLng(DecimalNum)) + ResultText
        end if
        ResultText = NegText + ResultText + "บาท"
        ThBahtText = ResultText + SatangText
    end if
End Function

' ----------------------------
' Convert Currency Number to Thai String
' Special limit : Not exceed 7 digit (Million).
' ----------------------------
Function ThaiSpellNumber(InputCurrency as Long) as String
    Dim NumArray, MultiArray as Variant
    Dim Edd, Yee, ThStr, NegText as String
    Dim InCurrency, iCal as Long
    Dim iCounter,iCalMod as Integer

    NumArray = Array("","หนึ่ง","สอง","สาม","สี่","ห้า","หก","เจ็ด","แปด","เก้า")
    MultiArray = Array("","สิบ","ร้อย","พัน","หมื่น","แสน","ล้าน")
    Zuun = "ศูนย์"
    Edd = "เอ็ด"
    Yee = "ยี่"

    NegText = ""
    ThStr = ""

    InCurrency = InputCurrency
    iCal = InCurrency
    iCalMod = 0

    if iCal < 0 then
        NegText = "ลบ"
        iCal = CLng(Abs(iCal))
        InCurrency = CLng(Abs(InCurrency))
    end if

    if iCal < 10 then
        if iCal = 0 Then
            ThStr = Zuun
        else
            ThStr = NumArray(iCal)
        end if
    else
        ' 10 or More
        iCounter = 1
        do while iCounter > 0
            iCounter = 0
            do while iCal > 9
                iCalMod = iCal mod 10
                iCal = Int(iCal/10)
                iCounter = iCounter + 1
            loop

            if iCounter = 1 and (iCal = 1 or iCal = 2) then
                ' 10 and 20
                if iCal = 1 then
                    ' Not include "หนึ่ง" in string when 10-19
'                    MsgBox "ThStr = " + ThStr + Chr(13) + "MultiArray = " + MultiArray(iCounter)
                    ThStr = ThStr + MultiArray(iCounter)
                else
                    ' iCal = 2  ----> Change "สอง" to "ยี่" when 20-29
'                    MsgBox "ThStr = " + ThStr + Chr(13) + "MultiArray = " + MultiArray(iCounter)
                    ThStr = ThStr + Yee + MultiArray(iCounter)
                end if
            else
                if iCounter = 0 and iCal = 1 then
                    ThStr = ThStr + Edd
                else
                    ThStr = ThStr + NumArray(iCal) + MultiArray(iCounter)
                endif
            end if

            iCal = InCurrency - (iCal * (10 ^ (iCounter)))
            InCurrency = iCal
        loop
    end if
    ThaiSpellNumber = NegText + ThStr   
End Function

ใน Code จะมีบางส่วนที่เป็น Comment Out ที่ใช้สำหรับการตรวจสอบหาจุดผิดพลาด ในระหว่างการเขียนโปรแกรมหลงเหลืออยู่ ซึ่งไม่มีผลกระทบกับการทำงานแต่อย่างใด

Comments

Bug ทศนิยมไม่รู้จบของเลขฐาน 2 อิอิอิ ผมเคยรันโปรแกรมดังต่อไปนี้ แล้ว Bug นะครับให้ I เท่ากับ 0ตราบเท่าที่  I  ไม่เท่ากับ 1 ให้ทำสิ่งต่อไปนี้ I = I + 0.1 จาก pseudo code จะเห็นว่ามันเป็น Loop อนันต์ :P เคยทำผมปวดหัวไป 3 วัน หา bug ไม่เจอ 55+