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