<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://wiki2.linuxformat.ru/skins/common/feed.css?97"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>LXF104:VBA - История изменений</title>
		<link>http://wiki2.linuxformat.ru/index.php?title=LXF104:VBA&amp;action=history</link>
		<description>История изменений этой страницы в вики</description>
		<language>ru</language>
		<generator>MediaWiki 1.11.1</generator>
		<lastBuildDate>Wed, 13 May 2026 20:59:00 GMT</lastBuildDate>
		<item>
			<title>Crazy Rebel: /* Библиотеки и модули */</title>
			<link>http://wiki2.linuxformat.ru/index.php?title=LXF104:VBA&amp;diff=7702&amp;oldid=prev</link>
			<description>&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Библиотеки и модули&lt;/span&gt;&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Версия 12:31, 21 апреля 2009&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 40:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 40:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;удалить нельзя, пусть даже в ней нет ни одного модуля.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;удалить нельзя, пусть даже в ней нет ни одного модуля.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Врезка|Содержание=[[Изображение:LXF104_85_1.&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;jpg&lt;/del&gt;|Рис. 2|300px]]Рис. 2. Окно IDE.|Ширина=300px}}&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Врезка|Содержание=[[Изображение:LXF104_85_1.&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;png&lt;/ins&gt;|Рис. 2|300px]]Рис. 2. Окно IDE.|Ширина=300px}}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Теперь перейдем непосредственно к ''IDE''. Я думаю, даже самые&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Теперь перейдем непосредственно к ''IDE''. Я думаю, даже самые&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Tue, 21 Apr 2009 12:31:57 GMT</pubDate>			<dc:creator>Crazy Rebel</dc:creator>			<comments>http://wiki2.linuxformat.ru/index.php/%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:LXF104:VBA</comments>		</item>
		<item>
			<title>Crazy Rebel: /* Основы */</title>
			<link>http://wiki2.linuxformat.ru/index.php?title=LXF104:VBA&amp;diff=7700&amp;oldid=prev</link>
			<description>&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Основы&lt;/span&gt;&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Версия 10:38, 21 апреля 2009&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 79:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 79:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Использовать кириллицу в именах процедур, функций и переменных напрямую, как в ''VBA'', нельзя. Для этих целей можно использовать только Escape-идентификаторы:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Использовать кириллицу в именах процедур, функций и переменных напрямую, как в ''VBA'', нельзя. Для этих целей можно использовать только Escape-идентификаторы:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt; Sub [Макрос]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt; Sub [Макрос]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;            Dim [Переменная] As String&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;            Dim [Переменная] As String&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;            [Переменная] = “Escape”&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;            [Переменная] = “Escape”&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</description>
			<pubDate>Tue, 21 Apr 2009 10:38:19 GMT</pubDate>			<dc:creator>Crazy Rebel</dc:creator>			<comments>http://wiki2.linuxformat.ru/index.php/%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:LXF104:VBA</comments>		</item>
		<item>
			<title>Crazy Rebel: викификация, оформление, иллюстрация</title>
			<link>http://wiki2.linuxformat.ru/index.php?title=LXF104:VBA&amp;diff=7699&amp;oldid=prev</link>
			<description>&lt;p&gt;викификация, оформление, иллюстрация&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая статья&lt;/b&gt;&lt;/p&gt;&lt;div&gt;: '''''OOo Basic''' Помогаем перенести макросы ''VBA'' на свободную платформу&lt;br /&gt;
