Как объединить значения ссылочных реквизитов в одну строку в 1С?

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

При разработке конфигураций и доработке прикладных решений разработчики часто сталкиваются с задачей сформировать составное строковое описание на основе нескольких реквизитов объекта. Например, требуется объединить в одну информационную строку наименование оборудования из справочника и выбранную технологическую операцию из перечисления. Однако простая попытка сложить эти значения через знак плюс нередко приводит к ошибке: «Преобразование значения к типу Число не может быть выполнено». Разберем по шагам, почему возникает эта ошибка во встроенном языке 1С и как правильно решить задачу.

Выясним причину ошибки: почему платформа требует число?

Проанализируем исходный код, вызвавший сбой:


Машина = ОбщиеМеханизмы.ПолучитьМашинуДляСлияния(Объект.ПечатнаяМашина);
Лакирование = ОбщиеМеханизмы.ПолучитьЛакирование(Объект.Лакирование);

Объект.ДопПараметрыКоличествоЛакВДСтолбик2 = Машина + Лакирование;

В этом примере реквизит Объект.ПечатнаяМашина представляет собой ссылку на элемент справочника (СправочникСсылка), а Объект.Лакирование — значение перечисления (ПеречислениеСсылка). В результирующий реквизит строкового типа мы пытаемся записать сумму двух объектов.

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

Кроме того, если пользовательская функция ПолучитьМашинуДляСлияния при неудачном поиске возвращает число (например, 0 или числовой код), переменная Машина становится числом, после чего платформа также пытается привести второй операнд к числу.

Способ 1. Явное приведение к строке через функцию Строка()

Самый надежный и понятный способ решения проблемы — явное преобразование каждого операнда к строковому типу с помощью встроенной функции Строка(). Посмотрим на пример реализации:


Машина = ОбщиеМеханизмы.ПолучитьМашинуДляСлияния(Объект.ПечатнаяМашина);
Лакирование = ОбщиеМеханизмы.ПолучитьЛакирование(Объект.Лакирование);

Объект.ДопПараметрыКоличествоЛакВДСтолбик2 = Строка(Машина) + " " + Строка(Лакирование);

Преимущество вызова Строка(Машина) перед прямым обращением через точку (например, Машина.Наименование) заключается в безопасности: если переменная окажется пустой ссылкой, вызов функции не вызовет критической ошибки «Поле агрегатного объекта не обнаружено», а просто вернет пустую строку.

Способ 2. Использование функции СтрШаблон()

Начиная с версии платформы 8.3.6, доступна функция СтрШаблон(). Она делает код гораздо более читаемым и автоматически преобразует переданные параметры в их строковые представления:


Машина = ОбщиеМеханизмы.ПолучитьМашинуДляСлияния(Объект.ПечатнаяМашина);
Лакирование = ОбщиеМеханизмы.ПолучитьЛакирование(Объект.Лакирование);

Объект.ДопПараметрыКоличествоЛакВДСтолбик2 = СтрШаблон("%1 %2", Машина, Лакирование);

Функция СтрШаблон() самостоятельно вызывает получение строкового представления для каждого переданного параметра и подставляет их на места спецификаторов %1 и %2.

Способ 3. Неявное приведение через пустую строку

Если требуется быстрый вариант конкатенации без вызова дополнительных функций, можно поставить в начало выражения пустую строку "":

Объект.ДопПараметрыКоличествоЛакВДСтолбик2 = "" + Машина + " " + Лакирование;

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

Подводные камни и важные особенности

Рассмотрим нюансы, о которых следует помнить при объединении ссылочных реквизитов:

  1. Основное представление объекта. Функция Строка(Ссылка) возвращает то представление, которое задано в конфигураторе для данного объекта (по наименованию или по коду), либо сформировано в обработчике ОбработкаПолученияПредставления модуля менеджера. Если для справочника выбрано представление по коду, строковое преобразование вернет код элемента, а не его наименование.
  2. Обработка значений Неопределено и NULL. Если функция поиска возвращает Неопределено, конкатенация выдаст текст "Неопределено". Чтобы этого избежать, используем проверку заполненности:
    
    ТекстМашины = ?(ЗначениеЗаполнено(Машина), Строка(Машина), "");
    ТекстЛака = ?(ЗначениеЗаполнено(Лакирование), Строка(Лакирование), "");
    
    Объект.ДопПараметрыКоличествоЛакВДСтолбик2 = СокрЛП(СтрШаблон("%1 %2", ТекстМашины, ТекстЛака));
    
  3. Ограничение длины реквизита. Если реквизит-приемник имеет фиксированную длину (например, Строка(50)), итоговая строка может быть обрезана без предупреждения, если сумма длин представлений превысит установленный лимит.
  4. Производительность в циклах. Получение строкового представления ссылки приводит к неявному чтению данных объекта из базы данных или кэша. Если необходимо объединять реквизиты в цикле для сотен строк, эффективнее выполнять слияние на уровне запроса с помощью функции ПРЕДСТАВЛЕНИЕ():
    
    ВЫБРАТЬ
        ПРЕДСТАВЛЕНИЕ(Документ.ПечатнаяМашина) + " " + ПРЕДСТАВЛЕНИЕ(Документ.Лакирование) КАК СоставноеЗначение
    ИЗ
        Документ.Заказ КАК Документ
    
    Это исключит избыточные обращения к базе данных при обходе выборки.
← На главную