Решение задач 1С:Предприятие 8 на примерах

Дата в запросе 1С: ДАТАВРЕМЯ, период, МЕЖДУ, пустая и текущая дата

ЗапросыОпубликовано

Даты в запросах 1С — источник частых ошибок: теряются документы последнего дня, не находится пустая дата, медленно работает отбор по месяцу. Здесь собраны все функции языка запросов для работы с датами с примерами и объяснением подводных камней.

Задача: отобрать и сгруппировать данные по датам

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

Дата в запросе: литерал ДАТАВРЕМЯ и параметры

Константную дату в тексте запроса задают функцией ДАТАВРЕМЯ(Год, Месяц, День) или с временем — ДАТАВРЕМЯ(Год, Месяц, День, Час, Минута, Секунда). Аргументы должны быть числовыми литералами: подставить в ДАТАВРЕМЯ поле таблицы или параметр нельзя.

ВЫБРАТЬ
    Реализация.Ссылка КАК Документ
ИЗ
    Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
    Реализация.Дата >= ДАТАВРЕМЯ(2026, 1, 1)
    И Реализация.Дата < ДАТАВРЕМЯ(2026, 4, 1)

На практике литералы нужны редко — для фиксированных граничных дат в настройках или отладке. Всё, что выбирает пользователь или вычисляет код, передаётся параметрами:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Реализация.Ссылка КАК Документ,
|    Реализация.Дата КАК Дата
|ИЗ
|    Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
|    Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода";

Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаНачала));
Запрос.УстановитьПараметр("КонецПериода", КонецДня(ДатаОкончания));

Условие МЕЖДУ и конец дня

Оператор МЕЖДУ ... И ... включает обе границы. Самая частая ошибка — передать конец периода без времени. Если пользователь выбрал 31 марта, в переменной лежит 31.03.2026 0:00:00, и все документы, созданные 31 марта днём, в выборку не попадут. Поэтому конец периода приводят к концу дня: на стороне кода — функцией КонецДня(), в самом запросе — через КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ).

ГДЕ
    Реализация.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ)
                          И КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)

Если пользователь выбирает период стандартным элементом «Период», в коде он хранится как СтандартныйПериод, и его свойство ДатаОкончания обычно уже содержит конец дня. Передавайте Период.ДатаНачала и Период.ДатаОкончания отдельными параметрами.

НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА: дата без времени

Функция НАЧАЛОПЕРИОДА(Дата, Период) округляет дату вниз до начала периода, КОНЕЦПЕРИОДА — вверх до последней секунды периода. Доступные значения второго параметра: МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД, ДЕКАДА, ПОЛУГОДИЕ.

Именно так получают дату без времени в запросе: НАЧАЛОПЕРИОДА(Реализация.Дата, ДЕНЬ). Это нужно для группировки по дням и для сравнения дат без учёта часов.

ВЫБРАТЬ
    НАЧАЛОПЕРИОДА(Реализация.Дата, ДЕНЬ) КАК День,
    КОЛИЧЕСТВО(Реализация.Ссылка) КАК КоличествоДокументов,
    СУММА(Реализация.СуммаДокумента) КАК Сумма
ИЗ
    Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
    Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода
    И Реализация.Проведен

СГРУППИРОВАТЬ ПО
    НАЧАЛОПЕРИОДА(Реализация.Дата, ДЕНЬ)

УПОРЯДОЧИТЬ ПО
    День

Аналогично НАЧАЛОПЕРИОДА(Дата, МЕСЯЦ) даёт первое число месяца — удобный ключ для помесячной группировки, который при выводе остаётся датой и правильно сортируется.

Готовые периоды: сегодня, прошлый месяц, текущий год

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

Сегодня = ТекущаяДатаСеанса();

// Сегодня
НачалоПериода = НачалоДня(Сегодня);
КонецПериода = КонецДня(Сегодня);

// Прошлый месяц
НачалоПериода = НачалоМесяца(ДобавитьМесяц(Сегодня, -1));
КонецПериода = КонецМесяца(НачалоПериода);

// С начала года по сегодня
НачалоПериода = НачалоГода(Сегодня);
КонецПериода = КонецДня(Сегодня);

Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);

Тот же результат можно получить и внутри запроса через НАЧАЛОПЕРИОДА(&Сегодня, МЕСЯЦ) и ДОБАВИТЬКДАТЕ, но вычисление в коде проще отлаживать: значения параметров видны в отладчике до выполнения запроса.

Год, месяц и день в запросе

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

  • ГОД(Дата) — год, например 2026;
  • КВАРТАЛ(Дата) — номер квартала от 1 до 4;
  • МЕСЯЦ(Дата) — номер месяца от 1 до 12;
  • ДЕНЬ(Дата) — день месяца, ДЕНЬГОДА(Дата) — день года;
  • НЕДЕЛЯ(Дата) — номер недели в году, ДЕНЬНЕДЕЛИ(Дата) — день недели, где 1 — понедельник;
  • ЧАС, МИНУТА, СЕКУНДА — части времени.
