При разработке отчетов на Системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда нужно сгруппировать данные по реквизиту документа, являющегося регистратором для регистра накопления. Однако в настройках отчета нужное поле либо отсутствует в списке доступных для группировки, либо вызывает ошибку при попытке выполнить отчет. Рассмотрим подробно, почему это происходит и какими методами можно решить данную проблему.
В регистрах накопления поле Регистратор всегда имеет составной тип данных, так как движения по регистру могут делать десятки различных видов документов. Когда мы обращаемся к реквизиту через точку от регистратора (например, Регистратор.Склад), система не всегда может однозначно определить тип данных этого реквизита, если он отличается в разных документах или если поле Регистратор не ограничено конкретным типом.
Проанализируем ситуацию: если в схеме компоновки данных поле определяется как «объект» или «любая ссылка», СКД может наложить ограничения на его использование в группировках. Это защитный механизм платформы, предотвращающий выполнение крайне неоптимальных SQL-запросов, которые могли бы возникнуть при попытке соединения со всеми возможными таблицами документов-регистраторов.
Одной из самых коварных причин является автоматическое приведение типа к строке неограниченной длины. В языке SQL группировка (GROUP BY) по полям типа TEXT или NVARCHAR(MAX) запрещена на уровне СУБД. Если СКД по какой-то причине решит, что ваш реквизит является строкой неограниченной длины, она просто исключит его из списка доступных полей для группировки.
Разберем, как это лечится. Единственный надежный способ — явное приведение типа в тексте запроса набора данных. Рассмотрим пример кода:
ВЫБРАТЬ
ВЫРАЗИТЬ(СебестоимостьТоваровОбороты.Регистратор КАК Документ.ПоступлениеТоваровУслуг).Номер КАК НомерДокумента,
ВЫРАЗИТЬ(СебестоимостьТоваровОбороты.Регистратор.Комментарий КАК СТРОКА(200)) КАК КомментарийДокумента
ИЗ
РегистрНакопления.СебестоимостьТоваров.Обороты КАК СебестоимостьТоваровОбороты
Используя конструкцию ВЫРАЗИТЬ, мы явно указываем системе, что поле Номер нужно брать из конкретного типа документа, а поле Комментарий ограничено 200 символами. После такого преобразования СКД позволит использовать эти поля в группировках без каких-либо проблем.
Часто в сложных запросах СКД разработчики используют временные таблицы для промежуточных расчетов. При помещении данных во временную таблицу (конструкция ПОМЕСТИТЬ) часть метаданных о типах может быть потеряна. Когда вы в конечном запросе выбираете поле из временной таблицы, СКД видит его как "просто поле", не понимая, что за ним стоит ссылка на документ со всеми его реквизитами.
Рассмотрим по шагам, как правильно работать с временными таблицами в СКД, чтобы сохранить возможность группировки:
*, а явно перечисляете поля.Посмотрим на примере, как может выглядеть такой запрос:
ВЫБРАТЬ
СебестоимостьТоваровОбороты.Регистратор КАК ДокументПоступления,
ВЫРАЗИТЬ(СебестоимостьТоваровОбороты.Регистратор КАК Документ.ПоступлениеТоваровУслуг).ХозяйственнаяОперация КАК Операция
ПОМЕСТИТЬ ВТ_Выборка
ИЗ
РегистрНакопления.СебестоимостьТоваров.Обороты(&ДатаНачала, &ДатаОкончания) КАК СебестоимостьТоваровОбороты
;
ВЫБРАТЬ
ВТ_Выборка.ДокументПоступления,
ВТ_Выборка.Операция
ИЗ
ВТ_Выборка КАК ВТ_Выборка
В современных конфигурациях, таких как ERP или Комплексная автоматизация, регистр СебестоимостьТоваров активно использует ключи аналитики. Обращение напрямую к Регистратор в виртуальных таблицах этого регистра может быть избыточным.
Проанализируем ситуацию: если ваша цель — сгруппировать данные по какому-то свойству номенклатуры или склада, лучше делать это через соединение с соответствующими справочниками аналитики, а не через регистратор. Группировка по реквизитам регистратора — это «тяжелая» операция, так как она заставляет систему анализировать таблицу движений, которая обычно является одной из самых больших в базе данных.
Даже если в запросе всё написано идеально, настройки самой схемы могут блокировать группировку. Выясним причину в настройках набора данных:
Если группировка всё равно не работает, выполните следующие действия:
CAST(NULL AS ...) или отсутствие поля в секции GROUP BY, значит, проблема в типизации в 1С.ГДЕ вашего запроса обязательно используйте ограничение по типам, если работаете с регистратором. Например: ГДЕ СебестоимостьТоваровОбороты.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг. Это подскажет оптимизатору СКД, с какими таблицами нужно работать.Подводя итог, можно сказать, что в 90% случаев проблема решается использованием ВЫРАЗИТЬ в тексте запроса и проверкой ограничений на вкладке «Наборы данных». Работа с СКД требует внимательности к типам данных, особенно когда речь идет о таких сложных объектах, как регистраторы в регистрах накопления с высокой нагрузкой.