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

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

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

Использование функции НАЧАЛОПЕРИОДА

Для того чтобы преобразовать любую дату в «первое число месяца», в языке запросов 1С предусмотрена встроенная функция НАЧАЛОПЕРИОДА. Она принимает два параметра: саму дату и тип периода (ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД и т.д.).

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


ВЫБРАТЬ
    НАЧАЛОПЕРИОДА(Продажи.Период, МЕСЯЦ) КАК Месяц
ИЗ
    РегистрНакопления.Продажи КАК Продажи

Если в таблице Продажи есть несколько записей за один и тот же месяц (например, от 05.01.2021 и 20.01.2021), функция вернет 01.01.2021 для каждой строки. Это приведет к дублированию дат в результате. Чтобы получить уникальный список месяцев, необходимо использовать ключевое слово РАЗЛИЧНЫЕ.


ВЫБРАТЬ РАЗЛИЧНЫЕ
    НАЧАЛОПЕРИОДА(Продажи.Период, МЕСЯЦ) КАК Месяц
ИЗ
    РегистрНакопления.Продажи КАК Продажи

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

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

Разберем, как сформировать календарь на год «на лету»:

  1. Создадим временную таблицу с числами от 0 до 11.
  2. Используем функцию ДОБАВИТЬКДАТЕ, чтобы прибавить эти числа к началу года.

ВЫБРАТЬ 0 КАК Цифра ПОМЕСТИТЬ ВТ_Цифры ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 1 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 2 
// ... и так далее до 11
;

ВЫБРАТЬ
    ДОБАВИТЬКДАТЕ(&НачалоГода, МЕСЯЦ, ВТ_Цифры.Цифра) КАК Месяц
ИЗ
    ВТ_Цифры КАК ВТ_Цифры

Такой подход гарантирует наличие всех двенадцати строк в итоговой выборке, независимо от наличия данных в регистрах.

Соединение данных: Как привязать объект ко всем датам

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

Способ 1: Использование параметров в выборке

Если нам нужно вывести конкретный город, выбранный пользователем на форме, мы можем просто добавить его как поле-константу в запрос по календарю. Это самый производительный метод.


ВЫБРАТЬ
    ВТ_Календарь.Месяц КАК Месяц,
    &ВыбранныйГород КАК Город
ИЗ
    ВТ_Календарь КАК ВТ_Календарь

Способ 2: Левое соединение по условию ИСТИНА (Cross Join)

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

Важный момент: Такое соединение создаст произведение таблиц (количество дат умножить на количество городов). Проанализируем пример:


ВЫБРАТЬ
    ВТ_Даты.Дата КАК Дата,
    ВТ_Города.Ссылка КАК Город
ИЗ
    ВТ_Даты КАК ВТ_Даты
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Города КАК ВТ_Города
        ПО ИСТИНА

Этот прием позволяет создать «сетку» отчета, которую затем можно наполнить реальными числовыми данными (например, суммами продаж) через еще одно левое соединение.

Использование функционала ИТОГИ ПО ПЕРИОДАМ

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


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

При использовании ПЕРИОДАМИ платформа сама добавит строки с «пустыми» значениями для тех месяцев, в которых не было оборотов. Это встроенное решение является наиболее «правильным» с точки зрения архитектуры 1С для построения периодических отчетов.

Полезные советы при работе с датами

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

← На главную