Как правильно составить запрос для получения состава спецификации и актуальных цен номенклатуры?

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

В процессе разработки в среде 1С часто возникает задача: получить список комплектующих для конкретной продукции (спецификацию) и дополнить этот список актуальными ценами из регистра сведений. Начинающие разработчики часто сталкиваются с дублированием строк, синтаксическими ошибками при обращении к табличным частям и неверным отображением данных. В этой статье мы подробно разберем, как построить оптимальный запрос, избегая типичных ловушек.

Разбор типичной ошибки: обращение к табличным частям

Одной из главных трудностей, описанных в обсуждении, является ошибка: «В условиях соединения запроса не допускается обращение к табличным частям». Проанализируем ситуацию: когда мы пытаемся соединить основную таблицу справочника Справочник.Спецификации с другой таблицей, используя поле вложенной табличной части Состав, платформа выдает ошибку. Это происходит потому, что табличная часть — это отдельная подчиненная таблица БД.

Чтобы избежать этой ошибки, мы должны выбирать данные не из «шапки» справочника, а напрямую из таблицы его состава. Рассмотрим правильную структуру источника данных:


ВЫБРАТЬ
    СпецификацииСостав.Номенклатура КАК Комплектующее,
    СпецификацииСостав.Количество КАК Количество,
    СпецификацииСостав.Ссылка.Владелец КАК Продукция
ИЗ
    Справочник.Спецификации.Состав КАК СпецификацииСостав
ГДЕ
    СпецификацииСостав.Ссылка.Владелец = &СсылкаНаПродукцию

Именно такое обращение позволяет нам работать с каждой строкой состава спецификации индивидуально, что является фундаментом для дальнейшего соединения с ценами.

Проблема дублирования данных и использование виртуальных таблиц

Если мы выполним ЛЕВОЕ СОЕДИНЕНИЕ с физической таблицей регистра сведений РегистрСведений.ЦеныНоменклатуры, мы получим серьезную проблему: для каждого комплектующего в результат попадут все цены, которые когда-либо устанавливались в системе. Это приведет к тому, что одна позиция в отчете размножится на десятки строк.

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


ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ) КАК ЦеныНоменклатуры
ПО СпецификацииСостав.Номенклатура = ЦеныНоменклатуры.Номенклатура

Использование СрезПоследних гарантирует, что для каждой номенклатуры будет найдена только одна запись, актуальная на указанную дату (параметр &Период).

Шаг 1: Правильная настройка связей и фильтрация по типу цен

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

  1. В параметрах таблицы СрезПоследних укажем условие: ВидЦены = &ВидЦены.
  2. Если используется учет по характеристикам, обязательно добавим связь по полю Характеристика.
  3. Применим функцию ЕСТЬNULL, чтобы вместо пустых значений для позиций без цены выводился ноль.

Проанализируем итоговый код запроса, который решает все поставленные задачи (отладить его можно, используя Консоль запросов для управляемых форм 8.3):


ВЫБРАТЬ
    СпецификацииСостав.Ссылка.Наименование КАК СпецификацияНаименование,
    СпецификацииСостав.Номенклатура КАК Номенклатура,
    СпецификацииСостав.Номенклатура.Представление КАК НоменклатураПредставление,
    СпецификацииСостав.Количество КАК Количество,
    ЕСТЬNULL(ЦеныНоменклатуры.Цена, 0) КАК Цена,
    ЕСТЬNULL(ЦеныНоменклатуры.Цена, 0) * СпецификацииСостав.Количество КАК Сумма
ИЗ
    Справочник.Спецификации.Состав КАК СпецификацииСостав
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ВидЦены = &ВидЦены) КАК ЦеныНоменклатуры
        ПО СпецификацииСостав.Номенклатура = ЦеныНоменклатуры.Номенклатура
ГДЕ
    СпецификацииСостав.Ссылка.Владелец = &НоменклатураВладелец

Шаг 2: Оптимизация через временные таблицы

Для более сложных задач, когда спецификаций много или требуется дополнительная обработка данных, рекомендуется использовать временные таблицы. Это делает запрос более читаемым и упрощает отладку в консоли запросов. Рассмотрим этот метод:

Сначала выберем состав во временную таблицу:


ВЫБРАТЬ
    СпецификацииСостав.Номенклатура КАК Номенклатура,
    СпецификацииСостав.Количество КАК Количество
ПОМЕСТИТЬ ВТ_Состав
ИЗ
    Справочник.Спецификации.Состав КАК СпецификацииСостав
ГДЕ
    СпецификацииСостав.Ссылка.Владелец = &НоменклатураВладелец
;

Затем соединим полученную временную таблицу с актуальными ценами (для работы с текстами таких запросов удобен Процессор схемы запроса):


ВЫБРАТЬ
    ВТ_Состав.Номенклатура КАК Номенклатура,
    ВТ_Состав.Количество КАК Количество,
    ЕСТЬNULL(Цены.Цена, 0) КАК Цена
ИЗ
    ВТ_Состав КАК ВТ_Состав
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ВидЦены = &ВидЦены) КАК Цены
        ПО ВТ_Состав.Номенклатура = Цены.Номенклатура

Важные замечания по синтаксису

Как было отмечено в сообщениях форума, часто причиной неработоспособности запроса являются банальные опечатки. Обратим внимание на несколько критических моментов:

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

← На главную