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