Система компоновки данных (СКД) в 1С:Предприятие — мощный инструмент для создания гибких отчетов, но даже опытные пользователи иногда сталкиваются с трудностями при настройке временных интервалов. Неправильно заданный период может исказить результаты, пропустить критические данные или, наоборот, перегрузить отчет лишней информацией. Эта статья поможет разобраться, как точно задавать временные рамки в СКД — от простых статических дат до динамических интервалов с учетом рабочих дней, кварталов или пользовательских условий.
Мы рассмотрим не только стандартные способы через конструктор отчетов, но и программные методы для разработчиков, а также типичные ошибки, которые приводят к некорректным данным. Особое внимание уделим нюансам работы с периодическими регистрами, когда период отчета влияет на агрегацию данных. Все примеры актуальны для последних версий платформы 1С:Предприятие 8.3 (включая 8.3.23 и новее), но большинство подходов применимы и к более ранним релизам.
Базовые способы задания периода в конструкторе СКД
Начнем с самого простого — ручной настройки периода через интерфейс конструктора отчетов. Этот метод подходит для большинства типовых отчетов, где не требуется сложная логика определения временных рамок. Чтобы задать период:
- Откройте отчет в режиме
1С:Предприятие(не в конфигураторе!). - Нажмите кнопку
Настройки(илиПоказать настройкив зависимости от версии). - Перейдите на вкладку
Параметры— здесь обычно располагаются поля для указания дат.
В большинстве типовых отчетов (Оборотно-сальдовая ведомость, Анализ субконто, Движения документов) вы увидите два ключевых поля:
- 📅 Начало периода — дата, с которой начинается выборка данных. Часто по умолчанию проставляется первое число текущего месяца или квартала.
- 📅 Конец периода — дата, по которую включаются данные в отчет. Обычно это текущая дата или последний день отчетного периода.
Для удобства рядом с полями есть календарь (выпадающий при клике на иконку 🗓️), а также кнопки быстрого выбора стандартных интервалов:
- 🔄
Текущий день— устанавливает сегодняшнюю дату в оба поля. - 📅
Текущий месяц— период с 1-го числа по текущую дату. - 📊
Текущий кварталилиТекущий год— аналогично, но для более длительных интервалов. - ⏮️
Предыдущий месяц/квартал/год— сдвигает период назад на один интервал.
Если в отчете нет вкладки "Параметры", проверьте настройки компоновки данных в конфигураторе — возможно, параметры периода скрыты или вынесены в отдельную форму.
Важно понимать, что включение границ периода зависит от логики отчета. Например, в Оборотно-сальдовой ведомости начало периода обычно включается в расчет (показываются остатки на эту дату), а конец периода — не включается (показываются обороты за день до конечной даты). Это правило может отличаться в других отчетах!
Динамические периоды: относительные даты и рабочие дни
Статичные даты удобны для разовых отчетов, но часто требуется гибкость — например, показать данные за последние 30 дней или за текущий рабочий квартал без выходных. В СКД это реализуется через вычисляемые параметры или настройки периода в схеме компоновки.
Рассмотрим два подхода:
1. Использование относительных дат в параметрах
В конструкторе отчетов можно задать период не фиксированными датами, а формулами. Например:
- 📅
НачалоПериода = ТекущаяДата() - 30— последние 30 дней. - 📅
КонецПериода = КонецМесяца(ТекущаяДата())— до конца текущего месяца. - 📅
НачалоПериода = НачалоКвартала(ТекущаяДата() - 90)— начало квартала, который был 3 месяца назад.
Для этого в настройках параметра периода выберите тип Вычисляемое значение и введите формулу на встроенном языке 1С. Поддерживаются все стандартные функции работы с датами:
НачалоГода(Дата)
КонецКвартала(Дата)
ДобавитьМесяц(Дата, Количество)
РабочийДень(Дата, Направление) // Для пропуска выходных
2. Настройка периода в схеме компоновки данных
Если вы разрабатываете отчет в конфигураторе, период можно задать непосредственно в схеме СКД. Для этого:
- Откройте схему компоновки данных в конфигураторе.
- Перейдите на вкладку
Параметры. - Добавьте новый параметр с типом
Дата. - В свойстве
Выражениеукажите формулу для динамического расчета.
Пример кода для параметра "НачалоМесяца":
Параметры.НачалоПериода = НачалоМесяца(ТекущаяДата());
Как учесть только рабочие дни в периоде?
Для фильтрации выходных используйте функцию РабочийДень() в сочетании с календарем рабочего времени. Пример:
// Получаем дату, пропуская выходные
ТекущаяДата = РабочийДень(ТекущаяДата(), 1);
// Проверяем, является ли дата рабочей
Если НЕ ЭтоРабочийДень(ДатаДокумента) Тогда
Продолжить;
КонецЕсли;
Обратите внимание: для корректной работы должен быть настроен Производственный календарь в справочнике Календари.
Критическая особенность: при использовании динамических периодов в отчетах с большими объемами данных (например, регистры накопления за несколько лет) может значительно возрасти время выполнения запроса. Всегда тестируйте производительность на реальных данных!
Период отчета и периодические регистры: нюансы агрегации
Одна из самых распространенных ошибок при работе с СКД — непонимание того, как период влияет на данные из периодических регистров (накопления, сведений, бухгалтерии). В отличие от документов, где период просто фильтрует записи, в регистрах он определяет границы агрегации.
Рассмотрим на примере регистра накопления "ТоварыНаСкладах":
- 📦 Если задать период
01.01.2026 - 31.01.2026, отчет покажет обороты за январь и остатки на 31.01.2026. - 📦 Если указать только
31.01.2026как конец периода, система может интерпретировать это как запрос остатков на начало дня 31.01.2026 (т.е. без учета движений за этот день!). - 📦 Для регистров сведений период определяет, какие версии записей будут включены (актуальные на дату или все изменения за интервал).
| Тип регистра | Период "01.01-31.01" | Период "31.01" | Период не задан |
|---|---|---|---|
| Регистр накопления (остатки) | Обороты за месяц + остатки на 31.01 | Остатки на начало 31.01 (без оборотов за день) | Ошибка или текущие остатки (зависит от отчета) |
| Регистр накопления (обороты) | Обороты за январь | Обороты за 31.01 | Обороты за весь период существования |
| Регистр сведений | Все изменения за январь | Актуальное значение на 31.01 | Текущее значение (последняя запись) |
Чтобы избежать ошибок:
⚠️ Внимание: Всегда проверяйте логику отчета вНастройках → Другие настройки → Использовать. Если стоит галочкаТолько остатки, период будет трактоваться как дата остатков, а не интервал оборотов.
Фиксированные даты (например, 01.01.2026-31.01.2026)|Относительные даты (последние 30 дней, текущий месяц)|Динамические выражения (начало квартала, конец года)|Не знаю, что это такое-->
Программное задание периода: методы для разработчиков
Когда стандартных средств СКД недостаточно, период можно задать программно — непосредственно в коде отчета. Это актуально для:
- 🛠️ Сложных отчетов с кастомной логикой.
- 🛠️ Интеграции с внешними системами, где период определяется API.
- 🛠️ Автоматических отчетов, запускаемых по расписанию.
Основные методы:
1. Передача параметров при открытии отчета
Если отчет открывается из кода, период можно передать как параметр:
ПараметрыОтчета = Новый Структура();
ПараметрыОтчета.Вставить("НачалоПериода", НачалоМесяца(ТекущаяДата()));
ПараметрыОтчета.Вставить("КонецПериода", ТекущаяДата());
Отчет = Отчеты.ОборотноСальдоваяВедомость.Создать();
Отчет.Параметры.Заполнить(ПараметрыОтчета);
Отчет.СкомпоноватьРезультаты();
Отчет.Показать();
2. Модификация схемы компоновки перед выполнением
Для динамического изменения периода непосредственно перед компоновкой:
СхемаКомпоновки = Отчет.КомпоновщикНастроек.ПолучитьСхемуКомпоновкиДанных();
Параметры = СхемаКомпоновки.Параметры;
Параметры.НачалоПериода.Значение = НачалоГода(ТекущаяДата());
Параметры.КонецПериода.Значение = КонецГода(ТекущаяДата());
Отчет.КомпоновщикНастроек.УстановитьСхемуКомпоновкиДанных(СхемаКомпоновки);
3. Использование временных таблиц для сложных периодов
Если нужно учитывать нестандартные интервалы (например, "каждый вторник и четверг за последние 3 месяца"), можно сгенерировать временную таблицу с датами и использовать её в отчете как источник данных для фильтрации.
Проверить права доступа к отчету в ролях|Создать резервную копию конфигурации|Протестировать код на копии базы|Документировать изменения для других разработчиков-->
При работе с программным заданием периода учитывайте:
- 🔹 Все изменения должны проходить через контроль версий (например, Git или хранилище 1С).
- 🔹 Для отчетов с большими данными используйте
ПоместитьВоВременноеХранилище(), чтобы избежать блокировок. - 🔹 Тестируйте отчеты на разных версиях платформы — в 1С:Предприятие 8.3.20+ появились новые методы работы с датами.
Типичные ошибки и как их избежать
Даже опытные пользователи и разработчики допускают ошибки при настройке периода в СКД. Вот наиболее распространенные проблемы и способы их решения:
1. Несовпадение периодов в связанных отчетах
Если у вас есть главный отчет и вложенные отчеты (например, детализация по строкам), убедитесь, что период передается корректно. Часто вложенный отчет игнорирует период основного, что приводит к несоответствиям.
⚠️ Внимание: В схеме компоновки проверьте свойство ИспользоватьПараметрыРодительскогоОтчета — оно должно быть включено для синхронизации периодов.
2. Игнорирование часовых поясов
В распределенных системах (например, с удаленными складами в разных регионах) период может сбиваться из-за разницы во времени. Всегда используйте:
НачалоДня(Дата) // Вместо просто Дата
КонецДня(Дата) // Для включения всего дня
3. Ошибки округления периодов
Функции вроде НачалоМесяца() или КонецКвартала() могут вести себя неочевидным образом:
- 📅
НачалоМесяца(ТекущаяДата())для даты31.01.2026 23:59:59вернет01.01.2026 00:00:00— время обнуляется! - 📅
КонецДня(ТекущаяДата())добавляет 23:59:59, а не 00:00:00 следующего дня.
| Ошибка | Причина | Решение |
|---|---|---|
| Период сбивается на 1 день | Неучет включения/исключения границ | Использовать НачалоДня()/КонецДня() явно |
| Отчет "висит" при большом периоде | Отсутствие индексов по датам в регистрах | Добавить индексы или разбить период на части |
| Данные за текущий день не попадают в отчет | Конец периода установлен на 00:00:00 | Использовать КонецДня(ТекущаяДата()) |
Всегда проверяйте период отчета на крайних случаях: пустой интервал, однодневный период, переход через границу года/квартала. Это выявляет 90% ошибок еще на этапе разработки.
Практические примеры: от простого к сложному
Разберем несколько реальных сценариев настройки периода в СКД — от типовых задач до нестандартных решений.
Пример 1: Отчет по продажам за последние 7 рабочих дней
Задача: показать продажи только по рабочим дням, исключая выходные и праздники.
Решение:
- Создайте параметр
ДатаОтчетас типомДата. - В выражении для начала периода используйте:
НачалоДня(РабочийДень(ТекущаяДата(), -7)) - Для конца периода:
КонецДня(ТекущаяДата()) - В настройках отчета добавьте фильтр по дате документа с учетом производственного календаря.
Пример 2: Сравнительный отчет за текущий и прошлый кварталы
Задача: показать данные за текущий квартал и аналогичный квартал прошлого года в одном отчете.
Решение:
- 📊 Создайте два набора данных в СКД с разными параметрами периода.
- 📊 Для текущего квартала:
НачалоКвартала(ТекущаяДата())КонецКвартала(ТекущаяДата())
- 📊 Для прошлого года:
НачалоКвартала(ДобавитьГод(ТекущаяДата(), -1))КонецКвартала(ДобавитьГод(ТекущаяДата(), -1))
- 📊 В настройках отчета используйте
Объединение данныхпо общему измерению (например,Номенклатура).
Пример 3: Период "с начала года по предыдущий месяц"
Задача: показать данные с 1 января по последний день предыдущего месяца (например, для отчета на 15 февраля период должен быть 01.01-31.01).
Решение:
НачалоПериода = НачалоГода(ТекущаяДата());
КонецПериода = КонецМесяца(ДобавитьМесяц(ТекущаяДата(), -1));
Как задать период "последний полный месяц"?
Используйте комбинацию функций:
НачалоМесяца(ДобавитьМесяц(ТекущаяДата(), -1)) // Первое число прошлого месяца
КонецМесяца(ДобавитьМесяц(ТекущаяДата(), -1)) // Последнее число прошлого месяца
Это гарантирует, что текущий (незавершенный) месяц не попадет в отчет, даже если он уже начался.
Оптимизация производительности при работе с большими периодами
Отчеты с длительными периодами (год и более) могут тормозить или даже "подвешивать" базу. Вот как этого избежать:
1. Разбивка периода на части
Instead of querying all data at once, split the period into smaller chunks (e.g., by month) and combine the results:
Результат = Новый ТаблицаЗначений;
Для Счетчик = 1 По 12 Цикл
ТекущийМесяц = ДобавитьМесяц(НачалоГода(ТекущаяДата()), Счетчик - 1);
Начало = НачалоМесяца(ТекущийМесяц);
Конец = КонецМесяца(ТекущийМесяц);
ЧастныйРезультат = ПолучитьДанныеЗаПериод(Начало, Конец);
Результат.Объединить(ЧастныйРезультат);
КонецЦикла;
2. Использование индексов
Убедитесь, что в регистрах, участвующих в отчете, есть индексы по полям дат. Например, для регистра накопления Продажи должен быть индекс по Период и Номенклатура.
3. Ограничение выборки на уровне запроса
В схеме компоновки добавьте фильтр по дате непосредственно в запрос:
ВЫБРАТЬ
...
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода
4. Кэширование результатов
Для часто используемых отчетов с фиксированными периодами (например, "за прошлый год") можно кэшировать результаты:
Если НЕ ЗначениеЗаполнено(Кэш.Получить(ИмяОтчета + "_2026")) Тогда
Кэш.Поместить(ИмяОтчета + "_2026", ПолучитьДанные());
КонецЕсли;
⚠️ Внимание: Интерфейсы платформы 1С:Предприятие и механизмы СКД могут изменяться в новых релизах. Для критических отчетов проверяйте актуальность синтаксиса в документации к вашей версии платформы.
FAQ: Частые вопросы по настройке периода в СКД
Как задать период "с начала года по вчерашний день"?
Используйте комбинацию функций:
НачалоПериода = НачалоГода(ТекущаяДата());
КонецПериода = ТекущаяДата() - 1;
Обратите внимание: ТекущаяДата() - 1 вернет вчерашнюю дату в 00:00:00. Если нужен полный вчерашний день, используйте КонецДня(ТекущаяДата() - 1).
Почему в отчете не показываются данные за сегодня, если период включает текущую дату?
Скорее всего, в настройках отчета стоит фильтр по времени. Проверьте:
- Открывает ли период весь день (с 00:00:00 до 23:59:59).
- Нет ли в схеме компоновки дополнительного фильтра по времени (например,
Дата < ТекущаяДата()). - Не используется ли в регистрах накопления флаг
Только проведенные, если документы еще не проведены.
Для включения сегодняшних данных явно укажите:
КонецПериода = КонецДня(ТекущаяДата());
Можно ли в одном отчете показать данные за разные периоды (например, текущий месяц и прошлый)?
Да, для этого нужно:
- Создать в схеме компоновки несколько наборов данных.
- Для каждого набора задать свои параметры периода.
- В настройках отчета использовать
Объединение данныхпо общему измерению (например, по номенклатуре или контрагенту). - Добавить в структуру отчета группировку по признаку периода (например, колонка "Период отчета").
Пример структуры отчета:
+----------------+----------------+----------------+
| Номенклатура | Текущий месяц | Прошлый месяц |
+----------------+----------------+----------------+
| Товар А | 100 000 | 80 000 |
| Товар Б | 150 000 | 120 000 |
+----------------+----------------+----------------+
Как сделать, чтобы период отчета автоматически устанавливался при открытии?
Есть два способа:
- Через настройки отчета:
- Откройте отчет в режиме
1С:Предприятие. - Задайте нужный период вручную.
- Сохраните настройки как
ПользовательскиеилиОбщие(в зависимости от версии).
- Откройте отчет в режиме
- Программно: в модуле отчета переопределите процедуру
ПриОткрытии:Процедура ПриОткрытии()ПараметрыОтчета = ЭтотОбъект.КомпоновщикНастроек.Настройки.ПараметрыДанных;
ПараметрыОтчета.НачалоПериода.Значение = НачалоМесяца(ТекущаяДата());
ПараметрыОтчета.КонецПериода.Значение = ТекущаяДата();
КонецПроцедуры
Почему при изменении периода в отчете данные не обновляются?
Возможные причины и решения:
- 🔄 Кэширование отчета: очистите кэш через
Все функции → Очистить кэш. - 🔄 Несохраненные настройки: после изменения периода нажмите
ВыполнитьилиСформировать. - 🔄 Ошибка в схеме компоновки: проверьте, не зафиксированы ли даты непосредственно в запросе (вкладка
Наборы данных). - 🔄 Права доступа: убедитесь, что у пользователя есть права на просмотр данных за выбранный период.
Если проблема сохраняется, проверьте журнал регистрации на наличие ошибок при выполнении запроса.