Как в запросе 1С превратить строку фиксированной длины в строку переменной длины и убрать лишние пробелы?

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

При работе с запросами в системе 1С:Предприятие программисты часто сталкиваются с особенностью хранения данных в СУБД: стандартные поля, такие как Код или Наименование, часто имеют фиксированную длину (тип CHAR в терминах SQL). При выгрузке результата такого запроса в таблицу значений (ТЗ) мы получаем колонку, где строки дополнены пробелами справа до максимальной длины. Это создает неудобства при дальнейшем сравнении строк, выводе в отчеты или поиске данных.

В данной статье мы подробно разберем, как изменить тип строки прямо в тексте запроса, как заставить систему воспринимать строку как поле переменной длины и какие существуют хитрости для обрезания лишних пробелов без использования циклов в коде 1С.

Метод 1: Использование оператора ВЫРАЗИТЬ

Первым делом проанализируем самый очевидный инструмент языка запросов — оператор ВЫРАЗИТЬ. Он позволяет явно указать тип данных для выбранного поля. Когда мы применяем его к строковому полю, мы можем попытаться изменить его квалификаторы.

Рассмотрим пример, когда поле Код имеет длину 10 символов с фиксированным заполнением пробелами. Попробуем преобразовать его:


ВЫБРАТЬ
    ВЫРАЗИТЬ(СправочникНоменклатура.Код КАК СТРОКА(10)) КАК КодПеременный
ИЗ
    Справочник.Номенклатура КАК СправочникНоменклатура

Важный нюанс: само по себе использование ВЫРАЗИТЬ(Поле КАК СТРОКА(N)) не всегда автоматически удаляет пробелы в результирующем наборе данных на уровне СУБД, так как платформа старается сохранить типизацию. Однако при выгрузке в таблицу значений 1С анализирует метаданные запроса. Если мы укажем длину, соответствующую или меньшую исходной, это может помочь системе определить колонку ТЗ как строку переменной длины, но «хвост» из пробелов часто остается. Чтобы решить проблему радикально, рассмотрим следующие подходы.

Метод 2: Приведение к строке неограниченной длины

В языке запросов 1С строки бывают ограниченной и неограниченной длины. Строки неограниченной длины всегда ведут себя как переменные. Один из эффективных трюков — заставить платформу считать колонку полем неограниченной длины. Разберем, как это сделать с помощью оператора ОБЪЕДИНИТЬ ВСЕ.

Проанализируем следующую конструкцию:


ВЫБРАТЬ
    Номенклатура.Код КАК ПолеКода
ИЗ
    Справочник.Номенклатура КАК Номенклатура

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ ПЕРВЫЕ 0
    Номенклатура.Комментарий
ИЗ
    Справочник.Номенклатура КАК Номенклатура

В этом примере мы объединяем результат основного запроса с пустым результатом (ВЫБРАТЬ ПЕРВЫЕ 0), где в той же колонке выбирается поле типа «строка неограниченной длины» (например, Комментарий или Содержание). Платформа 1С при объединении типов приведет общую колонку к наиболее широкому типу — строке неограниченной длины. При выгрузке такого запроса в таблицу значений колонка будет иметь тип Строка без ограничения длины, и лишние пробелы справа во многих случаях будут игнорироваться или автоматически отсекаться СУБД.

Метод 3: Имитация функции TRIM (удаление пробелов) в запросе

Иногда требуется именно удалить пробелы справа (сделать СокрП), но стандартной функции RTRIM в языке запросов 1С не существует. Если мы точно знаем максимальную длину кода и она невелика, мы можем использовать «извращенный», но рабочий метод с использованием функций ПОДСТРОКА и ВЫБОР.

Посмотрим на пример логики для кода длиной 4 символа:


