Как избежать дополнения строки пробелами при использовании ВЫРАЗИТЬ в 1С 8.3.10

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

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

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

Причина возникновения проблемы и технические нюансы

Выясним причину такого поведения платформы. При трансляции запроса 1С в язык T-SQL для СУБД Microsoft SQL Server конструкция ВЫРАЗИТЬ(... КАК СТРОКА(N)) преобразуется в приведение к фиксированному строковому типу (например, NCHAR(N) или вызов CAST). Согласно спецификации ANSI SQL, СУБД MS SQL Server при формировании строк фиксированной длины автоматически заполняет остаток длины символами пробела.

Проанализируем ситуацию на конкретном примере из кода встроенного языка 1С:


// Пример запроса с ограничением длины строки
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ВЫРАЗИТЬ(ВариантыОтчетов.Автор.Наименование КАК СТРОКА(1000)) КАК АвторПредставление
    |ИЗ
    |	Справочник.ВариантыОтчетов КАК ВариантыОтчетов";
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
    // В Выборка.АвторПредставление возвращается строка "Иванов И.И.                            "
    Если Не ЗначениеЗаполнено(Вариант.ПредставлениеАвтора.Значение) И ЗначениеЗаполнено(Выборка.АвторПредставление) Тогда
        Вариант.ПредставлениеАвтора.Значение = Выборка.АвторПредставление; // Записываем строку с сотнями пробелов!
    КонецЕсли;
КонецЕсли;

Возникает скрытый логический сбой. Важно помнить ключевую разницу в обработке строк:

  1. В языке запросов 1С оператор равенства = при сравнении строк игнорирует концевые пробелы. То есть запрос Поле = "МояСтрока" найдет значение "МояСтрока ".
  2. Во встроенном языке 1С сравнение строк через = является строгим. Выражение "МояСтрока" = "МояСтрока " вернет Ложь. Поиск объектов через Справочники.НайтиПоНаименованию() или выборка из соответствия/структуры по такому значению сработает некорректно.

Способ 1. Использование функции ПОДСТРОКА вместо ВЫРАЗИТЬ

Наиболее простым и эффективным способом решения проблемы на уровне языка запросов является замена конструкции ВЫРАЗИТЬ на функцию ПОДСТРОКА. При трансляции функции ПОДСТРОКА(Поле, 1, N) в СУБД MS SQL Server формируется тип строки переменной длины (NVARCHAR). В результате СУБД не дополняет строку концевыми пробелами.

Сравним два варианта написания запроса:


// Старый вариант (дополняет пробелами в 8.3.10+):
ВЫРАЗИТЬ(Номенклатура.Наименование КАК СТРОКА(150)) КАК НаименованиеОграниченное

// Рекомендуемый вариант (без лишних пробелов):
ПОДСТРОКА(Номенклатура.Наименование, 1, 150) КАК НаименованиеОграниченное

Использование ПОДСТРОКА полностью закрывает проблему приведения типа без изменения конечных данных в результате выборки.

Способ 2. Применение функций обрезки пробелов

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

1. Обработка во встроенном языке 1С:
При получении результата запроса в коде обрезаем концевые пробелы с помощью встроенной функции СокрП() или СокрЛП():


ОчищеннаяСтрока = СокрП(Выборка.АвторПредставление);
ИскомыйСсылка = Справочники.Пользователи.НайтиПоНаименованию(ОчищеннаяСтрока);

2. Использование функций языка запросов (платформа 8.3.20+):
Начиная с версии платформы 8.3.20.1549, функции работы со строками СокрП(), СокрЛ() и СокрЛП() доступны непосредственно в языке запросов 1С. Можно обернуть выражаемое поле прямо в запросе:


СокрП(ВЫРАЗИТЬ(Таблица.ПолеНеограниченнойДлины КАК СТРОКА(250))) КАК ОчищенноеПоле

Способ 3. Настройка в Системе компоновки данных (СКД)

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

  1. Перейдем на вкладку Вычисляемые поля в СКД.
  2. Добавим поле или отредактируем существующее, указав выражение: СокрП(АвторПредставление).
  3. Ибо на вкладке Настройки в секции Выбранные поля зададим выражение представления с использованием функции СокрП().

Способ 4. Использование режима совместимости

Проанализируем поведение платформы при настройках совместимости. Если в свойствах конфигурации установлен **Режим совместимости** с версией `8.3.9` или ниже, платформа использует прежние механизмы трансляции запросов. Дополнение строк пробелами в этом случае происходить не будет.

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

← На главную