Начало периода 1С: НачалоМесяца, КонецДня и другие

Дата: 06.10.2026 16:54:16
Даты
Встроенный язык
Язык запросов
НачалоМесяца
СтандартныйПериод
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Любые

Начало периода в 1С во встроенном языке получают парами функций: НачалоДня() и КонецДня(), НачалоМесяца() и КонецМесяца() и так далее, от минуты до года. Универсальная НАЧАЛОПЕРИОДА(Дата, МЕСЯЦ) есть только в языке запросов, а НачалоПериода(Дата, "Месяц") со строкой — только в выражениях СКД. Ниже — все функции с результатами, сравнение дат по дню, следующий месяц через КонецМесяца() + 1, декада и полугодие, запросы по месяцам и СтандартныйПериод в коде.

Платформа 8.3, конфигурация любая; имена объектов в запросах сверены по УТ 11.4.

Где встречается задача

  • Отбор документов за день, месяц или квартал: параметры запроса &НачалоПериода и &КонецПериода вычисляют из одной даты.
  • Отчёты с группировкой по дням, неделям и месяцам — в запросе и в СКД.
  • Регламентные задания и выгрузки «за вчера» и «за прошлый месяц».
  • Сроки оплаты и отгрузки, где важен день, а не время.
  • Обработка длинного периода по месяцам вместо одного тяжёлого запроса.
  • Поле выбора периода на форме — реквизит типа СтандартныйПериод.

Начало периода 1С: функции от НачалоМинуты до КонецГода

Где смотреть: в конфигураторе «Справка» → «Синтакс-помощник», раздел «Глобальный контекст», группа «Функции работы со значениями типа Дата». Функции начала периода возвращают его первую секунду, функции конца периода — последнюю: для дня и более крупных периодов это 0:00:00 и 23:59:59. Неделя начинается с понедельника.

ПериодНачалоКонецДля 13.08.2026 15:42:27
МинутаНачалоМинуты()КонецМинуты()15:42:00 — 15:42:59
ЧасНачалоЧаса()КонецЧаса()15:00:00 — 15:59:59
ДеньНачалоДня()КонецДня()13.08 0:00:00 — 13.08 23:59:59
НеделяНачалоНедели()КонецНедели()10.08 (пн) — 16.08 (вс)
МесяцНачалоМесяца()КонецМесяца()01.08 — 31.08
КварталНачалоКвартала()КонецКвартала()01.07 — 30.09
ГодНачалоГода()КонецГода()01.01 — 31.12
Декада, полугодиенетнетсвой модуль, см. ниже
&НаКлиенте
Процедура ПоказатьГраницыПериодов(Команда)

    Момент = Дата(2026, 8, 13, 15, 42, 27); // четверг, 13.08.2026 15:42:27

    // Минута и час
    Сообщить(НачалоМинуты(Момент));   // 13.08.2026 15:42:00
    Сообщить(КонецМинуты(Момент));    // 13.08.2026 15:42:59
    Сообщить(НачалоЧаса(Момент));     // 13.08.2026 15:00:00
    Сообщить(КонецЧаса(Момент));      // 13.08.2026 15:59:59

    // День: дата без времени и последняя секунда дня
    Сообщить(НачалоДня(Момент));      // 13.08.2026 0:00:00
    Сообщить(КонецДня(Момент));       // 13.08.2026 23:59:59

    // Неделя: с понедельника по воскресенье
    Сообщить(НачалоНедели(Момент));   // 10.08.2026 0:00:00
    Сообщить(КонецНедели(Момент));    // 16.08.2026 23:59:59

    // Месяц, квартал, год
    Сообщить(НачалоМесяца(Момент));   // 01.08.2026 0:00:00
    Сообщить(КонецМесяца(Момент));    // 31.08.2026 23:59:59
    Сообщить(НачалоКвартала(Момент)); // 01.07.2026 0:00:00
    Сообщить(КонецКвартала(Момент));  // 30.09.2026 23:59:59
    Сообщить(НачалоГода(Момент));     // 01.01.2026 0:00:00
    Сообщить(КонецГода(Момент));      // 31.12.2026 23:59:59

    // Соседние периоды: к дате прибавляются секунды
    Сообщить(КонецДня(Момент) + 1);                   // 14.08.2026 0:00:00 - завтра
    Сообщить(КонецМесяца(Момент) + 1);                // 01.09.2026 0:00:00 - следующий месяц
    Сообщить(НачалоМесяца(НачалоМесяца(Момент) - 1)); // 01.07.2026 0:00:00 - прошлый месяц
    Сообщить(КонецГода(Момент) + 1);                  // 01.01.2027 0:00:00 - следующий год

