В конфигурации 1С:Управление производственным предприятием 1.3 (УПП) задача сопоставления реализаций и возвратов часто вызывает затруднения у начинающих разработчиков. Это связано с тем, что связь между документами может быть организована несколькими способами: через реквизит ДокументОснование, через измерение Сделка или через записи в регистрах накопления. Разберем подробно, как правильно построить запрос, чтобы получить достоверные данные о возвратах в привязке к исходным отгрузкам.
Проанализируем работу регистра накопления Продажи. Это наиболее надежный источник данных в УПП для решения нашей задачи. При проведении документа Возврат товаров от покупателя система делает записи в этот регистр с отрицательными значениями (сторно оборотов). Важной особенностью является то, что в измерение ДокументПродажи записывается ссылка на исходную Реализацию товаров и услуг.
Рассмотрим пример запроса, который позволяет вытащить все возвраты и связанные с ними реализации. Мы будем использовать виртуальную таблицу Обороты регистра Продажи. Обратите внимание на использование условий в параметрах виртуальной таблицы — это существенно ускоряет выполнение запроса.
ВЫБРАТЬ
Продажи.ДокументПродажи КАК Реализация,
Продажи.Регистратор КАК Возврат,
-Продажи.КоличествоОборот КАК КоличествоВозврата,
-Продажи.СтоимостьОборот КАК СуммаВозврата
ИЗ
РегистрНакопления.Продажи.Обороты(
&НачалоПериода,
&КонецПериода,
Регистратор,
ТИПЗНАЧЕНИЯ(ДокументПродажи) = ТИП(Документ.РеализацияТоваровУслуг)
) КАК Продажи
ГДЕ
ТИПЗНАЧЕНИЯ(Продажи.Регистратор) = ТИП(Документ.ВозвратТоваровОтПокупателя)
УПОРЯДОЧИТЬ ПО
Реализация
Разберем, почему мы используем знак «минус» перед ресурсами. Так как возврат в регистре Продажи хранится как отрицательный оборот (например, -10 штук), то для корректного отображения в отчете мы инвертируем знак, чтобы получить положительное количество возвращенного товара.
Выясним причину, по которой КритерийОтбора.СвязанныеДокументы не всегда удобен для отчетов. Хотя этот механизм и позволяет найти все документы, созданные на основании реализации, программно обращаться к нему в цикле для каждой строки отчета крайне непроизводительно. На уровне базы данных критерий отбора — это индекс, который связывает поле Ссылка с полями типа ЛюбаяСсылка, где данная ссылка может встретиться.
Если нам нужно использовать этот механизм в запросе, мы обращаемся к таблице КритерийОтбора.СвязанныеДокументы. Однако помните, что в УПП документ возврата может быть создан без явного указания «Документа-основания» (например, через заполнение по заказу или сделке), и в этом случае критерий отбора может не показать связь, в то время как регистр Продажи её зафиксирует.
Рассмотрим ситуацию, когда нам необходимо получить список реализаций, по которым не было совершено возвратов. Для этого мы будем использовать ЛЕВОЕ СОЕДИНЕНИЕ таблицы реализаций с данными о возвратах из регистра. Проанализируем следующий подход:
Продажи).РеализацияТоваровУслуг с этой временной таблицей.ГДЕ мы отсекаем те записи, для которых данные в правой таблице (возвраты) равны NULL.Посмотрим на пример кода запроса:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Реализация.Ссылка КАК РеализацияСсылка
ПОМЕСТИТЬ ВТ_РеализацииСВозвратами
ИЗ
РегистрНакопления.Продажи.Обороты(, , Регистратор, ) КАК Продажи
ГДЕ
ТИПЗНАЧЕНИЯ(Продажи.Регистратор) = ТИП(Документ.ВозвратТоваровОтПокупателя)
И ТИПЗНАЧЕНИЯ(Продажи.ДокументПродажи) = ТИП(Документ.РеализацияТоваровУслуг)
СГРУППИРОВАТЬ ПО
Реализация.Ссылка
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка КАК ДокументРеализации,
РеализацияТоваровУслуг.Дата КАК ДатаРеализации
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_РеализацииСВозвратами КАК Возвраты
ПО РеализацияТоваровУслуг.Ссылка = Возвраты.РеализацияСсылка
ГДЕ
РеализацияТоваровУслуг.Проведен
И РеализацияТоваровУслуг.Дата МЕЖДУ &ДатаНачала И &ДатаКонец
И Возвраты.РеализацияСсылка ЕСТЬ NULL
Этот запрос выводит только те реализации, по которым за выбранный период не было зафиксировано ни одного возврата в регистре Продажи. Если же вам, наоборот, нужны реализации только с возвратами, замените ЕСТЬ NULL на НЕ Возвраты.РеализацияСсылка ЕСТЬ NULL.
При написании запросов в 1С важно учитывать производительность. Разберем два момента:
1. Оператор ССЫЛКА против ТИПЗНАЧЕНИЯ. В текстах запросов для проверки типа конкретного документа лучше использовать конструкцию ... ГДЕ Регистратор ССЫЛКА Документ.ВозвратТоваровОтПокупателя. Это работает несколько быстрее, так как платформа на уровне SQL может оптимизировать такой запрос лучше, чем через функцию TYPEOF (которой соответствует ТИПЗНАЧЕНИЯ).
2. Составные типы данных. Поле ДокументПродажи в регистре Продажи является составным. Чтобы получить доступ к реквизитам документа реализации (например, к складу или подразделению), всегда используйте функцию ВЫРАЗИТЬ(ДокументПродажи КАК Документ.РеализацияТоваровУслуг). Это предотвратит избыточное соединение со всеми возможными таблицами документов, входящими в составной тип.
Проанализируем ситуацию, упомянутую в обсуждении: иногда связь идет не напрямую, а через Сделку (заказ покупателя). В УПП это распространенная практика. Если возврат оформлен по заказу, он может автоматически «подцепить» реализацию, если она была единственной. Если же реализаций было несколько, система может распределить возврат по ним по методу ФИФО или оставить ДокументПродажи пустым (указав там сам возврат).
Если ваш учет настроен так, что связь гарантируется только через поле Сделка, запрос будет выглядеть так:
ВЫБРАТЬ
Реал.Ссылка КАК Реализация,
Возврат.Ссылка КАК Возврат
ИЗ
Документ.РеализацияТоваровУслуг КАК Реал
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ВозвратТоваровОтПокупателя КАК Возврат
ПО Реал.Сделка = Возврат.Сделка
ГДЕ
Реал.Проведен
И Возврат.Проведен
И НЕ Реал.Сделка = ЗНАЧЕНИЕ(Документ.ЗаказПокупателя.ПустаяСсылка)
Внимание: Этот метод менее точен, так как если по одному заказу было две реализации на разные товары, а возврат был только по одной, в данном запросе каждая реализация «увидит» этот возврат. Поэтому всегда приоритетным является использование регистра Продажи или анализ табличной части Товары документа возврата, где в поле ДокументПартии может быть указана конкретная реализация.
Таким образом, мы разобрали основные способы связки документов. Для быстрого отчета «Реализации с возвратами» используйте данные регистра Продажи, так как это штатный механизм системы для отслеживания истории движения товаров.