Click here to Skip to main content
15,881,882 members
Articles / Programming Languages / Visual Basic

Money DataType

Rate me:
Please Sign up or sign in to vote.
4.56/5 (12 votes)
4 Sep 200510 min read 115.5K   1.1K   49  
An article on creating a Money datatype with localized formatting and plugin conversion support.
''' <summary>
''' A FormatProvider specific to the Money structure, which will format the 
''' Money value the word representation.
''' </summary>
''' <remarks></remarks>
Public Class MoneyWordFormatter
    Implements ICustomFormatter, IFormatProvider

    Private _result As Text.StringBuilder

    Public Function Format(ByVal formatString As String, ByVal arg As Object, ByVal formatProvider As System.IFormatProvider) As String Implements System.ICustomFormatter.Format
        If TypeOf arg Is Money Then
            Dim mny As Money = CType(arg, Money)
            Return ValueToWords(mny)
        ElseIf TypeOf arg Is Decimal Then
            Return ValueToWords(New Money(arg))
        End If
        Return ""
    End Function

    Public Function GetFormat(ByVal formatType As System.Type) As Object Implements System.IFormatProvider.GetFormat
        If formatType Is GetType(ICustomFormatter) Then
            Return Me
        Else
            Return Nothing
        End If
    End Function

    Private Function ValueToWords(ByVal value As Money) As String
        Dim nfi As New NumberFormatInfo
        nfi.NumberGroupSeparator = ""

        Dim temp As String = Math.Abs(value.Value).ToString("N2", nfi)
        Dim m As Decimal = Decimal.Parse(temp)
        _result = New Text.StringBuilder
        If Math.Abs(m) < 1 Then
            _result.Append("No")
        Else
            temp = temp.PadLeft(15, "0"c)

            SubProcess(0, temp, "Billion")
            SubProcess(3, temp, "Million")
            SubProcess(6, temp, "Thousand")

            Dim number As Integer = Integer.Parse(temp.Substring(9, 3))
            If number > 0 And number < 100 Then
                If _result.ToString.Length > 0 Then
                    _result.Append("And ")
                End If
            End If
            SubProcess(9, temp)
        End If

        If Not _result.ToString.EndsWith(" ") Then
            _result.Append(" ")
        End If
        _result.Append("Dollar")
        If Decimal.Truncate(m) <> 1 Then
            _result.Append("s ")
        Else
            _result.Append(" ")
        End If

        Dim cents As Integer = 0
        Dim input As String = "000"
        input = temp.Substring(temp.IndexOf(".") + 1).PadRight(2, "0"c)
        If input.Length > 6 Then
            input = input.Substring(0, 6)
        End If
        cents = Integer.Parse(input)
        If cents = 0 Then
            _result.Append("And No")
        Else
            _result.Append("And ")
            SubProcess(0, input)
        End If
        If cents = 1 Then
            _result.Append(" Cent")
        Else
            _result.Append(" Cents")
        End If
        Return _result.ToString
    End Function

    Private Sub SubProcess(ByVal start As Integer, ByVal value As String, Optional ByVal wordToAdd As String = "")
        Dim input As String = value.PadLeft(3, "0").Substring(start, 3)
        Dim number As Integer = Integer.Parse(input)
        If number <> 0 Then
            ConvertInput(input)
            If wordToAdd.Length > 0 Then
                If Not _result.ToString.EndsWith(" "c) Then _result.Append(" ")
                _result.Append(wordToAdd)
                _result.Append(" ")
            End If
        End If
    End Sub

    Private Sub ConvertInput(ByVal input As String)
        Dim hundred As Integer = Integer.Parse(input.PadLeft(3, "0"c).Substring(0, 1))
        If hundred > 0 Then
            AppendLiteral(hundred)
            _result.Append(" Hundred")
        End If
        Dim tens As Integer = Integer.Parse(input.PadLeft(3, "0"c).Substring(1, 2))
        If hundred > 0 AndAlso tens > 0 Then
            _result.Append(" And ")
        End If
        AppendLiteral(tens)
    End Sub

    Private Sub AppendLiteral(ByVal index As Integer)
        If index < 20 Then
            _result.Append(GetString(index))
        Else
            Dim tens As Integer = Convert.ToInt32(index \ 10) * 10
            _result.Append(GetString(tens))
            If index > tens Then
                index -= tens
                _result.Append(" ")
                _result.Append(GetString(index))
            End If
        End If
    End Sub

    Private Function GetString(ByVal value As Integer) As String
        Select Case value
            Case 0
                Return ""
            Case Is < 10
                Return Choose(value, "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine")
            Case 11 To 19
                Return Choose(value - 10, "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen")
            Case Else
                Return Choose(value \ 10, "Ten", "Twenty", "Thirty", "Fourty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety")
        End Select
    End Function
End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions