Почему реквизит ФормаВыбора.ДокументОбъект сбрасывается в Неопределено при открытии формы и как это исправить?

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

При сопровождении и доработке конфигураций "1С:Предприятие" на обычных формах (таких как "Управление производственным предприятием 1.3", "Комплексная автоматизация 1.1" или "Бухгалтерия предприятия 2.0") разработчики часто сталкиваются с типовыми механизмами, которые сложно адаптировать под новые требования. Одним из таких механизмов является работа с регистром сведений СоставКомиссий.

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

---

Анализ исходного кода и сути проблемы

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


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

При вызове этой процедуры из стандартных документов (например, "Инвентаризация товаров на складе" или "Списание товаров") все работает отлично. Переданный документ записывается в свойство ФормаВыбора.ДокументОбъект, форма открывается, и выбранные члены комиссии успешно возвращаются назад.

Однако при попытке вызвать эту же процедуру из нового, созданного нами документа, происходит сбой. При пошаговой отладке мы видим следующую картину:

  1. В момент передачи параметра в процедуру переменная ДокументОбъект содержит валидный объект нашего нового документа (например, ДокументОбъект.МояНоваяИнвентаризация).
  2. В строке ФормаВыбора.ДокументОбъект = ДокументОбъект; происходит присвоение.
  3. Сразу после выполнения этой строки значение свойства ФормаВыбора.ДокументОбъект становится равным Неопределено. При этом никаких ошибок выполнения или предупреждений система не выдает.

---

Почему платформа 1С «тихо» очищает значение?

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

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

Когда мы пытаемся присвоить реквизиту формы значение, платформа 1С выполняет неявную проверку типов. Работает это следующим образом:

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

---

Вариант решения №1. Расширение составного типа данных (Стандартный путь)

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

Выполним это по шагам в конфигураторе:

  1. Откроем дерево конфигурации и найдем регистр сведений СоставКомиссий (или аналогичный регистр в вашей базе).
  2. Развернем ветку регистра, найдем раздел «Формы» и откроем форму списка, которая используется для выбора (в нашем примере это ФормаВыбора).
  3. В окне редактора формы (обычно в правой верхней части экрана) перейдем на вкладку «Реквизиты».
  4. Найдем в списке реквизитов строку с именем ДокументОбъект.
  5. Выделим этот реквизит и откроем окно его свойств (нажатием клавиши F4 или через контекстное меню).
  6. В палитре свойств найдем строку «Тип» и нажмем на кнопку выбора (три точки) в конце строки.
  7. Перед нами откроется стандартное окно выбора типов данных. Найдем в дереве типов ветку ДокументОбъект, развернем ее, найдем наш новый документ и установим напротив него флажок.
  8. Нажмем кнопку «ОК», сохраним изменения в конфигурации базы данных и проверим работу механизма в режиме "1С:Предприятие".

Преимущества метода: Сохраняется строгая типизация данных. Программист всегда видит в конфигураторе весь перечень документов, которые интегрированы с формой выбора состава комиссии.

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

---

Вариант решения №2. Использование произвольного типа данных (Универсальный путь)

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

Разберем по шагам, как сделать тип реквизита универсальным:

  1. Откроем форму выбора регистра сведений СоставКомиссий в конфигураторе.
  2. Перейдем на вкладку «Реквизиты» и найдем реквизит ДокументОбъект.
  3. Откроем палитру свойств реквизита (клавиша F4) и нажмем кнопку выбора в строке «Тип».
  4. В открывшемся окне выбора типов снимем флажки со всех документов и выберем самый верхний, универсальный тип — Произвольный.
  5. Сохраним изменения в конфигураторе.

Теперь платформа 1С перестанет контролировать тип передаваемого объекта при присвоении в строке ФормаВыбора.ДокументОбъект = ДокументОбъект;. В этот реквизит можно будет передать абсолютно любой документ.

Важное предупреждение при использовании произвольного типа: При переходе на тип Произвольный вся ответственность за совместимость кода ложится на разработчика. Внутри кода самой формы выбора (например, при нажатии кнопки "ОК") наверняка есть обращения к свойствам переданного документа. Например, заполнение табличной части:


// Пример гипотетического кода внутри ФормыВыбора при закрытии
Если ЗначениеЗаполнено(ДокументОбъект) Тогда
    // Заполняем ТЧ комиссии в документе-владельце
    ДокументОбъект.Комиссия.Очистить();
    Для Каждого СтрокаКомиссии Из ТаблицаВыбранныхЧленов Цикл
        НоваяСтрока = ДокументОбъект.Комиссия.Добавить();
        ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаКомиссии); КонецЦикла;
КонецЕсли;

Если ваш новый документ содержит точно такую же табличную часть (с теми же именами реквизитов Комиссия), то код отработает без ошибок. Если же в каком-то документе структура метаданных будет отличаться, система выдаст ошибку во время выполнения (Runtime Exception). Поэтому при использовании произвольного типа убедитесь, что все документы-клиенты имеют идентичную структуру реквизитов для интеграции с комиссиями.

---

Как этот механизм реализован в современных управляемых формах?

Для полноты картины рассмотрим, как разработчики фирмы «1С» ушли от подобных проблем при переходе на управляемый интерфейс (в конфигурациях ERP, КА 2, БП 3).

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

  1. В форму выбора передаются только легкие примитивные типы данных (например, ссылка на организацию в качестве параметра отбора) через структуру параметров открытия формы.
  2. Форма выбора открывается как модальное окно или с блокировкой формы владельца.
  3. Пользователь производит выбор членов комиссии.
  4. При подтверждении выбора форма закрывается и возвращает массив выбранных структур или ссылок назад в форму документа-источника через стандартный механизм ОповеститьОВыборе или через описание оповещения (ОписаниеОповещенияОЗакрытии).
  5. Обработчик выбора, находящийся непосредственно в модуле формы самого документа, принимает эти данные и самостоятельно заполняет свою табличную часть на клиенте или на сервере.

Такой подход полностью исключает возникновение конфликтов типов данных на уровне метаданных формы выбора и делает механизмы выбора максимально изолированными и универсальными.

← На главную