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