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