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