В данной статье приведен функционал, с помощью которого в обработке
"Импорт из EXCEL (xls) в 1С"
производится считывание данных из файлов табличного типа *xls.
Есть множество статей на эту тему:
- Метод "MS ADO" (Чтение файлов xls, xlsx средствами Microsoft ADO): //infostart.ru/public/163640/
- Метод "MS EXCEL" (Чтение файлов xls, xlsx с картинками средствами Microsoft Office): //infostart.ru/public/163641/
- Метод "LO CALC" (Чтение файлов xls, xlsx, ods, sxc с картинками средствами LibreOffice): //infostart.ru/public/163642/
- Метод "NativeXLSX" (Чтение файлов xlsx с картинками средствами 1С. ПостроительDOM): //infostart.ru/public/300092/
- Метод "NativeXLSX". Предыдущий вариант (Чтение файлов xlsx средствами 1С. ЧтениеXML)://infostart.ru/public/225624/
- Метод "Excel1C" (Загрузка на платформе 8.3.6 с картинками. Чтение файлов xls, xlsx, ods): //infostart.ru/public/341855/
- Список листов файла: //infostart.ru/public/163724/
Но всегда возникают какие-то проблемы:
При загрузке из EXCEL в 1С методом MS ADODB.Connection столкнулся со следующим:
-
пользователь выделил цветом всю таблицу Excel, что привело к считыванию всего листа книги.
-
EOF() оказался гораздо дальше чем реально пользователь видел при визуальном осмотре таблицы Excel, т. е. загружались пустые строки
-
необходимо было очищать таблицу от строк с наименованиями колонок
Это моя первая публикация. Буду рад вашим исправлениям и комментариям. P.S. Код написан только для расширения .xls.
&НаКлиенте
Процедура ЗагрузитьExcel(Команда)
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Заголовок = "Выберите файл";
Диалог.Фильтр = "|*.xls";
Диалог.МножественныйВыбор = Ложь;
Если Диалог.Выбрать() Тогда
Адрес = "";
ПоместитьФайл(Адрес,Диалог.ПолноеИмяФайла,,Ложь);
ЗагрузитьНаСервере(Адрес);
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ЗагрузитьНаСервере(Адрес)
ТЗ = ЗагрузитьТаблицуExcelНаСервере(Адрес);
//далее код работы с ТЗ ....
КонецПроцедуры
&НаСервереБезКонтекста
Функция ЗагрузитьТаблицуExcelНаСервере(Адрес)
ФайлИзХранилища = ПолучитьИзВременногоХранилища(Адрес);
ВременныйФайл = ПолучитьИмяВременногоФайла("xls");
//Сохранение во временнный файл на диске
ФайлИзХранилища.Записать(ВременныйФайл);
//Если опущен, тогда 1-й лист
еБаза=Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "
|Provider=Microsoft.Jet.OLEDB.4.0;
|Data Source="+ВременныйФайл+";
|Extended Properties=""Excel 8.0;IMEX=1;HDR=NO;"";";
Попытка
еБаза.Open(СтрокаПодключения);
Исключение
СтрокаПодключения = "
|Provider=Microsoft.ACE.OLEDB.12.0;
|Data Source="+ПутьКФайлу+";
|Extended Properties=""Excel 12.0;IMEX=1;HDR="+?(HDR,"Yes","No")+";"";";
Попытка
еБаза.Open(СтрокаПодключения);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецПопытки;
Catalog = Новый COMОбъект("ADOX.Catalog");
Catalog.ActiveConnection = еБаза;
лСпис=Новый СписокЗначений;
лИмяЛиста="";
Для iCount = 0 По Catalog.Tables.Count-1 Цикл
Если Catalog.Tables.Item(iCount).Type <> "VIEW" Тогда
лСпис.Добавить(Catalog.Tables.Item(iCount).Name);
КонецЕсли;
КонецЦикла;
Если лСпис.Количество()>0 И лИмяЛиста="" тогда
лИмяЛиста = лСпис[0];
Конецесли;
Catalog=Неопределено;
лСтрВнЗапроса="select * from ["+лИмяЛиста+"]";
RS = Новый COMОбъект("ADODB.Recordset");
rs.Open(лСтрВнЗапроса,еБаза,0);
лТз=Новый ТаблицаЗначений;
ЕстьОшибкиВИмениКолонки=Ложь;
Для iCount = 0 По rs.Fields.Count-1 Цикл
Если СокрЛП(rs.Fields.Item(iCount).Value) = "" Тогда //прервём на пустой ячейке имени колонки
Прервать;
КонецЕсли;
Попытка
лТз.Колонки.Добавить(rs.Fields.Item(iCount).Value,, rs.Fields.Item(iCount).Name); // Считаем что в первой строке заголовки колонок
Исключение
Сообщить(ОписаниеОшибки()+" «"+(rs.Fields(iCount).Value)+"»");
ЕстьОшибкиВИмениКолонки = Истина;
КонецПопытки;
КонецЦикла;
Если ЕстьОшибкиВИмениКолонки Тогда //прерываем, чтобы исправили
Возврат лТз;
КонецЕсли;
// Перебор данных
Строк=0;
rs.MoveFirst();
//пользователь выделил цветом весь лист Excel, в том числе и пустые ячейки
//добавим переменную для счета количества пустых ячеек,
//как только будет 10 пустых ячеек, считаем, что уже закончились строки в таблице
СчПустых = 0;
ПустыеСтроки = 0;
Пока rs.EOF() = 0 Цикл
СчПустых = 0;
Строк=Строк+1;
//как только будет 10 пустых ячеек, считаем, что уже закончились строки в таблице
Если ПустыеСтроки = 10 Тогда
Прервать;
КонецЕсли;
лТз.Добавить();
Для iCount = 0 По rs.Fields.Count-1 Цикл
Если СчПустых = 3 Тогда //подряд три пустых ячейки, прервём
СчПустых = 0;//уменьшим
ПустыеСтроки = ПустыеСтроки+1;
//Если три первые ячейки строки пустые, то удаляем строку
Если лТз[лтз.Количество()-1][0]=Неопределено И лТз[лтз.Количество()-1][0] = лТз[лтз.Количество()-1][1] И лТз[лтз.Количество()-1][1] = лТз[лтз.Количество()-1][2] Тогда
лТз.Удалить(лТз[лтз.Количество()-1]);
КонецЕсли;
Прервать;
КонецЕсли;
Если Строка(rs.Fields(iCount).Value) = "" Тогда
СчПустых = СчПустых+1;
Продолжить;
КонецЕсли;
Попытка
лТз[лтз.Количество()-1][iCount]=Строка(rs.Fields(iCount).Value);
ПустыеСтроки = 0;
Исключение
Прервать;
КонецПопытки;
КонецЦикла;
rs.MoveNext();
КонецЦикла;
rs=Неопределено;
еБаза.Close();
еБаза=Неопределено;
УдалитьИзВременногоХранилища(Адрес);
//Удалим первую строку с наименованием колонок
Если лТз[0][0] = лТз.Колонки[0].Имя Тогда
лТз.Удалить(лТз[0]);
КонецЕсли;
Возврат лТз;
КонецФункции