В сложнопридуманном акте с кучей группировок понадобилось выводить словами суммы по группам. В 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
Вызов: =Code.NumberToString(x). Возвращает словесное представление целой части числа.
Последняя функция вдогонку DecToString(x) возвращает дробную часть суммы, представленную в текстовом виде и дополненную нулем спереди, если она меньше 10.
Таким образом, вывод суммы в тексте у меня реализован так:
=Code.NumberToString(Fields!Amount_Including_VAT.Value) + " руб. " + Code.DecToString(Fields!Amount_Including_VAT.Value) + " коп."