При разработке или модификации типовых конфигураций на платформе 1С:Предприятие 8, таких как Управление торговлей 10.3, программисты часто сталкиваются с необходимостью программного заполнения записей регистров сведений. Одной из специфических проблем является работа с типом данных УникальныйИдентификатор. Давайте подробно разберем ситуацию, когда стандартный цикл обхода метаданных не справляется с копированием этого значения, и выясним, как решить эту задачу правильно.
Рассмотрим ситуацию: в типовой обработке редактирования контактной информации используется программный код, который перебирает ресурсы регистра сведений и копирует их значения из текущей строки табличного поля в МенеджерЗаписи. На первый взгляд, код выглядит абсолютно логично и универсально:
Для каждого Ресурс Из Метаданные.РегистрыСведений.КонтактнаяИнформация.Ресурсы Цикл
МенеджерЗаписи[Ресурс.Имя] = Элемент.ТекущиеДанные[Ресурс.Имя];
КонецЦикла;
Проблема заключается в том, что если мы добавим в регистр новый ресурс с типом УникальныйИдентификатор (UUID), то именно это поле в данной строке кода может не скопироваться. При этом остальные реквизиты (строки, числа, ссылки) переносятся без нареканий. Посмотрим на причины, по которым это происходит, и проанализируем поведение платформы.
В платформе 1С обращение к свойствам объекта через квадратные скобки [] (по строковому имени) и через точку (напрямую к свойству) реализовано на разных внутренних механизмах. Когда мы пишем МенеджерЗаписи[Ресурс.Имя], платформа пытается сопоставить передаваемое значение с типом приемника.
В обычных формах (используемых в УТ 10.3) данные в объекте ТекущиеДанные табличного поля могут быть представлены не совсем так, как они хранятся в базе данных. В некоторых случаях, если колонка не имеет жесткой типизации непосредственно в свойствах элемента управления формы, значение UUID может интерпретироваться платформой как строка. При попытке присвоить строку свойству, ожидающему УникальныйИдентификатор, через оператор индексации [], автоматического приведения типа может не произойти. Система просто игнорирует присвоение некорректного типа или оставляет значение в состоянии Неопределено.
Объект ТекущиеДанные возвращает строку таблицы. Заметим, что типы УникальныйИдентификатор и ХранилищеЗначения являются объектами, а не примитивными типами. В ряде релизов платформы 8.3.16 и смежных версиях наблюдались особенности десериализации UUID при передаче их через универсальные коллекции. Если идентификатор был получен из контекста данных формы, он мог потерять свою "объектную сущность" и стать строковым представлением, которое МенеджерЗаписи не принимает напрямую без явного преобразования.
Наиболее эффективным и правильным решением, которое устраняет "индусский код" (ручной перебор ресурсов), является использование встроенной функции ЗаполнитьЗначенияСвойств. Разберем, почему это работает:
ЗаполнитьЗначенияСвойств(МенеджерЗаписи, Элемент.ТекущиеДанные);
Функция ЗаполнитьЗначенияСвойств оптимизирована на уровне ядра платформы. Она выполняет следующие действия:
УникальныйИдентификатор).Это избавляет разработчика от необходимости знать внутреннюю структуру метаданных и гарантирует корректное заполнение всех полей, включая специфические типы данных.
Если по каким-то причинам нам необходимо оставить ручной перебор ресурсов (например, если логика требует дополнительной обработки каждого значения перед записью), мы должны гарантировать правильный тип данных. Проанализируем, как это можно реализовать:
Для каждого Ресурс Из Метаданные.РегистрыСведений.КонтактнаяИнформация.Ресурсы Цикл
ИмяПоля = Ресурс.Имя;
Значение = Элемент.ТекущиеДанные[ИмяПоля];
// Проверяем, является ли тип ресурса уникальным идентификатором
Если Ресурс.Тип.СодержитТип(Тип("УникальныйИдентификатор")) Тогда
Попытка
МенеджерЗаписи[ИмяПоля] = Новый УникальныйИдентификатор(Строка(Значение));
Исключение
// Обработка случая, если строка не является валидным UUID
КонецПопытки;
Иначе
МенеджерЗаписи[ИмяПоля] = Значение;
КонецЕсли;
КонецЦикла;
В этом примере мы используем конструктор Новый УникальныйИдентификатор(), передавая ему строковое представление значения. Это "жесткий" способ заставить платформу принять данные, если автоматика дает сбой.
Если вы столкнулись с подобной проблемой, рекомендуем выполнить следующие шаги в режиме отладки:
ТипЗнч(Элемент.ТекущиеДанные[Ресурс.Имя]). Выясните, что именно там находится в момент ошибки — УникальныйИдентификатор или Строка.Ресурс.Имя. Иногда ошибка может крыться в том, что цикл перебирает не те метаданные или обращается к ресурсу, который не определен в текущей строке данных формы.МенеджереЗаписи тип ресурса в конфигураторе установлен верно и совпадает с ожидаемым.Мы выяснили, что прямое присвоение через индекс [] для типа УникальныйИдентификатор может быть нестабильным из-за особенностей приведения типов в 1С. Главный вывод: всегда отдавайте предпочтение методу ЗаполнитьЗначенияСвойств при копировании данных между объектами и коллекциями. Это не только делает код короче и читаемее, но и защищает от скрытых ошибок типизации, характерных для определенных релизов платформы.
Использование этого подхода в УТ 10.3 и других конфигурациях на обычных формах является стандартом качественной разработки. Помните, что платформа постоянно развивается, и механизмы работы с памятью и типами могут меняться от релиза к релизу, поэтому использование проверенных системных функций — залог стабильности вашей программы.