Как получить остатки по всем товарам, включая нулевые, в запросе 1С?

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

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

Почему обычный запрос не показывает нулевые остатки?

Когда вы пишете запрос к регистру остатков, виртуальная таблица Остатки по умолчанию возвращает только те строки, где есть данные. Если товара нет на складе, запись в этой таблице физически отсутствует. При использовании ВНУТРЕННЕГО СОЕДИНЕНИЯ или при попытке наложить условие ГДЕ Остаток > 0, записи без остатков просто отбрасываются. Чтобы исправить это, мы должны изменить логику построения нашего запроса.

Решение через Левое соединение со справочником

Самый правильный подход — сделать справочник Номенклатура главной (левой) таблицей, а регистр остатков — подчиненной (правой). Таким образом, 1С выберет все элементы справочника, а для тех, данных по которым нет в регистре, подставит значение NULL.

Разберем пример кода для реализации этой задачи:


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

Важные нюансы и обработка значений NULL

При использовании ЛЕВОГО СОЕДИНЕНИЯ вы столкнетесь с тем, что для отсутствующих товаров поле количества будет содержать NULL. Это системное значение, которое может привести к ошибкам при расчетах. Всегда используйте функцию ЕСТЬNULL(Поле, ЗначениеЗамены). В качестве значения замены для количественных показателей указывайте 0.

Обратите внимание на следующие моменты:

  1. Исключение групп: В справочнике номенклатуры всегда есть папки (группы). Чтобы в отчете не было пустых строк по папкам, обязательно добавляйте условие ГДЕ Номенклатура.ЭтоГруппа = ЛОЖЬ.
  2. Типизация данных: Никогда не используйте строки (например, "0.00") вместо числового нуля в ЕСТЬNULL. Это приведет к тому, что поле станет строковым, и вы не сможете выполнять по нему арифметические операции или сортировку.
  3. Дублирование строк: Если вы соединяете справочник с несколькими регистрами сведений (например, цены и остатки), может возникнуть эффект дублирования записей. В таких случаях старайтесь выносить данные в ПОМЕСТИТЬ (временные таблицы) или используйте одно соединение с условием ИЛИ, а затем разделяйте данные через конструкцию ВЫБОР КОГДА.

Продвинутый пример: остатки и цены

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


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

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

Помните, что для больших справочников рекомендуется использовать временные таблицы — это повышает читаемость кода и упрощает отладку запросов в консоли запросов 1С.

← На главную