30.03.2018, 13:45 | #1 |
Участник
|
Перевод суммы в словесное представление в Reporting
В сложнопридуманном акте с кучей группировок понадобилось выводить словами суммы по группам. В Nav это делать не хотел. Так как не нашел ничего готового под рубли в интернете, накидал сам функции на основе найденных алгоритмов. Может кому понадобятся:
Код: Public Function NumberToString(ByVal num As Double) As String num = Int(num) If num = 0 Then Return "нуль" Static groups() As String = {"", "тысяч", "миллионов", "миллиардов"} Static groups1() As String = {"", "тысяча", "миллион", "миллиард"} Static groups2_4() As String = {"", "тысячи", "миллиона", "миллиарда"} Dim result As String = "" Dim quotient As Double Dim remainder As Integer Dim group_num As Integer = 0 Dim flag1000 As Boolean = false Do While num > 0 ' След группа из трех цифр quotient = Int(num / 1000) remainder = CInt(num - quotient * 1000) num = quotient If group_num = 1 Then flag1000 = true Else flag1000 = false ' перевод в слова If (remainder Mod 10) = 1 Then result = GroupToWords(remainder,flag1000) & " " & groups1(group_num) & " " & result End If If (remainder Mod 10) > 1 and (remainder Mod 10) < 5 Then result = GroupToWords(remainder,flag1000) & " " & groups2_4(group_num) & " " & result End If If (remainder Mod 10) > 4 or (remainder Mod 10) = 0 Then result = GroupToWords(remainder,flag1000) & " " & groups(group_num) & " " & result End If ' След номер группы group_num += 1 Loop ' убираем последний пробел If result.EndsWith(" ") Then result = result.Substring(0, result.Length - 1) End If Return result.Trim() End Function Public Function GroupToWords(ByVal num As Integer,flag As Boolean) As String Static one_to_nineteen() As String = {"ноль", "один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять", "десять", "одиннадцать", "двенадцать", "тринадцать", "четырнадцать", "пятнадцать", "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать"} Static one_to_nineteen1000() As String = {"ноль", "одна", "две", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять", "десять", "одиннадцать", "двенадцать", "тринадцать", "четырнадцать", "пятнадцать", "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать"} Static multiples_of_ten() As String = {"двадцать", "тридцать", "сорок", "пятьдесят", "шестьдесят", "семьдесят", "восемьдесят", "девяносто"} Static multiples_of_hundreds() As String = {"", "сто", "двести", "триста", "четыреста", "пятьсот", "шестьсот", "семьсот", "восемьсот", "девятьсот"} ' Если 0, то пусто If num = 0 Then Return "" ' сотни Dim digit As Integer Dim result As String = "" If num > 99 Then digit = num \ 100 num = num Mod 100 result = multiples_of_hundreds(digit) End If ' если num = 0, то есть только сотни If num = 0 Then Return result.Trim() ' Если остаток меньше 20 If num < 20 and flag = false Then ' ищем правильное слово result &= " " & one_to_nineteen(num) ElseIf num < 20 and flag = true Then result &= " " & one_to_nineteen1000(num) Else ' иначе десятки digit = num \ 10 num = num Mod 10 result &= " " & multiples_of_ten(digit - 2) ' последняя цифра If num > 0 and flag = false Then result &= " " & one_to_nineteen(num) ElseIf num > 0 and flag = true Then result &= " " & one_to_nineteen1000(num) End If End If Return result.Trim() End Function Public Function DecToString(ByVal num As Double) As String ' округляет и конвертирует дроб часть суммы в текст и добавляет 0 при необходимости Dim result As String = "" num = Round((num - Int(num)) * 100,2) If num >9 Then result = CStr(num) Else result = "0" & CStr(num) End If Return result.Trim() End Function Последняя функция вдогонку DecToString(x) возвращает дробную часть суммы, представленную в текстовом виде и дополненную нулем спереди, если она меньше 10. Таким образом, вывод суммы в тексте у меня реализован так: =Code.NumberToString(Fields!Amount_Including_VAT.Value) + " руб. " + Code.DecToString(Fields!Amount_Including_VAT.Value) + " коп." |
|
30.03.2018, 13:58 | #2 |
Участник
|
В процессе отладки, кстати, столкнулся с особенностью операций в Reporting.
Пример: ((X / 10) - Int(X / 10)) * 10 Если подать в это выражение, допустим целое число 41, то можно ожидать, что ответ будет равен 1. Но нет.... Такое выражение будет равно 0,999999999999996 Если затем использовать сравнения, то будут вылезать выводящие из себя и необъяснимые с первого взгляда ошибки. |
|
|
|