Имя: Пароль:
1C
1С v8
чтение ексель с помощью ADODB.Connection
0 serg-lom89
 
10.10.18
12:17
ДОбрый день уважаемые!
Прошу помощи
делаю обработку чтение ексель с помощью ADODB.Connection


    ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВременногоХранилища);
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла(".xls");
    
    ДвоичныеДанные.Записать(ИмяВременногоФайла);
    //
    ТЗПрочитанныеДанные = Новый ТаблицаЗначений;
    Для Каждого КлючИЗначение из СтруктураКолонок Цикл
        Если КлючИЗначение.Значение = 0 тогда
            СтруктураКолонок.Удалить(КлючИЗначение.Ключ);
            Продолжить;   // Дополнительная Проверка
        КонецЕсли;
        
        ТЗПрочитанныеДанные.Колонки.Добавить(КлючИЗначение.Ключ);
    КонецЦикла;
    
    СтрокаСоединения = "
    |Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+СокрЛП(ИмяВременногоФайла)+";
    |Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""";    
    
    Соединение = Новый COMОбъект("ADODB.Connection");    
    Попытка        
        Соединение.Open(СтрокаСоединения);                  
    Исключение      
        Ошибка = ОписаниеОшибки();
        УдалитьФайлы(ИмяВременногоФайла);
        Сообщить("При открытии приложения: " + Ошибка);
        Возврат Неопределено;
    КонецПопытки;
    
    НаименованиеЛиста = "Лист"+СокрЛП(НомерЛиста);//тут надо что бы по умолчанию щел лист с наименованием Лист1

    ТекстЗапроса = "SELECT * FROM `" + НаименованиеЛиста + "$A1:IV` ";

    
    ADODBRecordset = Новый COMОбъект("ADODB.Recordset");                  
    Попытка
        ADODBRecordset.Open(ТекстЗапроса, Соединение);
    Исключение
        Ошибка = ОписаниеОшибки();
        УдалитьФайлы(ИмяВременногоФайла);
        Сообщить("При чтении файла : " + Ошибка);
        Возврат Неопределено;
    КонецПопытки;       
    
    
    КолвоКолонокExcel = ADODBRecordset.Fields.Count;
    
    НомерСтроки = 0;
    Если не номерСтроки =0 тогда
        НомерСтроки =НомерПервойСтроки;    
    КонецЕсли;
    
    ТекСтрока = НомерПервойСтроки;
    //////обойдем наш лист ексель
    НомерСтроки = 0;
    
    НачСтрока =  НомерПервойСтроки;
    
    
    НомерСтроки = 1;
    
    Пока НЕ ADODBRecordset.EOF  Цикл    

        ADODBRecordset.MoveNext();   // Следующая строка.
    КонецЦикла;


и почему то когда в екселе только одна строчка то у меня не считывает этот файл?
что не так?
1 shuhard
 
10.10.18
12:29
(0)[почему то] - сам просишь не читать и почему

HDR=Yes
2 serg-lom89
 
10.10.18
12:38
(1) спасибо тебе.
Вопрос мож не к месту но как обойти этот лист ,
как по ячейкам как через ексель?
3 serg-lom89
 
10.10.18
12:39
т.е. получить строку по индекму и колонку по индексу
4 serg-lom89
 
10.10.18
12:56
и может кто знает как указать в запросе подключения что бы считывание происходило из нужной мне строки?
5 d4rkmesa
 
10.10.18
13:00
(2) Грузите содержимое в ТЗ и делайте с ней что хотите.
6 d4rkmesa
 
10.10.18
13:01
Как вариант, если 8.3, то открывать xls через табличный документ и работать уже с ним.
7 serg-lom89
 
10.10.18
13:03
(5) а как програмно его сразу в тз загнать можно?
8 d4rkmesa
 
10.10.18
13:09
(7) Только вручную. Копипаста в помощь:
http://catalog.mista.ru/public/163640/
9 Cyberhawk
 
10.10.18
13:11
Если файл xlsx, то все кроме "нативного" его чтения - УГ
10 serg-lom89
 
10.10.18
14:17
(8) че то условие то не отрабатывает которое в статье указано(
что бы считывало по номеру строки указаной
11 Cool_Profi
 
10.10.18
14:21
(9) Если угой считать то, что нативное чтение на пару порядков медленней - то согласен
12 serg-lom89
 
10.10.18
14:25
Функция ПолучитьТаблицуЗначенийИзЭксельЧерезADO(АдресВременногоХранилища, СтруктураКолонок, НомерЛиста = 1, НомерПервойСтроки = 0) экспорт
    
    
    ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВременногоХранилища);
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла(".xls");
    
    ДвоичныеДанные.Записать(ИмяВременногоФайла);
    //
    ТЗПрочитанныеДанные = Новый ТаблицаЗначений;
    Для Каждого КлючИЗначение из СтруктураКолонок Цикл
        Если КлючИЗначение.Значение = 0 тогда
            СтруктураКолонок.Удалить(КлючИЗначение.Ключ);
            Продолжить;   // Дополнительная Проверка
        КонецЕсли;
        
        ТЗПрочитанныеДанные.Колонки.Добавить(КлючИЗначение.Ключ);
    КонецЦикла;
    
    СтрокаСоединения = "
    |Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+СокрЛП(ИмяВременногоФайла)+";
    |Extended Properties=""Excel 8.0;HDR=NO;IMEX=1""";    
    
    Соединение = Новый COMОбъект("ADODB.Connection");    
    Попытка        
        Соединение.Open(СтрокаСоединения);                  
    Исключение      
        Ошибка = ОписаниеОшибки();
        УдалитьФайлы(ИмяВременногоФайла);
        Сообщить("При открытии приложения: " + Ошибка);
        Возврат Неопределено;
    КонецПопытки;
    
    НаименованиеЛиста = "Лист"+СокрЛП(НомерЛиста);//тут надо что бы по умолчанию щел лист с наименованием Лист1

    ТекстЗапроса = "SELECT * FROM `" + НаименованиеЛиста + "$A1:IV` ";

    
    ADODBRecordset = Новый COMОбъект("ADODB.Recordset");                  
    Попытка
        ADODBRecordset.Open(ТекстЗапроса, Соединение);
    Исключение
        Ошибка = ОписаниеОшибки();
        УдалитьФайлы(ИмяВременногоФайла);
        Сообщить("При чтении файла : " + Ошибка);
        Возврат Неопределено;
    КонецПопытки;       
    
    
    КолвоКолонокExcel = ADODBRecordset.Fields.Count;
    
      
    НомерСтроки = 0;
    Пока ADODBRecordset.EOF() = 0 Цикл
        
        НомерСтроки = НомерСтроки + 1;
        
        Если НомерСтроки <  НомерПервойСтроки Тогда    // Номер строки вне диапазона считываемых строк.
            ADODBRecordset.MoveNext();             // Следующая строка.
            Продолжить;
        КонецЕсли;
        
        
        
        СтрокаТаблицыЗначений = ТЗПрочитанныеДанные.Добавить();    
        
        Для каждого КлючИЗначение из СтруктураКолонок Цикл
            СтрокаТаблицыЗначений[КлючИЗначение.Ключ] = ADODBRecordset.Fields.Item(КлючИЗначение.Значение-1).Value;///РабочийЛист.Cells(ТекСтрока, КлючИЗначение.Значение).Value;
        КонецЦикла;
        ADODBRecordset.MoveNext();   // Следующая строка.
    КонецЦикла;
    
    
    возврат ТЗПрочитанныеДанные;
    
    
