Как правильно получить себестоимость товаров по документам реализации в 1С:Управление торговлей 10.3

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

При разработке отчетов по анализу затрат и финансового результата в конфигурации «1С:Управление торговлей 10.3» разработчики нередко сталкиваются со сложностями при попытке получить себестоимость проданного товара. Типичной ошибкой является построение многоуровневых вложенных запросов и попытка соединить регистр накопления сам с собой через поле ДокументОприходования. Разберем, как устроена структура данных партионного учета, почему возникают ошибки и как написать простой и эффективный запрос.

Анализ проблемы и структуры регистра «Продажи себестоимость»

Регистр накопления ПродажиСебестоимость является оборотным. Его основная задача — хранить финансовый результат и рассчитанную стоимость списания номенклатуры в разрезе каждой конкретной продажи. Каждая строка движения документа РеализацияТоваровУслуг уже содержит списанную себестоимость в ресурсе Стоимость.

Попытка повторно обращаться к регистру и соединять ДокументОприходования с полем Регистратор приводит к следующим проблемам:

  1. Поле составного типа: Измерение ДокументОприходования может содержать ссылки на самые разные документы (ПоступлениеТоваровУслуг, ОприходованиеТоваров, АвансовыйОтчет, ОтчетПроизводстваЗаСмену и др.). При прямом соединении без ограничения типа СУБД выполняет неявные соединения со всеми таблицами метаданных, входящими в составной тип, что катастрофически снижает производительность.
  2. Пустые значения и потеря строк: Если товар был оприходован не через документ поступления, а, например, введен начальными остатками или списан в рамках межфирменной передачи, цепочка связей разрывается, возвращая значения NULL.
  3. Избыточность выборки: Стоимость списания по учету текущей организации уже посчитана и зафиксирована в записи, где регистратором выступает сама исходная реализация. Повторно искать исходную партию для получения себестоимости продажи не требуется.

Оптимальный вариант получения себестоимости по документам реализации

Рассмотрим, как получить данные по себестоимости напрямую из регистра ПродажиСебестоимость. Чтобы отфильтровать движения только по нужным документам реализации (например, содержащим дополнительный флаг Гарантия), воспользуемся конструкцией явного приведения типа ВЫРАЗИТЬ().

Посмотрим на пример правильного текста запроса:


ВЫБРАТЬ
    ПродажиСебестоимость.Регистратор КАК ДокументПродажи,
    ПродажиСебестоимость.Номенклатура КАК Номенклатура,
    ПродажиСебестоимость.Количество КАК Количество,
    ПродажиСебестоимость.Стоимость КАК Себестоимость,
    ПродажиСебестоимость.ДокументОприходования КАК Партия
ИЗ
    РегистрНакопления.ПродажиСебестоимость КАК ПродажиСебестоимость
ГДЕ
    ВЫРАЗИТЬ(ПродажиСебестоимость.Регистратор КАК Документ.РеализацияТоваровУслуг).Гарантия = ИСТИНА

Разберем по шагам, почему этот вариант работает быстрее и надежнее:

  1. Отсутствие соединений: Запрос обращается к одной физической таблице регистра, не нагружая СУБД лишними LEFT JOIN.
  2. Явное сужение типов: Конструкция ВЫРАЗИТЬ(ПродажиСебестоимость.Регистратор КАК Документ.РеализацияТоваровУслуг) указывает платформе, к какой конкретно таблице документов нужно обратиться для проверки реквизита Гарантия.
  3. Корректные итоги: В поле Стоимость возвращается точная сумма списания партии в валюте управленческого учета.

Альтернативное решение: использование временных таблиц

Если в выборке требуется получить дополнительные реквизиты документа или табличной части (например, добавленные реквизиты шапки ГарантийныйТовар или СтатьяЗатрат), рекомендуется отказаться от тяжелых вложенных подзапросов в секциях ПО и использовать временные таблицы.

Проанализируем пример запроса с временной таблицей:


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

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

Важные особенности учета партий в УТ 10.3

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

  1. Режим списания партий: В настройках параметров учета 1С:УТ 10.3 может быть отключена опция списания партий при проведении документов. В этом случае движения по регистру ПродажиСебестоимость формируются только после выполнения регламентной обработки «Проведение по партиям».
  2. Использование функции ПРЕДСТАВЛЕНИЕ(): Функцию ПРЕДСТАВЛЕНИЕ() следует размещать только в итоговом блоке ВЫБРАТЬ для отображения данных пользователю. Категорически не рекомендуется использовать ее внутри подзапросов или условий соединения ПО, так как это блокирует оптимизацию запросов на уровне СУБД.
← На главную