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