&lt;br /&gt;
==Из ''VBA'' в ''OOo'': проблемы первого дня==&lt;br /&gt;
&lt;br /&gt;
: Не секрет, что объектные модели ''Microsoft Office'' и ''OpenOffice.org'' различаются, что представляет проблему при переносе готовых макросов. '''Александр Маджугин''' расскажет, как свести их к минимуму.&lt;br /&gt;
&lt;br /&gt;
Миграция на новое программное обеспечение всегда связана с некоторыми проблемами, и смена офисного пакета – не исключение. Если при переходе от ''Microsoft Office'' к ''OpenOffice.org'' «обычное» использование компонентов особых трудностей не вызывает – ''OOo'', в большинстве ситуаций, успешно справляется с открытием документов своего конкурента (в худшем случае,&lt;br /&gt;
у вас нарушится форматирование), то попытки использовать макросы,&lt;br /&gt;
написанные на ''VBA'', чаще всего обречены на неудачу. И если вы собираетесь использовать макросы в документах ''ODF'', придется переписать&lt;br /&gt;
их заново.&lt;br /&gt;
&lt;br /&gt;
Когда люди, освоившие в свое время макроязык офисного пакета от редмондовского гиганта, переходят на вариант ''Basic'', встроенный в пакет от Sun, в большинстве случаев они сталкиваются с одними и теми же трудностями – эта статья как раз и посвящена им.&lt;br /&gt;
Мы не ставим своей задачей ответить на весь тот сонм вопросов,&lt;br /&gt;
которые может вызвать у вас миграция на ''OpenOffice.org'': понятно,&lt;br /&gt;
что в рамках статьи это невозможно. Задача данной статьи – решить&lt;br /&gt;
«проблемы первого дня», то есть те, с которыми вы можете столкнуться при написании первого же макроса. Некоторые из этих&lt;br /&gt;
проблем вызваны, скажем так, «особенностями» ''OpenOffice.org'', но&lt;br /&gt;
подавляющее большинство – неминуемыми отличиями между таким&lt;br /&gt;
привычным ''MSO'' и ''OOo''. А отличия начинаются еще до того, как вы&lt;br /&gt;
написали первую строчку кода – например, в самом принципе сохранения макросов.&lt;br /&gt;
&lt;br /&gt;
===Библиотеки и модули===&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF104_84_1.jpg|Рис. 1|300px]]Рис. 1. Диалог Макрос OpenOffice.org Basic.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Процедуры и функции, логическую общность которых и представляют собой макросы, сохраняются в модулях. Модули, в свою очередь, хранятся в библиотеках, а библиотеки – в контейнерах библиотек. Контейнерами библиотек могут являться документы ''OpenOffice.org'', кроме того, существует глобальный контейнер, который в окне '''Макрос OpenOffice.org Basic''' представлен двумя узлами дерева – '''Мои макросы''' и '''Макросы OpenOffice.org'''. Первый хранит макросы пользователя, а второй – макросы, поставляемые с дистрибутивом.&lt;br /&gt;
Несмотря на то, что макросы этого контейнера сохранены в различных директориях, а для каждого пользователя набор ветви '''Мои макросы''' будет различен, глобальный контейнер логически является&lt;br /&gt;
единым целым, напоминая скорее не папку файловой системы, а&lt;br /&gt;
некоторый фильтр, как, например, фильтры сообщений в почтовом&lt;br /&gt;
клиенте ''M2''.&lt;br /&gt;
&lt;br /&gt;
Открыть среду разработки ''OOo Basic'' саму по себе не представляется возможным: ее окно создается только для редактирования&lt;br /&gt;
какого-либо модуля. Поэтому для начала работы откройте вышеупомянутое окно '''Макросы OpenOffice.org Basic''' (рис. 1), выбрав в меню&lt;br /&gt;
'''Сервис &amp;gt; Макросы &amp;gt; Управление макросами &amp;gt; OpenOffice.org Бэйсик...''',&lt;br /&gt;
и создайте в какой-либо библиотеке новый модуль. Сразу же после&lt;br /&gt;
этого откроется окно IDE (рис. 2).&lt;br /&gt;
&lt;br /&gt;
Имейте в виду, что каждый контейнер библиотек всегда содержит&lt;br /&gt;
как минимум одну библиотеку с именем '''Standard'''. Эту библиотеку&lt;br /&gt;
удалить нельзя, пусть даже в ней нет ни одного модуля.&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF104_85_1.jpg|Рис. 2|300px]]Рис. 2. Окно IDE.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Теперь перейдем непосредственно к ''IDE''. Я думаю, даже самые&lt;br /&gt;
фанатичные поклонники ''OpenOffice.org'' согласятся со мной – ''IDE OOo Basic'', как минимум, аскетична. Лично мне больше всего не хватает&lt;br /&gt;
кнопок «закомментировать/раскомментировать выделенный блок».&lt;br /&gt;
Приходится делать это с каждой строкой в отдельности. Также, некоторые проблемы вначале может вызывать подсветка синтаксиса. Но&lt;br /&gt;
только вначале: со временем вы поймете, что подсветка в ''OOo Basic'' гораздо более удобна, чем подсветка синтаксиса в стандартной ''IDE Microsoft Office''.&lt;br /&gt;
&lt;br /&gt;
Из набора инструментов отладки вам будут доступны окна наблюдения за объектами и стеком вызовов, расположенные в нижней&lt;br /&gt;
части рабочей области. В принципе, их можно открепить, то есть&lt;br /&gt;
сделать плавающими, и передвинуть в любое удобное для вас место.&lt;br /&gt;
Отсутствие возможности поставить макрос на паузу с лихвой компенсируется удобным управлением точками останова, для каждой из&lt;br /&gt;
которых можно установить количество пропусков перед срабатыванием, а также временное отключение.&lt;br /&gt;
&lt;br /&gt;
===Основы===&lt;br /&gt;
&lt;br /&gt;
Структурная часть языка практически не отличается от ''VBA'' и не&lt;br /&gt;
готовит каких-то особых сюрпризов. Доступны практически все простые типы данных, к которым вы могли привыкнуть, работая с ''MS Office''. Единственным заметным отличием может стать классическая&lt;br /&gt;
ошибка определения високосного года, унаследованная в типе ''Data''&lt;br /&gt;
от электронных таблиц, когда, например, 1900 год считается високосным. С одной стороны, это несомненный недостаток языка, с&lt;br /&gt;
другой – это повышает совместимость макросов с электронными&lt;br /&gt;
таблицами, где данная особенность глубоко укоренилась еще со&lt;br /&gt;
времен ''Lotus''.&lt;br /&gt;
&lt;br /&gt;
Об объявлении переменных нужно, пожалуй, сказать еще вот что.&lt;br /&gt;
При анализе синтаксиса компилятор не проверяет имена переменных&lt;br /&gt;
на совпадение с именами функций, полностью полагаясь на процедуру разрешения конфликтов. Это создает возможность явно объявить переменную с именем функции, полностью блокировав работу последней во всей области видимости данной переменной:&lt;br /&gt;
&lt;br /&gt;
 Sub VarIntExemple&lt;br /&gt;
            Print Int (52.3)&lt;br /&gt;
            Dim Int As Integer&lt;br /&gt;
            Int = 7&lt;br /&gt;
            Print Int (52.3)&lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
