Как правильно связать документы по номенклатуре в запросе 1С:ERP

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет
← На главную

При разработке в крупных конфигурациях, таких как 1С:ERP 2.4, начинающие разработчики часто сталкиваются с критикой со стороны архитекторов по поводу «кривых» запросов. Одной из самых частых проблем является попытка получить данные из цепочки документов без учета конкретных товарных позиций и без использования механизмов оптимизации. Рассмотрим ситуацию, когда нам необходимо получить значение «Несоответствие» из документа СТ_РегистрацияНесоответствий, основываясь на данных документа ВнутреннееПотреблениеТоваров.

Разберем основные ошибки исходного кода и построим правильный, оптимизированный запрос, учитывающий связь по номенклатуре и особенности работы платформы 1С:Предприятие 8.3.

Анализ проблемы: почему запрос считается «кривым»

Проанализируем типичные ошибки, которые делают запрос неэффективным и потенциально неверным:

  1. Отсутствие связи по номенклатуре: Если мы связываем документы только по ссылкам (например, ВнутреннееПотребление.Заказ = Заказ.Ссылка), то при наличии нескольких строк в табличной части запрос вернет «декартово произведение» — все товары одного документа соединятся со всеми товарами другого. Это приведет к дублированию строк и неверным результатам.
  2. Множественное обращение к одной таблице: Использование конструкции ОБЪЕДИНИТЬ для обращения к одной и той же таблице ВнутреннееПотреблениеТоваров с разными условиями — это лишняя нагрузка на СУБД. Проще выбрать данные один раз во временную таблицу.
  3. Работа с составными типами: Поле ДокументОснование обычно является составным. Соединение «через точку» или прямое соединение с таким полем заставляет 1С генерировать крайне тяжелый SQL-код, опрашивающий все возможные таблицы документов.
  4. Отсутствие фильтрации перед соединением: Внутренние соединения (ВНУТРЕННЕЕ СОЕДИНЕНИЕ) огромных таблиц до применения отбора по ссылке &Ссылка заставляют систему обрабатывать лишние данные.

Шаг 1: Использование временных таблиц для оптимизации

Первым делом мы должны отказаться от двойного выбора данных. Создадим временную таблицу, в которую поместим только нужные нам товары из текущего документа. Это позволит нам работать с ограниченным набором данных в оперативной памяти СУБД.

Рассмотрим, как правильно подготовить исходные данные:


ВЫБРАТЬ
    ВПТовары.Номенклатура КАК Номенклатура,
    ВПТовары.Характеристика КАК Характеристика,
    ВЫРАЗИТЬ(ВП.ДокументОснование КАК Документ.ЗаказНаВнутреннееПотребление) КАК ЗаказНВП,
    ВЫРАЗИТЬ(ВП.ДокументОснование КАК Документ.СТ_РегистрацияНесоответствий) КАК РегистрацияНесоответствий_Напрямую
ПОМЕСТИТЬ ВТ_ИсходныеДанные
ИЗ
    Документ.ВнутреннееПотреблениеТоваров.Товары КАК ВПТовары
    ЛЕВОЕ СОЕДИНЕНИЕ Документ.ВнутреннееПотреблениеТоваров КАК ВП
        ПО ВПТовары.Ссылка = ВП.Ссылка
ГДЕ
    ВПТовары.Ссылка В(&Ссылка)
ИНДЕКСИРОВАТЬ ПО
    Номенклатура,
    ЗаказНВП,
    РегистрацияНесоответствий_Напрямую
;

Обратите внимание на использование функции ВЫРАЗИТЬ. Это критически важный момент для производительности: мы заранее «подсказываем» системе, к какой таблице нужно обращаться, избавляя её от анализа составного типа ДокументОснование.

Шаг 2: Получение цепочки документов (Заказ -> Регистрация)

Теперь нам нужно определить, откуда пришло «Несоответствие». В 1С:ERP цепочка может быть разной: либо ВП -> Регистрация, либо ВП -> Заказ -> Регистрация. Разберем, как объединить эти пути в одной временной таблице.


