← Назад к вопросам

Вывод всех дат в заданном интервале

1.7 Middle🔥 161 комментариев
#Запросы и оптимизация#Стандарты разработки

Условие

Напишите код или запрос, который выводит все даты по порядку из заданного интервала.

Пример

Вход:

  • ДатаНачала = 01.01.2024
  • ДатаОкончания = 05.01.2024

Выход:

  • 01.01.2024
  • 02.01.2024
  • 03.01.2024
  • 04.01.2024
  • 05.01.2024

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Решение

Для вывода всех дат в интервале существует несколько подходов. Рассмотрим наиболее эффективные.

Способ 1: Цикл на встроенном языке (самый простой)

ДатаНачала = 2024-01-01;
ДатаОкончания = 2024-01-05;

ТекущаяДата = ДатаНачала;

Пока ТекущаяДата <= ДатаОкончания Цикл
    Сообщить(Текущая Дата);
    ТекущаяДата = ТекущаяДата + 86400; // 86400 секунд = 1 день
КонецЦикла;

Способ 2: Более универсальный вариант (через функцию БС)

Функция ПолучитьДатыИнтервала(ДатаНачала, ДатаОкончания)
    МассивДат = Новый Массив();
    ТекущаяДата = ДатаНачала;
    
    Пока ТекущаяДата <= ДатаОкончания Цикл
        МассивДат.Добавить(ТекущаяДата);
        ТекущаяДата = ТекущаяДата + 86400;
    КонецЦикла;
    
    Возврат МассивДат;
КонецФункции

// Использование
Даты = ПолучитьДатыИнтервала(2024-01-01, 2024-01-05);
Для Каждого Дата Из Даты Цикл
    Сообщить(Дата);
КонецЦикла;

Способ 3: Через запрос (самый мощный для больших интервалов)

ДатаНачала = 2024-01-01;
ДатаОкончания = 2024-01-05;

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

Запрос.Текст = 
"""ВЫБРАТЬ
    ПОЛУЧЕННЫЙСЕРВЕР() + КОЛИЧЕСТВО(*))*86400) КАК Дата
ИЗ
    РегистрСведений.ПримечанияСотрудников
ГРУППИРОВАТЬ ПО
    1
УПОРЯДОЧИТЬ ПО
    Дата
ЛИМИТ (@ДатаОкончания - @ДатаНачала + 1) СМЕЩЕНИЕ 0""";

ЭТОТ запрос слишком сложен. Лучше использовать проверенный вариант:

ДатаНачала = 2024-01-01;
ДатаОкончания = 2024-01-05;

Запрос = Новый Запрос();
Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания);
Запрос.УстановитьПараметр("Количество", Дата Окончания - ДатаНачала + 1);

Запрос.Текст = 
"""ВЫБРАТЬ
    @ДатаНачала + (ЗНАЧЕНИЕ(Константа.ПустойДатаВремя) + РегистрСведений.ПримечанияСотрудников.НомерСтроки - 1)*86400 КАК Дата
ИЗ
    РегистрСведений.ПримечанияСотрудников
ГДЕ
    РегистрСведений.ПримечанияСотрудников.НомерСтроки <= @Количество
ПОРЯДОКПО
    Дата""";

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

Способ 4: Через таблицу значений

ДатаНачала = 2024-01-01;
ДатаОкончания = 2024-01-05;

Таблица = Новая ТаблицаЗначений();
Таблица.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата"));

ТекущаяДата = ДатаНачала;
Пока ТекущаяДата <= ДатаОкончания Цикл
    НоваяСтрока = Таблица.Добавить();
    НоваяСтрока.Дата = ТекущаяДата;
    ТекущаяДата = ТекущаяДата + 86400;
КонецЦикла;

Для Каждого Строка Из Таблица Цикл
    Сообщить(Строка.Дата);
КонецЦикла;

Рекомендации по использованию:

Цикл (Способ 1-2):

  • Используй для небольших интервалов (до нескольких месяцев)
  • Простой, понятный код
  • Минимальные затраты памяти
  • Быстрое выполнение

Запрос (Способ 3):

  • Для очень больших интервалов (годы)
  • Если нужно фильтровать даты по определённым условиям
  • Если данные уже в БД

Таблица значений (Способ 4):

  • Если нужно работать с датами дальше (передать в запрос, сохранить)
  • Когда нужна структурированность данных

Важный момент:

Добавляем к дате именно 86400 секунд (24 часа), потому что в 1С даты хранятся как секунды, прошедшие с 1900 года. Это гарантирует точное добавление одного дня без ошибок с часовыми поясами.