Загрузка данных в табличную часть документа из Excel
Первое, с чем мне пришлось столкнуться при знакомстве с 1С — Загрузка данных из Excel…
Загрузка нужна была в нашей компании везде: продажи, закупки, характеристики, изменение цен и тд.
Ну и, как полагается, еще совсем зеленым я не особо понимал что и как делается.
Так что, если кто-то из Вас только начинает погружаться в удивительный мир возможностей 1С, знайте, у Вас все впереди!
Ничего страшного в незнании чего-либо НЕТ! Всегда можно найти ответ на любой вопрос и решить практически любую задачу!
Итак, загрузка из файла Excel в табличную часть любого документа…
Для примера создадим обработку с табличной частью.
К кнопке «Заполнить» привяжем нашу процедуру:
Процедура Заполнить(Кнопка) //В зависимости от того, сколько колонок нам необходимо прочитать, можно создать несколько //переменных для колонок. Например, нужно найти по артикулу номенклатуру, так же подгрузить //из файла количество и цену. //Данные переменные можно указать явно, если загрузка будет из однотипных документов //Если колонки будут разные, то после кажого выбора файла можем в ручную их проставить Перем Артикул, Количество, Цена; //Создаем диалог открытия файла ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие); //Здесь мы можем разрешить или запретить выбирать несколько файлов //Нам это не нужно ВыборФайла.МножественныйВыбор = Ложь; //Указываем заголовок диалога открытия файла ВыборФайла.Заголовок = "Выберите файл для загрузки"; //В фильтре мы можем указать какие именно документы разрешено открыть, //в нашем случае файлы Excel //Тут немного поподробнее: //В первой половине строки - "Документ Excel (*.xls,*.xlsx)" пишем текст, //который будет указан в фильтре //Во второй половине - "*.xls;*.xlsx" указываем непосредственно расширение файлов, //которые будут отображаться для выбора //Разделяются эти две половины с помощью пайпа - | (вертикальная черта). ВыборФайла.Фильтр = "Документ Excel (*.xls,*.xlsx)|*.xls;*.xlsx"; //Открываем диалог выбора файла ВыборФайла.Выбрать(); //Проверим, выбрали ли мы файл, с помощью проверки заполненности пути до файла Если ПустаяСтрока(ВыборФайла.ПолноеИмяФайла) Тогда Сообщить("Файл не выбран"); //Если мы файл не выбрали, то процедура прерывается, так как продолжать ее нет смысла. Возврат; Иначе Сообщить("Вы выбрали файл - "+ВыборФайла.ПолноеИмяФайла); КонецЕсли; //Создаем переменную для хранения пути к файлу ПутьКФайлу = ВыборФайла.ПолноеИмяФайла; //Далее нам необходимо создать новый COM объект для возможности работать с Excel'ем ПриложениеExcel = Новый COMОбъект("Excel.Application"); //Откроем выбранный ранее файл ФайлExcel = ПриложениеExcel.WorkBooks.Open(ПутьКФайлу); //Отключаем отображение всех предупреждений ФайлExcel.Application.DisplayAlerts = False; //Выбираем первый лист книги Excel для работы ЛистExcel = ФайлExcel.Sheets(1); //Теперь нам необходимо определиться с границами файла //Если структура файла правильная, без пустых строк, //то можно использовать следующую конструкцию: //ПоследняяСтрокаExcel = ЛистExcel.Cells.SpecialCells(xlCellTypeLastCell).Row; //Однако не всегда получается все так идеально, по этому можно использовать выражение: //ПоследняяСтрокаExcel = ЛистExcel.UsedRange.Rows.Count; //На нем мы и остановимся. ПоследняяСтрокаExcel = ЛистExcel.UsedRange.Rows.Count; //Теперь у нас есть практически все, что необходимо для загрузки данных. //Проставим нужные нам колонки ВвестиЧисло(Артикул,"Введите номер колонки Артикул",2,0); ВвестиЧисло(Количество,"Введите номер колонки Количество",2,0); ВвестиЧисло(Цена,"Введите номер колонки Цена",2,0); //Обработка по очереди проходит все строки, которые нашлись в файле и все колонки, //которые мы указали Для Строка = 1 По ПоследняяСтрокаExcel Цикл //Что бы получить значение ячейки нам необходимо получить адрес ячейки и извлечь из нее //значение, т.е. Value //В нашем примере мы ищем артикул товара. Берем первую строку и колонку с артикулами. ЗначениеЯчейки = ЛистExcel.Cells(Строка, Артикул).Value; СпрНом = Справочники.Номенклатура; //Теперь у нас есть значение ячейки. Найдем номенклатуру в нашей //базе по этому значению Номенклатура = СпрНом.НайтиПоРеквизиту("АртикулПроизводителя",ЗначениеЯчейки); //Проверяем, нашлась ли номенклатура Если НЕ Номенклатура.Пустая() Тогда //Если нашлась, то добавляем строку в нашу таблицу значений. Стр = Таблица.Добавить(); //Заполняем нашу строку необходимыми данными из файла. Стр.Номенклатура = Номенклатура; Стр.Артикул = Номенклатура.АртикулПроизводителя; //Берем количество из файла Excel Стр.Количество = Число(ЛистExcel.Cells(Строка, Количество).Value); //Берем цену из файла Excel Стр.Цена = Число(ЛистExcel.Cells(Строка, Цена).Value); КонецЕсли; КонецЦикла; //Обязательно закрываем приложение, что бы оно не висело в фоновом режиме //и не кушало нашу память. ПриложениеExcel.Quit(); КонецПроцедуры;
Теперь давайте посмотрим, как то все отработает.
В обработке нажимаем кнопку «Заполнить».
Открывается стандартный диалог открытия файлов.
Снизу справа видим наш фильтр, который дает открывать только файлы Excel.
Выбираем наш файл Тест.xls
Тестовый файл выглядит следующим образом:
Т.е. к примеру клиент прислал нам заказ, нам его нужно загрузить в реализацию.
После выбора файла нам предложат ввести номера колонок для конкретного файла:
Вводим соответствующие номера.
После этого начинается перебор файла и в итоге мы получаем следующий результат:
Все позиции нашлись, артикул подтягивали из номенклатуры, цены и количество так же загрузились в свои колонки.
Так же, после чтения каждой строки, можно выводить различные служебные сообщения, например, какая номенклатура нашлась, какая не нашлась и так далее.
От себя добавлю, что данную процедуру мы используем очень часто и в различных ситуациях.
Если у вас возникнут какие либо вопросы по данной обработке или заметите какую либо ошибку — пишите в комментариях, с удовольствием отвечу!
ДиалогВыбораФайла нельзя писать на сервре, а на клиенте нельзя обращаться к справочнику
Я, к сожалению, на данный момент работаю только с обычными формами, там все выполняется на клиенте и они директивы &НаСервере и &НаКлиенте не воспринимают…
А как загрузить в одну ТЧ строки из нескольких книг xls? Есть идеи?
Есть конечно! 🙂
Но боюсь, что задержался с ответом))
А в целом, в диалоге выбора файла изменяем доступность Множественного выбора
ВыборФайла.МножественныйВыбор = Истина;
Убираем проверку выбора файла:
//Проверим, выбрали ли мы файл, с помощью проверки заполненности пути до файла
Если ПустаяСтрока(ВыборФайла.ПолноеИмяФайла) Тогда
Сообщить(«Файл не выбран»);
//Если мы файл не выбрали, то процедура прерывается, так как продолжать ее нет смысла.
Возврат;
Иначе
Сообщить(«Вы выбрали файл — «+ВыборФайла.ПолноеИмяФайла);
КонецЕсли;
Переносим указание переменных артикул количество цена пораньше
//Теперь у нас есть практически все, что необходимо для загрузки данных.
//Проставим нужные нам колонки
ВвестиЧисло(Артикул,»Введите номер колонки Артикул»,2,0);
ВвестиЧисло(Количество,»Введите номер колонки Количество»,2,0);
ВвестиЧисло(Цена,»Введите номер колонки Цена»,2,0);
Ставим код сразу после:
//Открываем диалог выбора файла
ВыборФайла.Выбрать();
И берем в цикл наше заполнение:
Для Каждого стр Из ВыборФайла.ВыбранныеФайлы Цикл
//Создаем переменную для хранения пути к файлу
ПутьКФайлу = стр;
…..
Закрываем цикл в конце обработки
ПриложениеExcel.Quit();
КонецЦикла;
Это так, первое что пришло на ум из работоспособного. Можно немного более оптимизированным сделать код, что бы Excel только один раз открывался программно, ну и еще по мелочи.