Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
13 дек 2024, 15:08

Помогите разобраться с ADO и Excel

Автор beztrud, 19 июн 2014, 23:26

0 Пользователей и 1 гость просматривают эту тему.

beztrud

Здравствуйте! 1с 8.3 самописная, Такси. Пробую в обработке грузить данные из экселя через ADO

&НаКлиенте
Процедура ФайлНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ВыборФайла.ПроверятьСуществованиеФайла = Истина;
ВыборФайла.Фильтр = "Excel (*.xlsx; *.xls)|*.xlsx; *.xls";
ВыборФайла.МножественныйВыбор = Ложь;
Если НЕ ВыборФайла.Выбрать() Тогда
        ПоказатьПредупреждение(,"Файлы не выбраны", 5,"Внимание!");
Возврат
КонецЕсли;
Объект.Вычисления.Очистить();
НайтиФайл = ВыборФайла.ВыбранныеФайлы[0];
Объект.Файл=НайтиФайл;
СтрокаТабличнойЧасти = Элементы.Вычисления.ТекущиеДанные;
ВыполнитьЗагрузку(СтрокаТабличнойЧасти);
КонецПроцедуры

&НаСервере
Функция ВыполнитьЗагрузку(СтрокаТабличнойЧасти) Экспорт
Connection=Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+Строка(Объект.Файл)+";Extended Properties=""Excel 8.0;HDR=YES;IMEX=1""";
Попытка
Connection.Open(СтрокаПодключения);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
ТекстЗапроса =
"SELECT
|*
|FROM
|    [Лист1$] as Лист";
Выборка = Новый COMОбъект("ADODB.Recordset");
Попытка
Выборка.Open(ТекстЗапроса, Connection);
Исключение
Сообщить ("Проблемы с выполнением запроса");
Возврат Ложь;
КонецПопытки;
Пока НЕ Выборка.EOF() Цикл
    СтрокаТабличнойЧасти=Объект.Вычисления.Добавить();
СтрокаТабличнойЧасти.ЧастьИзделия = Выборка.Fields("Часть изделия").value;
СтрокаТабличнойЧасти.ВысотаФасада = Выборка.Fields("Высота фасада").value;
СтрокаТабличнойЧасти.ШиринаФасада = Выборка.Fields("Ширина фасада").value;
СтрокаТабличнойЧасти.КоличествоФасадов = Выборка.Fields("Количество фасадов").value;
Если СтрокаТабличнойЧасти.КоличествоФасадов = 1 Тогда
СтрокаТабличнойЧасти.Примечание = "глухая";
Иначе
Если СтрокаТабличнойЧасти.КоличествоФасадов >1 И СтрокаТабличнойЧасти.КоличествоФасадов <5 Тогда
СтрокаТабличнойЧасти.Примечание = "глухе";
Иначе
СтрокаТабличнойЧасти.Примечание = "глухих";
КонецЕсли;
КонецЕсли;
СтрокаТабличнойЧасти.КвадратураФасадов = СтрокаТабличнойЧасти.ВысотаФасада*СтрокаТабличнойЧасти.ШиринаФасада*СтрокаТабличнойЧасти.КоличествоФасадов/1000000;
    Выборка.MoveNext();   
КонецЦикла;
Выборка.Close();
КонецФункции


Ругается:
{Обработка.ВычислениеПластика.Форма.Форма.Форма(16)}: Ошибка при вызове метода контекста (ВыполнитьЗагрузку)
ВыполнитьЗагрузку(СтрокаТабличнойЧасти);
по причине:
Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа.
по причине:
Ошибка преобразования данных XDTO:
Запись значения свойства 'param':
   форма: Элемент
   имя: {http://v8.1c.ru/8.2/managed-application/modules}param
по причине:
Ошибка отображения типов:
Отсутствует отображение для типа 'ДанныеФормыЭлементКоллекции'

НО!!! После нажатии "закрыть" все данные находятся в табличной части.
Вопросы:
1)Что нужно описать/дописать, чтобы не выскакивала ошибка
2)Как обратиться к полю в эксель, которое не содержит имени в первой строке, т.е HDR=NO
3)Если файл эксель создан в формате *.xlsx, то тоже ругается
{Обработка.ВычислениеПластика.Форма.Форма.Форма(24)}: Ошибка при вызове метода контекста (Open): Произошла исключительная ситуация (Microsoft JET Database Engine): Внешняя таблица не имеет предполагаемый формат.
Проблемы с выполнением запроса

Заранее благодарю.

Dethmontt

Нельзя этот тип передавать на Сервер ДанныеФормыЭлементКоллекции = ВыполнитьЗагрузку(СтрокаТабличнойЧасти);
Цитата: beztrud от 19 июн 2014, 23:26Как обратиться к полю в эксель, которое не содержит имени в первой строке, т.е HDR=NO
Можно подробнее что надо то???

Цитата: beztrud от 19 июн 2014, 23:26Если файл эксель создан в формате *.xlsx, то тоже ругается
Используй другой драйвер
http://www.connectionstrings.com/excel/
Если долго всматриваться в учебник...то в голову может прийти мысль его открыть!

beztrud

