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