Нередко при разработке интерфейсов управляемого приложения 1С требуется разместить в форме элемента справочника (например, Контрагенты или Клиенты) связанный список документов по данному элементу. Для этого используется таблица с динамическим списком. При добавлении такой таблицы платформа автоматически создает стандартную командную панель с кнопкой Создать.
Однако при нажатии стандартной кнопки создается пустой документ, и ссылка на текущий элемент справочника в него не подставляется. Разберем основные способы реализации автозаполнения реквизитов создаваемого документа, проанализируем нюансы работы платформы и рассмотрим правильные варианты архитектурного решения.
Стандартная кнопка добавления привязана к системному действию таблицы динамического списка. Чтобы передать в создаваемый документ нужные значения без переопределения всей командной панели, воспользуемся событием таблицы формы ПередНачаломДобавления.
В этом событии параметр Параметр позволяет передать структуру со системным ключом ЗначенияЗаполнения или произвольными параметрами формы:
&НаКлиенте
Процедура ДокументыПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
// Проверяем, что текущий элемент справочника уже записан
Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
ПоказатьПредупреждение(, "Сначала необходимо записать элемент!");
Отказ = Истина;
Возврат;
КонецЕсли;
// Передаем структуру значений заполнения
СтруктураЗаполнения = Новый Структура("Клиент", Объект.Ссылка);
Параметр = Новый Структура("ЗначенияЗаполнения", СтруктураЗаполнения);
КонецПроцедуры
При таком подходе платформа передает переданные значения напрямую в механизм заполнения создаваемого объекта.
Рассмотрим, как правильно принять переданные данные в самом документе. Если параметры передаются через форму документа, обработаем их в процедуре ПриСозданииНаСервере формы документа.
Чтобы избежать ошибок при отсутствии параметра (например, когда документ создается из общего списка, а не из карточки контрагента), обязательно проверяем наличие свойства через метод Свойство():
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
// Проверяем наличие переданного параметра Клиент
ЗначениеКлиента = Неопределено;
Если Параметры.Свойство("Клиент", ЗначениеКлиента) Тогда
Объект.Клиент = ЗначениеКлиента;
ИначеЕсли Параметры.Свойство("ЗначенияЗаполнения") И Параметры.ЗначенияЗаполнения.Свойство("Клиент", ЗначениеКлиента) Тогда
Объект.Клиент = ЗначениеКлиента;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Рекомендация по стандартам разработки 1С: Логику начального заполнения реквизитов объекта предпочтительно размещать не в модуле формы, а в модуле объекта документа в процедуре ОбработкаЗаполнения. Это гарантирует правильное заполнение как при интерактивном вводе, так и при программном создании:
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
Если ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда
Если ДанныеЗаполнения.Свойство("Клиент") Тогда
ЭтотОбъект.Клиент = ДанныеЗаполнения.Клиент;
КонецЕсли;
ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("СправочникСсылка.Контрагенты") Тогда
ЭтотОбъект.Клиент = ДанныеЗаполнения;
КонецЕсли;
КонецПроцедуры
Платформа 1С:Предприятие 8.3 имеет встроенный механизм автоматического заполнения реквизитов по отбору динамического списка. Чтобы он сработал без написания кода в событии ПередНачаломДобавления, должны выполняться следующие условия:
Отбор (например, в свойствах динамического списка или через Список.ФиксированныеНастройки.Отбор).Клиент).Истина.Если отбор в динамическом списке задан через параметры произвольного запроса (например, Список.Параметры.УстановитьЗначениеПараметра(&Клиент, ...)), платформа не сможет сопоставить параметр с реквизитом документа, и автоматическое заполнение не сработает. В таком случае необходимо использовать явную передачу через событие таблицы списка (Способ 1).
Если требуется полностью переопределить логику создания или передать сложный контекст, можно отменить стандартное действие и программно открыть форму нового документа:
&НаКлиенте
Процедура ДокументыПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
Отказ = Истина; // Отменяем стандартное интерактивное добавление
Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
ПоказатьПредупреждение(, "Сначала необходимо записать элемент!");
Возврат;
КонецЕсли;
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ЗначенияЗаполнения", Новый Структура("Клиент", Объект.Ссылка));
// Передаем элемент списка третьим параметром для автоматического обновления и позиционирования
ОткрытьФорму("Документ.ЗаказКлиента.ФормаОбъекта", ПараметрыФормы, Элемент);
КонецПроцедуры
Передача ссылки на таблицу (параметр Элемент) в метод ОткрытьФорму связывает открываемую форму со списком-владельцем, благодаря чему после проведения или записи документа список в форме справочника автоматически обновится и сфокусируется на новой строке.