ЦитироватьНельзя этот тип передавать на Сервер ДанныеФормыЭлементКоллекции = ВыполнитьЗагрузку(СтрокаТабличнойЧасти);
А как правильно передать? И почему загрузка данных всё же происходит.

ЦитироватьКак обратиться к полю в эксель, которое не содержит имени в первой строке, т.е HDR=NO
Вот я обращаюсь через Fields("Часть изделия").value Т.е "Часть изделия" это имя Столбца, а если данные начинаются с первой строки и не содержат заголовок "Часть изделия"?

cska-fanat-kz

1. Почему бы не коннектиться к Эксель через
ФайлЭксель = ПолучитьCOMОбъект(ИмяФайла);
тогда не важно XLS или XLSX

2. Вы грузите из Эксель по одной строке? Исключительно не оптимально и долго
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

cska-fanat-kz

к любой ячейке можно обратиться по координатам

ЗначениеЯчейки = ФайлЭксель.Sheets(1).Cells(СчСтроки,Ш).Value;
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

beztrud

Цитата: cska-fanat-kz от 20 июн 2014, 10:43
1. Почему бы не коннектиться к Эксель через
ФайлЭксель = ПолучитьCOMОбъект(ИмяФайла);
тогда не важно XLS или XLSX

2. Вы грузите из Эксель по одной строке? Исключительно не оптимально и долго

Да, так и делал раньше, но вот хотелось бы просвятиться про АДО. Уж больно шустрый говорят. Если кому пригодиться вот код, которым я гружу сейчас.

ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ВыборФайла.ПроверятьСуществованиеФайла = Истина;
ВыборФайла.Фильтр = "Excel (*.xlsx; *.xls)|*.xlsx; *.xls";
ВыборФайла.МножественныйВыбор = Ложь;
Если НЕ ВыборФайла.Выбрать() Тогда
        Предупреждение("Файлы не выбраны");
Возврат
КонецЕсли;
Состояние("Выполняется чтение файла Excel");
НайтиФайл = ВыборФайла.ВыбранныеФайлы[0];
Поле = Строка(НайтиФайл);
Объект.ВыбратьФайл=НайтиФайл;
Объект.Обработка.Очистить();
Попытка
Эксель = Новый COMОбъект("Excel.Application");
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;

Книга = Эксель.WorkBooks.Open(НайтиФайл);
Лист = Книга.WorkSheets(1);
ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column;
ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row;
Для Строка = 1 По ВсегоСтрок Цикл
Состояние("Выполняется загрузка файла Excel",Строка);
СтрокаТабличнойЧасти=Объект.Обработка.Добавить();
СтрокаТабличнойЧасти.ЧастьИзделия=Лист.Cells(Строка,2).Value;
СтрокаТабличнойЧасти.Высота=Лист.Cells(Строка,4).Value;
СтрокаТабличнойЧасти.Высота=СтрокаТабличнойЧасти.Высота;
СтрокаТабличнойЧасти.Ширина=Лист.Cells(Строка,5).Value;
СтрокаТабличнойЧасти.Количество=Лист.Cells(Строка,6).Value;
СтрокаТабличнойЧасти.Примечание=Лист.Cells(Строка,7).Value;


Dethmontt

Цитата: beztrud от 20 июн 2014, 09:42А как правильно передать? И почему загрузка данных всё же происходит.
Не нужно передавать этот тип

1. Создаем реквизит формы Таблица
2. Заполняем ее на клиенте (отключаемся от ADO)
3. Идем на сервер с контекстом
4. На сервере обходим таблицу формы ну и грузим все что нам требуется

5. Все!

Цитата: beztrud от 20 июн 2014, 09:42Вот я обращаюсь через Fields("Часть изделия").value Т.е "Часть изделия" это имя Столбца, а если данные начинаются с первой строки и не содержат заголовок "Часть изделия"?
Так поставь всегда HDR=NO и смотри сам есть там данные или нет (не знаю как ты будешь это проверять)
Если долго всматриваться в учебник...то в голову может прийти мысль его открыть!

cska-fanat-kz

Чем плохо читать ячейки по координатам строки и столбца?

Все что надо это:
1. Начальная строка
2. Количество колонок
3. Признак когда остановиться
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

beztrud

ЦитироватьТак поставь всегда HDR=NO и смотри сам есть там данные или нет (не знаю как ты будешь это проверять)
А как тогда обратиться к Field&

Dethmontt

Зачем вообще знать имена?

Пока НЕ Об_РекордСет.EOF Цикл
                                   // Получаем данные из Об_РекордСет
                                   // ...
                                  Сообщить("");
                                  Для каждого ОБ_Поле Из Об_РекордСет.Fields Цикл
                                     // Пример вывода информации Сообщить(ОБ_Поле.Name,Об_РекордСет.Fields(ОБ_Поле.Name).value);
                                   КонецЦикла;
                                   // ...
                                   Об_РекордСет.MoveNext();
                        КонецЦикла;

Добавлено: 20 июн 2014, 12:28


Изучайте
http://help1c.com/faq8/view/625.html
Если долго всматриваться в учебник...то в голову может прийти мысль его открыть!

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск