Вопрос: Как делать в 1Сv8 SQL запросы к COM Объекту ?( Excel)? Кто нибудь делал?
06.04.2009
19:14
#1
Добрый день!
Возникла проблема. Я сделал выгрузку из Excel в 1С8. Выгрузилось, но при выборочной проверке выяснилось, что выгрузка получилось некорректной. Объем строк в Excel более 14000. 4 Столбца. Итого получается, что надо проверить 56000 ячеек. Это трудно.
Возникла тогда у меня идея сделать программу проверки выгрузки. То есть находт в 1С документ, ищет его в Excel (путем перебора! ) и ставит 1 если нашла. Не нашла- ничего не ставит.
Всё бы хорошо, да долго. Перебор значений с критерием по трем столбцам занимает мн-о-о-о-го времени. Дня так по моим подсчетам два. Два дня. А время не терпит.
Тогда то дошло до меня, что запрос быстрее. Суть запроса- выбрать сразу например некую область из Excel Range(А1:D14000) но фига не понимаю как обращаться к Com объекту! То есть простую вещь перебором цикла ДокЭксель.Sheets(1).Cells (n,7).Value (где n переменная) я понимаю. А чуть сложнее....увы.
Кто нибудь подскажет?
Возникла проблема. Я сделал выгрузку из Excel в 1С8. Выгрузилось, но при выборочной проверке выяснилось, что выгрузка получилось некорректной. Объем строк в Excel более 14000. 4 Столбца. Итого получается, что надо проверить 56000 ячеек. Это трудно.
Возникла тогда у меня идея сделать программу проверки выгрузки. То есть находт в 1С документ, ищет его в Excel (путем перебора! ) и ставит 1 если нашла. Не нашла- ничего не ставит.
Всё бы хорошо, да долго. Перебор значений с критерием по трем столбцам занимает мн-о-о-о-го времени. Дня так по моим подсчетам два. Два дня. А время не терпит.
Тогда то дошло до меня, что запрос быстрее. Суть запроса- выбрать сразу например некую область из Excel Range(А1:D14000) но фига не понимаю как обращаться к Com объекту! То есть простую вещь перебором цикла ДокЭксель.Sheets(1).Cells (n,7).Value (где n переменная) я понимаю. А чуть сложнее....увы.
Кто нибудь подскажет?
06.04.2009
22:56
#2
"можно через АДО только смысла нет - все равно цикл рекордсета придется перебирать
попробуй этот способ надеюсь разберешься ((((
Процедура Кнопка1Нажатие(Элемент)
ПутьКФайлу = "C:\Files\Обмен1с\Nomenklatura.xls";
попытка
Ексель = Новый COMОбъект("Excel.Application") ;
исключение
Сообщить(ОписаниеОшибки());
Сообщить("Не удалось инициализировать Excel");
Возврат;
КонецПопытки;
//..................................................
попытка
ФайлЕксель = Ексель.Workbooks.Open(ПутьКФайлу);
//..............................................
КС = Новый КвалификаторыСтроки(250);
Массив = Новый Массив;
Массив.Добавить(Тип("Строка"));
ОписаниеТиповС = Новый ОписаниеТипов(Массив, , КС);
//----будем считать что все данные в Эксель типа Строка---
ТЗ =Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Колонка1",ОписаниеТиповС);
ТЗ.Колонки.Добавить("Колонка2",ОписаниеТиповС);
ТЗ.Колонки.Добавить("Колонка3",ОписаниеТиповС);
ТЗ.Колонки.Добавить("Колонка4",ОписаниеТиповС);
//-----и сравнивать их будем тоже со строкой--------------------
ТЗДокументы =Новый ТаблицаЗначений;
ТЗДокументы.Колонки.Добавить("Номер",ОписаниеТиповС);
ТЗДокументы.Колонки.Добавить("Организация",ОписаниеТиповС);
ТЗДокументы.Колонки.Добавить("Контрагент",ОписаниеТиповС);
ТЗДокументы.Колонки.Добавить("Склад",ОписаниеТиповС);
Колонки =1;
Строки =2; //заголовок не берем
КоличествоСтраниц = 1;
ТекНомерЛиста =1;
//сколько непустых строк
ВсегоКоличестовСтрок = Ексель.Sheets(ТекНомерЛиста).UsedRange.row + Ексель.Sheets(ТекНомерЛиста).UsedRange.Rows.Count - 1;
//сколько непустых колонок
//ВсегоКоличестовКолонок = Ексель.Sheets(ТекНомер).UsedRange.Column + Ексель.Sheets(ТекНомер).UsedRange.Columns.Count - 1
для строки = 2 по ВсегоКоличестовСтрок цикл
//или
//Пока Ексель.Sheets(ТекНомер).Cells(Строки,1).Value <> Неопределено Цикл
НовСтрока =ТЗ.Добавить();
НовСтрока.Колонка1 = Ексель.Sheets(ТекНомерЛиста).Cells(Строки,Колонки ).Value;
НовСтрока.Колонка2 = Ексель.Sheets(ТекНомерЛиста).Cells(Строки,Колонки +1).Value;
НовСтрока.Колонка3 = Ексель.Sheets(ТекНомерЛиста).Cells(Строки,Колонки +2).Value;
НовСтрока.Колонка4 = Ексель.Sheets(ТекНомерЛиста).Cells(Строки,Колонки +3).Value;
КонецЦикла;
//-------------------------------------------------------------------
МенеджерВТ =новый МенеджерВременныхТаблиц;
Запрос =Новый Запрос;
Запрос.МенеджерВременныхТаблиц =МенеджерВТ;
Запрос.Текст = "ВЫБРАТЬ Колонка1,колонка2,колонка3,колонка4
| ПОМЕСТИТЬ ВременнаяТаблицаЭксель
| ИЗ
| &ВнешнийИсточник как ВнешнийИсточник
|";
Запрос.УстановитьПараметр("ВнешнийИсточник",ТЗ);
Запрос.Выполнить();
//----приводим все данные документов к строке т.к в запросе это сделать нельзя--------
Запрос.Текст ="ВЫБРАТЬ
| Представление(ПоступлениеТоваровУслуг.Номер) как Номер ,
| Представление(ПоступлениеТоваровУслуг.Организация) как Организация,
| Представление(ПоступлениеТоваровУслуг.Контрагент) как Контрагент ,
| Представление(ПоступлениеТоваровУслуг.Склад) как Склад
| ИЗ
| Документ.ПоступлениеТоваровУслуг как ПоступлениеТоваровУслуг
|";
выборка = Запрос.Выполнить().Выбрать();
Пока выборка.Следующий() цикл
НовСтрока= ТЗДокументы.Добавить();
НовСтрока.Номер =Строка(выборка.Номер);
НовСтрока.Организация =Строка(выборка.Организация);
НовСтрока.Контрагент =Строка(выборка.Контрагент);
НовСтрока.Склад =Строка(выборка.Склад);
КонецЦикла;
//-------------------------------------------------------------
Запрос.Текст = "ВЫБРАТЬ Номер,Организация,Контрагент,Склад
| ПОМЕСТИТЬ ВременнаяТаблицаДокументы
| ИЗ
| &ВнешнийИсточникДокументы как ВнешнийИсточникДокументы
|";
Запрос.УстановитьПараметр("ВнешнийИсточникДокументы",ТЗДокументы);
Запрос.Выполнить();
//----соедиянем таблицы там где ВТ.Колонка1 будет NULL значит этих документов нет в Эксель--
//--запрос можно перевернуть и проверить что есть в Эксель и чего нет в 1 с
//| ИЗ ВременнаяТаблицаЭксель как ВТ
//|ЛЕВОЕ СОЕДИНЕНИЕ
//| ВременнаяТаблицаДокументы как ВТД
//
Запрос.Текст ="ВЫБРАТЬ
|ВТД.Номер,
|ВТД.Организация,
|ВТД.Контрагент,
|ВТД.Склад ,
| ВТ.Колонка1,
| ВТ.Колонка2,
| ВТ.Колонка3 ,
| ВТ.Колонка4
| ИЗ ВременнаяТаблицаДокументы как ВТД
|ЛЕВОЕ СОЕДИНЕНИЕ
| ВременнаяТаблицаЭксель как ВТ
| ПО
| ВТД.НОМЕР = ВТ.Колонка1 И
| ВТД.Организация = ВТ.Колонка2 И
| ВТД.Контрагент = ВТ.Колонка3 И
| ВТД.Склад = ВТ.Колонка4
| ГДЕ ВТ.Колонка1 ЕСТЬ NULL
|
|";
//--------------------------------------------------------------------
Список= Запрос.Выполнить().Выгрузить();
Список.ВыбратьСтроку();
//Пока выборка.Следующий() цикл
// Сообщить(выборка.Организация) ;
//конецЦикла;
исключение
Сообщить(ОписаниеОшибки());
Ексель.Application.Quit();
конецПопытки;
КонецПроцедуры
"
попробуй этот способ надеюсь разберешься ((((
Процедура Кнопка1Нажатие(Элемент)
ПутьКФайлу = "C:\Files\Обмен1с\Nomenklatura.xls";
попытка
Ексель = Новый COMОбъект("Excel.Application") ;
исключение
Сообщить(ОписаниеОшибки());
Сообщить("Не удалось инициализировать Excel");
Возврат;
КонецПопытки;
//..................................................
попытка
ФайлЕксель = Ексель.Workbooks.Open(ПутьКФайлу);
//..............................................
КС = Новый КвалификаторыСтроки(250);
Массив = Новый Массив;
Массив.Добавить(Тип("Строка"));
ОписаниеТиповС = Новый ОписаниеТипов(Массив, , КС);
//----будем считать что все данные в Эксель типа Строка---
ТЗ =Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Колонка1",ОписаниеТиповС);
ТЗ.Колонки.Добавить("Колонка2",ОписаниеТиповС);
ТЗ.Колонки.Добавить("Колонка3",ОписаниеТиповС);
ТЗ.Колонки.Добавить("Колонка4",ОписаниеТиповС);
//-----и сравнивать их будем тоже со строкой--------------------
ТЗДокументы =Новый ТаблицаЗначений;
ТЗДокументы.Колонки.Добавить("Номер",ОписаниеТиповС);
ТЗДокументы.Колонки.Добавить("Организация",ОписаниеТиповС);
ТЗДокументы.Колонки.Добавить("Контрагент",ОписаниеТиповС);
ТЗДокументы.Колонки.Добавить("Склад",ОписаниеТиповС);
Колонки =1;
Строки =2; //заголовок не берем
КоличествоСтраниц = 1;
ТекНомерЛиста =1;
//сколько непустых строк
ВсегоКоличестовСтрок = Ексель.Sheets(ТекНомерЛиста).UsedRange.row + Ексель.Sheets(ТекНомерЛиста).UsedRange.Rows.Count - 1;
//сколько непустых колонок
//ВсегоКоличестовКолонок = Ексель.Sheets(ТекНомер).UsedRange.Column + Ексель.Sheets(ТекНомер).UsedRange.Columns.Count - 1
для строки = 2 по ВсегоКоличестовСтрок цикл
//или
//Пока Ексель.Sheets(ТекНомер).Cells(Строки,1).Value <> Неопределено Цикл
НовСтрока =ТЗ.Добавить();
НовСтрока.Колонка1 = Ексель.Sheets(ТекНомерЛиста).Cells(Строки,Колонки ).Value;
НовСтрока.Колонка2 = Ексель.Sheets(ТекНомерЛиста).Cells(Строки,Колонки +1).Value;
НовСтрока.Колонка3 = Ексель.Sheets(ТекНомерЛиста).Cells(Строки,Колонки +2).Value;
НовСтрока.Колонка4 = Ексель.Sheets(ТекНомерЛиста).Cells(Строки,Колонки +3).Value;
КонецЦикла;
//-------------------------------------------------------------------
МенеджерВТ =новый МенеджерВременныхТаблиц;
Запрос =Новый Запрос;
Запрос.МенеджерВременныхТаблиц =МенеджерВТ;
Запрос.Текст = "ВЫБРАТЬ Колонка1,колонка2,колонка3,колонка4
| ПОМЕСТИТЬ ВременнаяТаблицаЭксель
| ИЗ
| &ВнешнийИсточник как ВнешнийИсточник
|";
Запрос.УстановитьПараметр("ВнешнийИсточник",ТЗ);
Запрос.Выполнить();
//----приводим все данные документов к строке т.к в запросе это сделать нельзя--------
Запрос.Текст ="ВЫБРАТЬ
| Представление(ПоступлениеТоваровУслуг.Номер) как Номер ,
| Представление(ПоступлениеТоваровУслуг.Организация) как Организация,
| Представление(ПоступлениеТоваровУслуг.Контрагент) как Контрагент ,
| Представление(ПоступлениеТоваровУслуг.Склад) как Склад
| ИЗ
| Документ.ПоступлениеТоваровУслуг как ПоступлениеТоваровУслуг
|";
выборка = Запрос.Выполнить().Выбрать();
Пока выборка.Следующий() цикл
НовСтрока= ТЗДокументы.Добавить();
НовСтрока.Номер =Строка(выборка.Номер);
НовСтрока.Организация =Строка(выборка.Организация);
НовСтрока.Контрагент =Строка(выборка.Контрагент);
НовСтрока.Склад =Строка(выборка.Склад);
КонецЦикла;
//-------------------------------------------------------------
Запрос.Текст = "ВЫБРАТЬ Номер,Организация,Контрагент,Склад
| ПОМЕСТИТЬ ВременнаяТаблицаДокументы
| ИЗ
| &ВнешнийИсточникДокументы как ВнешнийИсточникДокументы
|";
Запрос.УстановитьПараметр("ВнешнийИсточникДокументы",ТЗДокументы);
Запрос.Выполнить();
//----соедиянем таблицы там где ВТ.Колонка1 будет NULL значит этих документов нет в Эксель--
//--запрос можно перевернуть и проверить что есть в Эксель и чего нет в 1 с
//| ИЗ ВременнаяТаблицаЭксель как ВТ
//|ЛЕВОЕ СОЕДИНЕНИЕ
//| ВременнаяТаблицаДокументы как ВТД
//
Запрос.Текст ="ВЫБРАТЬ
|ВТД.Номер,
|ВТД.Организация,
|ВТД.Контрагент,
|ВТД.Склад ,
| ВТ.Колонка1,
| ВТ.Колонка2,
| ВТ.Колонка3 ,
| ВТ.Колонка4
| ИЗ ВременнаяТаблицаДокументы как ВТД
|ЛЕВОЕ СОЕДИНЕНИЕ
| ВременнаяТаблицаЭксель как ВТ
| ПО
| ВТД.НОМЕР = ВТ.Колонка1 И
| ВТД.Организация = ВТ.Колонка2 И
| ВТД.Контрагент = ВТ.Колонка3 И
| ВТД.Склад = ВТ.Колонка4
| ГДЕ ВТ.Колонка1 ЕСТЬ NULL
|
|";
//--------------------------------------------------------------------
Список= Запрос.Выполнить().Выгрузить();
Список.ВыбратьСтроку();
//Пока выборка.Следующий() цикл
// Сообщить(выборка.Организация) ;
//конецЦикла;
исключение
Сообщить(ОписаниеОшибки());
Ексель.Application.Quit();
конецПопытки;
КонецПроцедуры
"
07.04.2009
00:11
#3
"через адо так
ПутьКФайлу = "C:\Files\Обмен1с\Nomenklatura.xls";
попытка
ЭксельСоединение = Новый COMОбъект("ADODB.Connection") ;
ЭксельСоединение.Open("Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + ПутьКФайлу + ";" +"Extended Properties=""""Excel 8.0;HDR=Yes;mode =Write""""");
исключение
Сообщить(ОписаниеОшибки());
Сообщить("Не удалось инициализировать Excel");
Возврат;
КонецПопытки;
Команда = Новый COMОбъект("ADODB.Command");
Команда.ActiveConnection = ЭксельСоединение;
Команда.CommandText = "select * from [Лист1$]" ;
Команда.CommandType = 1;
Рекордсет = Новый COMОбъект("ADODB.Recordset");
Рекордсет = Команда.Execute();
//Пока Рекордсет.EOF = 0 Цикл
// Для НомерСтолбца = 0 По Рекордсет.Fields.Count - 1 Цикл
// Сообщить (Рекордсет.Fields(НомерСтолбца).Value);
// КонецЦикла;
// Рекордсет.MoveNext();
//КонецЦикла;
Поле1 ="Колонка1";
Поле2 ="Колонка2";
Поле3 ="Колонка3";
Поле4 ="Колонка4";
Значение1="ТПК00000007";
Значение2="Торгово-производственная компания";
Значение3="ГлПоставщик";
Значение4="Склад1";
//гоняем фильтр рекордсета и можно в цикле
Рекордсет.Filter = """" + Поле1 + " like '" + Значение1 +"'" + " And " +
Поле2 +" like '" + Значение2 + "'" + " And " +
Поле3 + " like '" +Значение3 + "'" + " And " +
Поле4 + " like '" +Значение4 + "'" ;
//если не возвращается ни одна строка
Если Рекордсет.BOF = Истина Тогда
сообщить("не найдено");
Иначе
Сообщить(Рекордсет.Fields(Поле1).Value);
КонецЕсли;
Рекордсет.Close();
ЭксельСоединение.Close();
КонецПроцедуры
"
ПутьКФайлу = "C:\Files\Обмен1с\Nomenklatura.xls";
попытка
ЭксельСоединение = Новый COMОбъект("ADODB.Connection") ;
ЭксельСоединение.Open("Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + ПутьКФайлу + ";" +"Extended Properties=""""Excel 8.0;HDR=Yes;mode =Write""""");
исключение
Сообщить(ОписаниеОшибки());
Сообщить("Не удалось инициализировать Excel");
Возврат;
КонецПопытки;
Команда = Новый COMОбъект("ADODB.Command");
Команда.ActiveConnection = ЭксельСоединение;
Команда.CommandText = "select * from [Лист1$]" ;
Команда.CommandType = 1;
Рекордсет = Новый COMОбъект("ADODB.Recordset");
Рекордсет = Команда.Execute();
//Пока Рекордсет.EOF = 0 Цикл
// Для НомерСтолбца = 0 По Рекордсет.Fields.Count - 1 Цикл
// Сообщить (Рекордсет.Fields(НомерСтолбца).Value);
// КонецЦикла;
// Рекордсет.MoveNext();
//КонецЦикла;
Поле1 ="Колонка1";
Поле2 ="Колонка2";
Поле3 ="Колонка3";
Поле4 ="Колонка4";
Значение1="ТПК00000007";
Значение2="Торгово-производственная компания";
Значение3="ГлПоставщик";
Значение4="Склад1";
//гоняем фильтр рекордсета и можно в цикле
Рекордсет.Filter = """" + Поле1 + " like '" + Значение1 +"'" + " And " +
Поле2 +" like '" + Значение2 + "'" + " And " +
Поле3 + " like '" +Значение3 + "'" + " And " +
Поле4 + " like '" +Значение4 + "'" ;
//если не возвращается ни одна строка
Если Рекордсет.BOF = Истина Тогда
сообщить("не найдено");
Иначе
Сообщить(Рекордсет.Fields(Поле1).Value);
КонецЕсли;
Рекордсет.Close();
ЭксельСоединение.Close();
КонецПроцедуры
"
Бухгалтерия 8.1 ред 1.6 как сформировать сводную регламентированную отчетностьУчёт материалов с привязкой к сотруднику
Читают тему
(гостей: 1)