Skip to content

Latest commit

 

History

History
196 lines (127 loc) · 14.8 KB

homework-5-9.md

File metadata and controls

196 lines (127 loc) · 14.8 KB

Задание к занятию «Двоичные данные»

Результат выполнения первых двух задач вышлите одним файлом (.dt).

Задача 1. Создать в справочнике «Номенклатура» возможность загрузки и хранения картинки

Описание задачи

Добавить возможность загрузки и хранения картинки в справочнике «Номенклатура».

Требования к результату

Выгрузка информационной базы (.dt) с конфигурацией из предыдущих заданий, в которой реализована возможность загружать и просматривать из формы элемента номенклатуры.

Можно выбрать каталог и картинку для загрузки.

Номенклатура должна корректно записываться как с выбранной картинкой, так и с пустой картинкой.

Процесс выполнения

  1. Добавим реквизит «ФайлКартинки» с типом «Хранилище значения» в справочнике «Номенклатура».

  2. Добавим реквизит «ПутьКартинки» на форму элемента, укажем тип «Строка». В нём будет адрес картинки во временном хранилище. Разместим реквизит на форме с видом «Поле картинки». Установим для элемента формы флажок «Гиперссылка».

  3. Добавим на событие Нажатие процедуру «ПутьКартинкиНажатие».

  4. Внутри процедуры вызовем асинхронную процедуру для выбора файла с картинкой. Дополнительная процедура нужна, т.к. обработчик элемента формы не может быть асинхронной процедурой:

&НаКлиенте
Процедура ПутьКартинкиНажатие(Элемент, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;      
	
	ПрочитатьКартинкуНоменклатуры();
	
КонецПроцедуры

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

&НаКлиенте
Асинх Процедура ПрочитатьКартинкуНоменклатуры()
	
	ПараметрыПомещенияФайла = Новый ПараметрыДиалогаПомещенияФайлов;
	ПараметрыПомещенияФайла.Фильтр = "Картинка (*.jpg)|*.jpg";  
	
	ОписаниеФайла = Ждать ПоместитьФайлНаСерверАсинх(,,, ПараметрыПомещенияФайла, УникальныйИдентификатор);
	
	Если ОписаниеФайла = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ОписаниеФайла.ПомещениеФайлаОтменено Тогда
		Возврат;
	КонецЕсли;
	
	ПутьКартинки = ОписаниеФайла.Адрес;
	
КонецПроцедуры
  1. Перед записью на сервере запишем в хранилище значений картинку.

  2. При чтении на сервере получим картинку из хранилища значений.

Пример получения через временное хранилище и записи в реквизит объекта через Хранилище значений:

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

Задача 2. Сохранение картинки номенклатуры с установленной шириной

Описание задачи

Добавить возможность сохранения в файл картинки номенклатуры с шириной 100 пикселей.

Требования к результату

Выгрузка информационной базы (.dt) с конфигурацией из предыдущих заданий, в которой реализована возможность загружать и просматривать из формы элемента номенклатуры.

Ранее выбранную картинку номенклатуры можно сохранить в файл, при этом ширина сохранённой картинки будет 100 пикселей.

Процесс выполнения

  1. Добавим на форму элемента справочника «Номенклатура» команду «СохранитьКартинку», создадим связанную с командой кнопку на коммандной панели формы.

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

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

	ОбрабатываемаяКартинка = Новый ОбрабатываемаяКартинка(Картинка);
	ОбрабатываемаяКартинка.УстановитьРазмер(100, Неопределено);

	Картинка = ОбрабатываемаяКартинка.ПолучитьКартинку();
	
	ДвоичныеДанныеИзображения = Картинка.ПолучитьДвоичныеДанные();
	
	Возврат ПоместитьВоВременноеХранилище(ДвоичныеДанныеИзображения, УникальныйИдентификатор);
	
КонецФункции

Задача 3 (со звёздочкой). Разбить файл на части и склеить после этого

Описание задачи

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

  • разделить файл,
  • объединить файлы.

На первой закладке расположено поле «Имя файла», в котором пользователь с помощью стандартного диалога выберет произвольный файл на диске. Также на закладке расположено числовое поле «Размер части» и текстовое поле «Путь», где пользователь с помощью стандартного диалога выбора каталога выберет путь, в котором нужно разместить полученные части файла.

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

Порядок выполнения

Разбиение файлов

  • Создать внешнюю обработку с реквизитами: «ИмяФайла», «РазмерЧасти», «Путь», «Результат» и табличной частью «ИменаЧастей» с единственным реквизитом «ИмяЧасти».
  • В обработке создать форму и разместить в ней две страницы: «Разделить файл» и «Объединить файлы». На странице «Разделить файл» разместить реквизиты «Имя файла» и «Размер части».
  • В элементе управления «ИмяФайла» и «Путь» включить отображение кнопки выбора «КнопкаВыбора = Да».
  • Реализовать алгоритм выбора файла с помощью стандартного диалога в поле «ИмяФайла» в обработчике «НачалоВыбора».
  • Повторить для элемента управления «Путь», но использовать диалог в режиме выбора каталога.
  • Создать команду «РазделитьФайл» и разместить её на форме на закладке «Разделить файл».
  • Написать алгоритм разбиения файла на части. Каждая часть сохраняется в отдельный файл.

Подсказка по алгоритму разбиения

  • Выяснить размер исходного файла и записать в переменную «ОсталосьПрочитать». См. объект «Файл» и «ФайловыйПоток».
  • В цикле открыть новый файловый поток для записи. Имя части сгенерировать как "Часть_"+"Счетчик.
  • Записать в файловый поток части методом ИсходныйПоток.КопироватьВ(ПотокЧасти, РазмерЧасти).
  • Перед записью проконтролировать, что РазмерЧасти меньше переменной ОсталосьПрочитать. Если РазмерЧасти больше — скопировать только оставшееся число байт
  • Уменьшить переменную «ОсталосьПрочитать» на «РазмерЧасти».

Объединение файлов

  • На закладке «Объединение файлов» разместить табличную часть «ИменаЧастей» и поле реквизита «Результат».
  • В поле реквизита «Результат» включить отображение кнопки выбора и написать алгоритм выбора пути файла.
  • Создать команду «Объединить файлы» и разместить её на форме.
  • Написать обработчик команды таким образом, чтобы он создал файл с именем, указанным в поле «Результат» и перенёс в него содержимое всех файлов, перечисленных в таблице «ИменаЧастей».

Подсказка по алгоритму объединения

  • Открыть для записи поток в файл из поля «Результат».
  • В цикле по таблице ИменаЧастей открывать потоки для чтения текущей строки таблицы и копировать их в поток-результат методом ПотокИсточник.КопироватьВ.
  • Количество байт контролировать в этом случае не надо.