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