Почему функция УправлениеСвойствами.ЗначениеСвойства возвращает текст вместо значения и как это исправить?

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

В практике разработки на платформе 1С:Предприятие 8.3 с использованием Библиотеки стандартных подсистем (БСП) программисты часто сталкиваются с ситуацией, когда стандартная функция УправлениеСвойствами.ЗначениеСвойства ведет себя непредсказуемо. Вместо ожидаемой ссылки на справочник, числа или даты функция возвращает тип Строка, содержащую текстовое представление объекта. Рассмотрим подробнее, почему это происходит, разберем внутреннюю логику БСП и выясним, как гарантированно получать корректные данные.

Суть проблемы и механизм работы функции

Функция УправлениеСвойствами.ЗначениеСвойства предназначена для оперативного получения значения дополнительного реквизита или сведения для конкретного объекта. Казалось бы, её поведение должно быть однозначным: если реквизит имеет тип "Число", мы должны получить число; если "СправочникСсылка" — ссылку. Однако, начиная с версий БСП ветки 3.1 (конкретно упоминается 3.1.4.96), разработчики заметили странную особенность: если в табличной части дополнительных реквизитов заполнено поле ТекстоваяСтрока, функция игнорирует поле Значение и возвращает текст.

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

  1. Значение — имеет тип Характеристика.ДополнительныеРеквизитыИСведения. Это поле ограничено по длине для строковых типов (обычно до 1024 символов).
  2. ТекстоваяСтрока — имеет тип Строка неограниченной длины. Оно используется для хранения длинных текстов, которые не помещаются в основное поле.

Внутри функции УправлениеСвойствами.ЗначениеСвойства реализован запрос, который отдает безусловный приоритет полю ТекстоваяСтрока. Логика разработчиков БСП такова: если в текстовом поле что-то есть, значит, там хранится полное или актуальное значение свойства. При этом проверка типа самого свойства (является ли оно строкой) зачастую опускается, что и приводит к получению строки вместо ссылки.

Разберем по шагам: когда заполняется ТекстоваяСтрока?

Выясним причину появления данных в поле ТекстоваяСтрока. В штатном режиме работы системы (через типовые формы БСП) это поле заполняется только в одном случае: если пользователь вводит строку длиной более 1024 символов. Рассмотрим пример кода, который описывает эту логику в недрах БСП:


Если ТипЗнч(СтрокаТаблицыСвойств.Значение) = Тип("Строка") 
   И СтрДлина(СтрокаТаблицыСвойств.Значение) > 1024 Тогда 
    НоваяСтрока.ТекстоваяСтрока = СтрокаТаблицыСвойств.Значение; 
КонецЕсли;

Проблема возникает тогда, когда данные попадают в систему в обход типового механизма. Это может быть:

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

Как гарантированно получить значение свойства?

Рассмотрим несколько способов решения данной проблемы, в зависимости от ваших задач.

Способ 1: Использование функции ЗначенияСвойств

Если вам нужно получить значения нескольких свойств или вы хотите иметь больше контроля над результатом, используйте метод УправлениеСвойствами.ЗначенияСвойств. Он возвращает таблицу значений или структуру, где данные представлены более развернуто. Проанализируем пример получения значения:


ПараметрыСвойств = Новый Структура;
ПараметрыСвойств.Вставить("Объект", СсылкаНаОбъект);
ПараметрыСвойств.Вставить("Свойства", СсылкаНаСвойство);

ТаблицаЗначений = УправлениеСвойствами.ЗначенияСвойств(ПараметрыСвойств);

Если ТаблицаЗначений.Количество() > 0 Тогда
    // Здесь мы можем явно обратиться к полю Значение, 
    // если логика БСП в конкретной версии позволяет это сделать через колонки
    АктуальноеЗначение = ТаблицаЗначений[0].Значение;
КонецЕсли;

Способ 2: Прямой запрос к данным

Если критически важно получить именно типизированное значение (объектную ссылку) и вы не доверяете кэшированным функциям БСП, самым надежным способом будет прямой запрос к базе данных. Посмотрим на пример запроса для дополнительных реквизитов документа:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ДокументОбъект.Значение КАК Значение
    |ИЗ
    |	Документ.ЗаказПокупателя.ДополнительныеРеквизиты КАК ДокументОбъект
    |ГДЕ
    |	ДокументОбъект.Ссылка = &Ссылка
    |	И ДокументОбъект.Свойство = &Свойство";

Запрос.УстановитьПараметр("Ссылка", СсылкаНаОбъект);
Запрос.УстановитьПараметр("Свойство", СсылкаНаСвойство);

Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
    // Мы гарантированно получаем содержимое поля Значение
    Результат = Выборка.Значение;
КонецЕсли;

Способ 3: Очистка "мусорных" данных

Проанализируем ситуацию с данными в вашей базе. Если поле ТекстоваяСтрока заполнено для типов, отличных от строки, — это техническая ошибка данных. Рекомендуется провести аудит и очистить такие поля. Рассмотрим пример обработки для исправления ситуации:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ТЧ.Ссылка КАК Ссылка,
    |	ТЧ.НомерСтроки КАК НомерСтроки
    |ИЗ
    |	Справочник.Номенклатура.ДополнительныеРеквизиты КАК ТЧ
    |ГДЕ
    |	ТЧ.ТекстоваяСтрока <> """"
    |	И НЕ ТЧ.Свойство.ТипЗначения.Типы().Содержит(ТИП(""Строка""))";

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Объект = Выборка.Ссылка.ПолучитьОбъект();
    // Находим нужную строку ТЧ и очищаем ТекстоваяСтрока
    СтрокаТЧ = Объект.ДополнительныеРеквизиты[Выборка.НомерСтроки - 1];
    СтрокаТЧ.ТекстоваяСтрока = "";
    Объект.Записать();
КонецЦикла;

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

Нюанс с параметром КодЯзыка

В описании функции УправлениеСвойствами.ЗначениеСвойства указано, что параметр КодЯзыка позволяет получить представление на конкретном языке. Однако, как показывает практика и анализ кода, если заполнено поле ТекстоваяСтрока, алгоритм часто возвращает её содержимое до того, как начнет обрабатывать мультиязычные представления. Это еще один аргумент в пользу того, что ТекстоваяСтрока в БСП считается "финальным" и самым приоритетным значением.

Технический итог

Поведение функции УправлениеСвойствами.ЗначениеСвойства не является ошибкой в строгом смысле этого слова. Это особенность реализации БСП, направленная на поддержку длинных строк. Чтобы избежать проблем:

Понимание этой внутренней кухни позволит вам писать более отказоустойчивый код и быстрее диагностировать странное поведение системы при работе с дополнительными реквизитами.

← На главную