Как правильно запретить выбор некорректного элемента в 1С в процедуре ПриИзменении

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

При разработке управляемых форм в 1С часто возникает задача: ограничить выбор значений для реквизита так, чтобы пользователь не мог подставить неподходящий элемент. Однако разработчики сталкиваются с важной особенностью платформы — в клиентском событии ПриИзменении и серверном обработчике ПриИзмененииНаСервере у платформы нет параметров Отказ или СтандартнаяОбработка. В момент срабатывания этих процедур значение реквизита уже фактически изменилось, и отменить выбор простой командой нельзя.

Рассмотрим подробнее, как организовать валидацию данных, перехватить ввод по строке и корректно откатить выбор к предыдущему значению.

Ограничение быстрого ввода по строке и формы выбора

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

  1. Настройка связей и параметров выбора. Если допустимость элемента зависит от другого реквизита (например, организации или договора), на уровне элемента формы настраивается свойство СвязиПараметровВыбора или ПараметрыВыбора. Это автоматически фильтрует список и в открывающейся форме, и при подборе по строке.
  2. Обработчик ОбработкаПолученияДанныхВыбора в модуле менеджера. Это универсальный механизм для контроля автоподбора. Когда пользователь начинает набирать текст в поле ввода, платформа вызывает этот обработчик. В нем можно переопределить параметр ДанныеВыбора, сформировав свой СписокЗначений с допустимыми ссылками, и установить СтандартнаяОбработка = Ложь.
  3. Использование режима выбора из списка. Если список допустимых вариантов небольшой и фиксированный, установим у элемента формы свойство РежимВыбораИзСписка = Истина и заполним коллекцию СписокВыбора. В этом случае платформенный ввод произвольного текста из всей базы будет заблокирован.

Алгоритм проверки и отката значения в событии ПриИзменении

Если ограничить ввод заранее невозможно и требуется серверная проверка произвольного условия (например, проверка прав или присутствия физического лица в специальном реестре), выполним валидацию в событии ПриИзменении.

Поскольку параметр Отказ отсутствует, при обнаружении запрещенного элемента необходимо очистить поле либо вернуть то значение, которое находилось в реквизите до редактирования.

Проанализируем пошаговый алгоритм восстановления предыдущего значения:

  1. Зафиксируем значение реквизита до начала редактирования. Для этого в событии формы (например, ПриАктивизацииЭлемента или ПриНачалеРедактирования для табличной части) сохраним текущее значение в клиентскую переменную формы или временный реквизит ПредыдущееЗначение.
  2. В обработчике ПриИзменении вызовем серверную функцию проверки.
  3. Если выбранный элемент не проходит условие, присвоим реквизиту сохраненное ПредыдущееЗначение (или ПустаяСсылка()) и выведем сообщение пользователю.
  4. Если проверка прошла успешно, обновим ПредыдущееЗначение новым выбранным элементом.

Пример реализации кода

Посмотрим на пример реализации данного алгоритма для реквизита ФизЛицо в управляемой форме.

В модуле управляемой формы объявим переменную и пропишем обработчики событий:


&НаКлиенте
Перем ПредыдущийВыбор;

&НаКлиенте
Процедура ФизЛицоПриНачалеРедактирования/ПриАктивизации(Элемент)
    // Фиксируем значение до редактирования
    ПредыдущийВыбор = Объект.ФизЛицо;
КонецПроцедуры

&НаКлиенте
Процедура ФизЛицоПриИзменении(Элемент)
    
    Если Не ВыбранноеФизЛицоРазрешеноНаСервере(Объект.ФизЛицо) Тогда
        
        // Откатываем выбор к предыдущему значению
        Объект.ФизЛицо = ПредыдущийВыбор;
        
        ПоказатьОповещениеПользователю(
            "Ошибка выбора", 
            , 
            "Выбранный сотрудник недопустим для данного документа!", 
            СтатусОповещенияПользователя.Внимание
        );
        Возврат;
        
    КонецЕсли;
    
    // Если проверка пройдена, запоминаем новое корректное значение
    ПредыдущийВыбор = Объект.ФизЛицо;

КонецПроцедуры

&НаСервереБезКонтекста
Функция ВыбранноеФизЛицоРазрешеноНаСервере(Знач ФизЛицо)
    
    Если Не ЗначениеЗаполнено(ФизЛицо) Тогда
        Возврат Истина;
    КонецЕсли;
    
    // Выполняем проверку по бизнес-логике
    // ...
    
    Возврат Разрешено;

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

Финальная защита при записи

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

← На главную