КонецПроцедуры

Все 14 функций доступны в тонком и веб-клиенте — за началом месяца на сервер ходить не нужно. Оговорка синтакс-помощника одна: через COM-соединение эти методы не поддерживаются. Дата хранится с точностью до секунды, поэтому КонецДня(Дата) + 1 — ровно начало следующего дня, без зазоров и перекрытий.

Дата без времени и сравнение дат по дню

Значение типа Дата всегда содержит время, и оператор = сравнивает до секунды. «Дата без времени» в коде — это НачалоДня(Дата): то же число, время 0:00:00. На этом строятся три приёма:

  • тот же день — НачалоДня(Дата1) = НачалоДня(Дата2), тот же месяц — НачалоМесяца(Дата1) = НачалоМесяца(Дата2);
  • дата внутри дня — Дата >= НачалоДня(День) И Дата <= КонецДня(День), так же задают границы в запросе;
  • разница в календарных днях — (НачалоДня(Дата2) - НачалоДня(Дата1)) / 86400: целое число при любом времени в датах.
// Клиент-серверная функция: подойдёт для общего модуля или модуля формы.
// Срок сравнивается с датой проверки по календарным дням, время не учитывается:
// срок 15.08.2026 10:00 при проверке 15.08.2026 18:30 - «Срок сегодня», а не просрочка.
Функция СостояниеСрока(Срок, ДатаПроверки) Экспорт

    ДнейДоСрока = (НачалоДня(Срок) - НачалоДня(ДатаПроверки)) / 86400;

    Если ДнейДоСрока = 0 Тогда
        Возврат НСтр("ru = 'Срок сегодня'");
    ИначеЕсли ДнейДоСрока = 1 Тогда
        Возврат НСтр("ru = 'Срок завтра'");
    ИначеЕсли ДнейДоСрока > 1 Тогда
        Возврат СтрШаблон(НСтр("ru = 'До срока дней: %1'"), Формат(ДнейДоСрока, "ЧГ=0"));
    КонецЕсли;

    Возврат СтрШаблон(НСтр("ru = 'Просрочено дней: %1'"), Формат(-ДнейДоСрока, "ЧГ=0"));

КонецФункции

// СостояниеСрока('20260815100000', '20260815183000') -> «Срок сегодня»
// СостояниеСрока('20260815', '20260818')             -> «Просрочено дней: 3»

Без НачалоДня() срок в 10:00 при проверке в 18:30 того же дня дал бы около −0,35 дня и ушёл бы в просрочку. Дату без времени строкой выводит Формат() — см. статью про формат даты 1С.

Следующий месяц: КонецМесяца + 1

Арифметика с датой в 1С идёт в секундах: Дата + 1 — плюс одна секунда, разность двух дат — число секунд. Отсюда короткие формулы для соседних периодов:

  • первое число следующего месяца — КонецМесяца(Дата) + 1;
  • конец следующего месяца — КонецМесяца(КонецМесяца(Дата) + 1);
  • начало прошлого месяца — НачалоМесяца(НачалоМесяца(Дата) - 1);
  • начало следующего квартала и года — КонецКвартала(Дата) + 1 и КонецГода(Дата) + 1.

Для месяцев то же даёт ДобавитьМесяц(НачалоМесяца(Дата), 1), но «плюс секунда» универсальнее: работает для дня, недели и декады и не зависит от длины месяца. Пример — разбивка периода на календарные месяцы:

