Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как округлить число до 10 или 100 знаков до запятой?
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 8.2 > Программирование обычных форм 1С 8.2 и не интерфейсной логики
vbi
Есть число (чкажем 1289,45) Нужно его округлить, скажем, до 100, получится 1300. Как это сделать тексте запроса?
В запросе можно выразить как число(x,y), но y задает количество знаков после запятой.
Нужно при выводе динамических цен.
хакерок
Цитата(vbi @ 25.10.11, 14:27) необходимо зарегистрироваться для просмотра ссылки
Есть число (чкажем 1289,45) Нужно его округлить, скажем, до 100, получится 1300. Как это сделать тексте запроса?
В запросе можно выразить как число(x,y), но y задает количество знаков после запятой.
Нужно при выводе динамических цен.

порпробуйТЕ в запросе поделить на 100 (получиться 12,8945) а формате ячейки(там где выводит) сделать сдвиг и форматирование
alex040269
Цитата(vbi @ 25.10.11, 14:27) необходимо зарегистрироваться для просмотра ссылки
Есть число (чкажем 1289,45) Нужно его округлить, скажем, до 100, получится 1300. Как это сделать тексте запроса?
В запросе можно выразить как число(x,y), но y задает количество знаков после запятой.
Нужно при выводе динамических цен.

а число(x,-y)?
vbi
Цитата(alex040269 @ 25.10.11, 15:05) необходимо зарегистрироваться для просмотра ссылки
а число(x,-y)?


-Y - ругается.

Я кое чего не доглядел! Все намного сложнее.

Я должен вывести на печать цену. Тип цен этой цены имеет реквизит "ПорядокОкругления" - перечисление.
При выводе этой цены нужно учитывать порядок округления этого типа цен.
Порядок стоит перечисление с представлением "10".
Ладно, с 10 я справился следующим образом:
    КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления.Порядок = &п10
        ТОГДА (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 10 КАК ЧИСЛО(15, 0))) * 10

п10 - это то перечисление. Тоесть я делю на 10, округляю и умножаю на 10. Все норм.
С дробями тоже просто:
    КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления.Порядок = &п0_01
        ТОГДА ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) КАК ЧИСЛО(15, 2))


Но я бы хотел сделать универсально. Средствами перебора я смогу округлить таким способом порядки: 1, 10, 100, 0.1, 0.01, НО!

Там есть еще и такие порядки: 5, 50, 0.5, 0.05. Как их округлить в запросе?

То есть если есть число, скажем 1368,75. Его нужно округлить до 5. В случае до 10 оно округляется до ближайшего десятка, тоесть до 1360 или 1370 (ближайший 1370). В случае 5 оно еще может округлится и до 1365. Как в запросе это реализовать?

Цитата
Тоесть я делю на 10, округляю и умножаю на 10. Все норм

Блин и сдесь неправильно. Сдесь я отбрасываю дробную часть а не округляю...
vbi
Для 10 подойдет:
    КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления.Порядок = &п100
        ТОГДА (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена + 5, 0) / 10 КАК ЧИСЛО(15, 0))) * 10

Осталось разобратся для порядков 5, 50, 0.5, 0.05 smile.gif.

ну только не &п100 а &п10, ошибся smile.gif
vbi
Цитата(vbi @ 25.10.11, 17:58) необходимо зарегистрироваться для просмотра ссылки
-Y - ругается.

Я кое чего не доглядел! Все намного сложнее.

Я должен вывести на печать цену. Тип цен этой цены имеет реквизит "ПорядокОкругления" - перечисление.
При выводе этой цены нужно учитывать порядок округления этого типа цен.
Порядок стоит перечисление с представлением "10".
Ладно, с 10 я справился следующим образом:
КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления.Порядок = &п10
ТОГДА (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 10 КАК ЧИСЛО(15, 0))) * 10
п10 - это то перечисление. Тоесть я делю на 10, округляю и умножаю на 10. Все норм.
С дробями тоже просто:
КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления.Порядок = &п0_01
ТОГДА ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) КАК ЧИСЛО(15, 2))

