Помогите с картинкой на форме

1. ResAndDev 16.12.18 12:49 Сейчас в теме
Приветствую.

Задача - разместить фото сотрудника в элементе справочника.

На форме есть булев реквизит "Сохранять фото в базе".

В чем проблема - если фото изначально было сохранено не в базе а где то на диске, и теперь пользователь просто ставит галочку "Сохранять фото в базе", то при повторном открытии фотка исчезает.
Что я делаю не так ? Код привожу ниже.

Для галочки "сохранять в базе" поставил "изменяет данные", форма становится модифицированной. Однако не помогло.

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

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

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

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

Показать
По теме из базы знаний
Найденные решения
16. ResAndDev 17.12.18 20:38 Сейчас в теме
(13)
Все. Сделал.

Вот что получилось в итоге:

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

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

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

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

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Если Объект.Ссылка <> Справочники.ФизическиеЛица.ПустаяСсылка() Тогда
		Если Объект.МестоХраненияФайла = Перечисления.МестоХраненияФайла.ВБазе Тогда
			ЗначениеКлюча = Новый Структура;
			ЗначениеКлюча.Вставить("Сотрудник", Объект.Ссылка);
			
			КлючЗаписи = РегистрыСведений.ФотографииСотрудников.СоздатьКлючЗаписи(ЗначениеКлюча);
			
			Картинка = ПолучитьНавигационнуюСсылку(КлючЗаписи, "Фото");
		Иначе
			ПутьКФайлу = Константы.КаталогХраненияФотографий.Получить() +"\"+ Объект.Ссылка.УникальныйИдентификатор() + Объект.Ссылка.Расширение;
			Файл = Новый Файл(ПутьКФайлу);
			Если Файл.Существует() Тогда
				ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
				Картинка = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры


Показать
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. spacecraft 16.12.18 13:37 Сейчас в теме
(1)
Процедура ВыбратьКартинкуЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт

ВыбранноеИмяФайла это просто имя файла без пути.
Соответственно последующее открытие и "Картинка = ПоместитьВоВременноеХранилище(Новый Картинка(Объект.ПутьКФайлу));"
Объект.ПутьКФайлу содержить просто имя файла без пути.
3. ResAndDev 16.12.18 13:54 Сейчас в теме
(2)нет, это путь к файлу. Проверял отладчиком. Этот код не работает только если ранее не сохраненный в базе файл.
4. spacecraft 16.12.18 14:26 Сейчас в теме
(3) в Веб-клиенте это может не быть путь к файлу.
5. ResAndDev 16.12.18 14:28 Сейчас в теме
(4)я подключаюсь в тонком клиенте. Если ошибка при помещении в хранилище, тогда почему все работает через ВыбратьКартинку ? И в последующем считывании такого элемента отображение тоже в норме.
6. spacecraft 16.12.18 14:31 Сейчас в теме
(5) я к тому, что этот код не будет работать ожидаемо в веб-клиенте.
Ошибка пропадания картинки в тонком клиенте возможно в том коде, который мы не видим.
На изменение реквизита формы "СохранятьФотоВБазе" обработчик указан? Может там что меняется.
7. ResAndDev 16.12.18 14:33 Сейчас в теме
(6)обработчика там нет. Просто поставлена галочка "Сохраняемые данные" дабы при изменении состояния флажка форма становилось модифицированной.
8. spacecraft 16.12.18 14:54 Сейчас в теме
(7) проверьте что содержится в Картинка.
Если СохранятьФотоВБазе И ЭтоАдресВременногоХранилища(Картинка) Тогда

Картинка будет проходить проверку на ЭтоАдресВременногоХранилища, но в нем (временном хранилище) будет Неопределено.
Как вариант, проверять ПутьККартинке.
10. ResAndDev 16.12.18 15:33 Сейчас в теме
(8)Как в картинке будет Неопределено, если эта самая картинка сейчас на форме и ее видно нормально ?
11. spacecraft 16.12.18 15:36 Сейчас в теме
(10) не в картинке будет Неопределено, в во временном хранилище.
ПоместитьВоВременноеХранилище(Новый Картинка(Объект.ПутьКФайлу)) помещает двоичные данные. Но хранится они будут до первого же последующего серверного вызова.
Если не указан второй параметр :
"Если параметр не указан, помещенное значение будет удалено после очередного запроса сервера из общего модуля, при контекстном и неконтекстном серверном вызове из формы, при серверном вызове из модуля команды или при получении формы. "
9. spacecraft 16.12.18 15:13 Сейчас в теме
(1) В данном случае вот решение проблемы:
Картинка = ПоместитьВоВременноеХранилище(Новый Картинка(Объект.ПутьКФайлу),УникальныйИдентификатор);

