При разработке отчетов в системе 1С программисты часто сталкиваются с ситуацией, когда данные, относящиеся к одному дню, «разбегаются» по разным колонкам или строкам. Это происходит из-за того, что документы в системе регистрируются с точностью до секунды. Если в запросе или настройках системы компоновки данных (СКД) не указана правильная группировка, система воспринимает каждое уникальное время как отдельную точку на временной шкале.
В этой статье мы подробно разберем, почему возникает такая проблема, проанализируем типичные ошибки в запросах и рассмотрим несколько способов схлопывания данных в одну дату.
Рассмотрим ситуацию, представленную в вопросе автора. В запросе используется виртуальная таблица РегистрНакопления.ТоварыНаСкладе.Обороты. Основная ошибка кроется в параметрах этой таблицы. Давайте посмотрим на исходный код запроса:
ВЫБРАТЬ
ТоварыНаСкладеОбороты.Товар КАК Товар,
ТоварыНаСкладеОбороты.Склад КАК Склад,
ТоварыНаСкладеОбороты.КоличествоОборот КАК КоличествоОборот,
ТоварыНаСкладеОбороты.Период КАК Период
ИЗ
РегистрНакопления.ТоварыНаСкладе.Обороты(&НачалоПериода, &КонецПериода, Запись, ) КАК ТоварыНаСкладеОбороты
Обратим внимание на третий параметр виртуальной таблицы — Запись. Когда мы указываем периодичность Запись, платформа 1С возвращает данные по каждому отдельному движению регистратора (документа). Поскольку документы 01.08.2024 проводились в разное время (например, в 10:00:00 и 14:30:00), система формирует две разные записи, которые в кросс-таблице отчета превращаются в две разные колонки.
Самый простой и эффективный метод решения проблемы на уровне запроса — изменить параметр периодичности. Вместо значения Запись следует использовать значение День. Проанализируем, как изменится поведение системы: при такой настройке виртуальная таблица самостоятельно просуммирует все обороты за одни сутки и вернет одну строку (или колонку) на каждую дату.
Исправленный фрагмент запроса будет выглядеть так:
ИЗ
РегистрНакопления.ТоварыНаСкладе.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК ТоварыНаСкладеОбороты
Если вы хотите предоставить системе компоновки данных (СКД) возможность самостоятельно управлять детализацией, используйте значение Авто. Это позволит пользователю в настройках отчета выбирать, хочет ли он видеть данные по дням, неделям или месяцам.
Иногда требуется оставить периодичность Запись (например, если в этом же запросе нужны данные о конкретных регистраторах), но при этом сгруппировать данные по дням. В этом случае мы воспользуемся функциями языка запросов 1С для работы с датами.
Разберем по шагам, как привести время к началу дня:
НАЧАЛОПЕРИОДА(Период, ДЕНЬ).Пример реализации:
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(ТоварыНаСкладеОбороты.Период, ДЕНЬ) КАК ПериодДень,
ТоварыНаСкладеОбороты.Товар КАК Товар,
СУММА(ТоварыНаСкладеОбороты.КоличествоОборот) КАК КоличествоОборот
ИЗ
РегистрНакопления.ТоварыНаСкладе.Обороты(&НачалоПериода, &КонецПериода, Запись, ) КАК ТоварыНаСкладеОбороты
СГРУППИРОВАТЬ ПО
НАЧАЛОПЕРИОДА(ТоварыНаСкладеОбороты.Период, ДЕНЬ),
ТоварыНаСкладеОбороты.Товар
Важный момент: функция НАЧАЛОПЕРИОДА отсекает время, устанавливая его в 00:00:00. Теперь все записи за 01.08.2024 будут иметь одинаковую метку времени, и система сможет их объединить.
Если запрос написан корректно, но данные в отчете все равно не суммируются, необходимо проверить вкладку Ресурсы в схеме компоновки данных.
Выясним причину, почему это важно: СКД работает по принципу группировки. Если поле КоличествоОборот не добавлено в список ресурсов с функцией СУММА(), система будет пытаться вывести каждое значение как отдельную группировку. Чтобы данные «схлопнулись» в одну колонку даты, убедитесь, что:
СУММА(...).Период выбрана правильно.В ходе обсуждения на форуме один из участников предложил использовать поле ПериодДень, что вызвало ошибку. Проанализируем ситуацию: поля вида ПериодДень, ПериодНеделя, ПериодМесяц являются виртуальными полями дополнения. Они доступны только тогда, когда в параметрах виртуальной таблицы указана периодичность Авто, и только внутри механизмов СКД.
Если вы пишете обычный запрос в консоли запросов или используете периодичность Запись/День, таких полей в таблице просто не существует. Для СКД правильный подход — использовать периодичность Авто и в настройках роли поля Период указать соответствующие дополнительные поля периода.
Подводя итог нашему разбору, выделим основные правила для объединения данных по датам:
День.Авто и правильно настраивайте Роли для полей периода.ДФ=dd.MM.yyyy), чтобы скрыть время 00:00:00, которое остается после группировки.Используя эти методы, вы сможете создавать аккуратные и понятные отчеты, где данные за один день всегда будут собраны в одной колонке.