При разработке отчетов и обработок в системе 1С:Предприятие программисты регулярно сталкиваются с необходимостью предварительной обработки строк. Типичный пример — обрезка префиксов у номеров документов, удаление лишних знаков в артикулах или отсечение нескольких символов с конца строки — для этого подойдёт обработка очистки наименований и артикулов в 1С. В зависимости от версии платформы и механизма вывода данных (обычный запрос или Система компоновки данных — СКД) эту задачу можно решить разными способами.
В этой статье мы подробно разберем, как правильно отсекать символы в запросах и СКД, проанализируем ограничения классических методов и рассмотрим современные альтернативы, появившиеся в последних версиях платформы 1С.
ПОДСТРОКА в языке запросовСамым известным и кроссплатформенным решением для обрезки строки непосредственно в СУБД является использование стандартной функции языка запросов ПОДСТРОКА. Этот метод работает на любых версиях платформы 1С v8.
Синтаксис функции выглядит следующим образом:
ПОДСТРОКА(<Исходная строка>, <Начало>, <Длина>)
Разберем параметры функции подробнее:
Рассмотрим пример использования в реальном запросе. Предположим, у нас есть код номенклатуры формата "СП-0012345", и нам нужно убрать первые три символа ("СП-"), оставив только цифры:
ВЫБРАТЬ
ПОДСТРОКА(Номенклатура.Код, 4, 8) КАК ОбрезанныйКод
ИЗ
Справочник.Номенклатура КАК Номенклатура
Ограничения метода: функция ПОДСТРОКА отлично справляется с задачами, когда длина исходной строки и количество отсекаемых символов заранее строго определены. Однако, если строка имеет переменную длину (например, номера телефонов разного формата) и нам требуется отсечь ровно 3 символа с конца строки, чистый язык запросов старых версий платформы не предоставит нам простых инструментов, так как в нем отсутствует аналог функции определения длины строки СтрДлина. Для решения этой задачи можно использовать алгоритм определения длины строки в запросе методом половинного деления.
Если в вашей организации используется современная версия платформы 1С:Предприятие (начиная с релиза 8.3.20.1549), то вам больше нет необходимости ограничивать себя рамками функции ПОДСТРОКА. В платформу была добавлена полноценная поддержка стандартных строковых функций СУБД непосредственно в языке запросов.
Теперь в текстах запросов вы можете напрямую использовать:
ЛЕВ(<Строка>, <ЧислоСимволов>) — возвращает указанное количество символов с начала строки.ПРАВ(<Строка>, <ЧислоСимволов>) — возвращает указанное количество символов с конца строки.СтрНайти(<Строка>, <Подстрока>) — определяет позицию вхождения подстроки.Рассмотрим практический пример. Нам необходимо получить первые 5 символов артикула номенклатуры:
ВЫБРАТЬ
ЛЕВ(Номенклатура.Артикул, 5) КАК СокращенныйАртикул
ИЗ
Справочник.Номенклатура КАК Номенклатура
Эти новые функции делают код запросов гораздо более читаемым и избавляют от громоздких математических расчетов позиций символов.
Если конечной целью вашей задачи является вывод информации в отчет СКД, то перенос логики форматирования строк внутрь SQL-запроса зачастую считается плохой практикой разработки. Это усложняет чтение запроса и создает дополнительную вычислительную нагрузку на сервер базы данных.
Гораздо эффективнее и гибче решать эту задачу с помощью Языка выражений СКД на вкладке "Вычисляемые поля". В отличие от СУБД, среда выполнения СКД поддерживает полноценную работу со строковыми функциями, включая определение длины текста.
Для реализации этой схемы выполним следующие шаги:
НомерБезТрехСимволов) и путь к данным.Чтобы отрезать ровно 3 символа с конца у строки произвольной длины, используйте следующее выражение СКД:
Лев(Номер, СтрДлина(Номер) - 3)
Преимущества данного подхода:
Иногда алгоритм усечения или преобразования строки оказывается слишком сложным для написания формул (например, нужно отсечь символы, но только если они являются буквами, или удалить лидирующие нули с учетом префикса организации). В этом случае в выражении вычисляемого поля СКД можно вызвать экспортную функцию из общего модуля конфигурации.
Для этого в выражении СКД прописывается вызов функции в следующем формате:
ИмяОбщегоМодуля.МояФункцияОбработкиСтроки(ПолеСтроки)
Например, создадим в общем модуле РаботаСоСтрокамиКлиентСервер функцию:
Функция ИсключитьСпецСимволыИОбрезать(ИсходныйНомер) Экспорт
// Отрезаем пробелы
ВременныйНомер = СокрЛП(ИсходныйНомер);
// Логика отсечения последних 3 символов, если длина больше 5
Если СтрДлина(ВременныйНомер) > 5 Тогда
Возврат Лев(ВременныйНомер, СтрДлина(ВременныйНомер) - 3);
Иначе
Возврат ВременныйНомер;
КонецЕсли;
КонецФункции
В вычисляемом поле СКД выражение примет простой вид:
РаботаСоСтрокамиКлиентСервер.ИсключитьСпецСимволыИОбрезать(Номер)
Важное условие: общий модуль, в котором объявляется вызываемая функция, должен иметь активные флаги "Клиент", "Сервер" или "Внешнее соединение" (в зависимости от того, в каком контексте формируется отчет), а сама функция обязательно должна быть объявлена с ключевым словом Экспорт.
ПОДСТРОКА от ВЫРАЗИТЬРазработчики часто путают назначение функций ПОДСТРОКА и ВЫРАЗИТЬ при работе со строками в запросах 1С. Разберем принципиальное различие в их поведении при взаимодействии с СУБД, чтобы избежать скрытых ошибок в логике работы программы.
ВЫРАЗИТЬ(<Строка> КАК СТРОКА(<Длина>)) принудительно приводит строковое значение к строго заданному типу фиксированной длины. Если исходная строка короче указанной длины, СУБД автоматически дополняет результат пробелами справа. Например, результатом выражения ВЫРАЗИТЬ("123" КАК СТРОКА(6)) будет строка вида "123 ".ПОДСТРОКА(<Строка>, <Начало>, <Длина>) возвращает только реально существующую часть строки. Она не дополняет результат пробелами, если исходная строка оказалась короче, чем запрошенная длина. Результатом выражения ПОДСТРОКА("123", 1, 6) останется исходная короткая строка "123" без лишних пробелов на конце.Также помните, что при работе со строками неограниченной длины в клиент-серверном режиме использование функции ПОДСТРОКА с параметром длины более 1024 символов может приводить к ошибкам работы СУБД MS SQL Server, если это поле далее участвует в операциях группировки (СГРУППИРОВАТЬ ПО) или сортировки (УПОРЯДОЧИТЬ ПО). Всегда старайтесь ограничивать длину выбираемой подстроки разумными пределами.