Хочу поделиться опытом. Вот смотрю - на форуме все появляются новые и новые методы работы с Екселем - в основном, все обработки. А вот пришлось мне делать много импортов из екселя и пришлось постоянно в обработки писать кучу одного и того же кода. Потом я сделал одну, универсальную функцию, которая читает данные екселя и отдает таблицу значений.
Итак, рассказываю как работает данная функция.
- ИмяФайла - обязательный параметр;
- НачСтрока - обязательный параметр, здесь указывается начало строки с которого необходимо произвести чтение файла;
- КонСтрока - не обязательный параметр (если он опущен то строка будет определятся автоматически как последняя заполненная в файле, крайняя правая ячейка);
- НомЛиста - не обязательный параметр (если он опущен то будут данные загружаться со всех листов);
- СтруктураКолонок - это список значений, который вы задаете, например:
НомерКолонкиАртикул = 1;
НомерКолонкиНаименование = 2;
НомерКолонкиКодПрограммы1С = 3;
СтруктураКолонок = Новый СписокЗначений;
СтруктураКолонок.Добавить(НомерКолонкиАртикул,"Артикул");
СтруктураКолонок.Добавить(НомерКолонкиНаименование,"Наименование");
СтруктураКолонок.Добавить(НомерКолонкиКодПрограммы1С,"КодПрограммы1С");
ТаблицаФайла = ОбщийМодуль.ОбработкаИмпортаФайлаЕксель(ИмяФайла,НачСтрока,КонСтрока,НомЛиста,СтруктураКолонок);
После работы функции ТаблицаФайла будет содержать структуру колонок с данными, то есть "Артикул, Наименование, КодПрограммы1С". Теперь вы спокойно делаете простенький цикл обхода таблице значений по вашему вкусу!
//Обработка импорта файла Ексель
// СтруктураКолонок, должен содержать
// Представление: "Наименование колонки";
// Значение: "Номер колонки"
// если номер колонки не указан или передан служебный символ "#", будет создана просто пустая колонка
//
Функция ОбработкаИмпортаФайлаЕксель(ИмяФайла,НачСтрока=1,КонСтрока=0,НомерЛиста=0,СтруктураКолонок) Экспорт
Если НЕ ЗначениеЗаполнено(ИмяФайла) Тогда
#Если Клиент Тогда
Предупреждение("Необходимо указать путь к файлу",3);
#КонецЕсли
Возврат Неопределено;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(СтруктураКолонок) Тогда
#Если Клиент Тогда
Предупреждение("Необходимо указать структуру колонок",3);
#КонецЕсли
Возврат Неопределено;
КонецЕсли;
//Разбор листов
СписокИспользуемыхЛистов = Новый СписокЗначений;
КнигаExcel = ПолучитьCOMОбъект(ИмяФайла);
//есть несколько вариантов исчисления:
//1.Номер последней загружаемой строки. Если не указан, то ищется как последнее
// не пустой код производителя, тоесть не пустое последнее значение. А номер Листа определен
Если (ЗначениеЗаполнено(НомерЛиста))
И (НЕ ЗначениеЗаполнено(КонСтрока)) Тогда
//пользователь указал лист, но не указал КонСтрока
Лист = КнигаExcel.Worksheets(НомерЛиста);
ИспользуемыйДиапазон = Лист.UsedRange;
ПоследняяЯчейка = ИспользуемыйДиапазон.SpecialCells(11); //последня правая нижняя ячейка
Если ((ИспользуемыйДиапазон.Address<>ПоследняяЯчейка.Address) ИЛИ (ПоследняяЯчейка.Text<>"")) Тогда
СписокИспользуемыхЛистов.Добавить(ИспользуемыйДиапазон.Rows.Count(),Лист.Name);
Иначе
#Если Клиент Тогда
Предупреждение("Не могу опредилить конечную строку");
#КонецЕсли
Возврат Неопределено;
КонецЕсли;
ИначеЕсли (НЕ ЗначениеЗаполнено(НомерЛиста))
И (ЗначениеЗаполнено(КонСтрока)) Тогда
//во всех листах, но с определенными КонСтрока
Для ИндексЛиста = 1 По КнигаExcel.Worksheets.Count Цикл
Лист=КнигаExcel.Worksheets(ИндексЛиста);
СписокИспользуемыхЛистов.Добавить(КонСтрока,Лист.Name);
КонецЦикла;
ИначеЕсли (НЕ ЗначениеЗаполнено(НомерЛиста))
И (НЕ ЗначениеЗаполнено(КонСтрока)) Тогда
//во всех листах и нужно в каждом из них найти КонСТрока
Для ИндексЛиста = 1 По КнигаExcel.Worksheets.Count Цикл
Лист = КнигаExcel.Worksheets(ИндексЛиста);
ИспользуемыйДиапазон = Лист.UsedRange;
ПоследняяЯчейка = ИспользуемыйДиапазон.SpecialCells(11);
Если ((ИспользуемыйДиапазон.Address<>ПоследняяЯчейка.Address) ИЛИ (ПоследняяЯчейка.Text<>"")) Тогда
СписокИспользуемыхЛистов.Добавить(ИспользуемыйДиапазон.Rows.Count(),Лист.Name);
КонецЕсли;
КонецЦикла;
ИначеЕсли (ЗначениеЗаполнено(НомерЛиста))
И (ЗначениеЗаполнено(КонСтрока)) Тогда
//пользователь указал и Лист и КонСтрочку
Лист = КнигаExcel.Worksheets(НомерЛиста);
СписокИспользуемыхЛистов.Добавить(КонСтрока,Лист.Name);
КонецЕсли;
// по п. 1) КвоЛистов=СписокИспользуемыхЛистов.РазмерСписка();
// по п. 2) КвоСтрок=СписокИспользуемыхЛистов.Получить(ИмяЛиста);
КонСтрокаДляПрогреса = 0;
Для Каждого НомераКонСтроки Из СписокИспользуемыхЛистов Цикл
КонСтрокаДляПрогреса = КонСтрокаДляПрогреса + НомераКонСтроки.Значение;
КонецЦикла;
мФормаИндикатора = Неопределено;
#Если Клиент Тогда
Попытка
мФормаИндикатора = ПолучитьОбщуюФорму("ХодВыполненияОбработкиДанных");
мФормаИндикатора.КомментарийОбработкиДанных = "Выполняется обработка импорта с файла xls";
мФормаИндикатора.Значение = 0;
мФормаИндикатора.МаксимальноеЗначение = КонСтрокаДляПрогреса;
мФормаИндикатора.Открыть();
Исключение
мФормаИндикатора = Неопределено;
КонецПопытки;
#КонецЕсли
ТаблицаРезультатов = Новый ТаблицаЗначений;
ТаблицаРезультатов.Колонки.Добавить("Лист");
Для Каждого СтрокаКолонки Из СтруктураКолонок Цикл
Инд = СтрокаКолонки.Представление;
ТаблицаРезультатов.Колонки.Добавить(Инд);
КонецЦикла;
Для Каждого НомераКонСтроки Из СписокИспользуемыхЛистов Цикл
НомерЛиста = НомераКонСтроки.Представление;
КонСтрока = НомераКонСтроки.Значение;
СостояниеПрогреса = 0;
Для НомерОбработанойСтроки = НачСтрока По КонСтрока Цикл
#Если Клиент Тогда
ОбработкаПрерыванияПользователя();
#КонецЕсли
СостояниеПрогреса = СостояниеПрогреса + 1;
#Если Клиент Тогда
Если НЕ мФормаИндикатора = Неопределено Тогда
мФормаИндикатора.Значение = мФормаИндикатора.Значение + 1;
КонецЕсли;
#КонецЕсли
НоваяСтрока = ТаблицаРезультатов.Добавить();
НоваяСтрока.Лист = НомерЛиста;
Для Каждого ИндетификатораКолонки Из СтруктураКолонок Цикл
iCount = ИндетификатораКолонки.Значение;
Если (НЕ ЗначениеЗаполнено(iCount))
ИЛИ (iCount = "#") Тогда
//это структура пустой колонки
Продолжить;
КонецЕсли;
ЗначениеЗаписи = СтрЗаменить(СокрЛП(КнигаExcel.Sheets(НомерЛиста).Cells(НомерОбработанойСтроки,iCount).Value),Символ(160),"");
НоваяСтрока[ИндетификатораКолонки.Представление] = ЗначениеЗаписи;
КонецЦикла;
КонецЦикла;
КонецЦикла;
#Если Клиент Тогда
Состояние("Завершено!");
Если НЕ мФормаИндикатора = Неопределено Тогда
мФормаИндикатора.Закрыть();
КонецЕсли;
#КонецЕсли
Возврат ТаблицаРезультатов;
КонецФункции
Хочу подчеркнуть, что ход выполнения состояния работает только в типовых конфигурациях которые оснащены общей формой "ХодВыполненияОбработкиДанных", в противном случае часть кода где идет обращение к данной форме можете удалить и подставить свой если такой имеется!