Поэтому, объявляя переменные, надо быть предельно осторожным.&lt;br /&gt;
&lt;br /&gt;
Использовать кириллицу в именах процедур, функций и переменных напрямую, как в ''VBA'', нельзя. Для этих целей можно использовать только Escape-идентификаторы:&lt;br /&gt;
 Sub [Макрос]&lt;br /&gt;
&lt;br /&gt;
            Dim [Переменная] As String&lt;br /&gt;
            [Переменная] = “Escape”&lt;br /&gt;
            Print [Переменная]&lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
В остальном же здесь не должно возникнуть никаких трудностей.&lt;br /&gt;
Некоторое недоумение может вызвать разве что привычка интерпретатора всегда проверять все условия в операторах управления, даже&lt;br /&gt;
если после проверки первого уже понятно, что общее условие (не)&lt;br /&gt;
будет выполняться.&lt;br /&gt;
&lt;br /&gt;
Запуск уже существующего макроса обычно не вызывает проблем у тех, кто переходит на ''OOo Basic'' с ''VBA''. Здесь все почти то же&lt;br /&gt;
самое: можно связать макрос с объектом в документе, можно создать&lt;br /&gt;
пункт меню или кнопку на панели инструментов, можно назначить&lt;br /&gt;
горячие клавиши или определить запуск макроса по определенному&lt;br /&gt;
событию.&lt;br /&gt;
&lt;br /&gt;
Но все это только до тех пор, пока не потребуется вызвать процедуру из кода ''Basic'' по ее полному имени, включающему документ,&lt;br /&gt;
в котором она сохранена, библиотеку и модуль. Здесь все начинают лихорадочно искать аналог ''VBA''’шного '''Call''', а его нет. Можно,&lt;br /&gt;
конечно, попробовать использовать '''Shell (“LibraryName.ModuleName.MacroName'''”) и узнать, что такой файл не найден. Те, кто поупорнее, скоро обнаружат, что в пределах одного контейнера библиотек можно выполнить макрос и с помощью '''Shell''', если передать ей параметр, не заключая его в кавычки: Shell (LibraryName.ModuleName.MacroName)'''. Правда, при этом произойдет ошибка «Несовместимые типы», которую, конечно, можно перехватить. Но все это можно сделать и без '''Shell''' – '''LibraryName.ModuleName.MacroName''' тоже дает&lt;br /&gt;
неплохой результат.&lt;br /&gt;
&lt;br /&gt;
Можно попытаться развить идею дальше так:&lt;br /&gt;
&lt;br /&gt;
 Shell (“soffice”,,“““macro :///LibraryName.ModuleName.MacroName”””)&lt;br /&gt;
&lt;br /&gt;
или привлечь сервис '''SystemShellExecute''':&lt;br /&gt;
&lt;br /&gt;
 oSSE = createUnoService(“com.sun.star.system.SystemShellExecute”)&lt;br /&gt;
 oSSE.execute(“soffice”, “““macro:///LibraryName.ModuleName.&lt;br /&gt;
 MacroName”””, 0)&lt;br /&gt;
&lt;br /&gt;
фактически эмулируя запуск макроса из командной строки.&lt;br /&gt;
&lt;br /&gt;
Однако это все обходные и не очень удобные и красивые пути,&lt;br /&gt;
не позволяющие запустить макрос, сохраненный в определенном&lt;br /&gt;
документе. Между тем, ''OpenOffice.org'' имеет специально предназначенный для этих целей интерфейс '''com.sun.star.script.provider.XScript'''.&lt;br /&gt;
И если воспользоваться им, все получается относительно легко:&lt;br /&gt;
&lt;br /&gt;
 Sub RunMacroFromDocument (ByVal oDoc As Object)&lt;br /&gt;
          Dim aOutParamIndex (2)&lt;br /&gt;
          Dim aOutParam (2)&lt;br /&gt;
          ' Создаем СкриптПровайдер&lt;br /&gt;
          oSP = oDocA.ScriptProvider()&lt;br /&gt;
          ' Получаем скрипт&lt;br /&gt;
          oScript = oSP.getScript(“vnd.sun.star.script:Standard.Module1.Main?language=Basic&amp;amp;location=document”)&lt;br /&gt;
          ' Запускаем макрос&lt;br /&gt;
          oScript.invoke(Array(“1 параметр”, “2 параметр”, “3 параметр”),aOutParamIndex(),aOutParam())&lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
Примерно так может выглядеть запускаемый макрос:&lt;br /&gt;
&lt;br /&gt;
 Sub Main (a as String, ByVal b as string, c as string)&lt;br /&gt;
          print a&lt;br /&gt;
          print b&lt;br /&gt;
          print c&lt;br /&gt;
          a=b&lt;br /&gt;
          b = “b”&lt;br /&gt;
          c = “c”&lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
После выполнения этого кода массивы '''aOutParamIndex''' и '''aOutParam''' будут иметь следующее содержимое:&lt;br /&gt;
&lt;br /&gt;
* '''aOutParamIndex''' = {0,2} – позиции выходных параметров ['''out'''] или параметров, используемых как для входных, так и для выходных значений ['''inout'''] вызываемой функции. Сами аргументы передаются методу '''invoke()''' также в виде массива.&lt;br /&gt;
* '''aOutParam''' = {«2 параметр»,»c»} – этот массив содержит выходные значения параметров. Как видно, параметр '''b''' макроса '''Main''' в нем отсутствует, так как он является входящим для процедуры '''Main'''. На этот факт указывает и содержимое '''aOutParamIndex'''.&lt;br /&gt;
&lt;br /&gt;
===Изучаем объектную модель===&lt;br /&gt;
&lt;br /&gt;
Естественно, что для применения подобных методов необходимо хотя&lt;br /&gt;
бы немного знать ''API OpenOffice.org''. К сожалению, в ''IDE OOo'' отсутствует автодополнение. Затруднить изучение API методом «научного&lt;br /&gt;
тыка», на начальных этапах, могут и особенности макрорекордера.&lt;br /&gt;
Поэтому о записи макросов поговорим подробнее.&lt;br /&gt;
&lt;br /&gt;
Дело в том, что макрорекордер использует для записи макросов&lt;br /&gt;
так называемый диспетчер (dispatcher), работающий через весьма&lt;br /&gt;
специфический интерфейс ''UNO''. ''UNO'' – некоторое подобие среды&lt;br /&gt;
''COM'' в Windows, предназначенное для обеспечения взаимодействия&lt;br /&gt;
компонентов на любой платформе, так как понятно, что использовать&lt;br /&gt;
''COM'' в Linux или Mac OS не получится.&lt;br /&gt;
&lt;br /&gt;
Если не вдаваться в подробности, то диспетчер эмулирует действия пользователя. Чтобы было понятнее, приведем простой пример. Допустим, нам надо перенести данные из ячейки '''A1''' текущего листа книги ''Calc'' в ячейку '''A2'''. Вот какой код (за исключением комментариев, разумеется) будет сгенерирован макрорекордером, если запустить запись макроса и скопировать данные из первой ячейки&lt;br /&gt;
во вторую:&lt;br /&gt;
&lt;br /&gt;
 sub Main&lt;br /&gt;
 rem объявление переменных&lt;br /&gt;
 dim document as object&lt;br /&gt;
 dim dispatcher as object&lt;br /&gt;
 rem Получение доступа к фрэйму документа&lt;br /&gt;
 document = ThisComponent.CurrentController.Frame&lt;br /&gt;
 rem Создание сервиса диспетчера&lt;br /&gt;
 dispatcher = createUnoService(“com.sun.star.frame.DispatchHelper”)&lt;br /&gt;
 rem Установка значения свойств&lt;br /&gt;
 dim args1(0) as new com.sun.star.beans.PropertyValue&lt;br /&gt;
 args1(0).Name = “ToPoint”&lt;br /&gt;
 args1(0).Value = “$A$1”&lt;br /&gt;
 rem Выбор ячейки&lt;br /&gt;
 dispatcher.executeDispatch(document, “.uno:GoToCell”, ““, 0, args1())&lt;br /&gt;
 rem Копирование данных в буфер&lt;br /&gt;
 dispatcher.executeDispatch(document, “.uno:Copy”, ““, 0, Array())&lt;br /&gt;
 rem Установка значения свойств&lt;br /&gt;
 dim args3(0) as new com.sun.star.beans.PropertyValue&lt;br /&gt;
 args3(0).Name = “ToPoint”&lt;br /&gt;
 args3(0).Value = “$A$2”&lt;br /&gt;
 rem Выбор ячейки&lt;br /&gt;
 dispatcher.executeDispatch(document, “.uno:GoToCell”, ““, 0, args3())&lt;br /&gt;
 rem Вставка&lt;br /&gt;
 dispatcher.executeDispatch(document, “.uno:Paste”, ““, 0, Array())&lt;br /&gt;
 end sub&lt;br /&gt;
&lt;br /&gt;
Заметьте, что хотя для доступа к текущему документу используется глобальная переменная '''ThisComponent''', содержащая ссылку на текущий компонент, лист книги не получается из нее напрямую: используется ссылка на фрейм, являющийся элементом GUI. То есть доступ&lt;br /&gt;
осуществляется не непосредственно к листу книги, а к окну приложения. Затем выполняются стандартные операции копирования и вставки&lt;br /&gt;
с использованием буфера обмена. Такие действия приводят к тому, что&lt;br /&gt;
копируются не только данные, но и форматирование ячейки, а в случае, когда целевая ячейка уже содержит некоторые данные, пользователю будет выведено предупреждение о перезаписи. Кроме того, эти действия будут всегда производиться с текущим листом, а если будет&lt;br /&gt;
необходимо выполнить то же действие с чем-то другим, этот макрос&lt;br /&gt;
вам уже не поможет. Впрочем, это справедливо и для ''Excel''.&lt;br /&gt;
&lt;br /&gt;
Коренное же отличие от макрорекордера ''VBA'' – в том, что вместо&lt;br /&gt;
прямого доступа к элементу используется команда диспетчеру ''UNO''.&lt;br /&gt;
Сравните способ выбора ячейки в этом макросе:&lt;br /&gt;
&lt;br /&gt;
 dispatcher.executeDispatch(document, “.uno:GoToCell”, ““, 0, args1())&lt;br /&gt;
&lt;br /&gt;
и в аналогичном макросе, записанном в ''Excel'',&lt;br /&gt;
&lt;br /&gt;
 Range(“A1”).Select&lt;br /&gt;
&lt;br /&gt;
где используется объектная модель.&lt;br /&gt;
&lt;br /&gt;
Таким образом, получить представление об API, изучая записанные макросы в ''OOo Basic'', невозможно. Кроме того, вы не сможете&lt;br /&gt;
использовать диспетчер, если запустите пакет без GUI, например, в&lt;br /&gt;
режиме сервера. А между тем, только использование API позволяет&lt;br /&gt;
писать сложные макросы, действительно облегчающие работу.&lt;br /&gt;
&lt;br /&gt;
Посмотрим, как задачу выбора ячейки можно решить с использованием API, заодно ответив на один из самых часто задаваемых&lt;br /&gt;
новичками вопросов: «Как получать и записывать значение ячейки книги ''Calc''?».&lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующий код:&lt;br /&gt;
&lt;br /&gt;
 Sub Main&lt;br /&gt;
           Dim oDoc As Object ' это наш документ&lt;br /&gt;
           Dim oSheet As Object ' лист&lt;br /&gt;
           ' Ячейки&lt;br /&gt;
           Dim oCell1 As Object&lt;br /&gt;
           Dim oCell2 As Object&lt;br /&gt;
           oDoc = ThisComponent&lt;br /&gt;
           ' получаем активный (текущий) лист&lt;br /&gt;
           oSheet = oDoc.getCurrentController.ActiveSheet&lt;br /&gt;
           ' получаем ячейки листа&lt;br /&gt;
           oCell1 = oSheet.getCellRangeByName(“A1”)&lt;br /&gt;
           oCell2 = oSheet.getCellRangeByName(“A2”)&lt;br /&gt;
           ' Получаем значение ячейки A1&lt;br /&gt;
           ' и помещаем его в A2&lt;br /&gt;
           oCell2.setValue (oCell1.getValue)&lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
Как видите, здесь не используется диспетчер, а применен&lt;br /&gt;
«чистый» API. Текущий лист в этом коде получается из объекта&lt;br /&gt;
'''CurrentController''', возвращаемого методом '''getCurrentController'''. Метод&lt;br /&gt;
«знает» текущее состояние объекта, в частности, активный лист, что&lt;br /&gt;
нам и нужно. Если необходим какой-то конкретный лист, то нужно&lt;br /&gt;
сначала получить доступ к коллекции листов книги ('''Sheets''') и далее&lt;br /&gt;
выбирать листы с помощью методов '''getByIndex''' и '''getByName'', используя для идентификации листа его номер или имя:&lt;br /&gt;
&lt;br /&gt;
 oSheet = oDoc.getSheets.getByIndex(0) ' первый лист книги&lt;br /&gt;
 oSheet = oDoc.getSheets.getByName(“Лист1”) ' лист с именем Лист1&lt;br /&gt;
