При работе с конфигурацией 1С:УАТ (Управление автотранспортом) мы часто сталкиваемся с необходимостью построения сложных аналитических отчетов. Одной из распространенных задач является корректное отображение информации о заправках и расходе топлива, особенно когда путевые листы охватывают несколько дней или когда транспортное средство перемещается между различными зонами. В этом материале мы подробно разберем, как решить две типовые проблемы, возникающие при формировании таких отчетов: учет заправок для переходящих путевых листов и отображение истории местонахождения ТС по зонам.
Предположим, у нас есть задача извлечь все заправки за определенный период из путевых листов. Изначальный подход, как правило, включает фильтрацию регистра накопления уатОборотыПоЗаправкамГСМ по дате самого путевого листа, например, таким образом:
ВЫБРАТЬ
СУММА(уатОборотыПоЗаправкамГСМОбороты.КоличествоОборот) КАК Выдано,
уатОборотыПоЗаправкамГСМОбороты.ТС КАК ТС
ПОМЕСТИТЬ вт_ВыданоГСМ
ИЗ
РегистрНакопления.уатОборотыПоЗаправкамГСМ.Обороты(&ДатаНач, &ДатаОкон, , ) КАК уатОборотыПоЗаправкамГСМОбороты
ГДЕ
уатОборотыПоЗаправкамГСМОбороты.ПутевойЛист.Дата МЕЖДУ &ДатаНач И &ДатаОкон
На первый взгляд, этот запрос кажется логичным: мы отбираем заправки, которые произошли в указанный период, и привязаны к путевым листам, даты которых также находятся в этом периоде. Однако здесь скрывается ловушка, которую метко называют «ошибкой заборного столба» (аналогия с подсчетом количества пролетов забора по количеству столбов). Путевой лист — это документ, который описывает не мгновенное событие, а период действия транспортного средства. Он может быть выписан 31 октября, а его действие может продолжаться до 1 ноября. Заправка, произведенная 1 ноября, но относящаяся к путевому листу от 31 октября, не попадет в отчет за октябрь, если мы фильтруем по ПутевойЛист.Дата, которая является датой начала путевого листа.
Таким образом, основной причиной некорректного отображения заправок является то, что мы ориентируемся на дату шапки документа ПутевойЛист (которая обычно соответствует дате его выезда или формирования), а не на весь интервал его действия.
Для корректного учета заправок нам необходимо изменить логику отбора путевых листов. Вместо того чтобы фильтровать по дате создания документа, мы должны определить все путевые листы, период действия которых пересекается с нашим отчетным интервалом (&ДатаНач - &ДатаОкон). В конфигурации 1С:УАТ документ ПутевойЛист имеет реквизит, который указывает его продолжительность, например, «До какого числа действителен путевой лист» или «Дата возврата в гараж». Именно эти реквизиты мы и будем использовать.
Рассмотрим по шагам, как модифицировать запрос:
Определяем релевантные путевые листы. Создадим временную таблицу, которая будет содержать все путевые листы, чей период действия (от Дата до ДатаВозвратаВГараж или аналогичного реквизита) пересекается с заданным отчетным периодом.
ВЫБРАТЬ
ПутевыеЛисты.Ссылка КАК ПутевойЛист
ПОМЕСТИТЬ вт_ПутевыеЛистыЗаПериод
ИЗ
Документ.уатПутевойЛист КАК ПутевыеЛисты
ГДЕ
ПутевыеЛисты.Дата <= &ДатаОкон
И ПутевыеЛисты.ДатаВозвратаВГараж >= &ДатаНач // Используем реквизит, определяющий конец периода действия ПЛ
;
В этом запросе мы выбираем путевые листы, которые начались до или в дату окончания отчета, и закончились после или в дату начала отчета. Это гарантирует, что мы охватим все переходящие путевые листы, которые были активны хоть один день в нашем отчетном периоде.
Присоединяем заправки к отобранным путевым листам. Теперь, когда у нас есть список всех релевантных путевых листов, мы можем присоединить к ним записи из регистра уатОборотыПоЗаправкамГСМ. Важно понимать, что фильтр по периоду в функции Обороты(&ДатаНач, &ДатаОкон, , ) уже будет отбирать заправки, произошедшие только в нашем отчетном периоде, что корректно.
ВЫБРАТЬ
СУММА(уатОборотыПоЗаправкамГСМОбороты.КоличествоОборот) КАК Выдано,
уатОборотыПоЗаправкамГСМОбороты.ТС КАК ТС
ИЗ
РегистрНакопления.уатОборотыПоЗаправкамГСМ.Обороты(&ДатаНач, &ДатаОкон, , ) КАК уатОборотыПоЗаправкамГСМОбороты
ВНУТРЕННЕЕ СОЕДИНЕНИЕ вт_ПутевыеЛистыЗаПериод КАК вт_ПутевыеЛистыЗаПериод
ПО уатОборотыПоЗаправкамГСМОбороты.ПутевойЛист = вт_ПутевыеЛистыЗаПериод.ПутевойЛист
СГРУППИРОВАТЬ ПО
уатОборотыПоЗаправкамГСМОбороты.ТС
;
Таким образом, мы сначала идентифицируем все путевые листы, которые были в работе в наш период, а затем берем только те заправки, которые были сделаны в рамках этих путевых листов и также попадают в наш отчетный период. Этот подход позволяет корректно учитывать заправки, даже если дата путевого листа не совпадает с датой заправки, но заправка относится к этому путевому листу и произошла в его период действия.
Конфигурация 1С:УАТ, для повышения точности учета, позволяет настраивать проверку попадания заправок в период путевого листа. Это подтверждает, что разработчики системы изначально предусмотрели концепцию "переходящих" путевых листов и необходимость особого подхода к учету операций в их рамках.
Вторая проблема возникает, когда транспортное средство (ТС) перемещается между различными зонами (подразделениями, местами базирования) в течение отчетного периода, и отчет не показывает его на предыдущем месте базирования.
Изначальный запрос для определения ТС в зоне выглядит следующим образом:
ВЫБРАТЬ
уатМестонахождениеТССрезПоследних.ТС.Модель.ОсновноеТопливо КАК ВидТоплива,
уатМестонахождениеТССрезПоследних.ТС.ГаражныйНомер КАК ГаражныйНомер,
уатМестонахождениеТССрезПоследних.ТС КАК ТС
ПОМЕСТИТЬ вт_ТСвЗона
ИЗ
РегистрСведений.уатМестонахождениеТС.СрезПоследних(, ) КАК уатМестонахождениеТССрезПоследних
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Зона КАК Зона
ПО уатМестонахождениеТССрезПоследних.Колонна = Зона.Колонны.Колонна
ГДЕ
уатМестонахождениеТССрезПоследних.Период > уатМестонахождениеТССрезПоследних.ТС.ДатаВыбытия
И Зона.Ссылка = &Зона
СГРУППИРОВАТЬ ПО
уатМестонахождениеТССрезПоследних.ТС.ГаражныйНомер,
уатМестонахождениеТССрезПоследних.ТС.Модель.ОсновноеТопливо,
уатМестонахождениеТССрезПоследних.ТС
;
Основная причина некорректного отображения истории перемещений заключается в использовании функции СрезПоследних(, ) без указания периода. Когда мы вызываем СрезПоследних() без параметров, система возвращает актуальные данные на текущую дату. Если ТС было перемещено из одной зоны в другую (например, в середине месяца), то на текущую дату оно будет находиться в новой зоне, и его предыдущее местоположение в отчете за прошлый период просто исчезнет.
Регистры сведений в 1С предназначены именно для хранения исторических данных, так как они могут быть периодическими. Каждая запись в периодическом регистре сведений фиксирует изменение какого-либо свойства на определенную дату.
Для корректного отображения местонахождения ТС в отчете за определенный период нам необходимо учесть периодичность регистра сведений уатМестонахождениеТС.
Рассмотрим несколько подходов:
Если нам нужно увидеть, в какой зоне находилось ТС на конец нашего отчетного периода, мы можем использовать СрезПоследних с указанием даты окончания периода:
ВЫБРАТЬ
уатМестонахождениеТССрезПоследних.ТС.Модель.ОсновноеТопливо КАК ВидТоплива,
уатМестонахождениеТССрезПоследних.ТС.ГаражныйНомер КАК ГаражныйНомер,
уатМестонахождениеТССрезПоследних.ТС КАК ТС,
уатМестонахождениеТССрезПоследних.Колонна КАК КолоннаТС
ПОМЕСТИТЬ вт_ТСвЗонаНаКонецПериода
ИЗ
РегистрСведений.уатМестонахождениеТС.СрезПоследних(&ДатаОкон, ) КАК уатМестонахождениеТССрезПоследних
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Зона КАК Зона
ПО уатМестонахождениеТССрезПоследних.Колонна = Зона.Колонны.Колонна
ГДЕ
уатМестонахождениеТССрезПоследних.Период > уатМестонахождениеТССрезПоследних.ТС.ДатаВыбытия
И Зона.Ссылка = &Зона
;
Этот запрос покажет нам местонахождение ТС по состоянию на &ДатаОкон. Если ТС было перемещено до этой даты, мы увидим его последнее местонахождение. Однако, если нас интересует история перемещений внутри периода, этого будет недостаточно.
Чтобы отобразить все зоны, в которых находилось ТС в течение отчетного периода, нам необходимо запросить сам регистр сведений уатМестонахождениеТС, отфильтровав его по полю Период. Это позволит нам получить всю "историю" перемещений ТС в заданном интервале.
ВЫБРАТЬ
уатМестонахождениеТС.Период КАК ПериодПеремещения,
уатМестонахождениеТС.ТС КАК ТС,
уатМестонахождениеТС.Колонна КАК КолоннаТС,
Зона.Ссылка КАК ЗонаТС
ПОМЕСТИТЬ вт_ИсторияМестонахожденияТС
ИЗ
РегистрСведений.уатМестонахождениеТС КАК уатМестонахождениеТС
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Зона КАК Зона
ПО уатМестонахождениеТС.Колонна = Зона.Колонны.Колонна
ГДЕ
уатМестонахождениеТС.Период МЕЖДУ &ДатаНач И &ДатаОкон
И Зона.Ссылка = &Зона
;
Этот запрос создаст временную таблицу со всеми записями о перемещениях ТС, которые произошли в заданном диапазоне дат и относятся к указанной зоне. Далее, при связывании этих данных с заправками или расходом ГСМ, нам потребуется более сложная логика присоединения.
Если мы хотим корректно атрибутировать каждую заправку или расход ГСМ к той зоне, в которой находилось ТС в момент совершения операции, нам придется выполнить соединение по условию вхождения даты операции в период действия каждой записи из регистра сведений уатМестонахождениеТС для конкретного ТС. Это означает, что дата заправки (или расхода) должна быть больше или равна ПериодПеремещения текущей записи и меньше ПериодПеремещения следующей записи для того же ТС.
Такой подход потребует предварительной подготовки данных из уатМестонахождениеТС, чтобы для каждой записи о местонахождении определить ее "период действия" (от текущей даты записи до даты следующей записи). После этого можно будет соединять движения регистров накопления (заправки, расходы) с этой расширенной историей местонахождения по ТС и диапазону дат.
Например, модифицированный запрос для уатОборотыПоЗаправкамГСМ может выглядеть так:
ВЫБРАТЬ
уатОборотыПоЗаправкамГСМОбороты.Период КАК ДатаЗаправки,
уатОборотыПоЗаправкамГСМОбороты.ТС КАК ТСЗаправки,
уатОборотыПоЗаправкамГСМОбороты.КоличествоОборот КАК Выдано,
ИсторияМестонахождения.ЗонаТС КАК ЗонаНаМоментЗаправки
ИЗ
РегистрНакопления.уатОборотыПоЗаправкамГСМ.Обороты(&ДатаНач, &ДатаОкон, , ) КАК уатОборотыПоЗаправкамГСМОбороты
ВНУТРЕННЕЕ СОЕДИНЕНИЕ вт_ПутевыеЛистыЗаПериод КАК вт_ПутевыеЛистыЗаПериод
ПО уатОборотыПоЗаправкамГСМОбороты.ПутевойЛист = вт_ПутевыеЛистыЗаПериод.ПутевойЛист
ВНУТРЕННЕЕ СОЕДИНЕНИЕ (
ВЫБРАТЬ
ПериодНачала.Период КАК ПериодС,
ЕСТЬNULL(ПериодКонца.Период, ДАТАВРЕМЯ(3999, 12, 31, 23, 59, 59)) КАК ПериодПо,
ПериодНачала.ТС КАК ТС,
ПериодНачала.ЗонаТС КАК ЗонаТС
ИЗ
вт_ИсторияМестонахожденияТС КАК ПериодНачала
ЛЕВОЕ СОЕДИНЕНИЕ вт_ИсторияМестонахожденияТС КАК ПериодКонца
ПО ПериодНачала.ТС = ПериодКонца.ТС
И ПериодНачала.Период < ПериодКонца.Период
И НЕ ЕСТЬNULL(ПериодНачала.ЗонаТС = ПериодКонца.ЗонаТС, ЛОЖЬ) // Только при смене зоны
ГДЕ
ПериодКонца.Период = (
ВЫБРАТЬ МИНИМУМ(ВложенныйПериодКонца.Период)
ИЗ вт_ИсторияМестонахожденияТС КАК ВложенныйПериодКонца
ГДЕ ВложенныйПериодКонца.ТС = ПериодНачала.ТС
И ВложенныйПериодКонца.Период > ПериодНачала.Период
) ИЛИ ПериодКонца.Период ЕСТЬ NULL
) КАК ИсторияМестонахождения
ПО уатОборотыПоЗаправкамГСМОбороты.ТС = ИсторияМестонахождения.ТС
И уатОборотыПоЗаправкамГСМОбороты.Период МЕЖДУ ИсторияМестонахождения.ПериодС И ИсторияМестонахождения.ПериодПо
ГРУППИРОВАТЬ ПО
ИсторияМестонахождения.ЗонаТС,
уатОборотыПоЗаправкамГСМОбороты.ТС
;
Этот сложный запрос иллюстрирует принцип соединения событий с историческими состояниями. Вложенный запрос для ИсторияМестонахождения строит интервалы действия для каждой зоны для каждого ТС. Затем основной запрос присоединяет заправки, убеждаясь, что дата заправки попадает в соответствующий интервал действия зоны.
Для конфигурации 1С:УАТ также существует регистр сведений КоординатыПоМониторингу, который предназначен для хранения детальной истории местоположения ТС по данным спутникового мониторинга. Это еще раз подчеркивает важность и возможность отслеживания перемещений ТС и построения отчетов с учетом этой истории.
При построении сложных аналитических отчетов в 1С:УАТ критически важно глубоко понимать структуру данных и особенности каждого объекта: как документы (например, ПутевойЛист) имеют период действия, так и регистры сведений (например, уатМестонахождениеТС) хранят историю изменений.
Мы настоятельно рекомендуем:
СрезПоследних (актуальное состояние) и запросом всего регистра (история). Для отчетов, требующих исторической точности, используйте полные данные регистра сведений и соответствующую логику соединений по временным интервалам.Разработка отчетов в 1С:УАТ может быть непростой задачей из-за специфики учета и структуры регистров, но, применяя описанные подходы и понимая принципы работы с периодическими данными, мы сможем создавать точные и информативные аналитические инструменты.