// Делит период на отрезки по календарным месяцам:
// 20.01.2026 - 10.03.2026 -> 20.01-31.01, 01.02-28.02, 01.03-10.03.
// Пригодится, когда выгрузку или пересчёт за год удобнее вести помесячно.
//
// Возвращаемое значение:
//  Массив из Структура - ключи Начало и Окончание (Дата).
//
Функция РазбитьПоМесяцам(Знач ДатаНачала, Знач ДатаОкончания) Экспорт

    Отрезки = Новый Массив;
    ДатаНачала = НачалоДня(ДатаНачала);
    ДатаОкончания = КонецДня(ДатаОкончания);

    НачалоОтрезка = ДатаНачала;
    Пока НачалоОтрезка <= ДатаОкончания Цикл

        КонецОтрезка = Мин(КонецМесяца(НачалоОтрезка), ДатаОкончания);
        Отрезки.Добавить(Новый Структура("Начало, Окончание", НачалоОтрезка, КонецОтрезка));

        // Последняя секунда месяца + 1 секунда = первое число следующего месяца, 0:00:00
        НачалоОтрезка = КонецМесяца(НачалоОтрезка) + 1;

    КонецЦикла;

    Возврат Отрезки;

КонецФункции

Функция возвращает массив структур: его обходят циклом и выгружают или пересчитывают данные по месяцу за раз. Мин() обрезает последний отрезок по дате окончания. А вот почему «через месяц» нельзя считать сутками:

Срок = Дата(2026, 1, 31);

// Неправильно: месяц как 30 суток
ЧерезМесяц = Срок + 30 * 86400;                        // 02.03.2026 - февраль проскочили

// Правильно: границы следующего месяца
ПервоеЧисло = КонецМесяца(Срок) + 1;                   // 01.02.2026 0:00:00
КонецСледующего = КонецМесяца(КонецМесяца(Срок) + 1);  // 28.02.2026 23:59:59
ТоЖеЧисло = ДобавитьМесяц(Срок, 1);                    // 28.02.2026: 31 февраля не бывает

Декада, полугодие и периодичность строкой

Функций НачалоДекады() и НачалоПолугодия() во встроенном языке нет, хотя в запросе есть ДЕКАДА и ПОЛУГОДИЕ. Вторая частая задача — периодичность выбирает пользователь (день, неделя, месяц), и вместо цепочки Если в каждой процедуре нужна одна функция. В УТ 11.4 и КА 2.5 такие уже есть: ВыборПериодаКлиентСервер.НачалоПериодаОтчета(ВидПериода, Дата) и КонецПериодаОтчета(), вид периода — перечисление ДоступныеПериодыОтчета. Для любой конфигурации подойдёт свой общий модуль, где периодичность задаётся строкой, как в СКД:

// Общий модуль ГраницыПериодаКлиентСервер.
// Флаги: «Клиент (управляемое приложение)», «Сервер», «Внешнее соединение».
// Периодичность задаётся строкой, как в функции НачалоПериода() языка СКД.

#Область ПрограммныйИнтерфейс

// Начало периода, которому принадлежит дата.
//
// Параметры:
//  ИсходнаяДата  - Дата - любая дата внутри периода.
//  Периодичность - Строка - "Минута", "Час", "День", "Неделя", "Декада",
//                  "Месяц", "Квартал", "Полугодие" или "Год", регистр не важен.
//
// Возвращаемое значение:
//  Дата - первая секунда периода.
//
Функция НачалоПериода(ИсходнаяДата, Периодичность) Экспорт

    Вид = ВРег(Периодичность);

    Если Вид = "МИНУТА" Тогда
        Возврат НачалоМинуты(ИсходнаяДата);
    ИначеЕсли Вид = "ЧАС" Тогда
        Возврат НачалоЧаса(ИсходнаяДата);
    ИначеЕсли Вид = "ДЕНЬ" Тогда
        Возврат НачалоДня(ИсходнаяДата);
    ИначеЕсли Вид = "НЕДЕЛЯ" Тогда
        Возврат НачалоНедели(ИсходнаяДата);
    ИначеЕсли Вид = "ДЕКАДА" Тогда
        // Декады: 1-10, 11-20 и с 21-го до конца месяца
        НомерДекады = Мин(Цел((День(ИсходнаяДата) - 1) / 10), 2);
        Возврат НачалоМесяца(ИсходнаяДата) + НомерДекады * 10 * 86400;
    ИначеЕсли Вид = "МЕСЯЦ" Тогда
        Возврат НачалоМесяца(ИсходнаяДата);
    ИначеЕсли Вид = "КВАРТАЛ" Тогда
        Возврат НачалоКвартала(ИсходнаяДата);
    ИначеЕсли Вид = "ПОЛУГОДИЕ" Тогда
        // Второе полугодие начинается 1 июля
        Возврат ДобавитьМесяц(НачалоГода(ИсходнаяДата), ?(Месяц(ИсходнаяДата) > 6, 6, 0));
    ИначеЕсли Вид = "ГОД" Тогда
        Возврат НачалоГода(ИсходнаяДата);
    КонецЕсли;

    ВызватьИсключение ТекстОшибкиПериодичности(Периодичность);

