Как настроить корректное отображение элементов формы при копировании документа

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет Торговля и дистрибуция
← На главную

При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда видимость, доступность или расположение элементов на управляемой форме зависят от значения определенного реквизита (например, ВидДоставки). Однако при стандартном копировании документа («Создать копированием») платформа заполняет данные объекта, но не всегда корректно инициирует события формы, отвечающие за визуальное представление. В результате пользователь видит форму, не соответствующую логике выбранного значения. Разберем подробно, как решить эту проблему, основываясь на лучших практиках разработки.

Анализ проблемы: почему стандартные методы не работают

Проанализируем ситуацию: обычно логика управления интерфейсом прописывается в событии ПриИзменении соответствующего реквизита. Это событие является интерактивным — оно срабатывает только тогда, когда пользователь непосредственно меняет значение в поле ввода. При копировании документа данные в объект подтягиваются программно, и событие ПриИзменении не вызывается. Попытка вызвать этот обработчик напрямую из процедур открытия формы часто приводит к ошибкам, так как внутри него могут находиться интерактивные функции (например, ПоказатьВопрос), которые недопустимы в момент инициализации формы на сервере.

Шаг 1. Разделение логики на интерактивную и визуальную

Первым делом нам необходимо отделить код, который меняет данные (очищает табличные части, заполняет реквизиты), от кода, который управляет видимостью элементов. Рассмотрим пример правильной структуры модуля формы. Создадим общую процедуру УстановитьВидимостьЭлементовНаСервере, которую будем вызывать из разных точек.


&НаСервере
Процедура УстановитьВидимостьЭлементовНаСервере()
    
    // Определяем логику видимости в зависимости от реквизита ВидДоставки
    Если Объект.ВидДоставки = Перечисления.СТ_ВидыДоставки.Самовывоз Тогда
        Элементы.ГруппаАдресДоставки.Видимость = Ложь;
        Элементы.ГруппаПеревозчик.Видимость = Ложь;
    ИначеЕсли Объект.ВидДоставки = Перечисления.СТ_ВидыДоставки.ДоставкаКлиенту Тогда
        Элементы.ГруппаАдресДоставки.Видимость = Истина;
        Элементы.ГруппаПеревозчик.Видимость = Истина;
    КонецЕсли;
    
    // Дополнительная настройка для специфических видов доставки
    Элементы.ЗонаДоставки.Видимость = (Объект.ВидДоставки <> ПредопределенноеЗначение("Перечисление.СТ_ВидыДоставки.Переработка"));
    
КонецПроцедуры

Шаг 2. Настройка формы при создании (обработка копирования)

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем, что это создание нового документа, а не открытие существующего
    Если Объект.Ссылка.Пустая() Тогда
        
        // Проверяем, заполнено ли значение копирования (параметр платформы)
        Если Параметры.ЗначениеЗаполнено(Параметры.ЗначениеКопирования) Тогда
            // Если документ копируется, вызываем настройку интерфейса
            УстановитьВидимостьЭлементовНаСервере();
        Иначе
            // Если это просто создание нового, устанавливаем значения по умолчанию
            // Объект.ВидДоставки = ...
            УстановитьВидимостьЭлементовНаСервере();
        КонецЕсли;
        
    Иначе
        // При открытии существующего документа также нужно настроить видимость
        УстановитьВидимостьЭлементовНаСервере();
    КонецЕсли;
    
КонецПроцедуры

Шаг 3. Обработка интерактивных действий пользователя

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


&НаКлиенте
Процедура ВидДоставкиПриИзменении(Элемент)
    
    // Если в документе уже есть данные, спрашиваем пользователя об очистке
    Если Объект.Распоряжения.Количество() > 0 Тогда
        
        ОписаниеОповещения = Новый ОписаниеОповещения("ВидДоставкиЗавершение", ЭтотОбъект);
        ТекстВопроса = "При изменении вида доставки табличная часть будет очищена. Продолжить?";
        ПоказатьВопрос(ОписаниеОповещения, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
        
    Иначе
        // Если данных нет, просто обновляем форму
        ВидДоставкиОбновитьИнтерфейсНаСервере();
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Процедура ВидДоставкиОбновитьИнтерфейсНаСервере()
    // Вызываем нашу универсальную процедуру
    УстановитьВидимостьЭлементовНаСервере();
КонецПроцедуры

Важный момент: обратите внимание, что при копировании документа вопрос об очистке табличной части задаваться не будет, так как мы вызываем настройку видимости напрямую на сервере в ПриСозданииНаСервере, минуя клиентскую логику с вопросами. Это именно то поведение, которое ожидается от системы.

Шаг 4. Устранение проблем с "исчезающими" реквизитами

Рассмотрим ситуацию, когда при копировании реквизиты (например, ЗонаДоставки или АдресЗагрузки) заполнены в объекте, но не видны на форме или кажутся пустыми. Проанализируем возможные причины:

  1. Связи параметров выбора: Если у поля настроены связи по типу Отбор.Владелец(Объект.ВидДоставки), то при копировании платформа может не сразу сопоставить значения, если вид доставки и адрес заполняются одновременно. Помогает явный вызов обновления формы.
  2. Условное оформление: Проверьте, не скрываются ли элементы через динамические настройки в УсловноеОформление формы. Если там прописаны жесткие условия на пустую ссылку, при копировании они могут сработать неверно.
  3. Обновление данных формы: Иногда после программного изменения реквизитов на сервере требуется вызвать метод КопироватьДанныеФормы(Объект, ЭтаФорма.Объект), хотя в стандартных сценариях 1С 8.3 это происходит автоматически.

Использование функционала БСП для настройки формы

Если ваша конфигурация построена на базе БСП (Библиотеки Стандартных Подсистем), проанализируем современный подход. Вместо прямого управления свойством Видимость элементов, рекомендуется использовать процедуру ПриЧтенииНаСервере или специальные подсистемы управления интерфейсом. Однако для самописных документов метод с выносом логики в УстановитьВидимостьЭлементовНаСервере и ее вызовом из ПриСозданииНаСервере и ПриИзменении остается самым надежным и понятным.

Резюме: Чтобы при копировании документа форма отображалась корректно, никогда не полагайтесь на клиентские события ПриИзменении. Всегда создавайте отдельную серверную процедуру для настройки свойств элементов Видимость, Доступность и ТолькоПросмотр, и вызывайте её в обработчике создания формы на сервере, проверяя наличие данных в Параметры.ЗначениеКопирования.

← На главную