Как изменить значения в ячейках таблицы Excel используя технологию ADO
Доброго времени суток, коллеги.
Столкнулась с проблемой.
Нужно заполнить таблицу Excel по некому шаблону (довольно сложные таблицы), Нужно заполнить этот шаблон данными из документа 1С. Файлы большие и ole на некоторых не просто тормозит, а уходит и не возвращается. При помощи ADO все читается на ура. Но нужно внести новые значения в некие позиции, не меняя форматирования и пр. И тут возникает проблема. Читаю все строки листа Excel и в нужные позиции вношу изменения в соотвтетствии с документом. Если без лишних подробностей то код такой:
Смысл всего этого - в 3-ю колонку первой строки пытаюсь записать текст "ТЕСТ ADODB!!!"
Но это не прокатывает. Ошибка "Текущий объект Recordset не поддерживает обновление. Это связано с ограничением поставщика или с выбранным типом блокировки".
Можно пойти от обратного - по данным запроса к документу (например по штрихкоду товара) искать ячейки на листе в которые нужно внести данные, но с запросом UPDATE я не справилась.
Может быть кто-нибудь делал что-либо подобное?
Прошу помощи.
Столкнулась с проблемой.
Нужно заполнить таблицу Excel по некому шаблону (довольно сложные таблицы), Нужно заполнить этот шаблон данными из документа 1С. Файлы большие и ole на некоторых не просто тормозит, а уходит и не возвращается. При помощи ADO все читается на ура. Но нужно внести новые значения в некие позиции, не меняя форматирования и пр. И тут возникает проблема. Читаю все строки листа Excel и в нужные позиции вношу изменения в соотвтетствии с документом. Если без лишних подробностей то код такой:
Connection = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ПутьКФайлу;
СтрокаПодключения = СтрокаПодключения + "; Extended Properties=""Excel 12.0 Xml;HDR=NO"";";
Connection.Open(СтрокаПодключения);
Catalog = Новый COMОбъект("ADOX.Catalog");
Catalog.ActiveConnection = Connection;
Счетчик = 1;
ИмяТаблицы = "";
СписокЛистов = Новый СписокЗначений;
Для Каждого Table ИЗ Catalog.Tables Цикл
Если НомерЛиста = Счетчик Тогда
ИмяТаблицы = Table.Name;
КонецЕсли;
СписокЛистов.Добавить(Table.Name, "Лист " + Счетчик);
Счетчик = Счетчик + 1;
КонецЦикла;
Если ПустаяСтрока(ИмяТаблицы) Тогда
Connection.Close();
Возврат;
Иначе
Command = Новый COMОбъект("ADODB.Command");
RecordSet = Новый COMОбъект("ADODB.RecordSet");
Command.ActiveConnection = Connection;
Command.CommandText = "SEL ECT * FR OM [" + ИмяТаблицы + "]";
Command.CommandType = 1;
RecordSet = Command.Execute();
КоличествоКолонок = RecordSet.Fields.Count;
Счетчик = 1;
Пока НЕ RecordSet.EOF() Цикл
Если Счетчик = 1 Тогда
RecordSet.Fields(2).Value = "ТЕСТ ADODB!!!";
Прервать;
КонецЕсли;
RecordSet.MoveNext();
Счетчик = Счетчик + 1;
КонецЦикла;
КонецЕсли;
Connection.Close();
ПоказатьСмысл всего этого - в 3-ю колонку первой строки пытаюсь записать текст "ТЕСТ ADODB!!!"
Но это не прокатывает. Ошибка "Текущий объект Recordset не поддерживает обновление. Это связано с ограничением поставщика или с выбранным типом блокировки".
Можно пойти от обратного - по данным запроса к документу (например по штрихкоду товара) искать ячейки на листе в которые нужно внести данные, но с запросом UPDATE я не справилась.
Может быть кто-нибудь делал что-либо подобное?
Прошу помощи.
По теме из базы знаний
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1)
В памяти отложилось, что надо тщательно подбирать параметры подключения к ADO, иначе не работает. Вот рабочий кусочек кода, задача решалась еще для 7.7, но думаю, что будет понятно:
Сразу видно главное отличие: Mode=ReadWrite, ну и IMEX=0, хотя вот он уже не помню, на что влияет.
Может быть кто-нибудь делал что-либо подобное?
Приходилось - самописная выгрузка квитанций ЖКХ для последующей загрузки в ГИС. Там надо было сформировать большую таблицу XLS по шаблону, то есть берется файл с заголовками и в него дописывается куча строчек с данными.
В памяти отложилось, что надо тщательно подбирать параметры подключения к ADO, иначе не работает. Вот рабочий кусочек кода, задача решалась еще для 7.7, но думаю, что будет понятно:
Connection=СоздатьОбъект("ADODB.Connection");
Connection.ConnectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source="+ИмяФайла+";Mode=ReadWrite;Extended Properties=""Excel 12.0;HDR=NO;IMEX=0;""";
Connection.Mode=3;
Connection.Open();
(3) Ну, я же говорю - c параметрами надо шаманить, и не только строки подключения - Connection.Mode, RecordSet.CursorType и т.д
Поэтому просто приведу немного больше моего кода - подключение к файлу и прогон до конца строк заголовка:
Дальше там только добавление и заполнение новых строк:
И обратите внимание: изменение значений заканчивается RecordSe t1.Update(), чего я у вас не наблюдаю.
Поэтому просто приведу немного больше моего кода - подключение к файлу и прогон до конца строк заголовка:
Connection=СоздатьОбъект("ADODB.Connection");
Connection.ConnectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source="+ИмяФайла+";Mode=ReadWrite;Extended Properties=""Excel 12.0;HDR=NO;IMEX=0;""";
Connection.Mode=3;
Connection.Open();
RecordSet1=СоздатьОбъект("ADODB.RecordSet");
RecordSet1.ActiveConnection=Connection;
RecordSet1.CursorType = 3;
RecordSet1.CursorLocation=3;
RecordSet1.LockType=3;
RecordSet1.Source="SEL ECT * FR OM [Раздел 1$]";
RecordSet1.Open();
нПерваяСтр1=2;
Если (RecordSet1.EOF=0) ИЛИ (RecordSet1.BOF=0) Тогда
RecordSet1.MoveFirst();
КонецЕсли;
нСтр1=0;
Пока RecordSet1.EOF=0 Цикл
Если нСтр1>=нПерваяСтр1 Тогда
Прервать;
КонецЕсли;
RecordSet1.MoveNext();
нСтр1=нСтр1+1;
КонецЦикла;
ПоказатьДальше там только добавление и заполнение новых строк:
Если RecordSet1.EOF<>0 Тогда
RecordSet1.AddNew();
КонецЕсли;
нСтр1=нСтр1+1;
RecordSet1.Fields(0).Value=ИдентЖКУ;
RecordSet1.Fields(1).Value="Текущий";
RecordSet1.Fields(2).Value=НомерПД;
RecordSet1.Fields(21).Value=СокрЛП(Константа.ОГРН);
RecordSet1.Fields(22).Value=Константа.КПП;
RecordSet1.Upd ate();
ПоказатьИ обратите внимание: изменение значений заканчивается RecordSe t1.Update(), чего я у вас не наблюдаю.
(5)
Эти манипуляции тоже не помогли. Глючит, как и прежде на строке
RecordSet.Fields(0).Value = "!ТЕСТ ADODB!";
Насчет RecordSe t1.Update() Вы правы. Добавила, но до этого не доходит.
RecordSet1.ActiveConnection=Connection;
RecordSet1.CursorType = 3;
RecordSet1.CursorLocation=3;
RecordSet1.LockType=3;
RecordSet1.CursorType = 3;
RecordSet1.CursorLocation=3;
RecordSet1.LockType=3;
Эти манипуляции тоже не помогли. Глючит, как и прежде на строке
RecordSet.Fields(0).Value = "!ТЕСТ ADODB!";
Насчет RecordSe t1.Update() Вы правы. Добавила, но до этого не доходит.
(6)
Или драйвер ADO вообще не тот - может, надо использовать не ACE, а Jet:https://infostart.ru/1c/articles/163640/
Смутно помнится, что где-то в подобной задаче выбор драйвера делал программно (в коде), а от чего он зависел - уже не помню, кажется от формата файла: XLS или XLSX. Точнее вряд ли скажу - ту обработку найти не получается.
Хотя и с Jet возможны глюки:https://forum.infostart.ru/forum9/topic259625/
Эти манипуляции тоже не помогли. Глючит, как и прежде на строке
RecordSet.Fields(0).Value = "!ТЕСТ ADODB!";
А прочитать содержимое ячеек получается? Если да, то все-таки неправильно открыт файл, не с теми параметрами.
RecordSet.Fields(0).Value = "!ТЕСТ ADODB!";
Или драйвер ADO вообще не тот - может, надо использовать не ACE, а Jet:
Смутно помнится, что где-то в подобной задаче выбор драйвера делал программно (в коде), а от чего он зависел - уже не помню, кажется от формата файла: XLS или XLSX. Точнее вряд ли скажу - ту обработку найти не получается.
Хотя и с Jet возможны глюки:
(9)
Да. Прочитать получается.
(9)
Но, тот самый "вредный" файл с расширением xlsx поэтому в данном случае дело не в глюке драйвера Jet.
Пока проблему не смогла решить.
А прочитать содержимое ячеек получается? Если да, то все-таки неправильно открыт файл, не с теми параметрами.
Да. Прочитать получается.
(9)
выбор драйвера делал программно (в коде), а от чего он зависел - уже не помню, кажется от формата файла: XLS или XLSX
от формата. На самом деле я это делаю
Если Найти(ВРег(Файл.Расширение), "XLSX") > 0 ИЛИ
Найти(ВРег(Файл.Расширение), "XLSM") > 0 Тогда
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + СтруктураПараметров.ИмяФайла;
СтрокаПодключения = СтрокаПодключения + "; Extended Properties=""Excel 12.0 Xml;HDR=NO"";";
Иначе
СтрокаПодключения = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source = " + СтруктураПараметров.ИмяФайла;
СтрокаПодключения = СтрокаПодключения + "; Extended Properties = ""Excel 8.0;HDR=NO;IMEX=1"";";
КонецЕсли;
СтрокаПодключения = СтрокаПодключения + "Mode=ReadWrite;";
ПоказатьНо, тот самый "вредный" файл с расширением xlsx поэтому в данном случае дело не в глюке драйвера Jet.
Пока проблему не смогла решить.
ConString = Provider=Microsoft.ACE.OLEDB.12.0;Data Source=file.xlsx;Extended Properties="Excel 12.0 Xml;HDR=NO";
Q =
UPD ATE [Sheet1$A2:C100] a
SE T a.F2 = "123", a.F3 = "456"
WHERE a.F1 = "XXX";
Execute(Q, , 129);
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот