Skip to content

Instantly share code, notes, and snippets.

@wqweto
Last active March 13, 2016 18:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wqweto/d7ca68a5fd0368c08158 to your computer and use it in GitHub Desktop.
Save wqweto/d7ca68a5fd0368c08158 to your computer and use it in GitHub Desktop.
Конвертиране на число в словом с думи за VB.NET. По подразбиране работи за левове в мъжки род, но може да се използва и за мярка в женски род (например метро единици) или среден род (например евро)
Module ToWordsModule
Public Function ToWords(ByVal dblValue As Double, Optional Measure As Object = Nothing, Optional Gender As String = Nothing) As String
Dim vDigits As Object
Dim vGenderDigits As Object
Dim vValue As Object
Dim lIdx As Long
Dim lDigit As Long
Dim sResult As String = ""
Dim sString As New String("0", 18)
'--- init digits (incl. gender ones)
vDigits = Split("нула едно две три четири пет шест седем осем девет")
vGenderDigits = vDigits.Clone()
Select Case Left$(Gender, 1)
Case String.Empty, "M"
vGenderDigits(1) = "един"
vGenderDigits(2) = "два"
Case "F"
vGenderDigits(1) = "една"
End Select
'--- split input value on decimal point and pad w/ zeroes
vValue = Mid$(Format$(0, "0.0"), 2, 1)
vValue = Split(Format$(Math.Abs(dblValue), "0.00##"), vValue)
vValue(0) = Right$(sString & vValue(0), 18)
'--- loop input digits from right to left
For lIdx = 1 To Len(vValue(0))
If lIdx <= 3 Then
lDigit = Mid$(vValue(0), Len(vValue(0)) - lIdx + 1, 1)
Else
lDigit = Mid$(vValue(0), Len(vValue(0)) - lIdx - 1, 3)
lIdx = lIdx + 2
End If
If lDigit <> 0 Then
'--- separate by space (first time prepend "и" too)
If Len(sResult) <> 0 And (lIdx <> 2 Or lDigit <> 1) Then
If InStr(sResult, " и ") = 0 Then
sResult = " и " & sResult
Else
sResult = " " & sResult
End If
End If
Select Case lIdx
Case 1
sResult = vGenderDigits(lDigit) & sResult
Case 2
If lDigit = 1 Then
'--- 11 to 19 special wordforms
If Len(sResult) <> 0 Then
sResult = Replace(LTrim$(sResult), vGenderDigits(1), "еди")
sResult = Replace(sResult, vGenderDigits(2), "два") & "надесет"
Else
sResult = "десет"
End If
Else
sResult = IIf(lDigit = 2, "два", vDigits(lDigit)) & "десет" & sResult
End If
Case 3
'--- hundreds have special suffixes for 2 and 3
Select Case lDigit
Case 1
sResult = "сто" & sResult
Case 2, 3
sResult = vDigits(lDigit) & "ста" & sResult
Case Else
sResult = vDigits(lDigit) & "стотин" & sResult
End Select
Case 6
'--- thousands are in feminine gender
Select Case lDigit
Case 1
sResult = "хиляда" & sResult
Case Else
sResult = ToWords(lDigit, String.Empty, Gender:="F") & " хиляди" & sResult
End Select
Case 9, 12, 15
'--- no special cases for bigger values
sResult = ToWords(lDigit, String.Empty) & " " & Split("милион милиард трилион квадрилион")((lIdx - 9) \ 3) _
& IIf(lDigit <> 1, "а", String.Empty) & sResult
End Select
End If
Next
'--- handle zero and negative values
If Len(sResult) = 0 Then
sResult = vDigits(0)
End If
If dblValue < 0 Then
sResult = "минус " & sResult
End If
'--- apply measure (use String.Empty for none)
If IsNothing(Measure) Then
Measure = "лв.|ст."
Gender = "MF"
End If
If Len(Measure) <> 0 Then
If Right$(sResult, Len(vDigits(0))) = vDigits(0) And Val(vValue(1)) <> 0 And InStr(Measure, "|") > 0 Then
sResult = ToWords(IIf(dblValue < 0, -1, 1) * Val(vValue(1)), Split(Measure, "|")(1), Mid$(Gender, 2))
Else
sResult = sResult & " " & Split(Measure, "|")(0)
If Val(vValue(1)) <> 0 Then
sResult = sResult & " и " & Val(vValue(1))
If InStr(Measure, "|") > 0 Then
sResult = sResult & " " & Split(Measure, "|")(1)
End If
End If
sResult = UCase$(Left$(sResult, 1)) & Mid$(sResult, 2)
End If
End If
ToWords = sResult
End Function
End Module
Module Module1
Sub Main()
Debug.Assert(ToWords(0) = "Нула лв.")
Debug.Assert(ToWords(0.01) = "Една ст.")
Debug.Assert(ToWords(0.25) = "Двадесет и пет ст.")
Debug.Assert(ToWords(-0.25) = "Минус двадесет и пет ст.")
Debug.Assert(ToWords(-0.25, "лв.") = "Минус нула лв. и 25")
Debug.Assert(ToWords(35) = "Тридесет и пет лв.")
Debug.Assert(ToWords(167.42) = "Сто шестдесет и седем лв. и 42 ст.")
Debug.Assert(ToWords(-12341235) = "Минус дванадесет милиона триста четиридесет и една хиляди двеста тридесет и пет лв.")
Debug.Assert(ToWords(341.6, "МЕ|стотни", "FF") = "Триста четиридесет и една МЕ и 60 стотни")
Debug.Assert(ToWords(0.01, "МЕ|стотни", "FF") = "Една стотни")
Debug.Assert(ToWords(3125) = "Три хиляди сто двадесет и пет лв.")
Debug.Assert(ToWords(225) = "Двеста двадесет и пет лв.")
End Sub
End Module
@rboyadzhiev
Copy link

Супер! Благодаря много :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment