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