При разработке отчетов или обработок в 1С часто возникает задача сгруппировать данные по строковому полю, например, по «Наименованию». Разработчики сталкиваются с тем, что строки «Товар» и «товар» воспринимаются системой как разные значения. Давайте разберемся, почему это происходит и как решить задачу в рамках архитектуры платформы 1С.
Важно понимать, что язык запросов 1С — это абстрактный слой, который должен одинаково успешно работать с различными СУБД: MSSQL, PostgreSQL, Oracle и IBM DB2. Разные СУБД имеют разные правила работы с регистрами символов. Чтобы обеспечить максимальную кроссплатформенность и высокую производительность, разработчики платформы приняли решение не добавлять в язык запросов функции приведения регистра, которые требовали бы трансляции в специфические команды каждой конкретной базы данных.
Поведение группировки напрямую зависит от настроек Collation (сортировки) базы данных в СУБД. Рассмотрим основные аспекты:
MSSQL (например, Cyrillic_General_CI_AS). В такой базе данных строки «Товар» и «товар» для СУБД идентичны. Следовательно, оператор СГРУППИРОВАТЬ ПО автоматически объединит их в одну группу.CS, то СУБД будет считать разные регистры разными символами. В этом случае стандартный запрос с группировкой вернет два разных результата.Попытка принудительной смены Collation на стороне СУБД обычно не поддерживается платформой 1С и может привести к ошибкам в работе Конфигуратора или самого приложения.
Поскольку внутри запроса изменить регистр штатно нельзя, мы рассмотрим несколько эффективных подходов для обхода этого ограничения.
Если вы строите отчет на базе СКД, у вас есть мощный инструмент для постобработки данных. Мы можем получить результат из базы «как есть», а затем привести его к нужному виду:
ВРег(Наименование) или НРег(Наименование).В этом случае приведение к единому регистру произойдет на стороне сервера 1С после выборки данных, что позволит корректно объединить записи в отчете.
Если данные должны быть унифицированы всегда (например, в справочнике номенклатуры), лучше всего позаботиться об этом на этапе ввода информации:
При записи объекта в базу данных вы можете создать дополнительный реквизит (например, НаименованиеНормализованное), в который записывать значение, приведенное к верхнему регистру с помощью функции ВРег(). Тогда запрос будет выглядеть максимально просто:
ВЫБРАТЬ
Номенклатура.НаименованиеНормализованное,
СУММА(Продажи.Количество)
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГРУППИРОВАТЬ ПО
Номенклатура.НаименованиеНормализованное
Если данных не слишком много, можно выгрузить результат запроса в ТаблицуЗначений и выполнить группировку средствами встроенного языка 1С:
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
РезультатЗапроса.Колонки.Добавить("НаименованиеДляГруппировки");
Для Каждого Строка Из РезультатЗапроса Цикл
Строка.НаименованиеДляГруппировки = ВРег(Строка.Наименование);
КонецЦикла;
РезультатЗапроса.Свернуть("НаименованиеДляГруппировки", "Количество");
Этот метод позволяет гибко управлять логикой группировки, не завися от настроек СУБД.
Не пытайтесь найти «волшебную кнопку» внутри запроса для смены регистра — ее не существует из-за архитектурных особенностей платформы. Анализируйте задачу: если нужно просто вывести отчет — используйте СКД. Если нужно обеспечить чистоту данных в базе — нормализуйте значения при записи. А если требуется сложная выборка — используйте возможности ТаблицыЗначений после получения данных из СУБД. Эти подходы помогут вам эффективно решать задачи по унификации данных в любых проектах на 1С.