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