ВЫБРАТЬ
    ГОД(Реализация.Дата) КАК Год,
    МЕСЯЦ(Реализация.Дата) КАК Месяц,
    СУММА(Реализация.СуммаДокумента) КАК Сумма
ИЗ
    Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
    ДЕНЬНЕДЕЛИ(Реализация.Дата) В (6, 7)

СГРУППИРОВАТЬ ПО
    ГОД(Реализация.Дата),
    МЕСЯЦ(Реализация.Дата)

Этот запрос считает продажи выходного дня в разрезе года и месяца. Важный нюанс: условие вида ГОД(Реализация.Дата) = 2026 не позволяет СУБД использовать индекс по дате — функция применяется к каждой строке. Для отбора по году или месяцу лучше задать диапазон МЕЖДУ &НачалоГода И &КонецГода, а функции оставить для группировки и вывода.

Текущая дата в запросе

Функции текущей даты в языке запросов нет. Текущий момент передают параметром, и правильнее брать его функцией ТекущаяДатаСеанса(): она учитывает часовой пояс сеанса, а ТекущаяДата() возвращает время компьютера, на котором выполняется код, — на сервере это время сервера.

Запрос.Текст =
"ВЫБРАТЬ
|    Заказы.Ссылка КАК Заказ,
|    Заказы.ДатаОтгрузки КАК ДатаОтгрузки
|ИЗ
|    Документ.ЗаказКлиента КАК Заказы
|ГДЕ
|    Заказы.ДатаОтгрузки < &Сегодня
|    И Заказы.ДатаОтгрузки <> ДАТАВРЕМЯ(1, 1, 1)";

Запрос.УстановитьПараметр("Сегодня", НачалоДня(ТекущаяДатаСеанса()));

Пустая дата в запросе

Незаполненная дата в 1С — это 01.01.0001 0:00:00. В тексте запроса её записывают как ДАТАВРЕМЯ(1, 1, 1), а параметром передают Дата(1, 1, 1) или '00010101'.

// В тексте запроса
ГДЕ
    Заказы.ДатаОтгрузки = ДАТАВРЕМЯ(1, 1, 1)

// Через параметр
Запрос.УстановитьПараметр("ПустаяДата", Дата(1, 1, 1));

Не путайте пустую дату с NULL. Реквизит документа с типом «Дата» никогда не бывает NULL — он хранит пустую дату. NULL появляется в поле, полученном через левое соединение без парной записи, или в реквизите составного типа. Для таких случаев есть ЕСТЬNULL(Поле, ДАТАВРЕМЯ(1, 1, 1)).

РАЗНОСТЬДАТ: разность дат в запросе

Функция РАЗНОСТЬДАТ(Дата1, Дата2, Единица) возвращает число единиц между датами — положительное, если вторая дата позже первой. Единицы: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, КВАРТАЛ, ГОД.

ВЫБРАТЬ
    Заказы.Ссылка КАК Заказ,
    РАЗНОСТЬДАТ(Заказы.ДатаОтгрузки, &Сегодня, ДЕНЬ) КАК ДнейПросрочки
ИЗ
    Документ.ЗаказКлиента КАК Заказы
ГДЕ
    Заказы.ДатаОтгрузки <> ДАТАВРЕМЯ(1, 1, 1)
    И РАЗНОСТЬДАТ(Заказы.ДатаОтгрузки, &Сегодня, ДЕНЬ) > 3

Разность в днях считается по календарным границам, а не по полным суткам: между 10 марта 23:00 и 11 марта 01:00 функция с единицей ДЕНЬ вернёт 1. Если важно именно число полных суток, считайте в секундах и делите на 86400 либо приводите обе даты к НАЧАЛОПЕРИОДА(..., ДЕНЬ), чтобы результат был предсказуемым.

ДОБАВИТЬКДАТЕ: сдвиг даты в запросе

Функция ДОБАВИТЬКДАТЕ(Дата, Единица, Количество) прибавляет к дате нужное количество секунд, минут, часов, дней, недель, месяцев, кварталов или лет. Для вычитания передайте отрицательное количество.

ВЫБРАТЬ
    Реализация.Ссылка КАК Документ,
    Реализация.Дата КАК Дата,
    ДОБАВИТЬКДАТЕ(Реализация.Дата, ДЕНЬ, 14) КАК СрокОплаты
ИЗ
    Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
    Реализация.Дата >= ДОБАВИТЬКДАТЕ(&Сегодня, МЕСЯЦ, -3)

При сдвиге на месяц с конца месяца платформа корректирует день: 31 января плюс месяц даст последний день февраля. Если в коде нужно то же поведение, используйте функцию встроенного языка ДобавитьМесяц().

Граница и даты в виртуальных таблицах

