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

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

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

Проблема: Почему "пропадают" данные?

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

Когда мы используем ЛЕВОЕ СОЕДИНЕНИЕ, система берет все записи из левой таблицы и пытается найти соответствия в правой. Если соответствий нет, в полях правой таблицы появляется значение NULL. Но как только мы пишем в условии ГДЕ ПраваяТаблица.Период МЕЖДУ &ДатаНачало И &ДатаКонец, система исключает все строки, где период равен NULL (поскольку NULL не может входить в диапазон дат). Таким образом, наше левое соединение фактически превращается во ВНУТРЕННЕЕ, и все "неактивные" автомобили исчезают из результата.

Решение 1: Правильное использование условий в запросе

Первым делом нам необходимо исправить логику фильтрации. Условия на присоединяемую таблицу должны находиться не в блоке ГДЕ, а непосредственно в условии связи ПО или в параметрах виртуальной таблицы. Рассмотрим исправленный подход к структуре запроса.

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


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

В данном примере мы используем Справочник как ведущую таблицу. Это гарантирует, что в отчет попадут абсолютно все транспортные средства, зарегистрированные в базе. К ним мы присоединяем последнее известное состояние из регистра на дату окончания отчета.

Решение 2: Использование справочника как "фундамента" отчета

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

  1. Выбираем основную таблицу: Это должен быть справочник ТранспортныеСредства (или аналогичный в вашей конфигурации).
  2. Присоединяем данные: Используем ЛЕВОЕ СОЕДИНЕНИЕ с виртуальной таблицей СрезПоследних регистра сведений.
  3. Передаем параметры: Дату среза устанавливаем на &ДатаКонец.
  4. Обрабатываем пустые значения: Обязательно используем функцию ЕСТЬNULL, чтобы вместо пустых ячеек в колонке остатков красовался "0".

Пример реализации с обработкой NULL:


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

Решение 3: Особенности работы в СКД

Если вы строите отчет в Системе компоновки данных (СКД), важно учитывать роли полей. Чтобы система правильно понимала, что делать с автомобилями без движений, рекомендуется:

Во-первых, в настройках набора данных для полей остатков указать роль "Остатки". Во-вторых, если используется регистр накопления, в параметрах виртуальной таблицы ОстаткиИОбороты можно включить метод дополнения периодов, чтобы система сама "дорисовывала" строки для неактивных периодов.

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

Рекомендация по использованию Регистров накопления

Хотя в примере автора используется Регистр сведений, в классической архитектуре 1С для учета топлива правильнее использовать Регистры накопления. Это дает ряд преимуществ:

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

Итоги и выводы

Мы выяснили, что основной причиной "пропажи" данных в отчетах 1С является некорректная фильтрация в запросах с левым соединением. Запомните главное правило: никогда не накладывайте жесткие условия на поля правой (присоединяемой) таблицы в блоке ГДЕ, если хотите сохранить строки, для которых нет данных в этой таблице. Все подобные фильтры должны переноситься либо в условия связи ПО, либо в параметры виртуальных таблиц.

Использование справочника в качестве основы запроса и функции ЕСТЬNULL для оформления результата позволит вам создавать надежные и информативные отчеты, которые показывают реальное состояние всего автопарка предприятия.

← На главную