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