Версия для печати темы (https://pro1c.org.ua/index.php?s=1918d97543dc0cd24d3fbecc21517189&showtopic=5183)

Нажмите сюда для просмотра этой темы в обычном формате

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 _ Программирование обычных форм 1С 8.2 и не интерфейсной логики _ Как округлить число до 10 или 100 знаков до запятой?

Автор: vbi 25.10.11, 13:27

Есть число (чкажем 1289,45) Нужно его округлить, скажем, до 100, получится 1300. Как это сделать тексте запроса?
В запросе можно выразить как число(x,y), но y задает количество знаков после запятой.
Нужно при выводе динамических цен.

Автор: хакерок 25.10.11, 13:47

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

порпробуйТЕ в запросе поделить на 100 (получиться 12,8945) а формате ячейки(там где выводит) сделать сдвиг и форматирование

Автор: alex040269 25.10.11, 14:05

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

а число(x,-y)?

Автор: vbi 25.10.11, 16:58

Цитата(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 26.10.11, 8:47

Для 10 подойдет:

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

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

ну только не &п100 а &п10, ошибся smile.gif

Автор: vbi 26.10.11, 12:14

Цитата(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 27.10.11, 17:13

Очень сложно получилось 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 28.10.11, 9:07

Идея неплохая, но нужно над ней еще поработать:
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 28.10.11, 10:51

Ну если округляет (а не обрезает) - значит убери (+0.5). У меня получилось smile.gif

Что же касается
"ПорядокОкругления - это ссылка на перечисление (хотя тут пожно взять представление и преобразовать в число наверно. Не вопрос)"
То можно создать таблицу значений: с колонками ссылка, значение (для всех значений перечисления + пустая ссылка)
передать ее в запрос как параметр и связать с основным запросом левым соединением.
В запросе в таком случае использовать МенеджерВременныхТаблиц и набор из 2х запросов, где первый будет что-то типа:

ВЫБРАТЬ Ссылка, Значение ПОМЕСТИТЬ ПорядокОкругления ИЗ &ПорядокОкругления;

ну а второй - твой запрос с вставкой:
ЛЕВОЕ СОЕДИНЕНИЕ ПорядокОкругления ПО ПорядокОкругления.Ссылка = ЦеныНоменклатурыДругие.ТипЦен.ПорядокОкругления

Автор: vbi 28.10.11, 11:42

(ВЫРАЗИТЬ((Цена / ПорядокОкругления) КАК ЧИСЛО(15,0)) * ПорядокОкругления)

Работает идеально! Спасибо!

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua