Как в 1С настроить ввод числа, кратного 10, и почему для этого не подходит маска

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При проектировании пользовательских интерфейсов в 1С нередко возникает задача ограничить ввод числовых данных определенными рамками. Например, требуется, чтобы пользователь вводил положительное число не менее 10, у которого последняя цифра всегда должна оставаться нулем (значения 10, 20, 150, 4300 и так далее). Первое интуитивное желание разработчика в такой ситуации — настроить свойство Маска у элемента формы, задав шаблон вроде 99990. Однако на практике этот подход не дает желаемого результата. Разберем подробно, почему механизм масок не предназначен для таких сценариев и какими надежными способами можно реализовать требуемое поведение.

Выясним причину: почему маска не работает для чисел

Проанализируем архитектурные ограничения платформы 1С:Предприятие, из-за которых настройка маски оказывается неэффективной для решения поставленной задачи:

  1. Типизация свойства «Маска». В платформе 1С механизм масок ввода предназначен исключительно для данных строкового типа. Если реквизит имеет тип Число, свойство Маска игнорируется платформой. За визуальное представление числовых значений отвечают свойства Формат и ФорматРедактирования, но они оперируют разделителями групп, знаками дробной части и лидирующими нулями, а не фиксированием произвольных цифр в конкретных разрядах.
  2. Фиксированная длина строки. Даже если перевести реквизит в строковый тип данных, маска вида 9999\0 требует обязательного заполнения всех позиций шаблона. Это означает, что пользователь не сможет естественным образом ввести короткое число (например, 10 или 50) без предварительного заполнения ведущих позиций пробелами или нулями.
  3. Ограничение нижней границы. Свойство МинимальноеЗначение на уровне элемента формы способно ограничить нижний порог (например, не позволить ввести число меньше 10), однако оно не умеет контролировать шаг изменения и кратность значения.

Таким образом, попытка решить задачу через стандартные декларативные свойства элемента формы заводит в тупик. Перейдем к разбору практических вариантов реализации через программный код и интерфейсные механизмы.

Вариант 1. Автоматическая корректировка в событии «ПриИзменении»

Рассмотрим наиболее простой и распространенный подход — программную нормализацию значения сразу после того, как пользователь завершил ввод и покинул поле. Для этого создадим обработчик события ПриИзменении на клиенте.

В коде обработчика выполним математическое округление или отсечение до десятков, а также проконтролируем минимальную границу:


&НаКлиенте
Процедура ЧисловоеПолеПриИзменении(Элемент)
    // Проверяем минимальный порог
    Если Объект.ЧисловоеПоле < 10 Тогда
        Объект.ЧисловоеПоле = 10;
        Возврат;
    КонецЕсли;

    // Принудительно обнуляем единицы, делая число кратным 10
    Объект.ЧисловоеПоле = Цел(Объект.ЧисловоеПоле / 10) * 10;
КонецПроцедуры

Если пользователь введет 15 или 19, значение автоматически преобразуется в 10. Если требуется математическое округление до ближайшего десятка (например, чтобы 15 превращалось в 20), вместо функции Цел можно использовать функцию Окр:


&НаКлиенте
Процедура ЧисловоеПолеПриИзменении(Элемент)
    Если Объект.ЧисловоеПоле < 10 Тогда
        Объект.ЧисловоеПоле = 10;
    Иначе
        Объект.ЧисловоеПоле = Окр(Объект.ЧисловоеПоле / 10, 0) * 10;
    КонецЕсли;
КонецПроцедуры

Вариант 2. Использование кнопок регулирования с шагом 10

Посмотрим на более удобный для пользователя вариант интерфейса, когда число не только вводится вручную, но и может изменяться стрелками вверх и вниз. В свойствах числового поля ввода установим признак КнопкаРегулирования = Истина и назначим обработчик события Регулирование.

Разберем по шагам логику обработчика: мы перехватываем стандартное изменение (которое по умолчанию равно 1), отключаем его и прибавляем или вычитаем ровно 10:


&НаКлиенте
Процедура ЧисловоеПолеРегулирование(Элемент, Направление, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    Шаг = 10;
    НовоеЗначение = Объект.ЧисловоеПоле + (Направление * Шаг);
    
    // Защита от установки значения менее 10
    Если НовоеЗначение < 10 Тогда
        НовоеЗначение = 10;
    КонецЕсли;
    
    Объект.ЧисловоеПоле = НовоеЗначение;
КонецПроцедуры

Параметр Направление принимает значение 1 при нажатии стрелки вверх и -1 при нажатии стрелки вниз. Данный способ отлично дополняет проверку в событии ПриИзменении, гарантируя комфортный пошаговый ввод.

Вариант 3. Перехват набора через событие «ОкончаниеВводаТекста»

Рассмотрим ситуацию, когда пользователь набирает число вручную и мы хотим подставить завершающий ноль прямо в процессе фиксации текста, еще до того, как значение запишется в реквизит формы. Для этого воспользуемся событием ОкончаниеВводаТекста.


&НаКлиенте
Процедура ЧисловоеПолеОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
    ОчищенныйТекст = СокрЛП(Текст);
    
    Если ПустаяСтрока(ОчищенныйТекст) Тогда
        Возврат;
    КонецЕсли;
    
    ЧисловойТип = Новый ОписаниеТипов("Число");
    ВведенноеЧисло = ЧисловойТип.ПривестиЗначение(ОчищенныйТекст);
    
    // Если последняя цифра не 0, дописываем ноль или принудительно выравниваем
    Если ВведенноеЧисло < 10 Тогда
        Значение = 10;
    Иначе
        Значение = Цел(ВведенноеЧисло / 10) * 10;
    КонецЕсли;
    
    СтандартнаяОбработка = Ложь;
КонецПроцедуры

Установка СтандартнаяОбработка = Ложь сообщает платформе, что расчетное число из переменной Значение необходимо сразу поместить в поле без стандартного парсинга исходной строки.

Вариант 4. Интерфейсное разделение: ввод десятков

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

  1. Ограничиваем реквизит на форме вводом целого числа от 1 до 9999.
  2. В свойствах поля ввода используем отображение суффикса (свойство ТекстПослеПоляВвода) со значением 0 либо размещаем рядом статическую надпись.
  3. При сохранении данных или в расчетных алгоритмах значение умножается на 10.

При таком подходе пользователь вводит, например, 45, но в интерфейсе наглядно видит, что итоговое значение формируется как 450. Это полностью устраняет возможность некорректного ввода без единой строчки валидационного кода.

Вариант 5. Строгая серверная валидация в «ОбработкаПроверкиЗаполнения»

Клиентские перехваты обеспечивают удобство, но для надежности учета критически важно проверять данные перед записью объекта в базу данных. Для этого в модуле объекта или формы задействуем обработчик ОбработкаПроверкиЗаполнения.

Проверим кратность числа десяти при помощи оператора остатка от деления %:


&НаСервере
Процедура ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты)
    Если Объект.ЧисловоеПоле < 10 Или (Объект.ЧисловоеПоле % 10 <> 0) Тогда
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Значение поля должно быть не менее 10 и кратно 10!";
        Сообщение.Поле = "Объект.ЧисловоеПоле";
        Сообщение.УстановитьДанные(ЭтотОбъект);
        Сообщение.Сообщить();
        
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

Использование связки клиентского события ПриИзменении (для автоматической коррекции) и серверной валидации в ОбработкаПроверкиЗаполнения гарантирует, что в информационной базе всегда будут храниться корректные данные, соответствующие бизнес-правилам конфигурации.

← На главную