КонецФункции

// Конец периода, которому принадлежит дата: последняя секунда периода.
// Параметры - как у НачалоПериода.
Функция КонецПериода(ИсходнаяДата, Периодичность) Экспорт

    Вид = ВРег(Периодичность);

    Если Вид = "МИНУТА" Тогда
        Возврат КонецМинуты(ИсходнаяДата);
    ИначеЕсли Вид = "ЧАС" Тогда
        Возврат КонецЧаса(ИсходнаяДата);
    ИначеЕсли Вид = "ДЕНЬ" Тогда
        Возврат КонецДня(ИсходнаяДата);
    ИначеЕсли Вид = "НЕДЕЛЯ" Тогда
        Возврат КонецНедели(ИсходнаяДата);
    ИначеЕсли Вид = "ДЕКАДА" Тогда
        НачалоДекады = НачалоПериода(ИсходнаяДата, Вид);
        Если День(НачалоДекады) = 21 Тогда
            Возврат КонецМесяца(НачалоДекады); // третья декада - до конца месяца
        КонецЕсли;
        Возврат НачалоДекады + 10 * 86400 - 1;
    ИначеЕсли Вид = "МЕСЯЦ" Тогда
        Возврат КонецМесяца(ИсходнаяДата);
    ИначеЕсли Вид = "КВАРТАЛ" Тогда
        Возврат КонецКвартала(ИсходнаяДата);
    ИначеЕсли Вид = "ПОЛУГОДИЕ" Тогда
        Возврат ДобавитьМесяц(НачалоПериода(ИсходнаяДата, Вид), 6) - 1;
    ИначеЕсли Вид = "ГОД" Тогда
        Возврат КонецГода(ИсходнаяДата);
    КонецЕсли;

    ВызватьИсключение ТекстОшибкиПериодичности(Периодичность);

КонецФункции

// Первая секунда следующего периода.
Функция НачалоСледующегоПериода(ИсходнаяДата, Периодичность) Экспорт

    Возврат КонецПериода(ИсходнаяДата, Периодичность) + 1;

КонецФункции

// Начало предыдущего периода: секунда назад от начала текущего попадает в предыдущий.
Функция НачалоПредыдущегоПериода(ИсходнаяДата, Периодичность) Экспорт

    Возврат НачалоПериода(НачалоПериода(ИсходнаяДата, Периодичность) - 1, Периодичность);

КонецФункции

// Истина, если обе даты лежат в одном периоде: в одном дне, месяце и т. д.
Функция ЭтоОдинПериод(Дата1, Дата2, Периодичность = "День") Экспорт

    Возврат НачалоПериода(Дата1, Периодичность) = НачалоПериода(Дата2, Периодичность);

КонецФункции

// Начала периодов, которые пересекаются с интервалом от ДатаНачала до ДатаОкончания.
//
// Возвращаемое значение:
//  Массив из Дата - например, первые числа месяцев для колонок отчёта.
//
Функция НачалаПериодов(ДатаНачала, ДатаОкончания, Периодичность) Экспорт

    Результат = Новый Массив;
    ТекущееНачало = НачалоПериода(ДатаНачала, Периодичность);

    Пока ТекущееНачало <= ДатаОкончания Цикл
        Результат.Добавить(ТекущееНачало);
        ТекущееНачало = НачалоСледующегоПериода(ТекущееНачало, Периодичность);
    КонецЦикла;

    Возврат Результат;

