Разработка и Конфигурация · 10 мин
Как найти модуль числа в 1С
Как получить модуль числа в 1С: формулы через Макс и Мин, тернарный оператор, готовая функция, примеры для запросов, СКД и типичные ошибки разработчиков.
Модуль числа — это его абсолютное значение без знака: модуль −15 равен 15, модуль 15 тоже равен 15. Во встроенном языке 1С нет отдельной функции вида Abs() или Модуль(), поэтому разработчики вычисляют абсолютное значение через стандартные средства платформы. Задача возникает регулярно: при расчёте отклонений факта от плана, сравнении сумм независимо от знака, округлении разниц и проверке допусков.
Хорошая новость в том, что всё необходимое уже есть в платформе. Функции Макс() и Мин(), тернарный оператор ?() и арифметика позволяют получить модуль одной строкой кода. В языке запросов и СКД ситуация аналогичная — там тоже есть конструкции ВЫБОР и МАКСИМУМ, которыми решается та же задача.
Ниже разобраны рабочие способы вычисления модуля в коде, в запросах и в СКД, приведена готовая функция для общего модуля, а также типичные ошибки, из-за которых результат оказывается неверным. Все примеры можно скопировать и проверить в конфигураторе или консоли кода.
Почему в 1С нет готовой функции модуля
Разработчики, приходящие из других языков, первым делом ищут функцию Abs(), Math.Abs() или Модуль(). Во встроенном языке 1С её нет — ни в глобальном контексте, ни в составе арифметических функций. Доступны Цел(), Окр(), Макс(), Мин() и базовые операции, а модуль предполагается вычислять комбинацией этих средств.
Это не ограничение на практике: выражение для модуля занимает одну строку и выполняется так же быстро, как встроенная функция. Единственный реальный минус — читаемость: новичку неочевидно, что Макс(Число, -Число) означает абсолютное значение. Поэтому в крупных конфигурациях принято один раз написать функцию МодульЧисла() в общем модуле и вызывать её везде.
Способ 1. Модуль через функции Макс и Мин
Самый компактный и распространённый приём — использовать функцию Макс(). Если число отрицательное, то выражение -Число будет больше самого числа, и Макс вернёт именно его. Если число положительное или равно нулю, больше окажется само число:
Модуль = Макс(Число, -Число);
Тот же результат даёт функция Мин() с обратной логикой: Мин выбирает меньшее из значений, поэтому для модуля берётся вариант с минусом у отрицательного результата:
Модуль = -Мин(Число, -Число);
Оба варианта работают с целыми и дробными числами одинаково корректно. Первый вариант с Макс() встречается чаще, потому что читается проще и не требует внешнего унарного минуса перед всем выражением.
Число = -125.75;
Модуль = Макс(Число, -Число);
Сообщить(Модуль); // 125.75Способ 2. Тернарный оператор и конструкция Если
Тернарный оператор ?() явно проверяет знак числа и возвращает нужный вариант. Такой код длиннее, но его смысл очевиден даже тому, кто видит язык 1С впервые:
Модуль = ?(Число < 0, -Число, Число);
Классическая ветвящаяся конструкция делает то же самое и удобна, когда рядом с вычислением модуля нужно выполнить дополнительные действия, например залогировать отрицательное значение:
Если Число < 0 Тогда
Модуль = -Число;
Иначе
Модуль = Число;
КонецЕсли;
По скорости разницы между Макс() и ?() на практике нет — выбирайте тот вариант, который лучше читается в вашем коде. Для одиночного присваивания короче Макс(), для логики с побочными действиями — конструкция Если.
Готовая функция для общего модуля
Если модуль нужен в нескольких местах конфигурации, правильнее оформить его функцией в общем модуле, например ОбщегоНазначенияКлиентСервер или собственном модуле математических операций. Это убирает дублирование и делает намерение кода явным:
// Возвращает модуль (абсолютное значение) числа.
//
// Параметры:
// Число - Число - исходное значение.
//
// Возвращаемое значение:
// Число - абсолютное значение.
//
Функция МодульЧисла(Число) Экспорт
Возврат Макс(Число, -Число);
КонецФункции
Дальше в любом месте конфигурации вызов выглядит так: МодульЧисла(Отклонение). Если общий модуль клиент-серверный, функция доступна и на клиенте, и на сервере — удобно для форм, где модуль считается без обращения к серверу.
- 1Откройте конфигуратор и найдите подходящий общий модуль (или создайте новый с флагами Сервер и Клиент)
- 2Добавьте функцию МодульЧисла с кодом Возврат Макс(Число, -Число)
- 3Обновите конфигурацию базы данных
- 4Вызовите функцию из нужного места и проверьте результат на положительном, отрицательном и нулевом значении
Модуль числа в запросе
В языке запросов 1С функций Макс() и Мин() для двух произвольных выражений нет — там МАКСИМУМ работает как агрегатная функция по группе. Поэтому модуль в запросе вычисляется через конструкцию ВЫБОР:
ВЫБРАТЬ
ВЫБОР
КОГДА Таблица.Сумма < 0
ТОГДА -Таблица.Сумма
ИНАЧЕ Таблица.Сумма
КОНЕЦ КАК МодульСуммы
ИЗ
Документ.РеализацияТоваровУслуг КАК Таблица
Такой приём типичен для отчётов по отклонениям: например, нужно отобрать строки, где модуль разницы между планом и фактом больше допустимого порога. Условие записывается прямо в секции ГДЕ:
ГДЕ
ВЫБОР
КОГДА План - Факт < 0 ТОГДА -(План - Факт)
ИНАЧЕ План - Факт
КОНЕЦ > &ДопустимоеОтклонение
Учтите, что конструкция ВЫБОР в условии не позволяет использовать индекс по выражению, поэтому на очень больших таблицах такой отбор будет работать медленнее, чем сравнение по обычному полю. Если отбор по модулю выполняется часто, иногда выгоднее хранить абсолютное значение в отдельном реквизите и заполнять его при записи.
Модуль в СКД и вычисляемых полях
В системе компоновки данных модуль получают двумя путями. Первый — вычислить его ещё в запросе набора данных через ВЫБОР, как показано выше, и вывести готовое поле. Второй — создать вычисляемое поле на закладке «Вычисляемые поля» и написать выражение на языке выражений СКД:
Выбор Когда Сумма < 0 Тогда -Сумма Иначе Сумма Конец
Вычисляемое поле удобно, когда запрос формируется типовым механизмом и менять его нежелательно, а колонку с модулем нужно добавить только в отчёт. Если же модуль участвует в итогах и группировках, надёжнее посчитать его в запросе — тогда агрегирование по нему работает штатно, без дополнительных настроек ресурсов.
Где вычислять модуль
Подходит для алгоритмов, проведения документов, проверок в формах. Максимальная гибкость
Подходит для отборов и отчётов, где модуль нужен на уровне выборки данных
Подходит, когда запрос менять нельзя, а колонка нужна только для отображения
Проверка результата и контрольные точки
После внедрения вычисления модуля проверьте его на граничных значениях: положительном числе, отрицательном, нуле и дробном отрицательном значении. Все четыре случая должны дать корректный неотрицательный результат. Быстрее всего это сделать в консоли кода или через Сообщить() в отладочной процедуре.
Для запросов проверку выполняют в консоли запросов: откройте реальную таблицу, добавьте вычисляемое поле с ВЫБОР и убедитесь, что строки с отрицательными суммами показывают положительный модуль, а остальные значения не изменились.
Как проверить результат
Результат 125.75
Результат остался отрицательным или сменился знак у положительных
Результат 0
Ошибка выполнения или нечисловое значение
Значение не изменилось
Число стало отрицательным — перепутаны ветки условия
Все строки неотрицательные, итоги совпадают с ожиданием
Часть строк NULL или отрицательные значения
Типичные ошибки при вычислении модуля
Самая частая ошибка — попытка вызвать несуществующую функцию Abs() или Модуль() и получение ошибки «Процедура или функция с указанным именем не определена». Вторая по частоте — перепутанные ветки условия: разработчик пишет ?(Число > 0, -Число, Число), и модуль «работает наоборот», инвертируя знак положительных значений.
Отдельная группа проблем — нечисловые данные. Если в переменной может оказаться Неопределено, NULL или строка, выражение Макс(Число, -Число) завершится ошибкой. Перед вычислением проверяйте тип: либо гарантируйте число на входе, либо обрабатывайте нечисловые значения отдельно. В запросах NULL от незаполненного поля или левого соединения тоже требует обработки через ЕСТЬNULL.
Что важно запомнить
Встроенной функции модуля в 1С нет. В коде используйте Макс(Число, -Число) или тернарный оператор, в запросах и СКД — конструкцию ВЫБОР. Для повторного использования оформите функцию в общем модуле и проверьте её на отрицательных, положительных и нулевых значениях.
Частые вопросы
Есть ли в 1С функция Abs() или Модуль()?
Нет, во встроенном языке и языке запросов такой функции не существует. Абсолютное значение вычисляют через Макс(Число, -Число), тернарный оператор или конструкцию ВЫБОР — в зависимости от контекста.
Что быстрее: Макс() или тернарный оператор?
На практике разница в производительности незаметна даже в циклах на сотни тысяч итераций. Выбирайте вариант по читаемости: Макс() короче, ?() понятнее новичкам.
Как получить модуль разности двух чисел?
Сначала вычислите разность, затем примените любой из способов: Макс(А - Б, -(А - Б)) или ?(А - Б < 0, Б - А, А - Б). Скобки обязательны, чтобы унарный минус применялся ко всей разности.
Почему в запросе модуль возвращает NULL?
Если исходное поле содержит NULL (незаполненное поле или результат левого соединения), то и ВЫБОР вернёт NULL. Оберните исходное поле или всё выражение в ЕСТЬNULL(..., 0).
Можно ли вычислить модуль на управляемой форме без сервера?
Да. Выражение Макс(Число, -Число) работает и в клиентском контексте. Если функция вынесена в общий модуль, убедитесь, что у него установлен флаг «Клиент (управляемое приложение)» или «Клиент (обычное приложение)».
Как округлить модуль до нужного знака?
Комбинируйте с функцией Окр(): Окр(Макс(Число, -Число), 2) вернёт абсолютное значение, округлённое до двух знаков после запятой. Порядок функций можно менять — округление до или после взятия модуля даёт одинаковый результат по абсолютной величине.