Last active
March 13, 2016 18:06
-
-
Save wqweto/d7ca68a5fd0368c08158 to your computer and use it in GitHub Desktop.
Конвертиране на число в словом с думи за VB.NET. По подразбиране работи за левове в мъжки род, но може да се използва и за мярка в женски род (например метро единици) или среден род (например евро)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Супер! Благодаря много :)