Почему при конкатенации строк в 1С возникает ошибка преобразования к числу и как её исправить?

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

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

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

Причина ошибки: механизм работы оператора «+» и значение NULL

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

Рассмотрим проблемную строку кода:


ОбластьПодвал.Параметры.Поле1 = ВыборкаДетальныеЗаписи.Фамилия + " " + ВыборкаДетальныеЗаписи.Имя + " " + ВыборкаДетальныеЗаписи.Отчество;

Если в результате выполнения запроса в поле ВыборкаДетальныеЗаписи.Фамилия вернулось значение типа NULL, платформа не может распознать операцию как строковую конкатенацию. По умолчанию при наличии неопределенного типа или NULL в начале выражения платформа пытается выполнить арифметическое сложение. Встретив следующий операнд — строковый пробел " ", 1С пытается преобразовать строку к числу, что завершается аварийным падением с ошибкой типов.

Откуда берется NULL в строковых полях запроса?

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

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

Способ 1. Обработка значений в тексте запроса (рекомендуемый)

Наиболее надежный и профессиональный подход — не допускать появления значений NULL в результатах запроса. Для этого используем встроенную функцию языка запросов ЕСТЬNULL(), которая заменяет NULL на пустую строку.

Посмотрим на пример правильного оформления выборки полей:


ВЫБРАТЬ
    ЕСТЬNULL(СпрФизЛица.Фамилия, "") КАК Фамилия,
    ЕСТЬNULL(СпрФизЛица.Имя, "") КАК Имя,
    ЕСТЬNULL(СпрФизЛица.Отчество, "") КАК Отчество
ИЗ
    Документ.ПриемНаРаботу КАК Документ
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ФизическиеЛица КАК СпрФизЛица
        ПО Документ.Сотрудник = СпрФизЛица.Ссылка

Также конкатенацию можно выполнить непосредственно на стороне СУБД в самом тексте запроса:


ВЫБРАТЬ
    ЕСТЬNULL(СпрФизЛица.Фамилия, "") + " " + ЕСТЬNULL(СпрФизЛица.Имя, "") + " " + ЕСТЬNULL(СпрФизЛица.Отчество, "") КАК ФИО
ИЗ
    Справочник.Сотрудники КАК Сотрудники

Способ 2. Принудительное задание строкового контекста во встроенном языке

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


ОбластьПодвал.Параметры.Поле1 = "" + ВыборкаДетальныеЗаписи.Фамилия + " " + ВыборкаДетальныеЗаписи.Имя + " " + ВыборкаДетальныеЗаписи.Отчество;

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

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

Для предотвращения ошибок несовместимости типов в коде рекомендуется использовать специализированные строковые функции, которые безопасно приводят любые типы к строке:

  1. Функция СтрШаблон(): автоматически форматирует переданные аргументы и подставляет пустые значения вместо NULL:
    
    ОбластьПодвал.Параметры.Поле1 = СокрЛП(СтрШаблон("%1 %2 %3", 
        ВыборкаДетальныеЗаписи.Фамилия, 
        ВыборкаДетальныеЗаписи.Имя, 
        ВыборкаДетальныеЗаписи.Отчество));
    
  2. Явное приведение функцией Строка():
    
    ОбластьПодвал.Параметры.Поле1 = СокрЛП(Строка(ВыборкаДетальныеЗаписи.Фамилия) + " " 
        + Строка(ВыборкаДетальныеЗаписи.Имя) + " " 
        + Строка(ВыборкаДетальныеЗаписи.Отчество));
    

Способ 4. Корректное склеивание через массив и СтрСоединить()

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


ЧастиФИО = Новый Массив;

Если ЗначениеЗаполнено(ВыборкаДетальныеЗаписи.Фамилия) Тогда
    ЧастиФИО.Добавить(СокрЛП(ВыборкаДетальныеЗаписи.Фамилия));
КонецЕсли;

Если ЗначениеЗаполнено(ВыборкаДетальныеЗаписи.Имя) Тогда
    ЧастиФИО.Добавить(СокрЛП(ВыборкаДетальныеЗаписи.Имя));
КонецЕсли;

Если ЗначениеЗаполнено(ВыборкаДетальныеЗаписи.Отчество) Тогда
    ЧастиФИО.Добавить(СокрЛП(ВыборкаДетальныеЗаписи.Отчество));
КонецЕсли;

ОбластьПодвал.Параметры.Поле1 = СтрСоединить(ЧастиФИО, " ");

Способ 5. Применение механизмов БСП

Если конфигурация разработана на базе Библиотеки Стандартных Подсистем (БСП), для работы с ФИО и склеивания строк рекомендуется использовать готовые библиотечные методы:

  1. СтроковыеФункцииКлиентСервер.СоединитьСтрокиВМассив() — объединяет переданную коллекцию строк с разделителем, автоматически пропуская пустые и некорректные элементы.
  2. ФизическиеЛицаКлиентСервер.ФамилияИнициалы() — специализированная функция для корректного формирования фамилии и инициалов физлица.
← На главную