Пример автоматизации OpenOffice.org 2.2+ с программной записью и выполнением макроса на языке StarBa
Последнее время все больше и больше возрастает интерес к
автоматизации OpenOffice.org Calc и Writer, а доступных
русскоязычных источников по этой теме пока катострофически не
хватает. Не хватает, к сожалению времени, чтобы расписать все
подробно и по-русски, но очень надеюсь, что данный пример и его
части пригодятся тем, кто решил заняться автоматизацией
OpenOffice.org из VFP.
Данный пример включает в себя демонстрацию максимально большого количества из известных на данный момент
приемов для автоматизации OpenOffice.org Calc из VFP, накопленных из разнообразных источников в Internet и разработанных мною самостоятельно путем тяжелых проб и ошибок. Главный источник - англоязычная документация
по API OpenOffice.org. Так, что те кто еще не знает английский - вперед! Я учил в школе Deutsch...
Вы должны понимать, что при автоматизации можно обращаться к свойствам и методам создаваемых объектов, но
невозможно напрямую (без создания макросов на языке StarBasic) из VFP обращаться к функциям и командам языка
StarBasic. Например, в VFP вместо команды createUnoService("...") необходимо использовать
аналогичный ему вызов из библиотеки libOOo.prg, который называется OOoServiceManager_CreateInstance("..."),
если Вы планируете использовать данную библиотеку. К сожалению, эту библиотеку уже очень давно написал
Danny Brewer, и исправлять теперь названия в ней уже нет никакого смысла, т.к. исправив название этой функции
можно получить несовместимость с другими существующими примерами автоматизации OOo из VFP.
Лучше всего дополнять ее новыми функциями и публиковать свои дополнения.
Для демонстрации примера, подключите к проекту библиотеку libOOo.prg, содержащую ВСЕ необходимые функции
для работы ЭТОГО примера (если она отличается от имеющейся у Вас, то замените свою на прилагаемую здесь),
а также подключите и запускайте vfpcalcexample2.prg из прилагаемого архива.
Все комментарии внутри программы (см. исходный текст vfpcalcexample2.prg)
Обратите внимание, что в настройках OpenOffice.org, вызываемых через пункт главного меню Сервис->
Параметры-> Загрузка/сохранение-> Общие можно настроить форматы файлов по умолчанию: для
текстового документа "Microsoft Word 97/2000/XP", для электронной таблицы "Microsoft Excel
97/2000/XP", для презентации "Microsoft PowerPoint 97/2000/XP". Сохраняя документы в форматах
Microsoft с одной стороны, Вы получаете совместимость и переносимость Ваших документов на
компьютеры пользователей, у которых установлен пакет MS Office, а с другой стороны лишаете себя
возможности писать и использовать макросы на нескольких встроенных в OpenOffice.org языках, т.к. в
форматах от Microsoft макросы OpenOffice увы - не сохраняются.
rvc44
03.07.07 09:54:05
Кстати, вот аналогичный приведенному решению код на VBA для Excel, который приводил ранее на
форуме Юрий Рубинов с небольшим дополнением:
[code]
With .ActiveSheet.OLEObjects.Add("Forms.CommandButton.1")
.Left = 0 && 100
.Top = 0 && 200
.Width = 100
.Height = 25
.Object.Caption = "Записать на дискету"
.Object.Font.Name = "MS Sans Serif"
.Object.Font.Size = 8
lcClickCode=;
"Private Sub "+.Name+"_Click()"+CHR(13)+;
'MsgBox ("Вставьте дискету в дисковод и нажмите OK для начала записи")'+CHR(13)+;
'ActiveWorkbook.SaveAs Filename:="A:\'+ sFileName +'", FileFormat _'+CHR(13)+;
':=xlNormal, Password:="", WriteResPassword:="", ReadOnlyRecommended:= _'+CHR(13)+;
'False, CreateBackup:=False'+CHR(13)+;
'MsgBox ("Процесс записи завершен!")'+CHR(13)+;
"End Sub"
EndWith
[/code]
см. продолжение далее...
rvc44
03.07.07 09:55:21
...продолжение 1
[code]
TRY
* VBComponents(1) = VBComponents(loExcel.ActiveSheet.Name)
loExcel.Application.VBE.ActiveVBProject.VBComponents(1).CodeModule.AddFromString(lcClickCode)
CATCH
If Int(Val(loExcel.Version)) < 12 && Версии Excel до 12.0 (2007)
=MessageBox('Для работы в Excel на Вашем компьютере кнопки "Записать на дискету"'+Chr(13)+ ;
'необходимо сделать доверенным (разрешить) программный доступ к'+Chr(13)+ ;
'проекту Visual Basic. Для этого, в программе Excel выберите пункт меню'+Chr(13)+ ;
'Сервис -> Макрос -> Безопасность... На вкладке "Надежные издатели"'+Chr(13)+ ;
'установите галочку "Доверять доступ к Visual Basic Project".'+Chr(13)+ ;
'После этого ПОВТОРИТЕ ВЫГРУЗКУ РЕГИСТРА ЗАНОВО! Кнопка заработает.'+Chr(13)+Chr(13)+ ;
'С текущими настройками безопасности кнопка работать не будет.',64,'Сообщение')
[/code]
rvc44
03.07.07 09:58:35
...продолжение 2
[code]
Else
=MessageBox('Для работы в Excel на Вашем компьютере кнопки "Записать на дискету"'+Chr(13)+ ;
'необходимо сделать доверенным (разрешить) программный доступ к'+Chr(13)+ ;
'проекту Visual Basic. Для этого, в программе Excel 2007 нажмите круглую'+Chr(13)+ ;
'кнопку "Office" в верхнем левом углу, затем нажмите кнопку "Параметры Excel",'+Chr(13)+ ;
'выберите закладку "Центр управления безопасностью", нажмите кнопку'+Chr(13)+ ;
'"Параметры центра управления безопасностью"; выберите закладку'+Chr(13)+ ;
[/code]
rvc44
03.07.07 10:00:36
...продолжение 3
[code]
'"Параметры макросов", в разделе "Параметры макросов для разработчика"'+Chr(13)+ ;
'установите галочку "Доверять доступ к объектой модели VBA".'+Chr(13)+ ;
'После этого ПОВТОРИТЕ ВЫГРУЗКУ РЕГИСТРА ЗАНОВО! Кнопка заработает.'+Chr(13)+Chr(13)+ ;
'С текущими настройками безопасности кнопка работать не будет.',64,'Сообщение')
EndIf
ENDTRY
[/code]
Для использования этого примера склейте его со всеми тремя продолжениями. Удачи!
Doctor_y
29.07.07 17:12:05
Очень хороший пример. Много взял на заметку.
Роман, а можно ли аналогичный пример для swriter. Ну, практически, все что мне нужно - нашел. Не
могу найти, как уложить лист Lanscape и определить размеры листа и поля. Из этого примера не смог
сделать для swriter.
rvc44
31.07.07 12:21:52
Спасибо, Doctor_y! Пример для Writer подготовил.
Если людям он нужен, то попробую в первых числах августа
его опубликовать, т.к. необходимо еще скомпоновать код и
избавиться в примере от лишнего... а времени так не хватает!
Doctor_y
04.08.07 12:55:14
Буду ждать, хотя очень хочется побыстрее.
gavsisha
14.09.07 07:57:55
Здравствуйте, Роман!
Я долго искал ответ на вопросы,
сформулированные ниже, но
нигде не смог найти ответ,
все ссылаются только на Вас,
похоже Вы - единственный -
кто сможет мне помочь,
поэтому очень на Вас надеюсь и заранее
благодарен.
1.в Worde пользовался кодом для вставки строки текста
'Текст' в произвольную ячейку таблицы
( во вторую здесь ):
obj=oWrd.Range(;
oWrd.tables(1).range.end,;
oWrd.tables(1).range.end)
obj.move(10,-1)
obj.move(3,1)
obj.Insertafter('Текст')
Как то же самое сделать в Writer-e?
2.Не сочтите за труд отправить на мой
электронный адрес (gavsisha@yandex.ru)
подготовленный Вами в августе
пример работы с Writer-ом.
Заранее благодарен
Гнездилов Александр. Зеленогорск
rvc44
14.09.07 14:15:40
Пишите, пожалуйста, в форум. Он для этого и существует!!!
Или в специальный русский форум по Open Office:
http://community.i-rs.ru/index.php/board,9.0.html
rvc44
14.09.07 14:20:57
Здравствуйте, Александр!
Приношу свои извинения, но должен огорчить:
если Вы долго искали ответы на свои вопросы,
но нигде не смогли найти ответ, то это означает
лишь одно - плохо искали, либо определенно
не ставили себе цель - найти.
Не надо ждать, когда какой-нибудь дядя Вася за Вас все
сделает. Я сам порой ищу некоторые решения неделями,
но в конце концов нахожу, либо пишу их сам.
В форуме приводилась куча ссылок на документацию.
Воспользуйтесь поиском.
rvc44
14.09.07 14:21:49
2. По поводу Вашего вопроса хочу сказать, что подобные
письма мне приходят довольно часто.
Люди спрашивают об экзотических вещах и об обычных,
а я всегда рад помочь, если я уже писАл подобное решение,
но не в состоянии бросив всю работу отвечать на остальные,
которые я никогда не пробывал делать по причине того,
что ранее не было такой необходимости! ))
rvc44
14.09.07 14:22:43
3. Я просто убежден и моя твердая позиция заключается
в том, что вообще НЕ СЛЕДУЕТ пользоваться таблицами
Word/Writer, при наличии хотя бы малейшей возможности
сделать эту же задачу средствами Excel/Calc!
А таких задач большинство! Если я не прав - приведите пример.
Зачем мучать себя, а в первую очередь ДРУГИХ неудобными
плохо редактируемыми таблицами, когда Excel/Calc специально
"заточены" под это?
rvc44
14.09.07 14:24:53
4. Если Вам дорого Ваше мнение, то могу порекомендовать скачать бесплатную книгу по
программированию макросов OpenOffice.org с использованием API, с продуманной последовательностью
подачи учебного материала, включающий в себя справочник по всем конструкциям языка Star Basic и
огромное количество работающих примеров макросов, правда на бразильском языке , но запуская
макросы из книги легко понять о чем идет речь в соответствующих главах и почерпнуть бесценную
информацию. Очень ценный источник знаний.
rvc44
14.09.07 14:25:57
5. [b]Большой раздел в этой книге посвящен программированию таблиц (Tabela)
в текстовом редакторе Writer.[b] Описываемая бразильская версия
BROffice.org 100% совместима с русским OpenOffice.org 2.x
В книге 161 страница. Автор: Noelson Alves Duarte. Качаем здесь:
[url]www.fameg.edu.br/documentos/apostilas_broffice/programando_broo.odt[/url]
Дополнительный контент см. на сайте автора книги: [url]http://br.geocities.com/noelsonalves/[/url]
rvc44
14.09.07 14:27:00
6. В связи с большим объемом заданий на работе,
я пока так и не успел больше ничего опубликовать,
поскольку код (даже интересный), но "выдранный"
из контекста реального работающего приложения
отдельно работать не будет. А причесывать его
пока нет времени. А людям, как я уже давно понял,
интересны ТОЛЬКО ЗАКОНЧЕННЫЕ решения, которые
можно немедленно запустить на выполнение
и посмотреть результат. В противном случае -
высказывают претензии и недовольство, с чем я уже
не раз сталкивался.
С уважением,
Кольцов Роман.
ICQ 44612299
Doctor_y
14.09.07 19:22:57
Правильно, Роман. Согласен. Большинство ждет законченых решений. Надо понимать, что у одной
проблемы может быть огромное количество решений. Не можешь управлять OOo, сделай шаблон, открой
файл, заполняй и сохраняй его на здоровье (таких примеров полно для разных языков и на сайте
Openoffice.org и на других сайтах). А если человек не может перенести пример из java, C, я уже не
говорю об VB, то заниматься OLE и API ему рано.
gavsisha
17.09.07 02:13:34
Роман. Большое спасибо за Вашу информацию,
теперь смогу что-то сам сочинить
rvc44
30.11.07 12:59:12
После выхода OOo 2.3 стал тестировать этот пример и заметил, что код может не работать! Для
работоспособности кода необходимо в тексте сделать замену кода
[code]
*-- Add Code Module
oLibrary = oDoc.BasicLibraries.GetByName("Standard")
oLibrary.InsertByName(sBasicModuleName, sBasicModule)
[/code]
на следующий:
[code]
*-- Add Code Module
If oDoc.BasicLibraries.hasByName("Standard")
oLibrary = oDoc.BasicLibraries.getByName("Standard") && "Базовый"
If oLibrary.hasByName(sBasicModuleName)
oLibrary.replaceByName(sBasicModuleName, sBasicModule)
Else && динамический модуль не существует
oLibrary.insertByName(sBasicModuleName, sBasicModule)
EndIf
Else && динамическая библиотека не существует
oLibrary = oDoc.BasicLibraries.createLibrary("Standard")
oLibrary.insertByName(sBasicModuleName, sBasicModule)
EndIf
[/code]
Так будет работать на всех версиях, о чем я написАл здесь:
[url]http://www.oooforum.org/forum/viewtopic.phtml?p=265232[/url]
Berloga
19.12.07 08:22:51
to rvc44: Отличный пример.
Помогите пожалуйста разобраться. У меня при попытке выполнения :
oDoc = oDesktop.LoadComponentFromUrl("file:///C:/porder.ods","_blank",0,@aNoargs)
выходит ошибка "OLE IDispatch exception code 1001 from [automation bridge] :
com.sun.star.lang.IllegalArgumentException: URL seems to be an unsupported one...".
Хотя:
oDoc = oDesktop.LoadComponentFromUrl("private:factory/scalc","_blank",0,@aNoargs)
работает наура!
Почему не открывается ранее созданный Calc-документ?
Только что созданный документ открывает без проблем:
lcURL=OOoConvertToURL(_fname)
laArgs[1] = OOoMakePropertyValue("Overwrite",.T.)
loDoc.storeToUrl(lcURL,@laArgs)
loDoc.Close(1)
loDoc = OOoOpenURL(OOoConvertToURL(_fname))
Версия OOo 2.3 Pro. FoxPro 9. WindowsXP Home Edition SP2.
Berloga
19.12.07 08:42:55
И после попытки выполнения:
oDoc = Desktop.LoadComponentFromUrl("file:///C:/porder.ods","_blank",0,@aNoargs)
файл C:\porder.ods удаляется.
porder.ods - представляет из себя простой калк-документ созданный по умолчанию.
rvc44
21.12.07 17:02:33
Странно, но у меня ничего не удаляется!
P.S. Для обсуждения подобных проблем есть форум.
rvc44
21.12.07 17:02:53
Странно, но у меня ничего не удаляется!
P.S. Для обсуждения подобных проблем есть форум.
rvc44
27.02.09 19:05:10
Для корректной работы приведенного здесь решения потребуется учесть особенность, изложенную мной
здесь: http://forum.foxclub.ru/read.php?29,375058
В версиях OOo 3.0 и выше изменили систему безопасности запуска макросов, но совет не помешает и
для 2.x! Когда мы готовим новый документ и программно "начиняем" его макросами, и к тому же хотим,
чтобы эти макросы работали(!) надо ПРЕДВАРИТЕЛЬНО в настройках OOo в пункте
Сервис->Параметры...->OpenOffice.org->Безопасность->Безопасн. макросов выставить Средний уровень
безопасности, а ни в коем случае не Высокий и не Очень высокий!
rvc44
27.02.09 19:08:26
...[продолжение] Затем, чтобы работали макросы, надо обязательно при создании/открытии документа
выставлять режим MacroExecutionMode в значение, например, ooMacroExecModeALWAYS_EXECUTE. Например,
как в приведенном ниже примере:
[code]
LOCAL cURL, oDesktop, oDoc, aFileProperties[3] As com.sun.star.beans.PropertyValue
cURL = "file:///" + CHRTRAN( lcFileName, "\", "/" )
oDesktop = OOoGetDesktop()
aFileProperties[1] = OOoPropertyValue( "Hidden", .T. )
aFileProperties[2] = OOoPropertyValue( "FilterName", "HTML (StarCalc)" )
*-- hттp://www.oooforum.org/forum/viewtopic.phtml?t=58395
*-- hттp://api.openoffice.org/docs/common/ref/com/sun/star/document/MacroExecMode.html
aFileProperties[3] = OOoPropertyValue( "MacroExecutionMode", ooMacroExecModeALWAYS_EXECUTE )
oDoc = oDesktop.LoadComponentFromUrl( cURL, "_blank", 0, @ aFileProperties )
* Make sure that arrays passed to this document are passed zero based.
COMARRAY( oDoc, 10 )
[/code]
rvc44
27.02.09 19:09:53
...[продолжение] Где константы имеют следующие значения:
[code]
* constants group MacroExecMode Specify whether a macro can be executed since OpenOffice 1.1.2
* hттp://api.openoffice.org/docs/common/ref/com/sun/star/document/MacroExecMode.html
#define ooMacroExecModeNEVER_EXECUTE 0
#define ooMacroExecModeFROM_LIST 1
#define ooMacroExecModeALWAYS_EXECUTE 2
#define ooMacroExecModeUSE_CONFIG 3
#define ooMacroExecModeALWAYS_EXECUTE_NO_WARN 4
#define ooMacroExecModeUSE_CONFIG_REJECT_CONFIRMATION 5
#define ooMacroExecModeUSE_CONFIG_APPROVE_CONFIRMATION 6
#define ooMacroExecModeFROM_LIST_NO_WARN 7
#define ooMacroExecModeFROM_LIST_AND_SIGNED_WARN 8
#define ooMacroExecModeFROM_LIST_AND_SIGNED_NO_WARN 9
[/code]