AXForum  
Вернуться   AXForum > Microsoft Dynamics NAV > NAV: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 30.03.2018, 13:45   #1  
BuzCom is offline
BuzCom
Участник
 
48 / 13 (1) ++
Регистрация: 10.08.2017
Перевод суммы в словесное представление в 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
Вызов: =Code.NumberToString(x). Возвращает словесное представление целой части числа.
Последняя функция вдогонку DecToString(x) возвращает дробную часть суммы, представленную в текстовом виде и дополненную нулем спереди, если она меньше 10.
Таким образом, вывод суммы в тексте у меня реализован так:
=Code.NumberToString(Fields!Amount_Including_VAT.Value) + " руб. " + Code.DecToString(Fields!Amount_Including_VAT.Value) + " коп."
Старый 30.03.2018, 13:58   #2  
BuzCom is offline
BuzCom
Участник
 
48 / 13 (1) ++
Регистрация: 10.08.2017
В процессе отладки, кстати, столкнулся с особенностью операций в Reporting.
Пример:
((X / 10) - Int(X / 10)) * 10
Если подать в это выражение, допустим целое число 41, то можно ожидать, что ответ будет равен 1. Но нет....
Такое выражение будет равно 0,999999999999996
Если затем использовать сравнения, то будут вылезать выводящие из себя и необъяснимые с первого взгляда ошибки.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
dyn365finsupport: Using Web Services for reporting in Dynamics 365 for Financials Blog bot NAV: Blogs 0 03.10.2017 21:12
msdn.microsoft.com/nav: Update to the Vendor 1099 Information Reports for the tax reporting year 2016 Blog bot NAV: Blogs 0 06.01.2017 17:13
Корректировка рублевой суммы в покупке в валюте Cheb NAV: Функционал 5 22.11.2012 12:16
Зарплата: удержание процента от суммы "К ВЫПЛАТЕ" Павел Максимов NAV: Функционал 0 22.12.2004 18:12
Расшифровка суммы по англицки Dimon NAV: Программирование 19 14.02.2004 03:55
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 01:44.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.