При разработке отчетов на базе системы компоновки данных (СКД) в 1С программисты часто сталкиваются со специфическим поведением группировок при выводе документов-регистраторов. Типичный сценарий: пользователю нужен универсальный отчет, в котором можно анализировать показатели как в общем разрезе (по номенклатуре и контрагентам), так и с детальной расшифровкой до конкретного документа движения (регистратора). Однако при попытке реализовать такую гибкость стандартными средствами СКД разработчики натыкаются на дублирование строк при отключении регистратора или получают ошибку: «Совместная группировка по периодам с другими выражениями запрещена». Для анализа структуры данных и поиска причин подобных ошибок в реальном сеансе подойдёт расширение для отладки СКД и запросов под пользователем.
В этой статье мы подробно разберем, почему возникают эти проблемы, как устроены механизмы компоновки данных изнутри и как настроить отчет так, чтобы строки группировались корректно, а регистратор выводился в отдельной первой колонке без использования программного кода.
Рассмотрим ситуацию, когда в простейшем запросе к виртуальной таблице оборотов регистра накопления (например, РегистрНакопления.Продажи.Обороты) в качестве параметра периодичности жестко указан Регистратор. Если в настройках схемы компоновки данных (на вкладке «Настройки») отчет строится на базе структуры «Детальные записи» (группировка без указания полей), то при отключении поля «Регистратор» в выбранных полях отчет начинает двоить, троить или выдавать множество одинаковых строк с суммами.
Это происходит по нескольким причинам:
СУММА(), в детальных записях эта агрегация не применяется, если не задана группировка по измерениям.Регистратор, то платформа 1С всегда будет запрашивать из базы данных строки, детализированные до каждого документа. Даже если мы уберем колонку «Регистратор» из списка выбранных полей в настройках отчета, физически из базы все равно придут отдельные строки по каждому документу. СКД просто скроет саму колонку регистратора, но выведет все эти строки, из-за чего они будут казаться абсолютно одинаковыми (дублирующимися).Пытаясь исправить дублирование, разработчики часто пробуют добавить поле «Регистратор» в одну группировку вместе с другими измерениями (например, группировать по полям Номенклатура, Контрагент и Регистратор одновременно в одной строке настроек). При формировании такого отчета СКД выдает ошибку: «Совместная группировка по периодам с другими выражениями запрещена».
Давайте проанализируем, почему система ведет себя таким образом. Поля периодов (такие как ПериодСекунда, ПериодДень, Регистратор) в СКД имеют особую роль — «Период». Система использует их для вычисления остатков на контрольные моменты времени (так называемые «границы периодов»). Из-за сложных внутренних алгоритмов расчета остатков СКД накладывает жесткое ограничение: нельзя смешивать в одной строке группировки обычные измерения и поля, имеющие роль периода.
Для решения этой проблемы мы можем применить два эффективных подхода:
Способ 1. Построение иерархической структуры группировок
Мы можем разнести обычные измерения и периоды по разным уровням вложенности в настройках отчета. Для этого выполним следующие шаги:
Номенклатура).Регистратор.При такой структуре СКД сначала сгруппирует данные по номенклатуре (свернув все суммы), а затем внутри каждого товара покажет детальные строки по регистраторам. Если пользователь решит отключить вывод регистраторов, он просто снимет галочку с подчиненной группировки, и отчет автоматически свернется до уровня номенклатуры без каких-либо дублей.
Способ 2. Отключение роли «Период» у поля «Регистратор»
Если наш отчет строится исключительно по оборотам (например, по регистру продаж) и нам не требуется рассчитывать начальные и конечные остатки на каждую секунду или под каждый документ, то роль периода для регистратора нам абсолютно не нужна. Мы можем отключить ее, выполнив следующие действия:
Регистратор.После этого СКД начнет воспринимать поле Регистратор как обычную ссылку на документ (простое измерение). Теперь вы сможете спокойно группировать его в одной строке с номенклатурой, контрагентом и любыми другими полями, и вышеупомянутая ошибка больше не появится.
Когда мы настраиваем иерархические группировки (например, сначала по Номенклатура, а внутри по Регистратор), СКД по умолчанию выводит подчиненные записи со смещением вправо в той же колонке или создает древовидную структуру. Однако часто требуется, чтобы регистратор аккуратно выводился в своей отдельной колонке (желательно первой), а показатели номенклатуры красиво располагались в соседних колонках.
Многие разработчики начинают писать сложные макеты оформления или использовать программный вывод отчета. На самом деле эту задачу можно решить за несколько секунд с помощью стандартной настройки СКД под названием «Расположение реквизитов».
Давайте разберем по шагам, как настроить внешний вид отчета:
Что дает эта настройка? По умолчанию СКД стремится вывести все зависимые реквизиты (например, номер документа, дату документа или артикул номенклатуры) в одной ячейке с самим объектом-владельцем через запятую или в скобках. Установка значения «Отдельно» заставляет систему выделять под каждый выбранный реквизит или связанное поле собственную полноценную колонку в итоговой таблице отчета.
Чтобы регистратор выводился именно в первой колонке, достаточно в списке «Выбранные поля» расположить поле Регистратор на самой первой позиции сверху. Система автоматически отрисует его в крайней левой колонке отчета.
Для того чтобы отчет работал максимально быстро и не перегружал базу данных лишними запросами, крайне важно правильно спроектировать исходный запрос в СКД. Рассмотрим пример неоптимального запроса:
ВЫБРАТЬ
ПродажиОбороты.Регистратор КАК Регистратор,
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.КоличествоОборот КАК Количество,
ПродажиОбороты.СуммаОборот КАК Сумма
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, Регистратор, ) КАК ПродажиОбороты
В данном запросе параметр периодичности виртуальной таблицы жестко задан как Регистратор. Это означает, что даже если пользователь сформирует отчет только по номенклатуре (без вывода документов), СУБД выполнит тяжелую работу по извлечению всех документов движения, а затем СКД будет пытаться программно свернуть эти миллионы строк в памяти сервера приложений. На больших базах данных такой отчет быстро приведет к падению производительности или ошибке нехватки памяти. Для извлечения и отладки запросов из схем компоновки можно использовать инженерную консоль запросов для 1С с поддержкой СКД.
Правильным решением является использование периодичности «Авто». Перепишем наш запрос следующим образом:
ВЫБРАТЬ
ПродажиОбороты.Регистратор КАК Регистратор,
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.КоличествоОборот КАК Количество,
ПродажиОбороты.СуммаОборот КАК Сумма
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, Авто, ) КАК ПродажиОбороты
При использовании параметра Авто СКД берет на себя интеллектуальное управление запросом:
Регистратор для вывода в группировку или колонки, СКД динамически подставит периодичность Регистратор в SQL-запрос. Мы получим детальные данные до документов.Регистратор, СКД автоматически уберет эту детализацию из SQL-запроса. СУБД вернет легкие, предварительно сгруппированные на уровне базы данных строки (только по номенклатуре и агрегированным суммам). Это полностью исключает появление дублей и увеличивает скорость формирования отчета в десятки раз.Давайте подведем итоги и составим краткий чек-лист, который поможет вам всегда создавать быстрые, красивые и гибкие отчеты в СКД без дублирования данных:
Регистратор во вкладке «Наборы данных». Это избавит вас от ошибок совместной группировки.Применяя эти простые, но мощные механизмы платформы 1С:Предприятие, вы сможете создавать профессиональные и отказоустойчивые отчеты, которые будут радовать пользователей своей скоростью работы и аккуратным внешним видом. А для дополнительного контроля точности учёта после доработок полезно автоматически сверять бухгалтерские и налоговые проводки между базами 1С.