Но я бы хотел сделать универсально. Средствами перебора я смогу округлить таким способом порядки: 1, 10, 100, 0.1, 0.01, НО!

Там есть еще и такие порядки: 5, 50, 0.5, 0.05. Как их округлить в запросе?

То есть если есть число, скажем 1368,75. Его нужно округлить до 5. В случае до 10 оно округляется до ближайшего десятка, тоесть до 1360 или 1370 (ближайший 1370). В случае 5 оно еще может округлится и до 1365. Как в запросе это реализовать?


Блин и сдесь неправильно. Сдесь я отбрасываю дробную часть а не округляю...


И всетаки округляю а не отбрасываю smile.gif

Разобрался с этими динамическими ценами и округлением! Вообщем округлять можно так:

    ВЫБОР
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п100
            ТОГДА (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 100 КАК ЧИСЛО(15, 0))) * 100
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п10
            ТОГДА (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 10 КАК ЧИСЛО(15, 0))) * 10
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п1
            ТОГДА ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) КАК ЧИСЛО(15, 0))
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п0_1
            ТОГДА ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) КАК ЧИСЛО(15, 1))
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п0_01
            ТОГДА ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) КАК ЧИСЛО(15, 2))
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п50
                И ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 100 - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 100 - 0.5 КАК ЧИСЛО(15, 0))) >= 0.25
                И ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 100 - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 100 - 0.5 КАК ЧИСЛО(15, 0))) < 0.75
            ТОГДА (ВЫРАЗИТЬ((ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) - 25) / 100 КАК ЧИСЛО(15, 0))) * 100 + 50
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п50
                И (ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 100 - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 100 - 0.5 КАК ЧИСЛО(15, 0))) < 0.25
                    ИЛИ ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 100 - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 100 - 0.5 КАК ЧИСЛО(15, 0))) >= 0.75)
            ТОГДА (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 100 КАК ЧИСЛО(15, 0))) * 100
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п5
                И ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 10 - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 10 - 0.5 КАК ЧИСЛО(15, 0))) >= 0.25
                И ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 10 - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 10 - 0.5 КАК ЧИСЛО(15, 0))) < 0.75
            ТОГДА (ВЫРАЗИТЬ((ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) - 2.5) / 10 КАК ЧИСЛО(15, 0))) * 10 + 5
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п5
                И (ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 10 - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 10 - 0.5 КАК ЧИСЛО(15, 0))) < 0.25
                    ИЛИ ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 10 - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 10 - 0.5 КАК ЧИСЛО(15, 0))) >= 0.75)
            ТОГДА (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) / 10 КАК ЧИСЛО(15, 0))) * 10
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п0_5
                И ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) - 0.5 КАК ЧИСЛО(15, 0))) >= 0.25
                И ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) - 0.5 КАК ЧИСЛО(15, 0))) < 0.75
            ТОГДА (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) - 0.25 КАК ЧИСЛО(15, 0))) + 0.5
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п0_5
                И (ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) - 0.5 КАК ЧИСЛО(15, 0))) < 0.25
                    ИЛИ ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) - 0.5 КАК ЧИСЛО(15, 0))) >= 0.75)
            ТОГДА ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) КАК ЧИСЛО(15, 0))
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п0_05
                И ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) * 10 - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) * 10 - 0.5 КАК ЧИСЛО(15, 0))) >= 0.25
                И ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) * 10 - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) * 10 - 0.5 КАК ЧИСЛО(15, 0))) < 0.75
            ТОГДА (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) - 0.025 КАК ЧИСЛО(15, 1))) + 0.05
        КОГДА ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления = &п0_05
                И (ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) * 10 - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) * 10 - 0.5 КАК ЧИСЛО(15, 0))) < 0.25
                    ИЛИ ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) * 10 - (ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) * 10 - 0.5 КАК ЧИСЛО(15, 0))) >= 0.75)
            ТОГДА ВЫРАЗИТЬ(ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0) КАК ЧИСЛО(15, 1))
        ИНАЧЕ ЕСТЬNULL(ЦеныНоменклатурыДругие.Цена, 0)
    КОНЕЦ КАК Цена,


