# Задание к занятию "Файлы" Результат выполнения всех трех задач вышлите одним файлом (.dt) ## Задача 1 Создать обработку для загрузки цен из файла ### Описание задачи Создадим обработку для загрузки цен из файла CSV. Обработка создает новый документ Цены номенклатуры, в табличной части заполняет данные из файла. ### Требования к результату Выгрузка информационной базы (.dt), csv-файл содержащий список номенклатуры с ценами. Возможность выбора файла с фильтром *.CSV, обработка файла должна выполняться на клиенте. В файле разделитель ";" между колонками Возможность загрузить и создать документ Цены номенклатуры. Поиск номенклатуры по наименованию Если не найдена, вывести сообщение вида "Номенклатура: " + НаименованиеНоменклатуры + " не найдена" ### Процесс выполнения Создать файл с расширением .CSV формат: номенклатура;цена пример строки файла: Тапочки;1000 Хлеб;40 Создать новую обработку "Загрузка прайса из файла" Добавим команду Загрузить, вынесем в командную панель формы и назначим кнопкой по умолчанию Назначим обработчик команды со следующим алгоритмом: ```bsl Режим = РежимДиалогаВыбораФайла.Открытие; Диалог = Новый ДиалогВыбораФайла(Режим); //Создаем диалог в режиме открытия файла и заполняем свойства Фильтр = НСтр("ru = 'Файл CSV'; en = 'File CSV'") + "(*.csv)|*.csv"; Диалог.Фильтр = Фильтр; Диалог.Заголовок = "Выберите файл"; ВыбранныеФайлы = Ждать Диалог.ВыбратьАсинх(); //Открываем диалог Если ВыбранныеФайлы = Неопределено Тогда //Если пользователь ничего не выбрал, ничего не делаем Возврат; КонецЕсли; ДанныеФайла = Ждать ПрочитатьФайл(ВыбранныеФайлы[0]); СоздатьДокумент(ДанныеФайла); ``` Так как в обработчике используется ключевое слово Ждать перед словом Процедура добавим **Асинх** Далее обработаем файл на клиенте и подготовим данные для создания документа: ```bsl &НаКлиенте Асинх Функция ПрочитатьФайл(ПутьКФайлу) ТекстовыйФайлЗагрузки = Новый ТекстовыйДокумент; Разделитель = ";"; Ждать ТекстовыйФайлЗагрузки.ПрочитатьАсинх(ПутьКФайлу, КодировкаТекста.UTF8); Результат = Новый Массив; //Прочитаем строки файла Для НомерСтроки = 1 по ТекстовыйФайлЗагрузки.КоличествоСтрок() Цикл НоваяСтрока = ТекстовыйФайлЗагрузки.ПолучитьСтроку(НомерСтроки); // «парсим» строки по ";" // ищем позицию символа-разделителя Позиция = Найти(НоваяСтрока, ";"); // Получаем из строки наименование номенклатуры и цену // Наименование перед символом-разделителем, цена - после НаименованиеНоменклатуры = Сред(НоваяСтрока, 1, Позиция - 1); Цена = Сред(НоваяСтрока, Позиция + 1); // Готовим коллекцию данных для последующего заполнения документа ДанныеСтрокиДокумента = Новый Структура; ДанныеСтрокиДокумента.Вставить("НаименованиеНоменклатуры", НаименованиеНоменклатуры); ДанныеСтрокиДокумента.Вставить("Цена", Цена); Результат.Добавить(ДанныеСтрокиДокумента); КонецЦикла; Возврат Результат; КонецФункции ``` Теперь загрузим данные файла в ТЧ документа Цены номенклатуры Создам процедуру ЗагрузитьЦеныНоменклатуры(). Т.к. мы передаем только данные файла можно использовать директиву НаСервереБезКонтекста ```bsl &НаСервереБезКонтекста Процедура СоздатьДокумент(ДанныеФайла) // Создаем новый документ ДокументЦены = Документы.УстановкаЦенНоменклатуры.СоздатьДокумент(); ДокументЦены.Дата = ТекущаяДата(); // Обходим коллекцию с данными файла и заполняем строки табличной части Для Каждого ДанныеСтроки Из ДанныеФайла Цикл Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию(ДанныеСтроки.НаименованиеНоменклатуры); // Если номенклатура не найдена, то сообщаем об этом пользователю Если Не ЗначениеЗаполнено(Номенклатура) Тогда ШаблонСообщения = НСтр("ru = 'Номенклатура: %1 не найдена'"); Сообщение = Новый СообщениеПользователю; Сообщение.Текст = СтрШаблон(ШаблонСообщения, ДанныеСтроки.НаименованиеНоменклатуры); Сообщение.Сообщить(); Продолжить; КонецЕсли; НоваяСтрокаТЧ = ДокументЦены.Товары.Добавить(); НоваяСтрокаТЧ.Номенклатура = Номенклатура; НоваяСтрокаТЧ.Цена = ДанныеСтроки.Цена; КонецЦикла; ДокументЦены.Записать(); КонецПроцедуры ``` ## Задача 2 Развитие обработки для загрузки цен из файла ### Описание задачи Если при загрузке файла высняется, что хотя бы одной номенклатуры нет в базе задайте вопрос пользователю с текстом "Не все номенклатурные позиции из файла существуют в справочнике. Продолжить создание документа?" и вариантами ответа "Да" и "Нет". При ответе "Да" - записывать документа. При ответе "Нет" - приостанавливать работу алгоритма. ### Требования к результату Выгрузка информационной базы (.dt) из Задачи 1, в которой реализован вопрос пользователю. ### Процесс выполнения Разбейте процедуру СоздатьДокумент() на 2 отдельных метода. Первый метод сделайте функцией, которая будет возвращать информацию есть ли ненайденная номенклатура (Истина или Ложь). Одновременно с проверкой дополните данные файла ссылкой на номенклатуру: ```bsl Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию(ДанныеСтроки.НаименованиеНоменклатуры); ДанныеСтроки.Вставить("Номенклатура", Номенклатура); // Если номенклатура не найдена, то сообщаем об этом пользователю Если Не ЗначениеЗаполнено(Номенклатура) Тогда ШаблонСообщения = НСтр("ru = 'Номенклатура: %1 не найдена'"); Сообщение = Новый СообщениеПользователю; Сообщение.Текст = СтрШаблон(ШаблонСообщения, ДанныеСтроки.НаименованиеНоменклатуры); Сообщение.Сообщить(); Результат = Ложь; КонецЕсли; ``` Если функция вернула Ложь, то задайте вопрос пользователю с помощью функции **ВопросАсинх**. В противном случае сразу сохраните документ. Если пользователь ответил "Да", то сохраните документ, вызвав второй метод. Для заполнения документа используйте уже ранее полученные и сохраненные в данных файла ссылки на номенклатуру. Если номенклатура для какой-то строки не заполнена, то такая строка не должна создаваться в документе (не должно быть строк с пустой номенклатурой).