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