КонецФункции

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

Функция ТекстОшибкиПериодичности(Периодичность)

    Возврат СтрШаблон(НСтр("ru = 'Неизвестная периодичность «%1». Допустимо: Минута, Час, День, Неделя, Декада, Месяц, Квартал, Полугодие, Год.'"),
        Периодичность);

КонецФункции

#КонецОбласти

Примеры вызова — с клиента или с сервера, без разницы:

Момент = Дата(2026, 8, 13, 15, 42, 27);

НачалоДекады = ГраницыПериодаКлиентСервер.НачалоПериода(Момент, "Декада");         // 11.08.2026 0:00:00
КонецДекады = ГраницыПериодаКлиентСервер.КонецПериода(Момент, "Декада");           // 20.08.2026 23:59:59
НачалоПолугодия = ГраницыПериодаКлиентСервер.НачалоПериода(Момент, "Полугодие");   // 01.07.2026 0:00:00
КонецПолугодия = ГраницыПериодаКлиентСервер.КонецПериода(Момент, "Полугодие");     // 31.12.2026 23:59:59

СледующийКвартал = ГраницыПериодаКлиентСервер.НачалоСледующегоПериода(Момент, "Квартал"); // 01.10.2026 0:00:00
ПрошлаяДекада = ГраницыПериодаКлиентСервер.НачалоПредыдущегоПериода(Момент, "Декада");   // 01.08.2026 0:00:00

// Сравнение дат по дню и по месяцу
ТотЖеДень = ГраницыПериодаКлиентСервер.ЭтоОдинПериод(Момент, Дата(2026, 8, 13, 9, 5, 0)); // Истина
ТотЖеМесяц = ГраницыПериодаКлиентСервер.ЭтоОдинПериод(Момент, Дата(2026, 9, 1), "Месяц"); // Ложь

// Первые числа месяцев с марта по август - например, для колонок отчёта
Месяцы = ГраницыПериодаКлиентСервер.НачалаПериодов(Дата(2026, 3, 15), Момент, "Месяц");
// 01.03.2026, 01.04.2026, 01.05.2026, 01.06.2026, 01.07.2026, 01.08.2026

НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА в запросе

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

// Серверный общий модуль или модуль объекта обработки, имена - по УТ 11.

// Реализации по месяцам за год, в который попадает ДатаОтчета.
// СуммаДокумента - в валюте документа.
Функция РеализацииПоМесяцам(ДатаОтчета) Экспорт

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

    Возврат Запрос.Выполнить().Выгрузить();

КонецФункции

// Выручка по месяцам квартала из регистра накопления: периодичность Месяц
// задана в параметрах виртуальной таблицы, поле Период - начало месяца.
Функция ВыручкаПоМесяцам(ДатаОтчета) Экспорт

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

    Возврат Запрос.Выполнить().Выгрузить();

КонецФункции

В первом запросе реализации августа получают Месяц = 01.08.2026 0:00:00 и сворачиваются в одну строку, а границы года запрос считает сам из одного параметра. Во втором по месяцам группирует виртуальная таблица: при периодичности Месяц поле Период — начало месяца. Оба текста можно проверить в консоли запросов, а сдвиг даты в запросе разобран в статье про ДОБАВИТЬКДАТЕ.

В СКД своя функция — НачалоПериода(Дата, "Месяц"), тип периода здесь строка. Период отчёта обычно задают параметром Период типа СтандартныйПериод, а параметрам НачалоПериода и ОкончаниеПериода на вкладке «Параметры» пишут выражения &Период.ДатаНачала и &Период.ДатаОкончания с флажком «Ограничение использования». Так сделана, например, схема отчёта ВыручкаИСебестоимостьПродаж (синоним «Продажи») в УТ 11.4.

СтандартныйПериод в коде

СтандартныйПериод — тип поля периода с кнопкой выбора: он бывает у реквизитов формы и обработки, у параметров СКД и у свойства Период таблицы с динамическим списком. Свойства — Вариант, ДатаНачала, ДатаОкончания. Конструкторов три: Новый СтандартныйПериод() — произвольный период с пустыми датами, Новый СтандартныйПериод(ВариантСтандартногоПериода.ЭтотМесяц) — по варианту и Новый СтандартныйПериод(ДатаНачала, ДатаОкончания) — по датам. Для вариантов, кроме ПроизвольныйПериод, в настройках хранится только вариант, а даты синтакс-помощник описывает как границы, которые получатся, «если компоновку выполнить сейчас».