КонецФункции

вот моя функция...но почему то если передовать в нее ,номер строки, с какой хочу считать ,то не отрабатывает..
может я туплю(просто прощу разьяснить в чем у меня затык и что не так я делаю)
13 serg-lom89
 
10.10.18
14:28
сорян,там ошибка

Функция ПолучитьТаблицуЗначенийИзЭксельЧерезADO(АдресВременногоХранилища, СтруктураКолонок, НомерЛиста = 1, НомерПервойСтроки = 0) экспорт
    
    
    ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВременногоХранилища);
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла(".xls");
    
    ДвоичныеДанные.Записать(ИмяВременногоФайла);
    //
    ТЗПрочитанныеДанные = Новый ТаблицаЗначений;
    Для Каждого КлючИЗначение из СтруктураКолонок Цикл
        Если КлючИЗначение.Значение = 0 тогда
            СтруктураКолонок.Удалить(КлючИЗначение.Ключ);
            Продолжить;   // Дополнительная Проверка
        КонецЕсли;
        
        ТЗПрочитанныеДанные.Колонки.Добавить(КлючИЗначение.Ключ);
    КонецЦикла;
    
    СтрокаСоединения = "
    |Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+СокрЛП(ИмяВременногоФайла)+";
    |Extended Properties=""Excel 8.0;HDR=NO;IMEX=1""";    
    
    Соединение = Новый COMОбъект("ADODB.Connection");    
    Попытка        
        Соединение.Open(СтрокаСоединения);                  
    Исключение      
        Ошибка = ОписаниеОшибки();
        УдалитьФайлы(ИмяВременногоФайла);
        Сообщить("При открытии приложения: " + Ошибка);
        Возврат Неопределено;
    КонецПопытки;
    
    НаименованиеЛиста = "Лист"+СокрЛП(НомерЛиста);//тут надо что бы по умолчанию щел лист с наименованием Лист1

    ТекстЗапроса = "SELECT * FROM `" + НаименованиеЛиста + "$A1:IV` ";

    
    ADODBRecordset = Новый COMОбъект("ADODB.Recordset");                  
    Попытка
        ADODBRecordset.Open(ТекстЗапроса, Соединение);
    Исключение
        Ошибка = ОписаниеОшибки();
        УдалитьФайлы(ИмяВременногоФайла);
        Сообщить("При чтении файла : " + Ошибка);
        Возврат Неопределено;
    КонецПопытки;       
    
    
    КолвоКолонокExcel = ADODBRecordset.Fields.Count;
    
      
    НомерСтроки = 1;
    Пока ADODBRecordset.EOF() = 0 Цикл
        
        НомерСтроки = НомерСтроки + 1;
        
        Если НомерСтроки <  НомерПервойСтроки Тогда    // Номер строки вне диапазона считываемых строк.
            ADODBRecordset.MoveNext();             // Следующая строка.
            Продолжить;
        КонецЕсли;
        
        
        
        СтрокаТаблицыЗначений = ТЗПрочитанныеДанные.Добавить();    
        
        Для каждого КлючИЗначение из СтруктураКолонок Цикл
            СтрокаТаблицыЗначений[КлючИЗначение.Ключ] = ADODBRecordset.Fields.Item(КлючИЗначение.Значение-1).Value;///РабочийЛист.Cells(ТекСтрока, КлючИЗначение.Значение).Value;
        КонецЦикла;
        ADODBRecordset.MoveNext();   // Следующая строка.
    КонецЦикла;
    
    
    возврат ТЗПрочитанныеДанные;
    
    
КонецФункции


вот "правильная" моя ф-ция
14 Cyberhawk
 
10.10.18
15:03
(11) Так если не Винда, то какие альтернативы?
15 shuhard
 
10.10.18
15:08
(4)[как указать в запросе подключения что бы считывание происходило из нужной мне строки?]
https://support.microsoft.com/ru-ru/help/278973/excelado-demonstrates-how-to-use-ado-to-read-and-write-data-in-excel-w

Select * from [Sheet1$A1:B10]
16 shuhard
 
10.10.18
15:09
17 d4rkmesa
 
10.10.18
15:10
(13) Дык, если вы все-таки по-своему делаете, кто за вас это отладит? Я предлагал просто скопипастить процедуру.
18 serg-lom89
 
10.10.18
15:32
да уже разобрался..
счас вопрос задать чтение именно по определенному листу?
19 serg-lom89
 
10.10.18
15:32
номеру листа точнее
20 shuhard
 
10.10.18
15:42
(19) что-то в (15) не так ?
21 serg-lom89
 
10.10.18
15:45
(20) там обращение же по имени листа,а не по номеру его
22 serg-lom89
 
10.10.18
15:45
как я понял
23 Cool_Profi
 
10.10.18
15:46
(21) Sheet<1> - это не номер?
24 serg-lom89
 
10.10.18
15:49
(23) как я понимаю запрос должен быть тогда таким?
    ТекстЗапроса = "SELECT * FROM [Sheet1$]";
25 serg-lom89
 
10.10.18
15:54
(24) просто при таком запросе у меня ошибка почему(
26 _stay true_
 
10.10.18
16:38
Немного боянисто:

Читаешь файл эксель средствами платформы, получаешь на выходе таблицу значений и дальше делаешь с ней что хочешь.

6 строк кода

MXL=Новый ТабличныйДокумент;
MXL.Прочитать(АдресФайла);    
Построитель=Новый ПостроительОтчета;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(MXL.Область(1, 1, MXL.ВысотаТаблицы, MXL.ШиринаТаблицы));
Построитель.Выполнить();
ТЗ = Построитель.Результат.Выгрузить();
27 _stay true_
 
10.10.18
16:40
И, кстати, можно передать строку и колонку, с которой читать и ограничение
28 shuhard
 
10.10.18
17:06
(21)[а не по номеру его]
нужен номер в коллекции - определи его через ADOX