&lt;br /&gt;
«Отправной точкой» для объектов данного макроса можно назвать&lt;br /&gt;
глобальную переменную '''ThisComponent''', ссылающуюся на «этот&lt;br /&gt;
документ». Заметим тут следующее: термин «этот документ» в ''OOo Basic'' несколько сложнее, чем просто активный документ. Активный&lt;br /&gt;
документ можно получить из переменной '''StarDesktop''' методом&lt;br /&gt;
'''getCurrentComponent'''. Однако это не всегда удобно, поскольку IDE тоже является компонентом '''StarDesktop''' (как и справочная система),&lt;br /&gt;
и при запуске макроса из среды разработки вы будете получать ссылку именно на нее. Переменная же '''ThisComponent''' всегда ссылается на&lt;br /&gt;
документ, причем на активный, только в том случае, если встречается&lt;br /&gt;
в коде макроса, сохраненного в самом пакете ''OOo Basic'' (например, в&lt;br /&gt;
группе '''Мои макросы'''). Если же макрос сохранен непосредственно в&lt;br /&gt;
документе, то '''ThisComponent''' ссылается на этот документ, независимо от того, является ли он активным.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, за редкими исключениями, все объекты в ''OOo Basic'' наследуются от двух глобальных объектов, описанных выше,&lt;br /&gt;
т.е. '''ThisComponent''' и '''StarDesktop'''. Кроме них, есть еще две переменные, используемые не так часто – это '''BasicLibraries''' и '''DialogLibraries''', которые ссылаются на коллекции библиотек макросов данного контейнера (например, документа). В числе прочего, они предоставляют&lt;br /&gt;
интересную возможность переписывать код макроса программно –&lt;br /&gt;
исключение составляет лишь код модуля, макрос которого выполняется в текущий момент. Таким образом вы можете изменять даже&lt;br /&gt;
код той библиотеки, из которой выполняется ваш макрос. Это дает&lt;br /&gt;
удивительные возможности сохранения настроек прямо в коде вашего приложения.&lt;br /&gt;
&lt;br /&gt;
Чтобы получить библиотеки глобального контейнера из документа,&lt;br /&gt;
необходимо обратиться к переменным '''BasicLibraries''' и '''DialogLibraries'''&lt;br /&gt;
как к составляющим глобального обзора '''GlobalScope''':&lt;br /&gt;
&lt;br /&gt;
 cGlobalBLibraries = GlobalScope.BasicLibraries&lt;br /&gt;
