|
Работа с Excel документами d 1C без MS Office | ☑ | ||
---|---|---|---|---|
0
yabes
01.10.12
✎
14:57
|
Здравствуйте! Переводим всех пользователей на терминальный доступ к базе! Корпоративная версия MS Office стоит дорого и установлена не будет! У меня написано много обработок и отчетов по работе с Excel документами (чтение документов, создание и заполнение). Возможно ли не внося изменения в код читать данные из Excel документов и создавать документы без установленного MS Office? Ну или посоветуйте как с минимальными изменениями кода решить эту проблему!?
Я понимаю, что на эту тему в сети есть информация, но оптимального решения я так и не смог найти! |
|||
1
ProProg
01.10.12
✎
14:58
|
используй АДО
|
|||
2
yabes
01.10.12
✎
14:58
|
(1) Можно поподробнее пожалуйста! Я не сталкивался с этим!
|
|||
3
zladenuw
01.10.12
✎
14:59
|
можно еще http://www.openoffice.org/ru/
|
|||
4
ProProg
01.10.12
✎
14:59
|
&НаКлиенте
Процедура глЗагрузитьФайлИспользуя_MSADODB(ФайлИсходныхДанных, НомерЛиста = 1, СтрокаЗаголовкаИсходныхДанных = 1, НачальнаяСтрокаИсходныхДанных = 0, КонечнаяСтрокаИсходныхДанных = 0, ТабличныйДокумент) Экспорт Connection = Новый COMОбъект("ADODB.Connection"); СтрокаПодключения = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source = "+СокрЛП(ФайлИсходныхДанных)+"; Extended Properties = "+"""Excel 8.0"+";HDR=NO;IMEX=1"";"; Попытка Connection.Open(СтрокаПодключения); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; Command = Новый COMОбъект("ADODB.Command"); axCatalog = Новый COMОбъект("ADOX.Catalog"); axCatalog.ActiveConnection = Connection; //получим листы документа, //для обработки колонок листа можно обратится к коллекции Лист.Columns,которую тоже можно обойти посредством цикла Для каждого СписокЛистов = Новый СписокЗначений; Для каждого Лист ИЗ axCatalog.Tables Цикл ТекстЗапросаКолонки = ""; Если Лист.Name = "Excel_BuiltIn__FilterDatabase" Тогда // пропускаем технический лист Продолжить; КонецЕсли; Сообщить(Лист.Name); СписокЛистов.Добавить(Лист.Name); //Если Лист.Columns.Count() > 1 Тогда // на нашем листе должны быть как минимум соответствие чего-то чему-то, т.е. большой одной колонки // Для к = 1 По Лист.Columns.Count() Цикл // ТекстЗапросаКолонки = ТекстЗапросаКолонки + ?(ТекстЗапросаКолонки="","F"+Формат(к,"ЧЦ=15; ЧГ=0"),",F"+Формат(к,"ЧЦ=15; ЧГ=0")); // КонецЦикла; // // СписокЛистов.Добавить(Лист.Name,ТекстЗапросаКолонки); // Продолжить; //КонецЕсли; КонецЦикла; //////////////////////////////////////////////////////////////////////////// ////////////////////// работаем с записями ЧитаемСЛистаНомер = НомерЛиста-1; RecordSet = Новый COMОбъект("ADODB.RecordSet"); //Создание объекта набора записей Command.ActiveConnection = Connection; //Указание активного соединения // можем посчитать количество строк на листе Command.CommandText = "SELECT COUNT(*)FROM ["+СписокЛистов[ЧитаемСЛистаНомер].Значение+"]"; //получим количество строк в документе Command.CommandType = 1; //определение типа команды RecordSet = Command.Execute(); //Выполнение и получение набора данных КоличествоСтрок = RecordSet.Fields(0).Value; //первая запись это количество строк //Command.CommandText = "SELECT "+СписокЛистов[ЧитаемСЛистаНомер].Представление+" FROM ["+СписокЛистов[ЧитаемСЛистаНомер].Значение+"]"; //опредлеление текста команды Command.CommandText = "SELECT * FROM ["+СписокЛистов[ЧитаемСЛистаНомер].Значение+"]"; //опредлеление текста команды A1:B545 Command.CommandType = 1; //определение типа команды //Выполнение и получение набора данных Попытка RecordSet = Command.Execute(); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; // ограничим по количеству вменяемых строк НомерСтроки = 0; Пока RecordSet.EOF() = 0 Цикл НомерСтроки = НомерСтроки + 1; Если НомерСтроки < НачальнаяСтрокаИсходныхДанных Тогда Recordset.MoveNext(); Продолжить; КонецЕсли; Если КонечнаяСтрокаИсходныхДанных > 0 И НомерСтроки > КонечнаяСтрокаИсходныхДанных Тогда Прервать; КонецЕсли; Для Счетчик = 1 ПО Recordset.Fields.Count Цикл Поле = Recordset.Fields.Item(Счетчик - 1); ЗначениеЯчейки = СокрЛП(Строка(Поле.Value)); //ЗначениеЯчейки = УдалитьНедопустимыеСимволыXML(ЗначениеЯчейки); ТабличныйДокумент.Область("R" + Формат(НомерСтроки, "ЧГ=") +"C" + Формат(Счетчик, "ЧГ=")).Текст = ЗначениеЯчейки; КонецЦикла; Recordset.MoveNext(); КонецЦикла; Recordset.Close(); Connection.Close(); Recordset = Неопределено; Connection = Неопределено; КонецПроцедуры |
|||
5
yabes
01.10.12
✎
15:00
|
(3) А для OpenOffice надо сильно код переписывать?
|
|||
6
zladenuw
01.10.12
✎
15:02
|
Перем MassivParametrov;
Перем ТЧДанных; функция URLИзИмениФайла(Знач ИмяФайла) ИмяФайла = СтрЗаменить(ИмяФайла," ","%20"); ИмяФайла = СтрЗаменить(ИмяФайла,"\","/"); Возврат "file:/" + "/localhost/" + ИмяФайла; Конецфункции Процедура СоздатьТЧДанных() // Создание описателя типов для таблицы значений //КЧ = Новый КвалификаторыЧисла(15,2); КС = Новый КвалификаторыСтроки(50); Массив = Новый Массив; Массив.Добавить(Тип("Строка")); ОписаниеТиповС = Новый ОписаниеТипов(Массив, , КС); //Массив.Очистить(); //Массив.Добавить(Тип("Число")); //ОписаниеТиповЧ = Новый ОписаниеТипов(Массив, , ,КЧ); // Очистить предыдущие значения ТЧДанных.Очистить(); ТЧДанных.Колонки.Очистить(); // Создать колонки табличного документа ТЧДанных.Колонки.Добавить("Колонка0",ОписаниеТиповС,"Х"); ТЧДанных.Колонки.Добавить("Колонка1",ОписаниеТиповС,"ХХ"); ТЧДанных.Колонки.Добавить("Колонка2",ОписаниеТиповС,"ХХX"); //ТЧДанных.Колонки.Добавить("Колонка3",ОписаниеТиповС,"ХXXX"); //ТЧДанных.Колонки.Добавить("Колонка4",ОписаниеТиповС,"Норматив"); //ТЧДанных.Колонки.Добавить("Колонка5",ОписаниеТиповС,"Х"); //ТЧДанных.Колонки.Добавить("Колонка6",ОписаниеТиповС,"Кво"); КонецПроцедуры Функция ПрочитатьФайл(ИмяФайла) Экспорт ФайлОбмена = Соединение.LoadComponentFromURL(URLИзИмениФайла(ИмяФайла), "_blank", 0, MassivParametrov); ТекущийЛист = ФайлОбмена.sheets.getByIndex(0); //лпМассив = ВернутьМассивДиапазонДляOpenOffice(); СоздатьТЧДанных(); CellCursor = ТекущийЛист.createCursor(); CellCursor.gotoStartOfUsedArea(Ложь); CellCursor.gotoEndOfUsedArea(Истина); CellRangeAddress = CellCursor.getRangeAddress(); begCol = CellRangeAddress.StartColumn; //начальная колонка диапазона begRow = CellRangeAddress.StartRow; //нач ячейка endCol = CellRangeAddress.EndColumn; endRow = CellRangeAddress.EndRow; Range = ТекущийЛист.getCellRangeByPosition(begCol, begRow, endCol, endRow); //лпМассивCOM = Новый COMSafeArray("VT_VARIANT", Range.Columns.Count, Range.Rows.Count); //Состояние(НСтр("ru=""Получение диапазона данных из файла..."";uk=""Отримання діапазону даних з файлу...""")); Данные = Range.getDataArray().Выгрузить(); //Данные = лпМассивCOM.Выгрузить(); //Создание пустых строк по RowCount Для Счетчик = 1 По endRow Цикл НоваяСтрока = ТЧДанных.Добавить(); КонецЦикла; //Заполнение Тч данными Для Счетчик = 0 По endRow Цикл //ТЧДанных.ЗагрузитьКолонку(Данные[Счетчик], "Колонка"+Счетчик); НоваяСтрока = ТЧДанных.Вставить(Счетчик); МассивСтроки = Данные[Счетчик]; НомЭлемента = 0; Для каждого Колонка Из ТЧДанных.Колонки Цикл Попытка НоваяСтрока[Колонка.Имя] = МассивСтроки[НомЭлемента]; НомЭлемента = НомЭлемента+1; Исключение КонецПопытки; КонецЦикла; КонецЦикла; Возврат ТЧДанных; КонецФункции // ПрочитатьФайл() //Подключение к серверу автоматизации OpenOffice Попытка OpenOffice = Новый COMОбъект("com.sun.star.ServiceManager"); scr = Новый COMОбъект("MSScriptControl.ScriptControl"); scr.language = "javascript"; scr.eval("MassivParametrov = new Array()"); MassivParametrov = scr.eval("MassivParametrov"); scr.AddObject("OpenOffice", OpenOffice); scr.eval("MassivParametrov[0]=OpenOffice.Bridge_GetStruct('com.sun.star.beans.PropertyValue')"); scr.eval("MassivParametrov[0].Name='Hidden'"); scr.eval("MassivParametrov[0].Value=true"); Соединение = OpenOffice.createInstance("com.sun.star.frame.Desktop"); Исключение Предупреждение(ОписаниеОшибки() + Символы.ПС + "программа OpenOffice не установлена на данном компьютере!"); КонецПопытки; ТЧДанных = Новый ТаблицаЗначений; |
|||
7
yabes
01.10.12
✎
15:05
|
(3) Я так понимаю, что весь код придется переписать? Т.е. не только другое подключение к базе, но и все методы другие?
|
|||
8
yabes
01.10.12
✎
15:05
|
*(7) этот вопрос к (4)
|
|||
9
zladenuw
01.10.12
✎
15:07
|
(8) нет. там же все готово. передаешь файл и все
|
|||
10
acsent
01.10.12
✎
15:11
|
а адо без екселя то разве работает?
|
|||
11
yabes
01.10.12
✎
15:20
|
Ну вот основные моменты, которые мне нужно переписать! Как это сделать в АДО?
КомОбъект= Новый COMОбъект("Excel.Application"); Книга = КомОбъект.WorkBooks.Open(ПутьКФайлу); Лист = Книга.WorkSheets(1); ЗначениеЯчейки = Лист.Cells(1,1).Value; ПоискВСтолбце_B = Лист.Range("b1:b500").find(ИскомоеЗначение, Лист.Range("b1"), -4163, 1, 2); КомОбъект.Application.Visible = Истина; КомОбъект.Windows(1).Visible = 1; |
|||
12
zladenuw
01.10.12
✎
15:28
|
//гоняем фильтр рекордсета и можно в цикле
Рекордсет.Filter = "" + Поле1 + " like '" + Значение1 +"'" + " And " + Поле2 +" like '" + Значение2 + "'" + " And " + Поле3 + " like '" +Значение3 + "'" + " And " + Поле4 + " like '" +Значение4 + "'" ; //если не возвращается ни одна строка Если Рекордсет.BOF = Истина Тогда сообщить("не найдено"); Иначе Сообщить(Рекордсет.Fields(Поле1).Value); КонецЕсли; |
|||
13
yabes
01.10.12
✎
15:34
|
(12) Это так поиск производить в столбце?)))
|
|||
14
zladenuw
01.10.12
✎
15:40
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |