При разработке или модификации отчетов в системе 1С:Предприятие 8 программисты часто сталкиваются с необходимостью группировки данных по строковым полям, таким как Комментарий, Содержание или НаименованиеПолное. Если эти поля имеют неограниченную длину, стандартные механизмы Системы компоновки данных (СКД) могут выдавать критическую ошибку при попытке расшифровки: «Неверные параметры в операции сравнения. Нельзя сравнивать поля неограниченной длины и поля несовместимых типов».
В этой статье мы подробно проанализируем причины возникновения этой проблемы и рассмотрим несколько эффективных способов ее решения: от программной подмены условий до изменения архитектуры данных.
Разберем ситуацию с технической точки зрения. Поля неограниченной длины в базе данных (типа TEXT или MEMO в SQL-системах) имеют ряд ограничений. Основное из них — невозможность использования оператора равенства = в запросах WHERE и невозможность включения таких полей в секцию GROUP BY без предварительной обработки.
Когда мы добавляем группировку по полю Договор.Комментарий в отчете, платформа 1С на уровне запроса может отработать корректно, если это просто вывод. Однако, как только пользователь пытается сделать расшифровку (кликнуть на ячейку, чтобы увидеть детальные данные), СКД автоматически формирует новый запрос с отбором. По умолчанию для строк предлагается вид сравнения Равно. Именно здесь происходит сбой: СУБД не может сравнить длинную строку с переданным параметром с помощью оператора «равно».
Рассмотрим вариант, когда нам нужно быстро исправить отчет, не меняя структуру метаданных. Суть метода заключается в перехвате процесса формирования настроек расшифровки и замене условия Равно на Содержит (которое на уровне SQL транслируется в оператор LIKE, разрешенный для длинных строк).
Для типовых отчетов, построенных на базе стандартных бухгалтерских подсистем, мы можем внести изменения в общий модуль БухгалтерскиеОтчетыВызовСервера. Проанализируем пример кода, который проверяет элементы отбора и корректирует их:
// В процедуре подготовки настроек для компоновки макета
НастройкиДляКомпоновкиМакета = КомпоновщикНастроек.ПолучитьНастройки();
ЭлементыОтбора = НастройкиДляКомпоновкиМакета.Отбор.Элементы;
Для каждого ЭлементОтбора Из ЭлементыОтбора Цикл
// Проверяем, является ли левое значение нашим проблемным полем
Если ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Договор.Комментарий")
И ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно Тогда
// Заменяем "Равно" на "Содержит" для обхода ограничения СУБД
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит;
КонецЕсли;
КонецЦикла;
Если отчет использует стандартную обработку расшифровки БСП, целесообразно обратить внимание на процедуру ИнициализацияРасшифровкиПоВиду. Именно в ней происходит генерация параметров, которые система будет использовать для фильтрации данных при «провале» в детализацию.
Более элегантный и «чистый» способ решения проблемы внутри схемы компоновки данных — это явное приведение типа. Мы можем ограничить длину строки в самом запросе, что позволит системе работать с полем как со строкой фиксированной длины.
Рассмотрим, как это выглядит в тексте запроса. Вместо прямого обращения к полю Субконто2.Комментарий, мы будем использовать конструкцию ВЫРАЗИТЬ. Посмотрим на пример:
ВЫБРАТЬ
ХозрасчетныйОбороты.Договор КАК Договор,
ВЫРАЗИТЬ(ХозрасчетныйОбороты.Договор.Комментарий КАК СТРОКА(150)) КАК КомментарийГруппировки,
ХозрасчетныйОбороты.СуммаОборот КАК Сумма
ИЗ
РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, , , , , , ) КАК ХозрасчетныйОбороты
Преимущества этого метода:
Равно.Аналогично функции ВЫРАЗИТЬ, мы можем использовать функцию ПОДСТРОКА. В языке запросов 1С результат функции ПОДСТРОКА всегда имеет ограниченную длину, что автоматически снимает запрет на сравнение.
Пример использования в вычисляемом поле или в тексте запроса:
ПОДСТРОКА(Договор.Комментарий, 1, 255)
Проанализируем ситуацию: если пользователь ввел в комментарий 500 символов, группировка будет производиться по первым 255. В большинстве случаев (например, для меток «Аренда», «Парковка») этого более чем достаточно для корректного разделения данных в отчете.
Выясним причину, по которой вообще возникла необходимость группировки по комментарию. Зачастую это происходит из-за того, что в типовой конфигурации не хватает аналитического разреза. Использование поля Комментарий для хранения типов деятельности или категорий договоров — это «костыль», который ведет к ошибкам ввода данных (опечатки, лишние пробелы).
Рассмотрим правильный алгоритм действий:
Договоры контрагентов с названием «Тип договора».Дополнительное значение (ссылка на список, который вы сами создадите) или Строка ограниченной длины.Этот подход полностью снимает техническую проблему, так как дополнительные реквизиты хранятся в отдельных таблицах и СКД умеет работать с ними максимально эффективно, используя индексацию и корректные типы данных для сравнения.
Мы проанализировали проблему группировки по строкам неограниченной длины и нашли несколько путей решения. Если вам нужно срочное исправление без изменения структуры данных — используйте ВЫРАЗИТЬ(... КАК СТРОКА) в запросе СКД. Если вы хотите надежное решение, которое исключит ошибки пользователей и обеспечит высокую скорость работы отчета — перенесите данные из комментария в дополнительные реквизиты или сведения.
Помните, что группировка по неограниченным строкам значительно замедляет формирование отчетов на больших базах, так как СУБД вынуждена выполнять полное сканирование таблиц. Всегда старайтесь ограничивать длину строковых данных, участвующих в аналитике.