Интеграция OpenOffice Calc с 1С 7.7 Ключевые слова: UNO, OpenOffice, Calc, OpenDocument, Array, ODF, OpenXML, Office 2007, Интеграция, Excel
OpenOffice
Основная проблема при работе с 7.7 - это проблема передачи массивов через COM.
Здесь предлагается, вероятно, наилучшее решение этой проблемы.
Оно базируется на идее и коде smаhаrbА на Нью-Территории 1С.
scr = СоздатьОбъект("MSScriptControl.ScriptControl");
scr.language = "javascript";
scr.eval("Массив=new Array()");
Массив = scr.eval("Массив");
scr.AddCode("function SetItem(ind,val){Массив[ind]=val}");
ServiceManager=СоздатьОбъект("com.sun.star.ServiceManager");
scr.AddObject("ServiceManager",ServiceManager);
Desktop = ServiceManager.createInstance("com.sun.star.frame.Desktop");
Document = Desktop.LoadComponentFromURL("private:factory/scalc", "_blank", 0, Массив);
Листы = Document.getSheets();
Лист = Листы.getByIndex(0);
Для к = 0 По 10 Цикл
Лист.getCellByPosition(0,к).value = к;
КонецЦикла;
SaveParam = scr.Eval("ServiceManager.Bridge_GetStruct('com.sun.star.beans.PropertyValue')");
SaveParam.Name = "FilterName";
SaveParam.Value = "MS Excel 97";
scr.CodeObject.SetItem(0,SaveParam);
Document.storeToURL("file:///c:/Test.xls",Массив);
По адресу http://1c.proclub.ru/modules/mydownloads/personal.php?cid=5&lid=6573
можно найти первые наброски по разработке библиотеки классов 1С++ для автоматизации OO.
рабочий код по вставке диаграмм в Calc в нужную позицию и нужных размеров и заполнение их данными
Автор - r_newman (http://community.i-rs.ru/index.php/topic,5832.0.html)
Перем true, false;
////////////////////////////////////////////////////////////////////////
//функции для преобразования номера колонки в символьное представление//
////////////////////////////////////////////////////////////////////////
//---------------------------------------
//приводит десятичное число X к числу в системе счисления R
Функция IntToR(Знач X,R=16,Знач стр="",Знач буквенное=0)
Если стр="" Тогда
Если R=2 Тогда
стр="01";
ИначеЕсли R=8 Тогда
стр="01234567";
ИначеЕсли R=10 Тогда
стр="0123456789";
ИначеЕсли R=16 Тогда
стр="0123456789ABCDEF";
ИначеЕсли R=26 Тогда
стр="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
буквенное=1;
ИначеЕсли R=36 Тогда
стр="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
КонецЕсли;//
КонецЕсли;//
рез1="";
Пока X<>0 Цикл
_X=X/R;
ост=X-Цел(_X)*R;
X=Цел(_X);
Если буквенное=0 Тогда
рез1=рез1+Сред(стр,ост+1,1);
Иначе
Если ост=0 Тогда
рез1=рез1+Сред(стр,R,1);
X=X-1;
Иначе
рез1=рез1+Сред(стр,ост,1);
КонецЕсли;
КонецЕсли;
КонецЦикла;//
Если (рез1="")
И (буквенное=0) Тогда
рез1=Сред(стр,1,1);
КонецЕсли;//
рез="";
Для сч=-СтрДлина(рез1) По -1 Цикл
рез=рез+Сред(рез1,-сч,1);
КонецЦикла;
Возврат рез;
КонецФункции //IntToR
//---------------------------------------
Функция IntTo26(Ч)
Возврат IntToR(Ч,26);
КонецФункции //IntTo26
////////////////////////////////////////////////////////////////////////
//---------------------------------------
//выполняет указанную процедуру из макроса.
//параметры передаются в виде списка значений
Процедура Макрос_Выполнить(Скрипт,СервисМанагер,Стол,Frame,ИмяМодуля,Знач ИмяПроцедуры,Параметры=0)
Если ТипЗначенияСтр(Параметры)="СписокЗначений" Тогда
_Параметры="";
Для сч=1 По Параметры.РазмерСписка() Цикл
стр="";
зн=Параметры.ПолучитьЗначение(сч,стр);
_Параметры=_Параметры+?(_Параметры="","",", ")+зн;
КонецЦикла;
ИмяПроцедуры=ИмяПроцедуры+"("+_Параметры+")";
КонецЕсли;//
Массив=Скрипт.eval("new Array()");
URLМакроса=Скрипт.Eval("ServiceManager.Bridge_GetStruct('com.sun.star.util.URL')");
URLМакроса.Complete="macro://./Standard."+ИмяМодуля+"."+ИмяПроцедуры;
Dispatcher = Frame.queryDispatch(URLМакроса,"_self",0);
dispatcher.Dispatch(URLМакроса,Массив);
КонецПроцедуры //Макрос_Выполнить
//---------------------------------------
Функция ПолучитьТекстМодуля()
ТекстМодуля="
|sub AddDiagram(sDiagramName as String, iX as Integer, iY as Integer, iWidth as Integer, iHeight as Integer)
|
| dim Rect as new com.sun.star.awt.Rectangle
| dim Addresses as new com.sun.star.table.CellRangeAddress
|
| Document=ThisComponent
|
| Sheets=document.getSheets()
| SheetDiagram=Sheets.getByIndex(0)
| SheetData=Sheets.getByIndex(1)
|
| Charts=SheetDiagram.Charts
|
| Rect.X=iX
| Rect.Y=iY
| Rect.Width=iWidth
| Rect.Height=iHeight
|
| Addresses.Sheet=0
| Addresses.StartColumn=0
| Addresses.StartRow=0
| Addresses.EndColumn=10
| Addresses.EndRow=10
|
| Charts.AddNewByName(sDiagramName,Rect,Addresses,true,false)
|
|end sub";
Возврат ТекстМодуля;
КонецФункции //ПолучитьТекстМодуля
//---------------------------------------
//добавляет модуль макроса в документ OOo
Процедура Макрос_ДобавитьМодуль(Документ,ИмяМодуля,ТекстМодуля)
Библиотека=Документ.BasicLibraries.GetByName("Standard");
Библиотека.InsertByName(ИмяМодуля, ТекстМодуля);
КонецПроцедуры //Макрос_ДобавитьМодуль
//---------------------------------------
Функция ПолучитьДиаграммуПоИмени(ChartCollection,ИмяДиаграммы)
Диаграмма=ChartCollection.getByName(ИмяДиаграммы).EmbeddedObject;
Возврат Диаграмма;
КонецФункции //ПолучитьДиаграммуПоИмени
//---------------------------------------
//устанавливает некоторые параметры диаграммы (на самом деле сюда можно и побольше напихать :) )
Процедура УстановитьПараметрыДиаграммы(Диаграмма,ТипДиаграммы=1,ЛистДанных,НачСтрока,НачКолонка,КонСтрока,КонКолонка,ЗаголовокТекст="Диаграмма",ЗаголовокКурсив=0,ЗаголовокЖирный=0)
Если ТипДиаграммы=1 Тогда
Диаграмма.Diagram=Диаграмма.CreateInstance("com.sun.star.chart.LineDiagram");
Иначе
Диаграмма.Diagram=Диаграмма.CreateInstance("com.sun.star.chart.XYDiagram");
КонецЕсли;
Диаграмма.Diagram.SymbolType=-2;
Диаграмма.Diagram.DataRowSource=0;
Диаграмма.DataSourceLabelsInFirstColumn=true;
Диаграмма.DataSourceLabelsInFirstRow=true;
Диаграмма.ChartRangeAddress=ЛистДанных.Name+".$"+IntTo26(НачКолонка)+"$"+НачСтрока+":.$"+IntTo26(КонКолонка)+"$"+КонСтрока;
Wall=Диаграмма.Diagram.Wall;
Wall.FillStyle=0;
Title=Диаграмма.Title;
Title.String=ЗаголовокТекст;
Title.CharPosture=?(ЗаголовокКурсив=1,2,0);
Title.CharWeight=?(ЗаголовокЖирный=1,150,100);
Legend=Диаграмма.Legend;
Legend.Alignment=4;
Legend.FillStyle=0;
Legend.CharHeight=8;
КонецПроцедуры //УстановитьПараметрыДиаграммы
//---------------------------------------
//вставляет диаграмму на 1-й лист используя заранее внедренный макров AddDiagram
Процедура ВставитьДиаграмму(Скрипт,СервисМанагер,Стол,Frame,ИмяДиаграммы,X,Y,Ширина,Высота)
ПараметрыПроцедуры=СоздатьОбъект("СписокЗначений");
ПараметрыПроцедуры.ДобавитьЗначение(ИмяДиаграммы);
ПараметрыПроцедуры.ДобавитьЗначение(X);
ПараметрыПроцедуры.ДобавитьЗначение(Y);
ПараметрыПроцедуры.ДобавитьЗначение(Ширина);
ПараметрыПроцедуры.ДобавитьЗначение(Высота);
Макрос_Выполнить(Скрипт,СервисМанагер,Стол,Frame,"Module1","AddDiagram",ПараметрыПроцедуры);
КонецПроцедуры //ВставитьДиаграмму
//---------------------------------------
//сохраняет документ в формате XLS (глючит с диаграммами)
Процедура СохранитьВXLS(Скрипт,Документ,Путь)
Скрипт.eval("Массив=new Array()");
Массив = Скрипт.eval("Массив");
Скрипт.AddCode("function SetItem(ind,val){Массив[ind]=val}");
ЗначенияПараметра=Скрипт.Eval("ServiceManager.Bridge_GetStruct('com.sun.star.beans.PropertyValue')");
ЗначенияПараметра.Name="FilterName";
ЗначенияПараметра.Value="MS Excel 97";
Скрипт.CodeObject.SetItem(0,ЗначенияПараметра);
Документ.storeToURL("file:///"+Путь,Массив);
КонецПроцедуры //СохранитьВXLS
//---------------------------------------
//Сохраняет документ в формате OOo
Процедура Сохранить(Скрипт,Документ,Путь)
Массив=Скрипт.eval("new Array()");
Документ.storeAsURL("file:///"+Путь,Массив);
КонецПроцедуры //СохранитьВXLS
//*******************************************
Процедура Сформировать()
Скрипт=СоздатьОбъект("MSScriptControl.ScriptControl");
Скрипт.language="javascript";
СервисМанагер=СоздатьОбъект("com.sun.star.ServiceManager");
Скрипт.AddObject("ServiceManager",СервисМанагер);
Математика=Скрипт.eval("Math");
Скрипт.AddCode("function SetItem(ind,val){Массив[ind]=val}");
Массив=Скрипт.eval("new Array()");
true=Скрипт.Eval("true");
false=Скрипт.Eval("false");
ЗначенияПараметра=Скрипт.Eval("ServiceManager.Bridge_GetStruct('com.sun.star.beans.PropertyValue')");
ЗначенияПараметра.Name="Hidden";
ЗначенияПараметра.Value=true;
Массив.push(ЗначенияПараметра);
Стол=СервисМанагер.createInstance("com.sun.star.frame.Desktop");
Документ=Стол.LoadComponentFromURL("private:factory/scalc","_blank",0,Массив);
Frame = Документ.CurrentController.Frame;
//Документ.lockControllers();
//Документ.addActionLock();
Листы=Документ.getSheets();
ЛистДиаграмма=Листы.getByIndex(0);
ЛистДанные=Листы.getByIndex(1);
ChartCollection=ЛистДиаграмма.Charts;
Макрос_ДобавитьМодуль(Документ,"Module1",ПолучитьТекстМодуля());
//вставим на Лист1 5 диаграмм и на Лист2 заполним для них массив данных
НачСтрока=1;
НачКолонка=1;
Для сч=1 По 5 Цикл
ИмяДиаграммы="MyDiagram"+сч;
Ширина=25000;
Высота=7000;
X=500;
Y=1000+(сч-1)*(Высота+500);
ВставитьДиаграмму(Скрипт,СервисМанагер,Стол,Frame,ИмяДиаграммы,X,Y,Ширина,Высота);
яч=ЛистДанные.GetCellByPosition(НачКолонка-1,НачСтрока-1);
яч.String="Данные для диаграммы "+ИмяДиаграммы;
НачСтрока=НачСтрока+1;
ВысотаДанных=Макс(Цел(Математика.random(0)*5),1);
Для счY=1 По ВысотаДанных Цикл
яч=ЛистДанные.GetCellByPosition(НачКолонка-1,НачСтрока+счY-1);
яч.String="линия "+счY;
КонецЦикла;
ШиринаДанных=сч*2+1;
Для счX=1 По ШиринаДанных Цикл
яч=ЛистДанные.GetCellByPosition(счX,НачСтрока-1);
яч.String="месяц "+счX;
Для счY=1 По ВысотаДанных Цикл
яч=ЛистДанные.GetCellByPosition(счX,НачСтрока+счY-1);
яч.Value=Математика.random(0)*1000;
КонецЦикла;
КонецЦикла;
КонСтрока=НачСтрока+ВысотаДанных;
КонКолонка=ШиринаДанных+1;
Диаграмма=ПолучитьДиаграммуПоИмени(ChartCollection,ИмяДиаграммы);
УстановитьПараметрыДиаграммы(Диаграмма,1,ЛистДанные,НачСтрока,НачКолонка,КонСтрока,КонКолонка,"Заголовок диаграммы "+ИмяДиаграммы,0,1);
НачСтрока=КонСтрока+2;
КонецЦикла;
Сохранить(Скрипт,Документ,"c:/111.ods");
//Документ.unLockControllers();
//Документ.removeActionLock();
//Документ.close(-1);
//Массив=Скрипт.eval("new Array()");
//ЗначенияПараметра=Скрипт.Eval("ServiceManager.Bridge_GetStruct('com.sun.star.beans.PropertyValue')");
//ЗначенияПараметра.Name="Hidden";
//ЗначенияПараметра.Value=true;
//Массив.push(ЗначенияПараметра);
//Стол=СервисМанагер.createInstance("com.sun.star.frame.Desktop");
//Документ=Стол.LoadComponentFromURL("file:///c:/111.ods","_blank",0,Массив);
//СохранитьВXLS(Скрипт,Документ,"c:/111.xls");
//Документ.close(-1);
//ЗапуститьПриложение("c:/111.xls");
КонецПроцедуры
Документация
На Русском
Руководство по Calc
http://authors.i-rs.ru/03%20Calc%20Guide/0300CG-CalcGuide-Ru.pdf
Памятка для перехода с Word Excel (Microsoft Office) на OpenOffice краткая
http://buhcia.narod.ru/ForOpenOffice.zip
Программирование на языке OpenOffice.org Basic
http://authors.i-rs.ru/Basic/OpenOffice.org.BASIC%20Guide.pdf
Перевод книги Andrew Pitonyak "Useful Macro Information For OpenOffice"
http://buhcia.narod.ru/OpenOffice_Macros_rus.odt
На английском
Руководство Разработчика (> 1100 страниц)
http://api.openoffice.org/docs/DevelopersGuide/DevelopersGuide.pdf
советы по переходу с VBA
http://documentation.openoffice.org/HOW_TO/various_topics/VbaStarBasicXref.pdf
Упрощение миграции с MSO
Библиотека, упрощающая доступ к данным Open Office Calc. Предоставляет automation интерфейс, схожий с интерфейсом Excel.Application, что позволяет использовать созданные для Microsoft Excel продукты в среде OpenOffice.org с минимальными модификациями.
http://triteh.ru/xls1c/index.php
Nice Office Access, который призван упростить достаточно сложную объектную модель ОО
(но он, похоже, предназначен для разработки прилозений ОО на Ява)
http://ubion.ion.ag/loesungen/004niceofficeaccess
Библиотеки работы с OpenDocumentAODL для .Net
http://wiki.services.openoffice.org/wiki/AODL
Пример создания ODS файла с использованием AODL на Visual Basic .Net (2005):
Imports AODL.Document
Sub ExportODF(ByVal FileName As String)
'Create new spreadsheet document
Dim spreadsheetDocument As New SpreadsheetDocuments.SpreadsheetDocument
If System.IO.File.Exists(FileName) Then
spreadsheetDocument.Load(FileName)
Else
spreadsheetDocument.[New]()
End If
'Create a new table
Dim Jahr As Integer = CInt(JahrToolStripTextBox.Text)
Dim Monat As Integer = MonatToolStripComboBox.SelectedIndex + 1
Dim dt As New DateTime(Jahr, Monat, 1)
Dim table As New Content.Tables.Table(spreadsheetDocument, dt.ToString("MMMM yy"), "")
With DatenDataGridView
For rowIndex As Integer = 0 To .RowCount - 1
For colIndex As Integer = 1 To .ColumnCount - 1
Dim cell As Content.Tables.Cell = table.CreateCell()
Dim curItem As DataGridViewCell = .Item(colIndex, rowIndex)
Dim curValue As Object = curItem.Value
If Not IsNothing(curValue) Then
If IsNumeric(curValue) Then
cell.OfficeValueType = SpreadsheetDocuments.Tables.Style.OfficeValueTypes.Float
Else
cell.OfficeValueType = SpreadsheetDocuments.Tables.Style.OfficeValueTypes.String
End If
'cell.CellStyle.CellProperties.Border = AODL.Document.Styles.Border.NormalSolid
cell.OfficeValue = curValue.ToString
End If
table.InsertCellAt(rowIndex + 1, colIndex + 1, cell)
Next
Next
End With
'Insert table into the spreadsheet document
spreadsheetDocument.TableCollection.Add(table)
spreadsheetDocument.SaveTo(FileName)
End Sub
OO на компьютере не требуется, т.к. происходит непосредственное создание документа ODS.
Odf4j для Java
http://wiki.services.openoffice.org/wiki/Odf4j
Office 2007
SDK for Open XML Formats (Beta) - работа с файлами Office 2007 без Office из своих приложений
Требует .Net 3.0. Размер ДЛЛ - 200 Кб.
Все остальное - хороший Help.
http://www.microsoft.com/downloads/details.aspx?FamilyID=ad0b72fb-4a1d-4c52-bdb5-7dd7e816d046&DisplayLang=en
Лабораторные работы по OpenXML
http://www.gotdotnet.ru/Downloads/Examples/493404.aspx
Open XML Explained
http://openxmldeveloper.org/attachment/1970.ashx
http://openxmldeveloper.org/attachment/1690.ashx
Следуюший макрос использует специально оставленную товарищами
из Microsoft возможность бесконечно долгого бесплатного использования Excel 2007.
Сохранение документов отключено (будет выдаваться окно активации).
Но для VBA - разработчика (есть экспорт VBA обьектов) и использования Excel: составил отчет через OLE, распечатал и забыл - будет вполне достаточно.
Dim WExcel
Set WExcel = WScript.CreateObject("Excel.Application")
WExcel.Visible = True
WExcel.Workbooks.Add()
Sun ODF Plugin 1.0 for Microsoft Office
The Sun ODF Plug in for Microsoft Office gives users of Microsoft Word, Excel and Powerpoint the ability to read, edit and save to the ISO-standard Open Document Format. The ODF Plug in is available as a free download from the Sun Download Center (SDLC).
http://javashoplm.sun.com/ECom/docs/Welcome.jsp?StoreId=8&PartDetailId=ODF-WIN-G-F&TransactionId=noreg |