Имя: Пароль:
1C
1С v8
Работа с 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
AdBlock убивает бесплатный контент. 1Сергей