ВЫБРАТЬ
    ВЫБОР
        КОГДА ПОДСТРОКА(Номенклатура.Код, 4, 1) <> " " ТОГДА ПОДСТРОКА(Номенклатура.Код, 1, 4)
        КОГДА ПОДСТРОКА(Номенклатура.Код, 3, 1) <> " " ТОГДА ПОДСТРОКА(Номенклатура.Код, 1, 3)
        КОГДА ПОДСТРОКА(Номенклатура.Код, 2, 1) <> " " ТОГДА ПОДСТРОКА(Номенклатура.Код, 1, 2)
        ИНАЧЕ ПОДСТРОКА(Номенклатура.Код, 1, 1)
    КОНЕЦ КАК КодБезПробелов
ИЗ
    Справочник.Номенклатура КАК Номенклатура

Этот метод основан на проверке каждого символа с конца строки. Если символ не является пробелом, мы берем подстроку до этой позиции. Несмотря на громоздкость, этот метод работает на уровне СУБД и возвращает «чистые» данные в таблицу значений.

Метод 4: Предварительная типизация таблицы значений в коде

Часто проблема заключается не в самом запросе, а в том, как создается Таблица Значений. Если вы используете метод Запрос.Выполнить().Выгрузить(), 1С создает колонки автоматически на основе метаданных запроса. Если тип определен как фиксированная строка, то даже после применения СокрП() в цикле к значению в ячейке, строка может снова дополниться пробелами при записи обратно.

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


// Создаем таблицу значений вручную
ТЗ = Новый ТаблицаЗначений;
// Указываем тип "Строка" без квалификаторов длины (переменная длина)
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Строка"));
ОписаниеСтроки = Новый ОписаниеТипов(МассивТипов);

ТЗ.Колонки.Добавить("Код", ОписаниеСтроки);

// Выполняем запрос
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    НоваяСтрока = ТЗ.Добавить();
    // Теперь СокрП действительно сработает и не добавит пробелов назад
    НоваяСтрока.Код = СокрП(Выборка.Код);
КонецЦикла;

В этом случае колонка Код в ТЗ не имеет ограничения по длине, и любые строки будут храниться в ней ровно в том виде, в котором вы их запишете.

Метод 5: Использование временных таблиц для изменения типа

Рассмотрим ситуацию, когда нам нужно использовать типизированные данные внутри сложного пакета запросов. Мы можем поместить данные во временную таблицу, предварительно «обработав» их. В некоторых СУБД (например, Microsoft SQL Server) использование операций сложения строк может приводить к неявному преобразованию типов.

Посмотрим на пример:


ВЫБРАТЬ
    (Номенклатура.Код + "") КАК ПолеДляПреобразования
ПОМЕСТИТЬ ВтДанные
ИЗ
    Справочник.Номенклатура КАК Номенклатура
;
ВЫБРАТЬ
    ВЫРАЗИТЬ(ВтДанные.ПолеДляПреобразования КАК СТРОКА(100)) КАК Результат
ИЗ
    ВтДанные КАК ВтДанные

Хотя прибавление пустой строки (+ "") поддерживается не всеми версиями платформы в явном виде, комбинирование данных с полями переменной длины внутри временных таблиц заставляет оптимизатор запросов пересматривать типы полей.

Подведем итоги

Для эффективного превращения фиксированной строки в строку переменной длины в запросах 1С мы рекомендуем:

  1. Использовать ВЫРАЗИТЬ(Поле КАК СТРОКА(N)), чтобы задать желаемую максимальную длину в метаданных колонки.
  2. Применять трюк с ОБЪЕДИНИТЬ ВСЕ и полем неограниченной длины, если нужно полностью убрать ограничения.
  3. Если критически важно отсутствие пробелов на выходе запроса — использовать каскад ВЫБОР...ПОДСТРОКА.
  4. Всегда проверять ОписаниеТипов в колонках Таблицы Значений, куда выгружаются данные, так как именно метаданные ТЗ могут принудительно возвращать пробелы в строку.

Проанализировав эти методы, вы сможете гибко управлять типами данных в своих разработках и избегать типичных ошибок при работе со строковыми полями в 1С.

← На главную