Виртуальные таблицы регистров — Остатки, ОстаткиИОбороты, СрезПоследних — принимают дату первым параметром. Остатки на дату считаются на начало этого момента, поэтому, чтобы учесть движения последнего дня, передают конец дня или объект Граница:

Запрос.Текст =
"ВЫБРАТЬ
|    Остатки.Номенклатура КАК Номенклатура,
|    Остатки.КоличествоОстаток КАК Остаток
|ИЗ
|    РегистрНакопления.ТоварыНаСкладах.Остатки(&Граница, ) КАК Остатки";

Запрос.УстановитьПараметр("Граница", Новый Граница(КонецДня(ДатаОтчета), ВидГраницы.Включая));

// Остатки до проведения конкретного документа
// Запрос.УстановитьПараметр("Граница", Новый Граница(Документ.МоментВремени(), ВидГраницы.Исключая));

Для оборотных таблиц начало и конец периода передаются отдельными параметрами, и конец тоже нужно приводить к КонецДня(). Для отчётов с разбивкой по датам есть конструкция ИТОГИ ... ПО ПЕРИОДАМ(ДЕНЬ, &НачалоПериода, &КонецПериода), которая добавляет в итоги дни без движений.

Типичные ошибки с датами

  • Конец периода без времени — теряются документы последнего дня.
  • Попытка написать ДАТАВРЕМЯ(&Год, 1, 1) — аргументы функции только литералы; вычислите дату в коде и передайте параметром.
  • Отбор через ГОД(Дата) = ... или МЕСЯЦ(Дата) = ... на больших таблицах — медленно; используйте диапазон.
  • ТекущаяДата() вместо ТекущаяДатаСеанса() — расхождения при работе пользователей в разных часовых поясах.
  • Проверка незаполненной даты через ЕСТЬ NULL — у реквизита-даты это пустая дата, а не NULL.

Функции работы с датами: шпаргалка

ЗадачаКонструкция
Константная датаДАТАВРЕМЯ(2026, 3, 31)
Пустая датаДАТАВРЕМЯ(1, 1, 1)
Дата без времениНАЧАЛОПЕРИОДА(Дата, ДЕНЬ)
Конец месяцаКОНЕЦПЕРИОДА(Дата, МЕСЯЦ)
Номер месяца, годМЕСЯЦ(Дата), ГОД(Дата)
Разница в дняхРАЗНОСТЬДАТ(Дата1, Дата2, ДЕНЬ)
Плюс 3 месяцаДОБАВИТЬКДАТЕ(Дата, МЕСЯЦ, 3)
Текущая датаПараметр ТекущаяДатаСеанса()

Актуальность для новых версий

Функции ДАТАВРЕМЯ, НАЧАЛОПЕРИОДА, КОНЕЦПЕРИОДА, РАЗНОСТЬДАТ, ДОБАВИТЬКДАТЕ и функции извлечения частей даты одинаково работают во всех версиях платформы 8.3, включая 8.3.2x, и на всех поддерживаемых СУБД. В конфигурациях, где пользователи работают в разных часовых поясах, текущую дату для запросов всегда берите через ТекущаяДатаСеанса().

Частые вопросы

Как получить текущую дату в запросе 1С?

Функции текущей даты в языке запросов нет. Передайте её параметром: Запрос.УстановитьПараметр("Сегодня", ТекущаяДатаСеанса()).

Как проверить в запросе, что дата не заполнена?

Сравните поле с ДАТАВРЕМЯ(1, 1, 1) или с параметром Дата(1, 1, 1). Реквизит с типом Дата не бывает NULL — незаполненное значение хранится как пустая дата.

Почему МЕЖДУ не находит документы последнего дня?

Конец периода передан без времени, то есть на 0:00:00. Передавайте КонецДня(Дата) или используйте в запросе КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ).

Как сгруппировать данные по дням или месяцам?

Группируйте по НАЧАЛОПЕРИОДА(Дата, ДЕНЬ) или НАЧАЛОПЕРИОДА(Дата, МЕСЯЦ). Результат остаётся датой и корректно сортируется, в отличие от номеров из МЕСЯЦ() и ДЕНЬ().

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

Запросы

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

Запрос 1С, который генерирует даты по дням за период

Запросы

Готовый текст запроса 1С, который строит список всех дней между двумя датами без регистров и вспомогательных таблиц. Подходит для отчётов, где нужны строки по каждому дню.

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

Обычные формы, Управляемые формы, Запросы

Виртуальная таблица ОстаткиИОбороты не возвращает строки за дни без движений. Показываем запрос с таблицей дат, который даёт начальный и конечный остаток на каждый день периода.

XML в 1С программно: запись, чтение, DOM и выгрузка данных

Интеграция и веб-сервисы

Готовые примеры работы с XML на встроенном языке 1С: запись и чтение, DOM с XPath, преобразование XML в структуру, выгрузка справочника и разбор ошибок парсинга.