ВЫБРАТЬ
    Исходные.Номенклатура КАК Номенклатура,
    Исходные.Характеристика КАК Характеристика,
    ВЫБОР
        КОГДА Исходные.РегистрацияНесоответствий_Напрямую <> ЗНАЧЕНИЕ(Документ.СТ_РегистрацияНесоответствий.ПустаяСсылка)
            ТОГДА Исходные.РегистрацияНесоответствий_Напрямую
        ИНАЧЕ ВЫРАЗИТЬ(Заказ.ДокументОснование КАК Документ.СТ_РегистрацияНесоответствий)
    КОНЕЦ КАК РегистрацияСсылка
ПОМЕСТИТЬ ВТ_СвязиДокументов
ИЗ
    ВТ_ИсходныеДанные КАК Исходные
    ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказНаВнутреннееПотребление КАК Заказ
        ПО Исходные.ЗаказНВП = Заказ.Ссылка
ГДЕ
    (Исходные.РегистрацияНесоответствий_Напрямую <> ЗНАЧЕНИЕ(Документ.СТ_РегистрацияНесоответствий.ПустаяСсылка)
    ИЛИ ВЫРАЗИТЬ(Заказ.ДокументОснование КАК Документ.СТ_РегистрацияНесоответствий) <> ЗНАЧЕНИЕ(Документ.СТ_РегистрацияНесоответствий.ПустаяСсылка))
;

Шаг 3: Финальное соединение по номенклатуре

Выясним причину, по которой архитектор настаивал на связи по номенклатуре. Документ регистрации несоответствий содержит табличную часть с товарами. Если мы просто соединимся по ссылке документа, мы получим все несоответствия по всем товарам этого документа. Нам же нужно только то несоответствие, которое относится к конкретной строке (номенклатуре) нашего «Внутреннего потребления».

Сформулируем итоговый запрос:


ВЫБРАТЬ
    Связи.РегистрацияСсылка КАК ДокументОснование,
    РегистрацияТовары.Несоответствие КАК Несоответствие
ИЗ
    ВТ_СвязиДокументов КАК Связи
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.СТ_РегистрацияНесоответствий.Товары КАК РегистрацияТовары
        ПО Связи.РегистрацияСсылка = РегистрацияТовары.Ссылка
        И Связи.Номенклатура = РегистрацияТовары.Номенклатура
        И Связи.Характеристика = РегистрацияТовары.Характеристика
СГРУППИРОВАТЬ ПО
    Связи.РегистрацияСсылка,
    РегистрацияТовары.Несоответствие

Почему это решение лучше?

  1. Точность данных: Благодаря условию Связи.Номенклатура = РегистрацияТовары.Номенклатура, мы гарантированно получаем данные только по тому товару, который указан в исходном документе.
  2. Учет характеристик: В ERP 2.4 номенклатура без характеристики часто бывает недостаточно уникальной. Мы добавили связь по Характеристике, что является стандартом разработки.
  3. Производительность: Мы использовали временные таблицы (ПОМЕСТИТЬ) и индексацию. СУБД выполнит этот запрос в разы быстрее, так как объем обрабатываемых данных минимизирован на первом же этапе.
  4. Читаемость: Логика разбита на этапы: сначала отбираем исходные ссылки, потом выстраиваем цепочку документов, и в конце получаем детальные данные из табличной части.

Важный совет: При отладке таких запросов всегда проверяйте, не помечен ли документ-основание на удаление. Для этого в финальном запросе можно добавить условие ГДЕ НЕ РегистрацияТовары.Ссылка.ПометкаУдаления. Также рекомендуется использовать консоль запросов с возможностью просмотра временных таблиц, чтобы видеть, на каком шаге пропадают данные, если результат запроса оказывается пустым.

Проанализировав данную структуру, мы видим, что «правильный» запрос в 1С — это не просто написание текста ВЫБРАТЬ...ИЗ, а проектирование оптимального пути движения данных от первичного документа до конечного результата.

← На главную