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