При сопровождении и доработке конфигураций "1С:Предприятие" на обычных формах (таких как "Управление производственным предприятием 1.3", "Комплексная автоматизация 1.1" или "Бухгалтерия предприятия 2.0") разработчики часто сталкиваются с типовыми механизмами, которые сложно адаптировать под новые требования. Одним из таких механизмов является работа с регистром сведений СоставКомиссий.
В этой статье мы подробно разберем классическую проблему: почему при добавлении возможности выбора комиссии в новый (кастомный) документ переменная ФормаВыбора.ДокументОбъект внутри универсальной процедуры неожиданно принимает значение Неопределено, хотя сам параметр передается в процедуру корректно. Мы выясним внутренние причины такого поведения платформы 1С и изучим два способа решения этой проблемы.
---
Рассмотрим стандартную процедуру, которая используется в конфигурации для вызова формы выбора состава комиссии:
Процедура ВыбратьСоставКомиссии(ДокументОбъект, Владелец) Экспорт
ФормаВыбора = РегистрыСведений.СоставКомиссий.ПолучитьФормуСписка("ФормаВыбора", Владелец);
ФормаВыбора.ДокументОбъект = ДокументОбъект;
ФормаВыбора.ПараметрОтборПоИзмерению = Новый Структура("Организация", ДокументОбъект.Организация);
ФормаВыбора.РежимВыбора = Истина;
ФормаВыбора.ЗакрыватьПриВыборе = Истина;
ФормаВыбора.Открыть();
КонецПроцедуры // ВыбратьСоставКомиссии()
При вызове этой процедуры из стандартных документов (например, "Инвентаризация товаров на складе" или "Списание товаров") все работает отлично. Переданный документ записывается в свойство ФормаВыбора.ДокументОбъект, форма открывается, и выбранные члены комиссии успешно возвращаются назад.
Однако при попытке вызвать эту же процедуру из нового, созданного нами документа, происходит сбой. При пошаговой отладке мы видим следующую картину:
ДокументОбъект содержит валидный объект нашего нового документа (например, ДокументОбъект.МояНоваяИнвентаризация).ФормаВыбора.ДокументОбъект = ДокументОбъект; происходит присвоение.ФормаВыбора.ДокументОбъект становится равным Неопределено. При этом никаких ошибок выполнения или предупреждений система не выдает.---
Для того чтобы понять причины такого поведения платформы, проанализируем устройство обычных форм. В отличие от управляемых форм, в обычных формах на вкладке «Реквизиты» объявляются локальные переменные формы со строгой типизацией.
В форме выбора регистра сведений СоставКомиссий создан локальный реквизит с именем ДокументОбъект. Этот реквизит имеет составной тип данных. При разработке типовой конфигурации в этот составной тип разработчики фирмы «1С» жестко прописали список документов, которые могут использовать этот регистр. Напротив них в конфигураторе установлены соответствующие флажки.
Когда мы пытаемся присвоить реквизиту формы значение, платформа 1С выполняет неявную проверку типов. Работает это следующим образом:
Неопределено).Поскольку наш новый документ не был добавлен в составной тип реквизита ДокументОбъект на форме выбора регистра, платформа блокирует передачу этого объекта на уровне интерфейсных механизмов.
---
Если мы хотим сохранить строгий контроль типов и гарантировать, что форма выбора будет работать только с четко определенным списком документов, нам необходимо добавить наш новый документ в список разрешенных типов реквизита формы.
Выполним это по шагам в конфигураторе:
СоставКомиссий (или аналогичный регистр в вашей базе).ФормаВыбора).ДокументОбъект.F4 или через контекстное меню).ДокументОбъект, развернем ее, найдем наш новый документ и установим напротив него флажок.Преимущества метода: Сохраняется строгая типизация данных. Программист всегда видит в конфигураторе весь перечень документов, которые интегрированы с формой выбора состава комиссии.
Недостатки метода: Если в дальнейшем нам потребуется добавить состав комиссий в еще один новый документ, нам придется заново открывать форму выбора регистра в конфигураторе и вручную добавлять новый тип. Это усложняет поддержку и обновление конфигурации.
---
Если перед нами стоит задача сделать форму выбора абсолютно универсальной, чтобы она могла без доработок принимать любые документы (включая те, которые будут созданы другими разработчиками в будущем), нам следует отказаться от строгого составного типа для реквизита формы.
Разберем по шагам, как сделать тип реквизита универсальным:
СоставКомиссий в конфигураторе.ДокументОбъект.F4) и нажмем кнопку выбора в строке «Тип».Произвольный.Теперь платформа 1С перестанет контролировать тип передаваемого объекта при присвоении в строке ФормаВыбора.ДокументОбъект = ДокументОбъект;. В этот реквизит можно будет передать абсолютно любой документ.
Важное предупреждение при использовании произвольного типа: При переходе на тип Произвольный вся ответственность за совместимость кода ложится на разработчика. Внутри кода самой формы выбора (например, при нажатии кнопки "ОК") наверняка есть обращения к свойствам переданного документа. Например, заполнение табличной части:
// Пример гипотетического кода внутри ФормыВыбора при закрытии
Если ЗначениеЗаполнено(ДокументОбъект) Тогда
// Заполняем ТЧ комиссии в документе-владельце
ДокументОбъект.Комиссия.Очистить();
Для Каждого СтрокаКомиссии Из ТаблицаВыбранныхЧленов Цикл
НоваяСтрока = ДокументОбъект.Комиссия.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаКомиссии); КонецЦикла;
КонецЕсли;
Если ваш новый документ содержит точно такую же табличную часть (с теми же именами реквизитов Комиссия), то код отработает без ошибок. Если же в каком-то документе структура метаданных будет отличаться, система выдаст ошибку во время выполнения (Runtime Exception). Поэтому при использовании произвольного типа убедитесь, что все документы-клиенты имеют идентичную структуру реквизитов для интеграции с комиссиями.
---
Для полноты картины рассмотрим, как разработчики фирмы «1С» ушли от подобных проблем при переходе на управляемый интерфейс (в конфигурациях ERP, КА 2, БП 3).
В управляемых формах передача тяжелых серверных объектов типа ДокументОбъект на клиентскую часть (в форму выбора) считается плохой практикой и часто технически невозможна. Вместо этого используется событийная модель взаимодействия форм:
ОповеститьОВыборе или через описание оповещения (ОписаниеОповещенияОЗакрытии).Такой подход полностью исключает возникновение конфликтов типов данных на уровне метаданных формы выбора и делает механизмы выбора максимально изолированными и универсальными.