Как программно получить и вывести изображение из справочника «Файлы» на форму в 1С

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

При разработке внешних обработок или расширении функционала типовых конфигураций (таких как ЗУП 3.1, ERP или УТ 11) часто возникает задача вывести на форму изображение, которое хранится в стандартном справочнике Файлы. На первый взгляд задача кажется простой, но новички часто сталкиваются с тем, что обычное получение навигационной ссылки на элемент справочника выдает «пустую картинку» или крестик. Разберем подробно, как устроена подсистема работы с файлами и как правильно извлекать из нее данные.

Почему стандартный метод НайтиПоНаименованию и ПолучитьНавигационнуюСсылку не работает напрямую

Проанализируем структуру хранения данных. Справочник Файлы в типовых конфигурациях, построенных на базе БСП (Библиотеки стандартных подсистем), является лишь «оболочкой» или владельцем. Сами данные (двоичный код картинки, документа и т.д.) хранятся не в самом элементе справочника, а в связанных объектах. Каждый файл может иметь несколько версий, которые хранятся в справочнике ВерсииФайлов. А уже содержимое конкретной версии записывается либо в специализированный регистр сведений, либо в тома на диске (в зависимости от настроек программы).

Поэтому попытка вызвать ПолучитьНавигационнуюСсылку(ОбъектЭлемента, "ТекстХранилище") для элемента справочника Файлы не дает результата, так как реквизит ТекстХранилище в самом справочнике обычно пуст или используется для других целей.

Способ 1. Прямое обращение к регистрам сведений (быстрое решение)

Если нам нужно быстро получить данные, зная имя файла, мы можем воспользоваться механизмом запросов. Рассмотрим ситуацию, когда файлы хранятся непосредственно в базе данных. В старых версиях БСП за это отвечал регистр ХранимыеФайлыВерсий, в новых — ДвоичныеДанныеФайлов.

Проанализируем пример кода, который позволяет достать двоичные данные картинки по ее наименованию в справочнике:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ХранимыеФайлыВерсий.ХранимыйФайл КАК Файл
    |ИЗ
    |	РегистрСведений.ХранимыеФайлыВерсий КАК ХранимыеФайлыВерсий
    |		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВерсииФайлов КАК ВерсииФайлов
    |		ПО ХранимыеФайлыВерсий.ВерсияФайла = ВерсииФайлов.Ссылка
    |ГДЕ
    |	ВерсииФайлов.Наименование ПОДОБНО &Наименование + ""%""
    |	И ВерсииФайлов.ПометкаУдаления = ЛОЖЬ";

Запрос.УстановитьПараметр("Наименование", "Логотип");
РезультатЗапроса = Запрос.Выполнить();

Если Не РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий();
    
    // Получаем двоичные данные из хранилища значения
    ДвоичныеДанные = Выборка.Файл.Получить();
    
    // Помещаем во временное хранилище для отображения на форме
    АдресКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
КонецЕсли;

Важное замечание: Этот способ имеет существенный недостаток. Если в настройках системы включено «Хранение файлов в томах на диске», этот запрос вернет пустой результат или ошибку, так как двоичные данные в базе отсутствуют — они лежат в сетевой папке.

Способ 2. Использование штатного API БСП (Рекомендуемый)

Чтобы наш код не «сломался» при изменении настроек хранения или обновлении конфигурации, мы должны использовать функции общего модуля РаботаСФайлами. Рассмотрим наиболее правильный алгоритм получения изображения.

Выясним, какие функции нам понадобятся. Основная функция — это РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаНаФайл). Она универсальна: сама определит, где лежит файл (в базе или в томе), проверит права доступа пользователя и вернет объект ДвоичныеДанные.

Пример правильной реализации для управляемой формы:


&НаСервере
Процедура ОбновитьЛоготипНаСервере()
    
    // 1. Находим ссылку на файл
    СсылкаНаФайл = Справочники.Файлы.НайтиПоНаименованию("Логотип", Истина);
    
    Если Не СсылкаНаФайл.Пустая() Тогда
        // 2. Используем штатный метод БСП для получения навигационной ссылки
        // Этот метод возвращает URL, который можно сразу присвоить реквизиту формы
        // связанному с полем картинки.
        ПолеЛоготип = РаботаСФайлами.СсылкаНаДвоичныеДанныеФайла(СсылкаНаФайл);
    КонецЕсли;
    
КонецПроцедуры

В данном случае ПолеЛоготип — это реквизит формы с типом Строка. В свойствах элемента формы «Поле картинки» в качестве данных нужно указать именно этот реквизит.

Разбор работы с версиями файлов

Как мы уже выяснили, справочник Файлы — это иерархический список «карточек» файлов. У каждой карточки есть реквизит ТекущаяВерсия. Если вы работаете с объектом вручную, всегда проверяйте этот реквизит. Рассмотрим, как программно получить данные именно последней версии:

  1. Находим нужный элемент в Справочники.Файлы.
  2. Обращаемся к реквизиту ТекущаяВерсия (тип СправочникСсылка.ВерсииФайлов).
  3. Если версия найдена, передаем ее в методы работы с данными.

Проанализируем ситуацию, когда нам нужно получить именно двоичные данные для какой-то обработки (например, для отправки по почте):


// Пример получения двоичных данных для выгрузки
ДанныеФайла = РаботаСФайлами.ДанныеФайла(СсылкаНаФайл);
Если ДанныеФайла.ФайлСуществует Тогда
    ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаНаФайл);
    // Теперь с объектом ДвоичныеДанные можно работать (записать на диск, отправить и т.д.)
    // ДвоичныеДанные.Записать("C:\Temp\logo.png");
КонецЕсли;

Программное добавление файла в справочник

Иногда требуется решить обратную задачу: программно загрузить картинку в справочник Файлы. Это сложнее, так как нужно создать записи сразу в трех местах: справочник файлов, справочник версий и регистр данных.

Разберем пример создания файла из внешней обработки (актуально для ЗУП 3.1):


&НаСервере
Процедура ЗагрузитьФайлНаСервере(ПутьКФайлу, ПапкаФайлов)
    
    ФайлОбъект = Новый Файл(ПутьКФайлу);
    ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
    
    // Помещаем во временное хранилище, чтобы БСП могла забрать данные
    АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанные);
    
    // Подготавливаем структуру сведений о файле
    СведенияОФайле = РаботаСФайламиКлиентСервер.СведенияОФайле("Логотип", ФайлОбъект);
    СведенияОФайле.АдресВременногоХранилищаФайла = АдресХранилища;
    СведенияОФайле.ИмяБезРасширения = "Логотип_Фирмы";
    СведенияОФайле.РасширениеБезТочки = ФайлОбъект.Расширение;
    
    // Вызываем служебный метод для создания всех необходимых записей
    НовыйФайлСсылка = РаботаСФайламиСлужебныйВызовСервера.СоздатьФайлСВерсией(ПапкаФайлов, СведенияОФайле);
    
КонецПроцедуры

Резюме и рекомендации

Подведем итоги нашего анализа работы с подсистемой хранения файлов:

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

← На главную