При разработке и настройке торгового учета в конфигурациях на платформе «1С:Предприятие 8» (таких как «Управление торговлей 11», «Комплексная автоматизация 2» или «ERP Управление предприятием») программисты часто сталкиваются с задачей сопоставления документов. Типичный пример — необходимость определить, по какому именно Заказу клиента был оформлен возврат, если сам возврат создавался на основании документа Реализация товаров и услуг.
В этой статье мы подробно разберем, как связать строки табличной части документа возврата со строками реализации, проанализируем типовые механизмы платформы, выявим распространенные заблуждения разработчиков и предложим готовые решения для реализации этой задачи.
Среди разработчиков 1С распространено мнение, что для связи строк между различными документами можно использовать стандартный реквизит ИдентификаторСтроки, расположенный в табличной части Товары. Однако на практике этот подход не работает.
Выясним причину, почему это так:
ИдентификаторСтроки (тип значения — строка или уникальный идентификатор UUID) генерируется динамически при создании строки в конкретном документе. Он уникален исключительно в пределах одного физического документа.КлючСвязи также не решает задачу междокументного сопоставления. Его ключевое назначение — связывать строки разных табличных частей внутри одного документа (например, сопоставлять строку товаров со строкой серий или скидок).Таким образом, использовать данные реквизиты для прямой связи строк возврата и реализации невозможно.
Рассмотрим, как данная задача решена в типовом функционале «1С:Управление торговлей 11». Начиная с ранних версий ERP-платформ, связь между возвращаемым товаром и его продажей фиксируется на уровне строк табличной части.
В табличной части Товары документа ВозвратТоваровОтКлиента присутствует важнейший реквизит — ДокументПродажи.
Когда пользователь оформляет возврат (даже если он создается по нескольким документам продажи сразу), система распределяет номенклатуру по строкам и в каждой строке явно указывает ссылку на конкретный документ РеализацияТоваровУслуг. Если в реализации был указан конкретный ЗаказКлиента (в шапке или в строках ТЧ), мы можем извлечь его, связав таблицы этих документов.
Рассмотрим подробнее, как составить оптимальный запрос для получения заказов-оснований по каждой строке возврата. Для этого мы соединим табличную часть товаров возврата с табличной частью товаров реализации по номенклатурным позициям, характеристикам и сериям (если они используются).
Разберем по шагам логику построения запроса:
Товары нашего документа возврата.Товары документа реализации, используя условие равенства документов: ТЧВозврата.ДокументПродажи = ТЧРеализации.Ссылка.ЗаказКлиента. Обратите внимание: в реализации заказ может быть указан как в строке табличной части (при детализации по заказам в строках), так и в шапке документа. Поэтому мы используем функцию ЕСТЬNULL для выбора заказа из строки, а при его отсутствии — из шапки реализации.Посмотрим на пример такого запроса:
ВЫБРАТЬ
ВозвратТовары.Ссылка КАК ДокументВозврата,
ВозвратТовары.НомерСтроки КАК НомерСтрокиВозврата,
ВозвратТовары.Номенклатура КАК Номенклатура,
ВозвратТовары.Характеристика КАК Характеристика,
ЕСТЬNULL(РеализацияТовары.ЗаказКлиента, РеализацияШапка.ЗаказКлиента) КАК ЗаказКлиента,
ВозвратТовары.Количество КАК КоличествоВозврата
ИЗ
Документ.ВозвратТоваровОтКлиента.Товары КАК ВозвратТовары
// Соединение с ТЧ Товары Реализации для поиска заказа в строке
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТовары
ПО ВозвратТовары.ДокументПродажи = РеализацияТовары.Ссылка
И ВозвратТовары.Номенклатура = РеализацияТовары.Номенклатура
И ВозвратТовары.Характеристика = РеализацияТовары.Характеристика
// Соединение с шапкой Реализации для поиска заказа, если он указан на весь документ
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК РеализацияШапка
ПО ВозвратТовары.ДокументПродажи = РеализацияШапка.Ссылка
ГДЕ
ВозвратТовары.Ссылка = &СсылкаВозврат
Описанный выше запрос отлично работает в большинстве стандартных ситуаций. Однако существует проблема «дублей», когда в одном документе реализации присутствуют две или более абсолютно одинаковые строки товара (например, две одинаковые позиции по разным заказам или с разной ценой/скидками).
Если клиент возвращает только одну единицу товара, стандартный запрос через левое соединение вернет обе строки реализации, что приведет к задвоению данных в выборке. Как решить эту проблему?
В рамках типового функционала без изменения метаданных со 100%-й точностью определить конкретную строку невозможно. В реальности система распределяет возвраты по принципу LIFO (или FIFO), списывая товар с наиболее поздних или ранних партий продаж. На практике для автоматического распределения в 1С используется документ Заявка на возврат товаров от клиента, который помогает интерактивно подобрать нужные строки продаж при помощи формы подбора.
Если перед вами стоит задача обеспечить гарантированную сквозную связь строк «Реализация <-> Возврат» без риска дублирования, оптимальным решением будет доработка конфигурации с помощью механизма расширений.
Проанализируем этот алгоритм:
Товары документа ВозвратТоваровОтКлиента. Назовите его, например, УникальныйКлючСтрокиПродажи (тип: Строка или УникальныйИдентификатор). Также добавьте аналогичный реквизит в документ РеализацияТоваровУслуг, если там еще нет уникального UUID для каждой строки.ЗаполнитьПоДокументуПродажи).Пример программного заполнения в расширении:
&После("ЗаполнитьТоварыПоРеализации")
Процедура Расш_ЗаполнитьТоварыПоРеализации(ДокументПродажи)
// Объект — это наш документ ВозвратТоваровОтКлиента
Для Каждого СтрокаВозврата Из ЭтотОбъект.Товары Цикл
// Находим соответствующую строку в исходной реализации по номеру строки или иным параметрам
// и переносим уникальный сквозной идентификатор
СтрокаРеализации = ДокументПродажи.Товары.Найти(СтрокаВозврата.НомерСтроки - 1);
Если СтрокаРеализации <> Неопределено Тогда
СтрокаВозврата.УникальныйКлючСтрокиПродажи = СтрокаРеализации.ИдентификаторСтроки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
После такой доработки ваш запрос связи документов будет соединять таблицы не по номенклатуре, а по точному соответствию полей УникальныйКлючСтрокиПродажи и ИдентификаторСтроки, что полностью исключит коллизии и дублирование данных в отчетах.
При работе со связями возвратов и реализаций важно помнить о двух важных аспектах учета в 1С:
ДокументПродажи заполнена, при проведении документа и последующем расчете себестоимости программа сможет точно вернуть товар на склад по той стоимости, по которой он был списан в момент продажи (используя регистр ВыручкаИСебестоимостьПродаж).Заказы клиентов. Заказ не откроется заново для повторной отгрузки. Если клиенту требуется предоставить замену, необходимо использовать бизнес-процесс с созданием документа Заявка на возврат товаров от клиента с типом операции «Замена товаров».Используя предложенные методики, вы сможете легко решить задачу связывания строк документов возврата и реализации, построить корректные отчеты и при необходимости реализовать точный сквозной аналитический учет.