Но далее возникает другая проблема. Когда пользователь снимает флаг сохранения в базе. Картинка пропадет.
12. ResAndDev 16.12.18 18:31 Сейчас в теме
(9)Тогда придется писать обработчик для СохранятьФотоВБазе. Только вот как сделать обратный процесс - картинку из формы сохранить на диск ? Пока вот, сижу читаю синтаксис-помощник.
13. spacecraft 16.12.18 18:49 Сейчас в теме
(12) могу подбросить идеи. Как это делается в типовых.
1. картинки в базе не желательно хранить в самом справочнике. Лучше использовать отдельный справочник "СотрудникиПрисоединенныеФайлы" или регистрСведений
2. всю логику по хранению и получению картинки реализовать в отдельном общем модуле.
3. Хранить файлы не с путями клиентских компьютеров, в в отдельной папке "На Сервере".
4. Имена файлов не обязательно такие же, как и загружаемые. Генерировать свои уникальные имена. Сохранять их в реквизит.
5. При выборе хранения в базе загружать ДД в реквизит хранилище данных. При наличии файла на сервере - удалять этот файл.
6. При выборе хранения в файлах, выгружать из хранилища и записывать в файлы, как указано выше.

Рассмотреть возможность внедрения БСП(если ее еще нет в конфигурации) и использовать подсистему РаботаСФайлами.
14. ResAndDev 16.12.18 19:06 Сейчас в теме
(13)Буду делать регистр сведений.
Туки Туки; +1 Ответить
15. Туки Туки 51 17.12.18 03:06 Сейчас в теме
(14) В ЗУП 3.1(или скорее всего в БСП в целом) фотографии сотрудников это как раз регистр сведений, можешь взять за основу
16. ResAndDev 17.12.18 20:38 Сейчас в теме
(13)
Все. Сделал.

Вот что получилось в итоге:

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

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

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

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

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Если Объект.Ссылка <> Справочники.ФизическиеЛица.ПустаяСсылка() Тогда
		Если Объект.МестоХраненияФайла = Перечисления.МестоХраненияФайла.ВБазе Тогда
			ЗначениеКлюча = Новый Структура;
			ЗначениеКлюча.Вставить("Сотрудник", Объект.Ссылка);
			
			КлючЗаписи = РегистрыСведений.ФотографииСотрудников.СоздатьКлючЗаписи(ЗначениеКлюча);
			
			Картинка = ПолучитьНавигационнуюСсылку(КлючЗаписи, "Фото");
		Иначе
			ПутьКФайлу = Константы.КаталогХраненияФотографий.Получить() +"\"+ Объект.Ссылка.УникальныйИдентификатор() + Объект.Ссылка.Расширение;
			Файл = Новый Файл(ПутьКФайлу);
			Если Файл.Существует() Тогда
				ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
				Картинка = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры


Показать
17. IgorXml 724 18.12.18 10:48 Сейчас в теме
Файл картинки тип ХранилищеЗначений. Поле на форме АдресКартинки тип "Поле HTML документа":

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	НаборЗаписей = РегистрыСведений.РасчетныеЛисткиBonus.СоздатьНаборЗаписей();
	НаборЗаписей.Отбор.ФизЛицо.Установить( запись.ИсходныйКлючЗаписи.ФизЛицо);
	НаборЗаписей.Отбор.Период.Установить( Запись.ИсходныйКлючЗаписи.Период) ;
	НаборЗаписей.Прочитать();
	Если НаборЗаписей.Количество() > 0 Тогда
		ДанныеФайла = НаборЗаписей[0].ФайлКартинки.Получить();
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	Если  ТипЗнч(ДанныеФайла) = тип("ДвоичныеДанные") Тогда
		ИмяФайла = ПолучитьИмяВременногоФайла("htm");
		ДанныеФайла.Записать(ИмяФайла);
		АдресКартинки = ИмяФайла ;
	КонецЕсли;
КонецПроцедуры
Показать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот