Как в запросе 1С удалить часть строки после точки?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки отчетов или обработки данных в 1С:Предприятие часто возникает задача очистки строковых данных. Типичный пример — необходимость отсечь лишние символы после определенного разделителя, например, точки. Сложность заключается в том, что стандартный язык запросов 1С долгое время был ограничен в функциях работы со строками, а длина исходных данных может варьироваться. В этой статье мы подробно разберем все способы решения этой задачи: от классических конструкций до современных функций, появившихся в последних версиях платформы.

Способ 1. Использование современных функций запроса (для платформы 8.3.20 и выше)

Если ваша база работает на платформе версии 8.3.20.1549 или более новой, вам повезло. В языке запросов появились долгожданные функции СТРНАЙТИ и ЛЕВ, которые делают решение задачи элегантным и быстрым. Проанализируем, как работает эта связка.

Для того чтобы обрезать строку до точки, нам нужно сначала определить позицию этой точки, а затем взять все символы, которые находятся левее. Рассмотрим пример кода в запросе:


ВЫБОР
    КОГДА СТРНАЙТИ(ИсходнаяТаблица.ПолеСтрока, ".") > 0
        ТОГДА ЛЕВ(ИсходнаяТаблица.ПолеСтрока, СТРНАЙТИ(ИсходнаяТаблица.ПолеСтрока, ".") - 1)
    ИНАЧЕ ИсходнаяТаблица.ПолеСтрока
КОНЕЦ КАК Результат

Разберем этот фрагмент по шагам:

  1. Функция СТРНАЙТИ(Поле, ".") возвращает порядковый номер первого вхождения точки в строку. Если точки нет, функция вернет 0.
  2. Мы обязательно используем конструкцию ВЫБОР. Это необходимо для обработки строк, в которых точка отсутствует. Если попытаться передать в функцию ЛЕВ нулевой или отрицательный параметр длины, запрос может завершиться ошибкой или вернуть пустой результат.
  3. Если точка найдена, функция ЛЕВ забирает количество символов, равное ПозицияТочки - 1, тем самым исключая саму точку и всё, что идет за ней.

Важный нюанс: если в строке несколько точек, этот метод удалит всё после самой первой точки. Если вам нужно найти последнюю точку (например, чтобы отсечь расширение файла), используйте направление поиска: СТРНАЙТИ(Поле, ".", НаправлениеПоиска.СКонца).

Способ 2. Конструкция «Лесенка» (для старых версий платформы)

В версиях платформы ниже 8.3.20 функции СТРНАЙТИ в запросах не существует. В этом случае программисты вынуждены использовать «переборный» метод с помощью функции ПОДСТРОКА. Выясним, как реализовать такую логику.

Суть метода заключается в последовательной проверке каждого символа строки на равенство точке. Рассмотрим пример для строки, длина которой не превышает 5 символов (для реальных задач «лесенку» продлевают):


ВЫБОР
    КОГДА ПОДСТРОКА(Т.Поле, 1, 1) = "." ТОГДА ""
    КОГДА ПОДСТРОКА(Т.Поле, 2, 1) = "." ТОГДА ПОДСТРОКА(Т.Поле, 1, 1)
    КОГДА ПОДСТРОКА(Т.Поле, 3, 1) = "." ТОГДА ПОДСТРОКА(Т.Поле, 1, 2)
    КОГДА ПОДСТРОКА(Т.Поле, 4, 1) = "." ТОГДА ПОДСТРОКА(Т.Поле, 1, 3)
    КОГДА ПОДСТРОКА(Т.Поле, 5, 1) = "." ТОГДА ПОДСТРОКА(Т.Поле, 1, 4)
    ИНАЧЕ Т.Поле
КОНЕЦ

Этот метод имеет ряд ограничений:

Способ 3. Использование возможностей СКД

Если ваша задача решается в рамках Системы компоновки данных (СКД), вы можете вынести логику обработки строк из самого запроса в «Вычисляемые поля». Это значительно упрощает работу, так как в выражениях СКД доступно гораздо больше функций встроенного языка.

Посмотрим на два варианта реализации в СКД:

  1. Функция СтрРазделить: В выражении вычисляемого поля можно написать: СтрРазделить(ИмяПоля, ".")[0]. Это создаст массив из частей строки и возьмет первый элемент.
  2. Общие модули: Вы можете создать в конфигурации общий модуль (например, РаботаСоСтрокамиСервер) и написать там функцию, использующую регулярные выражения или стандартный поиск. В СКД выражение будет выглядеть так: РаботаСоСтрокамиСервер.ОбрезатьДоТочки(ИмяПоля).

Преимущество этого метода в том, что код становится читаемым и легко поддерживаемым. Однако помните, что вызов функций общего модуля для каждой строки отчета может существенно замедлить его формирование, если данных очень много.

Способ 4. Метод «Таблицы чисел» (Универсальный для SQL)

Проанализируем продвинутый метод, который позволяет найти позицию символа в запросе без длинных конструкций ВЫБОР. Этот способ часто называют методом вспомогательных таблиц.

Идея заключается в следующем: мы соединяем нашу таблицу с виртуальной таблицей чисел (от 1 до максимально возможной длины строки). Условие соединения — символ в этой позиции равен точке.


// Сначала подготавливаем таблицу чисел (например, через ВЫБРАТЬ 1 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 2...)
// Допустим, она называется ВТ_Числа с полем Число

ВЫБРАТЬ
    ИсходныеДанные.ПолеСтрока КАК Оригинал,
    МИНИМУМ(ВТ_Числа.Число) КАК ПозицияТочки
ПОМЕСТИТЬ ВТ_Позиции
ИЗ
    ИсходныеДанные КАК ИсходныеДанные
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Числа КАК ВТ_Числа
        ПО ПОДСТРОКА(ИсходныеДанные.ПолеСтрока, ВТ_Числа.Число, 1) = "."
СГРУППИРОВАТЬ ПО
    ИсходныеДанные.ПолеСтрока
;

ВЫБРАТЬ
    ВТ_Позиции.Оригинал,
    ПОДСТРОКА(ВТ_Позиции.Оригинал, 1, ВТ_Позиции.ПозицияТочки - 1) КАК Результат
ИЗ
    ВТ_Позиции КАК ВТ_Позиции

Этот метод работает динамически и не зависит от жестко прописанного количества условий ВЫБОР КОГДА. Он эффективен, когда нужно обработать большой массив данных на старых версиях 1С.

Рекомендации по архитектуре

Разберем напоследок важный совет. Если вам постоянно требуется обрезать строку по точке в разных отчетах и формах, это сигнализирует о проблемах в архитектуре базы данных. Выполнение строковых операций в запросах — ресурсоемкая операция для СУБД.

Рассмотрим правильный подход: если часть строки до точки имеет самостоятельный смысл (например, это артикул или код группы), лучше хранить ее в отдельном реквизите при записи объекта. Это позволит вам строить индексы по этому полю и выполнять мгновенные выборки без использования сложных функций ПОДСТРОКА или СТРНАЙТИ.

Таким образом, для разовых задач и небольших отчетов идеально подходит использование новых функций платформы или СКД. Для системных задач лучше рассмотреть рефакторинг хранения данных.

← На главную