&lt;br /&gt;
Тут-то и становится ясно, почему в начале мы говорили, что глобальный контейнер один.&lt;br /&gt;
&lt;br /&gt;
===Рентген для ''OpenOffice.org''===&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF104_87_1.jpg|Рис. 3|300px]]Рис. 3. ''Xray'' – незаменимый инструмент при разработке макросов для ''OpenOffice.org''. |Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Вернемся к изучению API ''OpenOffice.org''. При использовании API&lt;br /&gt;
всегда встает вопрос о том, как узнать все свойства и методы того&lt;br /&gt;
или иного объекта. И если со свойствами все более-менее понятно – их, вместе с их значениями, можно просматривать в стандартном окне наблюдения IDE, то методы обычно вызывают некоторые&lt;br /&gt;
затруднения. Между тем, практически каждый объект объектной&lt;br /&gt;
модели ''OpenOffice.org'' имеет методы и свойства – '''Dbg_Methods''' и&lt;br /&gt;
'''Dbg_Properties''', соответственно. На практике очень удобно использовать утилиту ''Xray'', выводящую свойства и методы в удобной форме и&lt;br /&gt;
предоставляющую дополнительные возможности для изучения объекта. Найти ее можно на сайте http://www.ooomacros.org/dev.php#101416&lt;br /&gt;
или на других ресурсах, посвященных ''OpenOffice.org''.&lt;br /&gt;
&lt;br /&gt;
Использование этого инструмента чрезвычайно просто – достаточно включить в ваш код вызов ''Xray'', передав ему в качестве параметра интересующий вас объект:&lt;br /&gt;
&lt;br /&gt;
 xray VarObject&lt;br /&gt;
