К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как отрицательное число сделать положительным в 1С

Способы получить положительное значение из отрицательного числа в 1С: функция МодульЧисла, Max, умножение на -1, условный оператор. Примеры кода и запросов.

Задача преобразовать отрицательное число в положительное возникает в 1С постоянно: при расчёте разниц сумм, обработке сторно, выводе остатков по модулю, формировании отчётов, где знак минус недопустим. Во встроенном языке 1С нет привычной функции Abs(), поэтому разработчики используют несколько рабочих приёмов — от простого умножения на минус единицу до функции Макс() и конструкций в языке запросов.

Выбор способа зависит от контекста: код в модуле, выражение в запросе, формула в СКД или вычисляемое поле в макете. Ниже разобраны все основные варианты с примерами кода, указаны ограничения каждого метода и типичные ошибки, из-за которых результат получается не таким, как ожидалось.

Способ 1. Условный оператор и тернарное выражение

Самый читаемый вариант — проверить знак числа и при необходимости изменить его. В модуле это делается через Если...Тогда или через компактное тернарное выражение с оператором ?():

Число = -125.50;

// Вариант с Если

Если Число < 0 Тогда

Число = -Число;

КонецЕсли;

// Вариант с тернарным оператором

Число = ?(Число < 0, -Число, Число);

Оба варианта дают одинаковый результат: на выходе всегда неотрицательное значение. Тернарная форма удобна, когда преобразование нужно встроить прямо в выражение — например, при присвоении реквизита или выводе в сообщение. Конструкция с Если нагляднее, если вместе со сменой знака выполняются дополнительные действия: запись в журнал, пересчёт связанных значений.

Обратите внимание: унарный минус перед переменной (-Число) меняет знак, а не «обрезает» его. Если применить -Число к уже положительному значению, получится отрицательное. Поэтому проверка условия обязательна — без неё вы просто инвертируете знак, а не получаете модуль.

Способ 2. Функция Макс() — короткая запись модуля числа

Популярный приём среди опытных разработчиков 1С — получить модуль через функцию Макс(), сравнив число с его отрицательной копией:

Число = -78;

МодульЧисла = Макс(Число, -Число); // 78

Логика проста: для отрицательного числа значение -Число будет больше, для положительного — наоборот, само число больше. В обоих случаях Макс() вернёт положительную величину. Для нуля оба аргумента равны, результат — ноль, что корректно.

Этот способ короче тернарного выражения и хорошо читается тем, кто знаком с приёмом. Но для новичков в команде он менее очевиден — при сопровождении чужого кода смысл записи приходится расшифровывать. Если код будет поддерживать не один разработчик, предпочтительнее явная проверка условия или собственная функция с говорящим именем.

Способ 3. Умножение на -1 и когда оно опасно

Иногда встречается вариант «просто умножить на минус единицу»:

Число = Число * -1; // НЕ модуль, а инверсия знака!

Это распространённая ошибка. Умножение на -1 не делает число положительным — оно меняет знак на противоположный. Отрицательное станет положительным, но положительное станет отрицательным. Такой код корректен только если вы гарантированно знаете, что на входе всегда отрицательное значение, например при обработке сторнирующих записей, отобранных по условию Сумма < 0.

Если гарантии нет, обязательно добавляйте проверку знака. Безопасная форма:

Если Число < 0 Тогда

Число = Число * -1;

КонецЕсли;

Типичные ошибки
01
Умножение на -1 без проверки знака: положительные значения превращаются в отрицательные, итоги отчёта уходят в минус
02
Попытка вызвать Abs() как в других языках: во встроенном языке 1С такой функции нет, код не скомпилируется
03
Применение смены знака к NULL из запроса: получение ошибки или неожиданного значения вместо числа
04
Округление до смены знака: модуль округлённого отрицательного числа может отличаться от округлённого модуля

Своя функция МодульЧисла в общем модуле

Если преобразование нужно во многих местах конфигурации, правильно оформить его один раз — в общем модуле. Это избавляет от дублирования логики и упрощает поддержку:

// Общий модуль РаботаСЧислами

Функция МодульЧисла(Значение) Экспорт

Возврат ?(Значение < 0, -Значение, Значение);

КонецФункции

Вызов из любого места конфигурации:

РазницаСумм = РаботаСЧислами.МодульЧисла(СуммаДебет - СуммаКредит);

Такой подход особенно удобен при расчёте разниц, где знак результата заранее неизвестен: абсолютная величина расхождения нужна для анализа, а знак обрабатывается отдельно. При необходимости функцию легко расширить — например, добавить обработку Неопределено с возвратом нуля.

Порядок действий
  1. 1
    Определите, где нужно преобразование: в коде модуля, в запросе или в СКД
  2. 2
    Для кода используйте ?(Число < 0, -Число, Число) или Макс(Число, -Число)
  3. 3
    При повторном использовании вынесите логику в функцию общего модуля
  4. 4
    Для запросов и СКД примените конструкцию ВЫБОР КОГДА...ИНАЧЕ КОНЕЦ
  5. 5
    Проверьте результат на отрицательном, положительном и нулевом значениях

Положительное число в запросе и СКД

В языке запросов 1С функций Макс() и тернарного оператора нет, поэтому используется конструкция ВЫБОР:

ВЫБРАТЬ

ВЫБОР

КОГДА Остатки.СуммаОстаток < 0

ТОГДА -Остатки.СуммаОстаток

ИНАЧЕ Остатки.СуммаОстаток

КОНЕЦ КАК СуммаПоМодулю

ИЗ

РегистрНакопления.Взаиморасчеты.Остатки КАК Остатки

Та же конструкция работает в вычисляемых полях СКД на уровне выражения запроса. Если поле формируется на языке выражений СКД, там доступна функция Макс(), и запись сокращается до Макс(Сумма, -Сумма).

