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, в которой реализован вопрос пользователю.
Процесс выполнения
Создайте серверную функцию без контекста ПодобратьНоменклатуру(), в которой нужно перебрать в цикле все строки массива ДанныеФайла и выполнить поиск номенклатуры. Функция должна возвращать данные файла, дополненные ссылкой на номенклатуру.
Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию(ДанныеСтроки.НаименованиеНоменклатуры);
ДанныеСтроки.Вставить("Номенклатура", Номенклатура);
Данную функцию следует вызвать в обработчике команды после чтения данных файла.
Далее обойдите массив и проверьте для всей ли номенклатуры подобраны ссылки, если есть номенклатура без ссылки, то нужно задать пользователю вопрос нужно ли сохранить документ с помощью функции ВопросАсинх. В противном случае сразу сохраните документ.
Если пользователь ответил «Да», то сохраните документ.
Для заполнения и сохранения документа используйте уже ранее полученные и сохранённые в данных файла ссылки на номенклатуру. Если номенклатура для какой-то строки не заполнена, то такая строка не должна добавляться в документ. Не должно быть строк с пустой номенклатурой.