&lt;br /&gt;
где '''VarObject''' – объект, который вы хотите изучить. Например:&lt;br /&gt;
  Sub Main&lt;br /&gt;
           xray ThisComponent&lt;br /&gt;
  End Sub&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
 Sub Main&lt;br /&gt;
           Dim oDoc As Object&lt;br /&gt;
            oDoc = ThisComponent&lt;br /&gt;
           xray oDoc&lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
Как только при выполнении макроса очередь дойдет до строки,&lt;br /&gt;
вызывающей ''Xray'', будет выполнена его основная процедура, и вы&lt;br /&gt;
увидите окно, подобное показанному на рис. 3.&lt;br /&gt;
&lt;br /&gt;
Вы можете копировать содержимое основного окна ''Xray'' как&lt;br /&gt;
обычный текст. Двойной щелчок по свойству в этом окне позволит&lt;br /&gt;
просматривать с помощью ''Xray'' объект, возвращаемый этим свойством – конечно, только в том случае, если это свойство не предназначено только для записи. То же касается и методов, просматриваемого объекта, в том случае, если методы возвращают некоторый&lt;br /&gt;
объект.&lt;br /&gt;
&lt;br /&gt;
Если на вашем компьютере установлен ''SDK OpenOffice.org'', то вы&lt;br /&gt;
можете переходить к описанию объекта в нем, нажав соответствующую кнопку на панели ''Xray''. Выбрав необходимые пункты в списке,&lt;br /&gt;
можно ознакомиться с интерфейсами и сервисами, поддерживаемыми изучаемым объектом.&lt;br /&gt;
&lt;br /&gt;
Из всего вышеописанного можно сделать вывод, что в ''OpenOffice.org'' используется несколько необычная объектная модель. Фактически,&lt;br /&gt;
можно сказать, что в ней не используется такое понятие, как классы,&lt;br /&gt;
а стало быть, создавать свои классы тоже нельзя. Вместо них здесь&lt;br /&gt;
используются родственные понятия: интерфейсы и сервисы.&lt;br /&gt;
&lt;br /&gt;
Интерфейсы предоставляют объектам методы, причем один&lt;br /&gt;
интерфейс может включать другой, «подчиненный» интерфейс, и&lt;br /&gt;
соответственно предоставлять объекту методы этого «подчиненного». Естественно, что один объект не может содержать только&lt;br /&gt;
часть методов какого-то интерфейса: он поддерживается непременно полностью. Таким образом, если мы знаем, что объект имеет&lt;br /&gt;
метод '''getByIndex''', то можем быть уверены, что этот объект имеет и&lt;br /&gt;
метод '''getCount''', предоставляемый тем же интерфейсом '''com.sun.star.container.XIndexAccess'''. Однако на практике подобные рассуждения&lt;br /&gt;
опасны, и лучше знать наверняка, поддерживает ли объект нужный&lt;br /&gt;
вам интерфейс, так как случается, что методы с одинаковыми именами предоставляются различными интерфейсами. Например, функция '''endProperty()''' может быть предоставлена и интерфейсом '''com::sun::star::configuration::backend::XlayerHandler''', и интерфейсом '''com::sun::star::configuration::backend::XUpdateHandler'''. Узнать, какими именно интерфейсами обладает данный объект, помогает свойство '''Dbg_SupportedInterfaces''', возвращающее список всех интерфейсов.&lt;br /&gt;
&lt;br /&gt;
Сервисы представляют собой наборы интерфейсов, свойств&lt;br /&gt;
и методов, и в большой степени напоминают привычные классы.&lt;br /&gt;
Свойство объекта '''SupportedServiceNames''' является строковым массивом, содержащим имена всех поддерживаемых объектом сервисов.&lt;br /&gt;
Кроме того, метод '''supportsService''', требующий в качестве параметра&lt;br /&gt;
имя сервиса в виде строки, возвращает '''True''', если данный сервис поддерживается данным объектом.&lt;br /&gt;
&lt;br /&gt;
Такая организация объектной модели может вначале показаться&lt;br /&gt;
несколько сложной и непривычной. Однако, поработав некоторое&lt;br /&gt;
время с ''API OOo Basic'', вы поймете, что она гораздо мощнее и гибче&lt;br /&gt;
традиционной – пусть и нелегка в освоении, особенно на ранних этапах работы. Именно она делает ''OOo Basic'' намного более перспективным макроязыком, чем его прямые конкуренты. '''LXF'''&lt;br /&gt;
&lt;br /&gt;
===Полезные ссылки===&lt;br /&gt;
&lt;br /&gt;
* http://api.openoffice.org/ – подробное описание интерфейсов и сервисов можно найти здесь.&lt;br /&gt;
* http://documentation.openoffice.org/HOW_TO/various_topics/VbaStarBasicXref.pdf – документ, посвященный переходу с ''VBA'' на ''OOo Basic''. О, как мне его не хватало пару лет назад!&lt;/div&gt;</description>
			<pubDate>Tue, 21 Apr 2009 10:37:29 GMT</pubDate>			<dc:creator>Crazy Rebel</dc:creator>			<comments>http://wiki2.linuxformat.ru/index.php/%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:LXF104:VBA</comments>		</item>
	</channel>
</rss>