Учитывайте нюанс с NULL: если поле в запросе может принимать NULL (например, при левом соединении), сравнение NULL < 0 не выполняется, и ВЫБОР вернёт ветку ИНАЧЕ — то есть сам NULL. Обычно это приемлемо, но если NULL недопустим в результате, оберните поле в ЕСТЬNULL(Поле, 0) до преобразования.

Маршрут решения

Как выбрать действие

Преобразование нужно один раз в коде модуляИспользуйте ?(Число < 0, -Число, Число)
Нужна короткая запись модуля в выраженииПримените Макс(Число, -Число)
Преобразование повторяется в разных объектах конфигурацииСоздайте функцию МодульЧисла в общем модуле
Значение вычисляется в запросе или наборе данных СКДИспользуйте ВЫБОР КОГДА Значение < 0 ТОГДА -Значение ИНАЧЕ Значение КОНЕЦ
На входе гарантированно только отрицательные числа (например, сторно)Допустимо умножение на -1 без проверки знака

Практические сценарии: сторно, разницы, остатки

Вывод отрицательных остатков как положительных

В управленческих отчётах отрицательный остаток по складу часто показывают отдельной колонкой «Недостача» с положительным знаком. Здесь условие в запросе решает обе задачи сразу — и фильтрацию, и смену знака:

ВЫБОР

КОГДА Остаток < 0 ТОГДА -Остаток

ИНАЧЕ 0

КОНЕЦ КАК Недостача

Абсолютная разница двух сумм

При сверке данных (например, план против факта) важна величина отклонения независимо от направления. Здесь удобнее всего обёртка функцией: МодульЧисла(План - Факт). Знак отклонения при этом можно вывести отдельной колонкой через тот же ВЫБОР.

Обработка сторнирующих движений

Сторно в учётных регистрах хранится с отрицательными суммами. Если документ-обработка должна «развернуть» такие движения в положительные для дальнейшего расчёта, применяйте смену знака только к строкам, отобранным условием Сумма < 0. Массовое умножение всей таблицы на -1 сломает и обычные записи.

Контрольные точки

Как проверить результат

Отрицательное число на входе
Норма

Стало положительным с той же абсолютной величиной

Тревожный признак

Осталось отрицательным или обнулилось

Положительное число на входе
Норма

Не изменилось

Тревожный признак

Стало отрицательным — значит, использована инверсия знака без проверки

Ноль на входе
Норма

Остался нулём

Тревожный признак

Ошибка выполнения или нечисловое значение

NULL или Неопределено
Норма

Обработано через ЕСТЬNULL или проверку типа

Тревожный признак

Ошибка преобразования или неожиданный NULL в итогах

Ограничения и частые вопросы производительности

Все описанные приёмы выполняются за константное время и не влияют на производительность даже в больших циклах. В запросах конструкция ВЫБОР по числовому полю также практически бесплатна — она не мешает использованию индексов, если применяется к уже выбранным данным, а не к условию соединения.

Ограничение одно, но принципиальное: все способы работают только с типом Число. Строку вида "-125,50" сначала нужно преобразовать — например, через выражение Число() в коде, предварительно убедившись, что формат строки корректен (разделитель, пробелы, символ минуса). Тип Дата, Булево и ссылочные типы в таких выражениях вызовут ошибку.

Итог

Что важно запомнить

В 1С нет функции Abs(): модуль числа получают через ?(Число < 0, -Число, Число) или Макс(Число, -Число), а в запросах и СКД — через ВЫБОР КОГДА. Умножение на -1 без проверки знака лишь инвертирует значение и является частой причиной ошибок в отчётах.

Частые вопросы

Есть ли в 1С встроенная функция Abs()?

Нет, во встроенном языке 1С функции Abs() нет. Вместо неё используют Макс(Число, -Число), тернарное выражение ?(Число < 0, -Число, Число) или собственную функцию в общем модуле. Попытка написать Abs() приведёт к ошибке компиляции модуля.

Как сделать положительными все числа в колонке таблицы значений?

Пройдите по таблице циклом Для Каждого Строка Из Таблица Цикл и примените к нужной колонке проверку: Если Строка.Сумма < 0 Тогда Строка.Сумма = -Строка.Сумма. Если сумма вычисляемая, часто проще исправить её на этапе запроса через ВЫБОР, чем корректировать готовую таблицу.

Что будет, если применить смену знака к Неопределено?

Возникнет ошибка выполнения, так как арифметические операции с Неопределено недопустимы. Перед преобразованием проверяйте значение: Если ТипЗнч(Значение) = Тип("Число") Тогда ... либо подставляйте значение по умолчанию через ?(Значение = Неопределено, 0, Значение).

Как получить модуль числа в вычисляемом поле СКД?

Если поле считается в запросе набора данных — используйте ВЫБОР КОГДА Поле < 0 ТОГДА -Поле ИНАЧЕ Поле КОНЕЦ. Если выражение пишется на языке выражений СКД (вычисляемое поле, ресурс), там доступна функция Макс(), и запись сокращается до Макс(Поле, -Поле).

Чем отличается смена знака от получения модуля?

Смена знака (умножение на -1 или унарный минус) делает отрицательное положительным, но и положительное — отрицательным. Модуль всегда возвращает неотрицательное значение: положительные числа и ноль остаются без изменений. Для модуля проверка условия обязательна.

Работает ли Макс(Число, -Число) с дробными числами и нулём?

Да, приём корректно работает с любыми числовыми значениями, включая дробные: Макс(-3.75, 3.75) вернёт 3.75. Для нуля оба аргумента равны нулю, результат — ноль. Ограничение одно: оба аргумента должны быть числами.