Округление результатов арифметических операций в запросах
Область применения: управляемое приложение, мобильное приложение, обычное приложение.
Методическая рекомендация (полезный совет)
1. Если в операции деления заранее известны порядки числителя и знаменателя, то следует по возможности избегать выполнения деления числа заведомого маленького порядка на число заведомо большого порядка. Например, вместо:
0.02 / 28346 * 9287492
0.02 * 9287492 / 28346
2. При выполнении арифметических операций в запросах к базе данных платформа 1С:Предприятия поддерживает точность вычислений до 8 разрядов дробной части. Однако, из-за особенностей работы различных СУБД в некоторых ситуациях точность результатов может отличаться от 8. Более подробно о вычислении разрядности результатов можно почитать в статье ИТС Разрядность результатов выражений и агрегатных функций в языке запросов.
Если точность результата выполнения запроса к базе данных, содержащего
- арифметические операции деления,
- агрегатные функции СРЕДНЕЕ ,
- арифметические операции умножения, если каждый из множителей может иметь дробную часть,
различается на различных СУБД, то рекомендуется к операндам и/ или результатам этих операций применять оператор явного приведения разрядности и точности числовых данных:
ВЫРАЗИТЬ(. КАК Число(m, n))
Оператор ВЫРАЗИТЬ следует применять к операндам, если на какой-нибудь СУБД точность получаемого результата недостаточна. Например, требуется 10 разрядов после запятой, а получается 6.
При этом указанная общая разрядность операндов должна быть минимальной, но не меньше той, которая достаточна для представления значений каждого из операндов. Неоправданное завышение разрядности может привести к потере точности последующих вычислений и несколько снизить скорость выполнения запроса.
Важно иметь в виду, что на разных СУБД имеются различные ограничения на максимальную разрядность десятичных чисел. Самое жесткое ограничение — это 31 разряд в целой и дробной частях. Чем меньшее значение разрядности будет указано для операндов, тем выше сможет быть точность результата. Например, если в результате требуется не менее 10 разрядов дробной части, первый операнд заведомо помещается в 15 разрядов целой части, а второй операнд заведомо помещается в 5 знаков целой части, то выражение может быть записано так:
ВЫБРАТЬ
ВЫРАЗИТЬ(Таблица.Множитель * Таблица.Числитель КАК Число(25,10)) / ВЫРАЗИТЬ(Таблица.Знаменатель КАК Число(15,10)) КАК Результат
ИЗ Таблица КАК Таблица
Оператор ВЫРАЗИТЬ следует применять к результату, если точность вычислений на всех СУБД достаточна, но на некоторых она больше, а на других меньше. При этом указанная общая разрядность результата должна быть минимальной, но не меньше той, которая достаточна для представления значений результата. Если в приведенном примере известно, что Знаменатель не может быть меньше 0.00001, то для представления результата достаточно 20 разрядов целой части. В этом случае выражение может быть записано так:
ВЫБРАТЬ
ВЫРАЗИТЬ(Таблица.Множитель * Таблица.Числитель / Таблица.Знаменатель КАК Число(30,10)) КАК Результат
ИЗ Таблица КАК Таблица
Иногда может быть целесообразно выполнить приведения к требуемой точности как операндов, так и результата. Например:
ВЫБРАТЬ
ВЫРАЗИТЬ(ВЫРАЗИТЬ(Таблица.Множитель * Таблица.Числитель КАК Число(25,10)) / ВЫРАЗИТЬ(Таблица.Знаменатель КАК Число(15,10)) КАК Число(30,10)) КАК Результат
ИЗ Таблица КАК Таблица
Как в 1С Округлять числа программно
Сразу скажу что я не гуру 1С программист, опыт у меня не совсем большой но все же он есть. Я достаточно часто пишу статьи в которых стараюсь поделиться полезными советами или дать более полный ответ на какой либо вопрос касаемый 1С разработки. Я когда то сам был новичком и пытался найти ответы на свои вопросы на различных форумах. Где как правило сидят опытные программисты и они дают советы с высоты своего опыта. Которые в свою очередь новичкам мало чем помогают. Сегодня хочу разобрать тему округления чисел. Поговорим об округление целой и дробной части.
Если вы только начинаете свой путь 1С программиста то рекомендую прочитать следующие статьи.
Программное округление целой и дробной части числа
И так программно можно округлить любое число как до целых так и до десятых , сотых. Делается это с помощью функции Окр, синтаксис такой.
Окр — сама функция
Число — соответственно число которое хотим округлить
0 — разрядность, число знаков после запятой
0 — Режим округления 0 в меньшую сторону 1 в большую, его можно не указывать по умолчанию всегда 0
Скажем если взять число = 12,123 то после применения Окр(Число , 0, 0); число будет 12.
Надеюсь объяснил понятно если нет то можете открыть Синтаксис-помощник.
Для примера я сделал форму, на которой размести реквизит «Цена» и 4 кнопки. Первая округляет введённое число в большую сторону, вторая в меньшею. Т.е если будет например число 10,12 при нажатии первой кнопки число округлиться до 11 а при нажатии второй до 10.
Третья и четвертая кнопка округляет дробную часть, т.е копейки, возьмем тоже число 10,12. Если нажмем третью кнопку результатом будет число 10,20, а если нажмем четвертую то 10,10.
Допустим у вас есть табличная часть, в которой выбирается номенклатура и подставляется цена из справочника. Что бы округлить число в этом случае нужно создать событие при изменение табличной части и написать вот такой код.
&НаКлиенте
Процедура ТабличнаяЧастьПриИзмененииПосле(Элемент)
// Вставить содержимое обработчика.
Округление = Элементы.ТабличнаяЧасть.ТекущиеДанные;
Округление.Сумма = Окр(Округление.Сумма-0.05,1);КонецПроцедуры
В результате все суммы будут округлены до сотых причем в меньшую сторону. Надеюсь все объяснил достаточно подробно но если остались вопросы обязательно спрашивайте!
ВЫРАЗИТЬ КАК ЧИСЛО в запросе
Встроенная функция запроса ВЫРАЗИТЬ() используется не только для приведения, но и для округления чисел.
Для этого используется такой синтаксис:
ВЫРАЗИТЬ(<ОбрабатываемоеЧисло> КАК ЧИСЛО (<ДлинаЦелойЧасти>.<ДлинаДробнойЧасти>))
Общие особенности использования в запросе
Если в качестве параметра передано не числовое значение, это может не вызывать ошибки выполнения запроса, но значение корректно не обработается:
Например, если передан NULL или он сформировался при соединениях таблиц, значение на выходе останется NULL:
Передача же “Неопределено” вызывает ошибку “Несовместимые типы ВЫРАЗИТЬ”:
- Ссылочные типы или значения БУЛЕВО вызывают такую же ошибку (ИСТИНА не приводится к 1, а ЛОЖЬ к 0).
- ВЫРАЗИТЬ строку как число также нельзя, используя эту функцию.
Поэтому следует обрабатывать/проверять значение до его передачи в качестве параметра функции.
Обработка значения производится по методам округления (0.5 округляется до 1.0), поэтому, если требуется получить целое значение, то следует перед округлением вычесть 0.5 (половину цены шага)
Для округления до десятых в меньшую сторону вычесть 0.5, до сотых 0.05.
Демонстрация использования ВЫРАЗИТЬ в запросе для округления
Если бы рекламодатели тратили на улучшение своей продукции те деньги, которые они тратят на рекламу, их продукция не нуждалась бы в рекламе.
— Уилл Роджерс