Как открыть картинку из ХранилищеЗначений во внешней программе по умолчанию?

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

Нередко в прикладных решениях 1С графические файлы хранятся в реквизитах справочников или регистров с типом ХранилищеЗначений. Типовая задача, с которой сталкиваются разработчики при проектировании интерфейса, — предоставить пользователю возможность просмотреть изображение не только в миниатюре внутри формы, но и в полноразмерном окне с помощью стандартного средства просмотра операционной системы.

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

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

Проанализируем архитектурные ограничения взаимодействия 1С и операционной системы. Когда мы считываем данные из базы, они помещаются в оперативную память текущего сеанса как объект типа Картинка или ДвоичныеДанные. Команда вызова внешней программы ЗапуститьПриложение ожидает строку с исполняемой командой или полным путем к файлу в файловой системе.

Стандартный механизм файловых ассоциаций Windows и подавляющее большинство сторонних графических просмотрщиков требуют физический путь к файлу на диске. Они не поддерживают получение бинарного потока из чужого процесса через аргументы командной строки. Соответственно, единственный способ передать изображение внешнему просмотрщику — предварительно сохранить его на жесткий диск.

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

Рассмотрим подробнее шаги, которые необходимо выполнить для решения поставленной задачи:

  1. Извлечение объекта из хранилища: вызываем метод Получить() у реквизита с типом ХранилищеЗначений.
  2. Определение формата и имени временного файла: получаем уникальное имя во временном каталоге с правильным расширением.
  3. Запись на диск: выгружаем двоичные данные или объект картинки на диск.
  4. Запуск приложения: передаем путь к созданному файлу в системную функцию ЗапуститьПриложение.

Реализация выгрузки и открытия файла

Посмотрим на пример кода обработки события таблицы или формы. Чтобы временные файлы не конфликтовали между собой, используем функцию ПолучитьИмяВременногоФайла(), передавая ей требуемое расширение, либо формируем путь через КаталогВременныхФайлов().

Разберем практический пример:


// Получаем ссылку на текущую строку
ТекСсылка = ЭлементыФормы.тпНаряды.ТекущиеДанные.Ссылка;

// Извлекаем объект из ХранилищаЗначений
ДанныеКартинки = ТекСсылка.Изображение.Получить();

Если ДанныеКартинки = Неопределено Тогда
    Предупреждение("Изображение не найдено в хранилище!");
    Возврат;
КонецЕсли;

// Определяем расширение файла
Расширение = "jpg";
Если ТипЗнч(ДанныеКартинки) = Тип("Картинка") Тогда
    Формат = ДанныеКартинки.Формат();
    Если Формат = ФорматКартинки.PNG Тогда
        Расширение = "png";
    ИначеЕсли Формат = ФорматКартинки.BMP Тогда
        Расширение = "bmp";
    ИначеЕсли Формат = ФорматКартинки.GIF Тогда
        Расширение = "gif";
    ИначеЕсли Формат = ФорматКартинки.TIFF Тогда
        Расширение = "tif";
    КонецЕсли;
КонецЕсли;

// Формируем уникальный путь во временной директории
ПутьКФайлу = ПолучитьИмяВременногоФайла(Расширение);

// Записываем данные на диск
Если ТипЗнч(ДанныеКартинки) = Тип("Картинка") Тогда
    ДанныеКартинки.Записать(ПутьКФайлу);
ИначеЕсли ТипЗнч(ДанныеКартинки) = Тип("ДвоичныеДанные") Тогда
    ДанныеКартинки.Записать(ПутьКФайлу);
КонецЕсли;

// Открываем файл во внешнем просмотрщике по умолчанию
ЗапуститьПриложение(ПутьКФайлу);

Важные нюансы работы с временными файлами

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

  1. Расширение файла: если не указать расширение при вызове ПолучитьИмяВременногоФайла(), операционная система Windows не сможет определить, какой программой открывать файл, и предложит пользователю диалог выбора приложения. Определение расширения через свойство Картинка.Формат() гарантирует корректный выбор ассоциированной программы.
  2. Удаление файла: если вызвать УдалитьФайлы(ПутьКФайлу) сразу после команды ЗапуститьПриложение(ПутьКФайлу), внешний просмотрщик может не успеть прочитать файл с диска и выдаст ошибку. Если же передать параметр ожидания завершения, интерфейс 1С окажется заблокированным до момента, пока пользователь не закроет окно внешней программы. Поэтому временные файлы рекомендуется оставлять в системном каталоге КаталогВременныхФайлов(), позволяя операционной системе очищать их самостоятельно, либо производить очистку созданной подпапки при завершении работы программы.

Альтернативные варианты без выгрузки на диск

Если задача заключается исключительно в том, чтобы предоставить пользователю возможность рассмотреть изображение в полном масштабе, не обязательно обращаться к внешним приложениям:

  1. Открытие во встроенной форме: можно создать отдельную экранную форму с элементом управления ПолеКартинки. В этом случае данные извлекаются методом ХранилищеЗначений.Получить() и напрямую назначаются свойству поля формы без сохранения на физический диск: ЭлементыФормы.ПолеКартинки.Картинка = Хранилище.Получить().
  2. Использование объекта ТабличныйДокумент: изображение можно поместить в коллекцию Рисунки табличного документа и вызвать метод ТабличныйДокумент.Показать(). Это дает встроенные возможности масштабирования и печати штатными средствами платформы.
← На главную