И все отлично работает. Проверял. Если интересно почему так, могу обяснить smile.gif
kivals
Очень сложно получилось smile.gif

Отбрасывание от округления отличается ровно на 0.5

Проверьте: (ВЫРАЗИТЬ((Цена / ПорядокОкругления + 0.5) КАК ЧИСЛО(15,0)) * ПорядокОкругления) работает правильно для любых значений ПорядокОкругления (кроме 0, естественно): будь то 10, 100, 0.1, 0.01, 0.5, и даже 0.333 smile.gif
Возможно для полноты картины выразите результат как ЧИСЛО(15, 2)
P.S. Проблемы могут быть при переполнении разрядной сетки, т.е. Округлить 100 000 000 000 000 до 0.01 может вылезти за 15 знаков - тогда просто увеличте количество знаков в параметре ВЫРАЗИТЬ ... КАК ЧИСЛО(ХХ, 0): ХХ должно быть равным исходному количеству знаков реквизита Цена + количество дробных знаков в реквизите ПорядокОкругления
P.P.S. Для проверки в MS Excel есть функция MRound()
vbi
Идея неплохая, но нужно над ней еще поработать:
1. ПорядокОкругления - это ссылка на перечисление (хотя тут пожно взять представление и преобразовать в число наверно. Не вопрос)
2. Это динамические цены. Там нет таких товаров стоящих больше 100 000 000 000 000.
3. Формула бы работала идеально, если б ВЫРАЗИТЬ( ... КАК ЧИСЛО(Х,У)) просто отбрасывало бы ненужные разряды числа. Но оно округляет его, и внекоторых случаях работает неправильно. Вот скриншот консоли запроса:

На скриншоте мы видим как округляется по даной формуле число "1456.66".

В первом случае должно было бы получится "1450";
Во втором "1455";
В третем "1456.5";
В четвертом "1456.65";

Для копипаста smile.gif
ВЫБРАТЬ
    (ВЫРАЗИТЬ(1456.66 / 50 + 0.5 КАК ЧИСЛО(15, 0))) * 50 КАК КруглениеК50,
    (ВЫРАЗИТЬ(1456.66 / 5 + 0.5 КАК ЧИСЛО(15, 0))) * 5 КАК КруглениеК5,
    (ВЫРАЗИТЬ(1456.66 / 0.5 + 0.5 КАК ЧИСЛО(15, 0))) * 0.5 КАК КруглениеК0_5,
    (ВЫРАЗИТЬ(1456.66 / 0.05 + 0.5 КАК ЧИСЛО(15, 0))) * 0.05 КАК КруглениеК0_05
kivals
Ну если округляет (а не обрезает) - значит убери (+0.5). У меня получилось smile.gif

Что же касается
"ПорядокОкругления - это ссылка на перечисление (хотя тут пожно взять представление и преобразовать в число наверно. Не вопрос)"
То можно создать таблицу значений: с колонками ссылка, значение (для всех значений перечисления + пустая ссылка)
передать ее в запрос как параметр и связать с основным запросом левым соединением.
В запросе в таком случае использовать МенеджерВременныхТаблиц и набор из 2х запросов, где первый будет что-то типа:
ВЫБРАТЬ Ссылка, Значение ПОМЕСТИТЬ ПорядокОкругления ИЗ &ПорядокОкругления;

ну а второй - твой запрос с вставкой:
ЛЕВОЕ СОЕДИНЕНИЕ ПорядокОкругления ПО ПорядокОкругления.Ссылка = ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления
vbi
(ВЫРАЗИТЬ((Цена / ПорядокОкругления) КАК ЧИСЛО(15,0)) * ПорядокОкругления)

Работает идеально! Спасибо!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.