При разработке сложных отчетов и выборке данных в платформе 1С:Предприятие часто возникает необходимость работать не с конкретной точкой во времени, а с целым временным интервалом. Для этой цели существует специальный тип данных, который позволяет оперировать периодами: сутками, месяцами, кварталами или годами. Понимание механизмов работы с этим типом критически важно для написания корректных и производительных запросов.
Стандартный тип Дата хранит точное значение времени с точностью до секунды. Однако в бизнес-логике часто требуются операции типа "получить все документы за январь" или "сравнить два квартала". Именно здесь на сцену выходит модификатор КАК ПЕРИОД. Он преобразует обычную дату в интервал, что упрощает синтаксис и повышает читаемость кода.
Синтаксис объявления переменной периода
Чтобы использовать дату как период в теле запроса, необходимо явно указать это в секции параметров или в тексте запроса. Платформа автоматически интерпретирует значение как границы интервала. Это позволяет избежать ручного вычисления начала и конца месяца или года с помощью функций НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА.
Рассмотрим базовый пример объявления параметра в коде на встроенном языке. Мы создаем структуру и заполняем её значением, указывая тип периода.
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Справочник.Номенклатура.Наименование КАК Товар
|ИЗ Справочник.Номенклатура КАК Справочник.Номенклатура
|ГДЕ Справочник.Номенклатура.ДатаВключения В ПЕРИОД(&Период)";
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("Период", Новый Граница(ТекущаяДата(), ВидГраницы.ВидПериода.Месяц));
// Или более простой способ через тип значения
СтруктураПараметров.Вставить("Период", Новый Значение(ТекущаяДата(), Тип("Дата(Период.Месяц)")));
Результат = Запрос.Выполнить(СтруктураПараметров);
Использование типа Дата как период в параметрах делает код более гибким. Вам не нужно передавать две отдельные даты (начало и конец). Достаточно передать одно значение с указанием granularity (детализации) периода. Система сама поймет, что нужно выбрать данные от первого до последнего числа месяца.
Однако стоит помнить, что тип периода доступен только в определенных контекстах. В обычных переменных встроенного языка тип Дата остается точечным. Преобразование в период происходит именно на уровне движка запросов или при использовании специальных объектов-границ.
Операторы сравнения для периодов
Самая мощная возможность работы с периодами — это использование специализированных операторов сравнения. Стандартные операторы =, <, > работают с периодами иначе, чем с обычными датами. Они сравнивают интервалы целиком, а не отдельные точки.
- 📅 Оператор В ПЕРИОДЕ проверяет, попадает ли значение поля в заданный интервал. Это аналог конструкции
Между ... И ..., но более читаемый. - ⏳ Оператор ПО ПЕРИОДУ используется для группировки данных. Он позволяет автоматически сгруппировать записи по месяцам или кварталам без явного вызова функций форматирования.
- 🔄 Оператор СДВИГПОПЕРИОДУ позволяет выполнять арифметические операции с периодами, например, сдвигать дату на один квартал вперед или назад.
При использовании оператора В ПЕРИОДЕ важно понимать логику включения границ. Если вы сравниваете дату документа с периодом "Месяц", то документ, созданный в любую секунду этого месяца, удовлетворит условию. Вам не нужно вручную обрезать время до 23:59:59.
⚠️ Внимание: Не пытайтесь использовать оператор равенства
=для сравнения обычной даты и периода. Это приведет к ошибке выполнения или неверному результату, так как типы несовместимы для прямого сравнения на равенство.
Также существует возможность сравнения двух периодов между собой. Например, можно проверить, пересекаются ли два временных интервала или следует ли один период за другим. Это часто используется в задачах планирования и контроля занятости ресурсов.
Группировка данных по периодам
Одной из самых частых задач в отчетности является группировка данных по временным срезам. Конструкция ПО ПЕРИОДУ в секции СГРУППИРОВАТЬ ПО позволяет решить эту задачу элегантно и эффективно. Движок запросов сам определит границы группировки на основе типа переданного периода.
Допустим, вам нужно получить обороты продаж по месяцам. Вместо того чтобы извлекать месяц из даты функцией МЕСЯЦ() и год функцией ГОД(), вы можете использовать период напрямую.
ВЫБРАТЬ
Продажи.Период КАК Период,
СУММА(Продажи.Сумма) КАК СуммаОборота
ИЗ
РегистрНакопления.Продажи КАК Продажи
СГРУППИРОВАТЬ ПО
Продажи.Период КАК Период (МЕСЯЦ)
В данном примере ключевым моментом является указание (МЕСЯЦ) после псевдонима поля. Это сообщает системе, что группировку нужно выполнять с точностью до месяца. Все записи, попавшие в один календарный месяц, будут объединены в одну строку результата.
Аналогично можно группировать по кварталам или годам, просто изменив параметр на КВАРТАЛ или ГОД. Это особенно удобно при построении динамических отчетов, где пользователь может менять детализацию (Drill-down) без переписывания текста запроса.
При группировке по периоду убедитесь, что поле, по которому идет группировка, действительно имеет тип Дата. Попытка сгруппировать строку или число как период вызовет ошибку компиляции запроса.
Функции работы с периодами в выражениях
Помимо операторов, в языке запросов 1С существует набор функций, специально предназначенных для манипуляций с периодами. Они позволяют получать начало, конец, длительность и другие характеристики временного интервала.
Функция НАЧАЛОПЕРИОДА возвращает дату начала заданного периода. Если передать ей дату внутри месяца с указанием периода "Месяц", она вернет первое число этого месяца с временем 00:00:00. Это полезно для нормализации дат перед сравнением.
Функция КОНЕЦПЕРИОДА действует симметрично, возвращая последнюю возможную дату и время в рамках периода. Для месяца это будет последний день в 23:59:59. Использование этих функций гарантирует корректность диапазонов даже в високосные годы или месяцы с разным количеством дней.
| Функция | Описание | Пример результата для 15.05.2026 |
|---|---|---|
НАЧАЛОПЕРИОДА(Дата, МЕСЯЦ) |
Начало месяца | 01.05.2026 00:00:00 |
КОНЕЦПЕРИОДА(Дата, МЕСЯЦ) |
Конец месяца | 31.05.2026 23:59:59 |
НАЧАЛОПЕРИОДА(Дата, КВАРТАЛ) |
Начало квартала | 01.04.2026 00:00:00 |
СДВИГПОПЕРИОДУ(Дата, МЕСЯЦ, 1) |
Следующий месяц | 15.06.2026 (сохраняет день) |
Важно отметить, что функция СДВИГПОПЕРИОДУ ведет себя умно при переходе через границы месяцев. Если вы сдвигаете дату 31 января на один месяц вперед, система корректно обработает тот факт, что в феврале 31 дня нет, и вернет последний день февраля или 1 марта в зависимости от реализации, но чаще всего она сохраняет логику календаря.
Производительность и индексы
Использование периодов в условиях отбора (ГДЕ) напрямую влияет на производительность запроса. Правильное использование типа Дата как период позволяет оптимизатору запросов 1С эффективнее использовать индексы по полям даты.
Когда вы пишете условие ГДЕ Дата В ПЕРИОД(&Параметр), система может преобразовать это в диапазонное условие Дата >= Начало И Дата <= Конец на уровне SQL. Это позволяет СУБД использовать B-деревья индексов для быстрого поиска, вместо полного сканирования таблицы.
⚠️ Внимание: Избегайте использования функций в левой части условия сравнения, например
ГДЕ МЕСЯЦ(Дата) = 5. Это приводит к потере индекса и резкому замедлению работы на больших объемах данных. Используйте сравнение с периодом вместо этого.
Для виртуальных таблиц регистров накопления использование периодов является обязательным требованием для эффективной работы. Механизм итогов и срезов в 1С заточен именно под работу с интервалами. Игнорирование этого правила может привести к тому, что запрос будет выполняться минутами вместо секунд.
Использование операторов работы с периодами вместо функций в условиях WHERE — главный способ ускорения отчетов в 1С на больших базах данных.
Типичные ошибки и ограничения
Несмотря на удобство, работа с периодами имеет свои нюансы, которые часто становятся источником ошибок у начинающих разработчиков. Одна из самых распространенных проблем — несовместимость типов при передаче параметров из внешней системы или при joins.
При соединении таблиц (ЛЕВОЕ СОЕДИНЕНИЕ) убедитесь, что типы полей совпадают. Если вы пытаетесь соединить поле типа Дата с полем, которое в другом запросе приведено к периоду, может возникнуть ошибка типов или непредсказуемый результат соединения.
Также стоит учитывать ограничение на вложенность периодов. Нельзя создать "период внутри периода" в одном выражении без явного приведения типов. Например, попытка сравнить период "Год" с периодом "Месяц" требует явного указания, как именно сравнивать эти интервалы (по вложению или по пересечению).
Что делать, если параметр приходит строкой?
Если пользователь вводит период в виде строки "01.2026", используйте функцию НАЧАЛОПЕРИОДА(СТРОКАДАТЫ(Строка), МЕСЯЦ) для преобразования в нужный тип перед передачей в запрос.
Еще один момент — это работа с пустыми значениями (NULL). Если параметр периода не заполнен, условие В ПЕРИОДЕ может вести себя по-разному в зависимости от версии платформы и настроек совместимости. Всегда проверяйте параметр на заполненность перед формированием текста запроса или используйте конструкцию ЕСТЬNULL.
Можно ли использовать "Дата как период" в обычных переменных 1С?
Нет, в обычном коде (не в запросе) тип значения всегда остается Дата. Конструкция "как период" работает только внутри текста запроса или при использовании объекта Граница для передачи параметров. В переменной хранится просто дата, а интерпретация как периода происходит движком запросов.
Как получить количество дней в периоде через запрос?
Используйте функцию РАЗНОСТЬДАТ. Передайте в неё начало и конец периода, полученные через НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА, и укажите единицу измерения ДЕНЬ. Это вернет точное количество суток в выбранном интервале.
Почему запрос с периодом работает медленнее, чем с конкретными датами?
Обычно запрос с периодом работает быстрее или так же. Если наблюдается замедление, проверьте план выполнения запроса. Возможно, оптимизатор не смог использовать индекс из-за сложных выражений в условии или статистика по таблице устарела. Само по себе использование В ПЕРИОДЕ не является причиной тормозов.
Поддерживается ли тип периода в СКД (Система Компоновки Данных)?
Да, СКД полностью поддерживает работу с периодами. В настройках полей компоновки можно указать "Период" как тип группировки. Это позволяет пользователю в интерфейсе отчета переключать детализацию (день, месяц, год) без изменения макета отчета.