При разработке отчетов и обработке данных в 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью изменить регистр строковых значений. Типичная задача — привести наименование товара к нижнему регистру или сделать первую букву предложения строчной. Однако стандартный язык запросов 1С накладывает жесткие ограничения на манипуляции со строками. В этой статье мы подробно разберем, почему функции типа НРег() не работают в тексте запроса и какие альтернативные механизмы предоставляет Система компоновки данных (СКД) для решения этой задачи.
Прежде всего, проанализируем ситуацию с точки зрения архитектуры платформы. Когда мы пишем запрос в 1С, он транслируется в SQL-запрос к СУБД (например, MS SQL Server или PostgreSQL). В языке запросов 1С отсутствуют встроенные функции для изменения регистра (такие как LOWER() или UPPER() в SQL), так как платформа стремится к унификации работы с различными базами данных и обеспечивает строгую типизацию. Попытка написать НРег(Поле) в консоли запросов приведет к ошибке синтаксиса, так как эта функция относится к встроенному языку (клиентскому или серверному), а не к языку запросов.
Важно понимать: если вам нужно изменить регистр данных прямо «на лету» в запросе, стандартных средств для этого нет. Единственное исключение — использование крайне громоздких конструкций ВЫБОР КОГДА для каждого символа, что на практике не применяется из-за катастрофического падения производительности.
Рассмотрим основной способ решения задачи в рамках системы компоновки данных. В отличие от текста запроса, выражения в вычисляемых полях СКД обрабатываются процессором компоновки уже после получения данных из БД. Здесь нам доступен гораздо более широкий набор функций.
Для того чтобы перевести строку в нижний регистр, выполним следующие шаги:
НРег(ИмяПоля).Важный нюанс: если ИмяПоля имеет составной тип или тип «Ссылка», функция НРег() может выдать ошибку или вернуть пустую строку. Чтобы избежать этого, проанализируем тип данных и применим явное приведение к строке:
НРег(ВЫРАЗИТЬ(ИмяПоля КАК СТРОКА(200)))
Если задача стоит более узко — например, нужно перевести в нижний регистр только первую букву, — мы можем скомбинировать строковые функции:
НРег(Лев(ИмяПоля, 1)) + Сред(ИмяПоля, 2)
Посмотрим на ситуацию, когда нам не нужно использовать преобразованное значение для группировок или отборов, а нужно лишь корректно отобразить его пользователю в отчете. В этом случае лучше использовать «Выражение представления».
Разберем, почему это эффективно: процессор компоновки данных будет вычислять это выражение только для тех записей, которые непосредственно выводятся на экран (с учетом постраничного вывода или иерархии). Это снижает общую нагрузку на сервер.
На закладке «Наборы данных» найдите нужное поле и в колонке «Выражение представления» укажите ту же функцию: НРег(ИмяПоля). Сами данные в базе останутся в исходном регистре, но в отчете пользователь увидит текст в нижнем регистре.
Иногда логика преобразования слишком сложна для одной строки выражения СКД. В таких случаях мы можем вызвать экспортную функцию из общего модуля. Рассмотрим по шагам, как это реализовать:
Функция ПреобразоватьРегистр(Значение) Экспорт
Если ТипЗнч(Значение) <> Тип("Строка") Тогда
Возврат Строка(Значение);
КонецЕсли;
// Например, делаем только первую букву строчной
Возврат НРег(Лев(Значение, 1)) + Сред(Значение, 2);
КонецФункции
ИмяМодуля.ПреобразоватьРегистр(ИмяПоля).Важно: Для работы внешних функций в СКД убедитесь, что в настройках отчета не стоит запрет на исполнение кода (в новых версиях платформы по умолчанию вызов функций разрешен, но в некоторых конфигурациях может потребоваться флаг «Разрешить внешние функции»).
Начиная с версии платформы 8.3.10, появилась универсальная функция СтрРегистр(). Проанализируем ее преимущества: она более гибкая, чем старые НРег() и ВРег(), так как вторым параметром принимает вид регистра.
Пример использования в вычисляемом поле:
СтрРегистр(ИмяПоля, ВидРегистра.Нижний)
Также доступны варианты ВидРегистра.Верхний и ВидРегистра.Титульный (каждое слово с заглавной буквы). Использование этой функции делает ваш код более современным и читаемым.
Выясним причину, по которой иногда кажется, что 1С игнорирует регистр. По умолчанию большинство баз данных 1С на MS SQL Server создаются с параметром сортировки (Collation) _CI_AS (Case Insensitive), что означает нечувствительность к регистру при сравнении.
Это означает, что запрос:
ГДЕ Поле = "Текст"
Найдет и "ТЕКСТ", и "текст". Однако это никак не влияет на вывод данных. Если ваша задача — именно визуальное изменение регистра в печатной форме или отчете, то настройки SQL вам не помогут, и следует использовать методы, описанные выше (СКД или функции общего модуля).
Подведем итоги нашего исследования. Мы выяснили, что напрямую в запросе регистр изменить нельзя. Для решения задачи в отчетах мы рекомендуем:
НРег(), если преобразованное значение нужно для расчетов или группировок.ВЫРАЗИТЬ, чтобы избежать ошибок исполнения в СКД.Применяя эти методы, вы сможете гибко управлять отображением текстовой информации в любых отчетах на платформе 1С:Предприятие 8.3.