From 98380594fdc5da2b57991c2f3029e4bcd811c770 Mon Sep 17 00:00:00 2001 From: Matvey Seregin Date: Thu, 3 Feb 2022 00:41:17 +0300 Subject: [PATCH] =?UTF-8?q?=D0=90=D0=BA=D1=82=D1=83=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B4=D0=BE=D0=BC=D0=B0=D1=88?= =?UTF-8?q?=D0=BD=D0=B5=D0=B3=D0=BE=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D0=B4=D0=BE=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B8=20=D0=BF=D1=80=D0=B5=D0=B7?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- homework-5-7.md | 189 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 130 insertions(+), 59 deletions(-) diff --git a/homework-5-7.md b/homework-5-7.md index 66b554b..de03153 100644 --- a/homework-5-7.md +++ b/homework-5-7.md @@ -1,5 +1,7 @@ # Задание к занятию "Файлы" +Результат выполнения всех трех задач вышлите одним файлом (.dt) + ## Задача 1 Создать обработку для загрузки цен из файла ### Описание задачи @@ -35,78 +37,147 @@ Создать новую обработку "Загрузка прайса из файла" -Добавим поле "ПутьКФайлу" с диалогом выбора -На событие "Начало выбора" добавим обработчик -```bsl +Добавим команду Загрузить, вынесем в командную панель формы и назначим кнопкой по умолчанию +Назначим обработчик команды со следующим алгоритмом: +```bsl Режим = РежимДиалогаВыбораФайла.Открытие; - Диалог = Новый ДиалогВыбораФайла(Режим); //Создаем диалог в режиме открвтия файла и заплняем свойства - Фильтр = НСтр("ru = 'Текст'; en = 'Text'") - + "(*.txt)|*.txt"; + Диалог = Новый ДиалогВыбораФайла(Режим); //Создаем диалог в режиме открытия файла и заполняем свойства + Фильтр = НСтр("ru = 'Файл CSV'; en = 'File CSV'") + + "(*.csv)|*.csv"; Диалог.Фильтр = Фильтр; - Диалог.МножественныйВыбор = Ложь; Диалог.Заголовок = "Выберите файл"; - Оповещение = Новый ОписаниеОповещения("ВыборФайлаЗавершение", ЭтотОбъект); //Процедура, которая запустится после закрытия диалога - Диалог.Показать(Оповещение); //Открываем диалог -``` -В этом же модуле нужно объявить процедуру-обработчик закрытия диалога: -```bsl -Процедура ВыборФайлаЗавершение(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт + + ВыбранныеФайлы = Ждать Диалог.ВыбратьАсинх(); //Открываем диалог + Если ВыбранныеФайлы = Неопределено Тогда //Если пользователь ничего не выбрал, ничего не делаем Возврат; КонецЕсли; - ПутьКФайлу = ВыбранныеФайлы[0]; -КонецПроцедуры + + ДанныеФайла = Ждать ПрочитатьФайл(ВыбранныеФайлы[0]); + + СоздатьДокумент(ДанныеФайла); ``` -Добавим реквизит формы -АдресВХранилище (Строка) -На форму его отображать не нужно +Так как в обработчике используется ключевое слово Ждать перед словом Процедура добавим **Асинх** -В реквизит поместим путь к файлу +Далее обработаем файл на клиенте и подготовим данные для создания документа: ```bsl -АдресВХранилище = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ПутьКФайлу)); -``` -Далее загрузим данные файла в ТЧ документ Цены номенклатуры - -Создам процедуру на сервере ЗагрузитьЦеныНоменклатуры() -```bsl -&НаСервере -Процедура ЗагрузитьЦеныНоменклатуры() - Файл = ПолучитьИмяВременногоФайла("csv"); - ФайлХранилища = ПолучитьИзВременногоХранилища(АдресВХранилище); - ФайлХранилища.Записать(Файл); +&НаКлиенте +Асинх Функция ПрочитатьФайл(ПутьКФайлу) ТекстовыйФайлЗагрузки = Новый ТекстовыйДокумент; Разделитель = ";"; + + Ждать ТекстовыйФайлЗагрузки.ПрочитатьАсинх(ПутьКФайлу, КодировкаТекста.UTF8); - Попытка - ТекстовыйФайлЗагрузки.Прочитать(Файл); + Результат = Новый Массив; + + //Прочитаем строки файла + Для НомерСтроки = 1 по ТекстовыйФайлЗагрузки.КоличествоСтрок() Цикл - ДокументЦены = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент(); - //Прочитаем строки файла - Для НомерСтроки=1 по ТекстовыйФайлЗагрузки.КоличествоСтрок() Цикл - НоваяСтрока = ТекстовыйФайлЗагрузки.ПолучитьСтроку(НомерСтроки); - // «парсим» строки по ";" - // ищем позицию символа-разделителя - Позиция = Найти(НоваяСтрока, ";"); - НаименованиеНоменклатуры = Сред(НоваяСтрока,1,Позиция-1); - Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию(НаименованиеНоменклатуры); - Если Не ЗначениеЗаполнено(Номенклатура) Тогда - Сообщение = Новый СообщениеПользователю; - Сообщение.Текст = "Номенклатура: " + НаименованиеНоменклатуры + " не найдена"; - Сообщение.Сообщить(); - Продолжить; - КонецЕсли; - // за символом-резделителем – цена - Цена = Сред (НоваяСтрока, Позиция+1); - НоваяСтрокаТЧ = ДокументЦены.Товары.Добавить(); - НоваяСтрокаТЧ.Номенклатура = Номенклатура; - НоваяСтрокаТЧ.Цена = Цена; - КонецЦикла; - ДокументЦены.Записать(); - Исключение - Сообщение = Новый СообщениеПользователю; - Сообщение.Текст = ОписаниеОшибки(); - Сообщение.Сообщить(); - КонецПопытки; + НоваяСтрока = ТекстовыйФайлЗагрузки.ПолучитьСтроку(НомерСтроки); + + // «парсим» строки по ";" + // ищем позицию символа-разделителя + Позиция = Найти(НоваяСтрока, ";"); + + // Получаем из строки наименование номенклатуры и цену + // Наименование перед символом-разделителем, цена - после + НаименованиеНоменклатуры = Сред(НоваяСтрока, 1, Позиция - 1); + Цена = Сред(НоваяСтрока, Позиция + 1); + + // Готовим коллекцию данных для последующего заполнения документа + ДанныеСтрокиДокумента = Новый Структура; + ДанныеСтрокиДокумента.Вставить("НаименованиеНоменклатуры", НаименованиеНоменклатуры); + ДанныеСтрокиДокумента.Вставить("Цена", Цена); + + Результат.Добавить(ДанныеСтрокиДокумента); + + КонецЦикла; + + Возврат Результат; + +КонецФункции +``` + +Теперь загрузим данные файла в ТЧ документа Цены номенклатуры + +Создам процедуру ЗагрузитьЦеныНоменклатуры(). Т.к. мы передаем только данные файла можно использовать директиву НаСервереБезКонтекста +```bsl +&НаСервереБезКонтекста +Процедура СоздатьДокумент(ДанныеФайла) + + // Создаем новый документ + ДокументЦены = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент(); + ДокументЦены.Дата = ТекущаяДата(); + + // Обходим коллекцию с данными файла и заполняем строки табличной части + Для Каждого ДанныеСтроки Из ДанныеФайла Цикл + + Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию(ДанныеСтроки.НаименованиеНоменклатуры); + + // Если номенклатура не найдена, то сообщаем об этом пользователю + Если Не ЗначениеЗаполнено(Номенклатура) Тогда + + ШаблонСообщения = НСтр("ru = 'Номенклатура: %1 не найдена'"); + + Сообщение = Новый СообщениеПользователю; + Сообщение.Текст = СтрШаблон(ШаблонСообщения, ДанныеСтроки.НаименованиеНоменклатуры); + Сообщение.Сообщить(); + + Продолжить; + + КонецЕсли; + + НоваяСтрокаТЧ = ДокументЦены.Товары.Добавить(); + НоваяСтрокаТЧ.Номенклатура = Номенклатура; + НоваяСтрокаТЧ.Цена = ДанныеСтроки.Цена; + + КонецЦикла; + + ДокументЦены.Записать(); + КонецПроцедуры ``` +## Задача 2 Развитие обработки для загрузки цен из файла + +### Описание задачи + +Если при загрузке файла высняется, что хотя бы одной номенклатуры нет в базе задайте вопрос пользователю с текстом "Не все номенклатурные позиции из файла существуют в справочнике. Продолжить создание документа?" и вариантами ответа "Да" и "Нет". + +При ответе "Да" - записывать документа. + +При ответе "Нет" - приостанавливать работу алгоритма. + +### Требования к результату + +Выгрузка информационной базы (.dt) из Задачи 1, в которой реализован вопрос пользователю. + +### Процесс выполнения + +Разбейте процедуру СоздатьДокумент() на 2 части. + +Первую часть сделайте функцией, которая будет возвращать информацию есть ли ненайденная номенклатура (Истина или Ложь). +Одновременно с проверкой дополните данные файла ссылкой на номенклатуру: +```bsl + Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию(ДанныеСтроки.НаименованиеНоменклатуры); + ДанныеСтроки.Вставить("Номенклатура", Номенклатура); + + // Если номенклатура не найдена, то сообщаем об этом пользователю + Если Не ЗначениеЗаполнено(Номенклатура) Тогда + + ШаблонСообщения = НСтр("ru = 'Номенклатура: %1 не найдена'"); + + Сообщение = Новый СообщениеПользователю; + Сообщение.Текст = СтрШаблон(ШаблонСообщения, ДанныеСтроки.НаименованиеНоменклатуры); + Сообщение.Сообщить(); + + Результат = Ложь; + + КонецЕсли; +``` + +Если функция вернула Ложь, то задайте вопрос пользователю. В противном случае сразу сохраните документ. + +Если пользователь ответил "Да", то сохраните документ, вызвав вторую часть. + +Для заполнения документа используйте уже ранее полученные и сохраненные в данных файла ссылки на номенклатуру. Если номенклатура для какой-то строки не заполнена, то такая строка не должна создаваться в документе (не должно быть строк с пустой номенклатурой).