Как открыть файл из ХранилищаЗначения в 1С 8.3

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

В прикладных решениях 1С часто требуется не просто отобразить картинку на управляемой форме, а предоставить пользователю возможность просмотреть или открыть прикрепленный файл (документ PDF, таблицу Excel, архив или изображение) во внешней программе операционной системы. Разберем по шагам, как правильно организовать загрузку, хранение в реквизите с типом ХранилищеЗначения и последующее открытие файла, а также выясним, какие ошибки часто возникают при реализации этого механизма.

Структура данных и архитектура решения

Для реализации хранения файла в объекте конфигурации (например, в справочнике или документе) нам понадобятся следующие реквизиты:

  1. Хранилище (тип ХранилищеЗначения) — используется непосредственно для хранения бинарных данных файла.
  2. ИмяФайла (тип Строка) — необходимо для сохранения оригинального имени и, главное, расширения файла (например, .pdf или .docx). Без корректного расширения операционная система пользователя не сможет определить, какой программой следует открывать файл.

На управляемой форме также создается реквизит Файл (тип Строка) для хранения адреса во временном хранилище при интерактивной работе пользователя.

Помещение файла в базу: выбор и сохранение

Рассмотрим процесс помещения файла с клиентского компьютера на сервер. Для интерактивного выбора файла в современных версиях платформы 1С:Предприятие 8.3 применяются асинхронные методы.

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


&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
    
    Оповещение = Новый ОписаниеОповещения("ОбработатьВыборФайла", ЭтотОбъект);
    НачатьПомещениеФайла(Оповещение,,, Истина, УникальныйИдентификатор);
    
КонецПроцедуры

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

Обратим внимание на важную деталь: процедура обратного вызова ОбработатьВыборФайла обязательно должна иметь директиву компиляции &НаКлиенте и ключевое слово Экспорт. Попытка объявить обработчик с директивой &НаСервере приведет к ошибке во время выполнения.

Кроме того, для выделения имени файла не следует вручную парсить строку через разделитель \, так как на рабочих станциях под управлением Linux или macOS разделителем пути выступает /, а в веб-клиенте путь может формироваться иначе. Использование объекта Файл гарантирует кроссплатформенность.

Теперь разберем, как сохранить полученные данные из временного хранилища в реквизит объекта при записи формы:


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

Параметр Новый СжатиеДанных(9) позволяет максимально сжать бинарные данные перед помещением в базу, экономя дисковое пространство СУБД.

Открытие файла во внешнем приложении

Чтобы открыть файл, сохраненный в базе данных, нам необходимо выполнить обратную последовательность действий:

  1. Сформировать навигационную ссылку на реквизит или извлечь двоичные данные.
  2. Сформировать путь во временном каталоге на клиенте с правильным расширением.
  3. Сохранить файл на локальный диск пользователя.
  4. Запустить файл через ассоциированную программу операционной системы.

Проанализируем распространенную ошибку: попытку вызвать метод КаталогВременныхФайлов() на сервере для последующего сохранения на клиенте. В клиент-серверном режиме вызов на сервере вернет путь в файловой системе сервера (например, /tmp/ или C:\Windows\Temp\), к которому у клиента нет прямого доступа. Путь для сохранения должен определяться строго на стороне клиента.

Посмотрим на реализацию открытия файла с учетом отказа от устаревших синхронных вызовов:


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

&НаКлиенте
Процедура ПослеПолученияФайла(ИмяФайла, ПутьКФайлу) Экспорт
    
    Если ЗначениеЗаполнено(ПутьКФайлу) Тогда
        // Запуск ассоциированного приложения ОС
        ЗапуститьПриложение(ПутьКФайлу);
    КонецЕсли;
    
КонецПроцедуры

Использование метода НачатьПолучениеФайла вместо устаревшего синхронного метода ПолучитьФайл исключает падение конфигурации, если в свойствах установлен режим совместимости с версией платформы выше 8.3.3 или включен запрет синхронных вызовов.

Использование функций Библиотеки Стандартных Подсистем (БСП)

Если конфигурация разработана с использованием БСП, не требуется создавать собственные механизмы хранения бинарных данных с нуля. В составе БСП предусмотрена типовая подсистема «Работа с файлами».

При использовании БСП открытие файла сводится к вызову типовой клиентской процедуры:


&НаКлиенте
Процедура ОткрытьЧерезБСП(СсылкаНаФайл)
    
    ДанныеФайла = РаботаСФайламиКлиентСервер.ДанныеФайла(СсылкаНаФайл);
    РаботаСФайламиКлиент.ОткрытьФайл(ДанныеФайла, Ложь);
    
КонецПроцедуры

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

← На главную