// Модуль формы обработки. У обработки есть реквизит Период типа СтандартныйПериод,
// на форме - поле Объект.Период и команда «Выбрать период».

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    // Храним вариант, а не даты: в сентябре «прошлый месяц» сам станет августом
    Объект.Период = Новый СтандартныйПериод(ВариантСтандартногоПериода.ПрошлыйМесяц);

КонецПроцедуры

&НаКлиенте
Процедура ВыбратьПериод(Команда)

    Диалог = Новый ДиалогРедактированияСтандартногоПериода;
    Диалог.Период = Объект.Период;
    Диалог.Показать(Новый ОписаниеОповещения("ВыбратьПериодЗавершение", ЭтотОбъект));

КонецПроцедуры

&НаКлиенте
Процедура ВыбратьПериодЗавершение(ВыбранныйПериод, ДополнительныеПараметры) Экспорт

    Если ВыбранныйПериод = Неопределено Тогда
        Возврат; // диалог закрыли без выбора
    КонецЕсли;
    Объект.Период = ВыбранныйПериод;

    // Полный месяц выводится как «Июль 2026 г.», если конец - 23:59:59
    Если ЗначениеЗаполнено(ВыбранныйПериод.ДатаОкончания) Тогда
        ТекстПериода = ПредставлениеПериода(ВыбранныйПериод.ДатаНачала, КонецДня(ВыбранныйПериод.ДатаОкончания));
    Иначе
        ТекстПериода = СтрШаблон(НСтр("ru = 'С %1'"), Формат(ВыбранныйПериод.ДатаНачала, "ДЛФ=Д; ДП='начала учета'"));
    КонецЕсли;
    ПоказатьПредупреждение(, СтрШаблон(НСтр("ru = '%1: проведено реализаций %2'"),
        ТекстПериода, КоличествоРеализаций(ВыбранныйПериод)));

КонецПроцедуры

&НаСервереБезКонтекста
Функция КоличествоРеализаций(Знач Период)

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

    Выборка = Запрос.Выполнить().Выбрать();
    Возврат ?(Выборка.Следующий(), Выборка.Документов, 0);

КонецФункции

&НаСервереБезКонтекста
Функция КонецПериодаДляЗапроса(Период)

    // Произвольный период без даты окончания: «с 01.03.2026 и дальше»
    Если Не ЗначениеЗаполнено(Период.ДатаОкончания) Тогда
        Возврат Дата(3999, 12, 31, 23, 59, 59);
    КонецЕсли;

    // Дату окончания могли задать программно, без времени
    Возврат КонецДня(Период.ДатаОкончания);

КонецФункции

В настройках СКД значение задают методом Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период", Новый СтандартныйПериод(ВариантСтандартногоПериода.ПрошлыйКвартал)): он сразу включает использование параметра, а если параметра с таким именем нет, вызывает исключение. Период списка документов задаёт свойство таблицы формы: Элементы.Список.Период = Новый СтандартныйПериод(ВариантСтандартногоПериода.ЭтотМесяц).

Разбор ключевых строк

Декада одной формулой

Цел((День(ИсходнаяДата) - 1) / 10) даёт 0 для 1–10 числа, 1 для 11–20 и 2 для 21–30; 31-е дало бы 3, отсюда Мин(…, 2). Третья декада заканчивается вместе с месяцем, поэтому в ней от 8 до 11 дней.

Полугодие через ДобавитьМесяц

Начало — начало года плюс 0 или 6 месяцев, конец — начало плюс шесть месяцев минус секунда. Дата 30 июня в коде не зашита.

Соседние периоды и циклы

НачалоСледующегоПериода — это КонецПериода() + 1, НачалоПредыдущегоПериода отступает на секунду от начала текущего периода. Обе работают и для декады: от 01.03 шаг назад даёт 21.02. В НачалаПериодов и РазбитьПоМесяцам дата на каждой итерации переходит в следующий период, поэтому цикл гарантированно заканчивается.

Исключение вместо тихого результата

Опечатка в периодичности («Месц») вызывает исключение. Если молча вернуть исходную дату, ошибка всплывёт только в цифрах отчёта.

Границы СтандартныйПериод для запроса

КонецПериодаДляЗапроса закрывает два случая: пустую дату окончания у произвольного периода (иначе запрос ничего не вернёт) и дату окончания без времени. Пустая дата начала не мешает: 01.01.0001 — минимальная дата. По той же причине заголовок без даты окончания собирается отдельно: «С 01.03.2026».

Типичные ошибки

  • «Процедура или функция с указанным именем не определена (НачалоПериода)». НачалоПериода(Дата, "Месяц") перенесли из СКД во встроенный язык, где такой функции нет. Нужна НачалоМесяца() или модуль выше.
  • Тип периода в кавычках. НАЧАЛОПЕРИОДА(Док.Дата, "МЕСЯЦ") запрос не примет: тип периода в запросе — ключевое слово.
  • Документы последнего дня не попали в отчёт. Правая граница Дата(2026, 8, 31) — это 0:00:00; передавайте КонецДня() или КонецМесяца().
  • «Первое число» оказалось концом дня. КонецМесяца(Дата) + 86400 для августовской даты даёт 01.09.2026 23:59:59: прибавляются секунды, а нужна всего одна.
  • «Через месяц» как 30 суток. От 31.01.2026 это 02.03.2026. Нужны КонецМесяца() + 1 или ДобавитьМесяц().
  • Даты сравнили со временем. СрокОплаты = ТекущаяДатаСеанса() почти никогда не Истина; сравнивайте НачалоДня() обеих дат.
  • Функция над полем в условии. НАЧАЛОПЕРИОДА(Док.Дата, ДЕНЬ) = &День работает, но индекс по дате СУБД, как правило, не использует. Быстрее Док.Дата МЕЖДУ &НачалоДня И &КонецДня.
  • «Процедура или функция с указанным именем не определена (ТекущаяДатаСеанса)». Вызов в клиентском коде: функция есть на сервере и в толстом клиенте, но не в тонком и веб-клиенте. В конфигурациях на БСП на клиенте есть ОбщегоНазначенияКлиент.ДатаСеанса().

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

Как получить начало и конец текущего месяца в 1С 8.3?

На сервере — НачалоМесяца(ТекущаяДатаСеанса()) и КонецМесяца(ТекущаяДатаСеанса()). На клиенте в конфигурациях на БСП вместо ТекущаяДатаСеанса() передайте ОбщегоНазначенияКлиент.ДатаСеанса(). Начало года и дня — НачалоГода() и НачалоДня().

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

НачалоНедели() возвращает понедельник. Неделя с воскресенья: НачалоДня(Дата) - (ДеньНедели(Дата) % 7) * 86400 — для четверга 13.08.2026 это воскресенье 09.08.2026.

Есть ли функция начала декады или полугодия?

Во встроенном языке нет: подойдёт модуль выше, а в УТ 11.4 и КА 2.5 — ВыборПериодаКлиентСервер. В запросе — НАЧАЛОПЕРИОДА(Дата, ДЕКАДА) и НАЧАЛОПЕРИОДА(Дата, ПОЛУГОДИЕ), в СКД — НачалоПериода(Дата, "Декада").

Чем НачалоМесяца отличается от НАЧАЛОПЕРИОДА?

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

Как сравнить две даты без учёта времени?

В коде — НачалоДня(Дата1) = НачалоДня(Дата2), в запросе — НАЧАЛОПЕРИОДА(Поле1, ДЕНЬ) = НАЧАЛОПЕРИОДА(Поле2, ДЕНЬ). Для отбора по одной дате передайте в запрос границы дня.

Когда проще заказать

Если нужен отчёт с выбором периода, группировкой по неделям или декадам и сравнением с прошлым годом, а разбираться с запросами и СКД некогда, поручите его программисту: отчёты и обработки 1С. Разместите задачу — оценка на площадке бесплатная, ответ в течение рабочего дня.

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.