LXF83:OOo Basic
|
|
|
OOo Basic: полезные советы
ЧАСТЬ 4 Продвинем знания о макросах с помощью мудрых советов Марка Бейна.
За последние три выпуска я показал вам несколько своих любимых приемов написания макросов для Writer и Calc, входящих в состав открытого офисного пакета OpenOffice.org. Мы автоматизировали выполнение задач и создание отчетов, писали в документы из командной строки, ускорили получение полезной информации из базы данных… На сей раз я поднесу вам на блюдечке 14 полезных советов для работы с OOo Basic – они помогут вам повысить эффективность макросов, вне зависимости от программы офисного пакета, с которой вы их используете.
Правильная структура данных
Строго говоря, это совет скорее не для OOo Basic, а для программирования вообще: подумайте о своих данных до того, как будете с ними работать – в дальнейшем это избавит вас от множества проблем.
Рассмотрим один из распространенных примеров использования макроса в OOo: вы захотели создать справочник имен и адресов. Если вы новичок в создании баз данных, то, скорее всего, вы создадите одну таблицу, содержащую, скажем, пять полей – имя, адрес, телефон, мобильный телефон и email. На вид вполне разумно; но давайте немного подумаем. Представьте, что вы имеете дело с большой организацией.
Может оказаться, что несколько людей проживают по одному адресу – в результате получится дублирование данных. Согласитесь, что это не здорово: гробится больше дискового пространства, чем надо, и существует большая вероятность того, что данные могут быть неверными. Взгляните на следующий пример:
Таблица - Покупатели
Имя | Адрес |
Джо Твайтс, | Ансэнк, Камбрия, CA11 9TG |
Джозеф Твайтс, | Ансэнк, Камбрия, CA10 9TG |
Зная, что один Ансэнк имеет почтовый индекс CA11, а другой CA10, и что Твайтс – довольно распространенная фамилия в этом районе, мы не можем сказать, два ли это разных человека по имени Джо Твайтс или же он один, но в почтовом индексе была допущена ошибка. При правильном проектировании баз данных такие ошибки могут быть сведены к минимуму.
О проектировании баз данных я рассказывать не собираюсь – этот вопрос требует отдельного рассмотрения и достоин целой книги. Но существует простое правило, которым вы можете воспользоваться: проектируйте вашу базу данных так, чтобы каждое поле вводилось только один раз. Поэтому в нашем примере вместо одной таблицы можно использовать две:
Таблица - Покупатели
ID | Имя | Фамилия | Адрес_id |
1 | Джо | Твайтс | 1 |
2 | Джозеф | Твайтс | 2 |
Таблица - Адреса
ID | Город | Графство | Почтовый_индекс |
1 | Ансэнк | Камбрия | CA11 9TG |
2 | Ансэнк | Камбрия | CA10 9TG |
Теперь можно видеть, что это два разных покупателя с одинаковым именем, но проживающих по разным адресам. Кому интересно, Джо (владелец передвижной лавки видеофильмов, который заявляется к нам домой каждый вторник) на самом деле живет в Лэнгветби, но ради нашего примера я это подправил.
Максимум пользы от базы данных
При правильно построенной базе данных вы сможете избежать одной из позорнейших ошибок: набора значений, забитого в макрос. Предположим, у вас есть форма для добавления адресов в таблицу, а одна из колонок называется County (графство). Можно и просто забить все данные в таблицу – но зачем это нам? Куда как лучше использовать диалоговое окно и макрос, пусть они вкалывают.
Вернемся к вводу данных: очевидно, лучшим решением является создание ниспадающего списка из названий округов. Другие варианты реализации: А – написать макрос, содержащий массив названий, из которых потом составляется список, или В – хранить имена округов в таблице базы данных, а затем заполнять список из нее. Если вы выбрали вариант А – получите общественное «у-у-уу», а если В – чувство глубокого морального удовлетворения.
Почему вариант В лучше? Потому, что вещи имеют свойство меняться со временем («Когда я служил под знаменами герцога Камберлендского, внучек, никаких ваших Камбрий и в помине не было, а был Камберленд».). Не будете же вы редактировать код каждый раз при добавлении новых данных! Поэтому храните данные в базе и поручите макросу сделать работу за вас. Это подводит нас к следующему совету: «ХРАНИТЕ ДАННЫЕ В БАЗЕ И ПОРУЧИТЕ МАКРОСУ СДЕЛАТЬ РАБОТУ ЗА ВАС.»
Автоматизация диалоговыми окнами
Если вам комфортно работать с данными из командной строки, замечательно. Но если нет, или вы хотите поручить работу ещё кому-то, подумайте об использовании диалоговых окон. Таким способом возможно добавить данные, написав макрос, который составляет запрос insert и берет значения из поля ввода, таким образом:
SQL = “insert into county (name) values (‘” + textbox.value + “‘)”
Вы также можете изменить данные, используя список, поле ввода и запрос update:
SQL = “update county set name = ‘” + textbox.value + “‘” + “ where name =’” + listbox.value + “‘”
Работайте с OOo 2.0
Прежде чем приняться за создание приложений, удостоверьтесь, что работаете с OpenOffice.org 2.0. Может оказаться, что ваш любимый дистрибутив по умолчанию не содержит последней стабильной версии офисного пакета – если вы, например, используете Debian Sarge, то по умолчанию будет установлен OOo 1.1.3. Прежде чем приступать к работе, вам следует установить версию 2.0. Почему? Потому что в этой версии были расширены возможности OOo Basic; в частности, теперь вы можете использовать код для добавления пунктов меню.
Если вы создали макрос в OOo 1.x.x, а затем обновились до OOo 2.x.x, то обнаружите, что ваши модули исчезли – нажитое непосильным трудом кануло в никуда… Не отчаивайтесь, ничего не потерялось. Запустите ваш любимый терминал, перейдите в домашний каталог и наберите ls -la. Среди множества каталогов вы увидите каталоги с похожим названием:
drwxr-xr-x 3 bainm bainm 4096 1999-10-20 04:08 .openoffice drwx------ 3 bainm bainm 4096 2006-05-31 20:30 .OpenOffice.org2
Разработчики OpenOffice.org не волки и ваших макросов не съели – просто они хранятся в другом каталоге. Если вы просмотрите содержимое этих каталогов, то встретите похожие названия: .openoffice/1.1.3/user/basic/Standard и .OpenOffice.org2/user/basic/Standard. Это каталоги, где находятся ваши модули и диалоги, поэтому прежде чем кодировать, удостоверьтесь, что OOo 2.0 имеет доступ к старым макросам:
mv .OpenOffice.org2/user/basic/Standard .OpenOffice.org2/user/basic/Standard_old ln -s .openoffice/1.1.3/user/basic/Standard OpenOffice.org2/user/basic/Standard
Перезапустите OpenOffice.org, теперь он должен обнаружить ваши макросы.
Запуск макросов из меню
Вы уже привыкли запускать макросы с помощью кнопки Run в окне Basic (там, где вы набираете код). Вы также знаете, как запустить макрос через меню Tools > Macros > Macro... Мило, но раздражающе долго, особенно если макрос часто используется. Почему бы не добавить ссылку на полезный макрос в меню OOo? Отличная идея!
Перейдите к меню OOo, нажмите на Tools и выберите Configure... OOo отобразит диалог настроек – проверьте, что выбрана вкладка Menu. В нижней половине экрана выберите макрос для добавления в меню. В верхней половине экрана найдите место для нового пункта меню, а затем нажмите New, чтобы создать его.
Теперь вы можете запросто вызвать макрос, когда захотите. Если вы любите клавиатуру больше, чем мышь, то назначьте горячие клавиши для быстрого вызова макроса: снова отправляйтесь в диалог OOo Configuration, но теперь выберите вкладку Keyboard. Чтобы запустить макрос при открытии документа… угадали: используйте диалог Configuration. Если вы выберете закладку Events, то увидите всевозможные события, к которым можно назначить макрос – все, что надо сделать, это выбрать Open Document.
Добавьте меню автоматически
Если вы используете или обновились до OOo 2.0, то сможете создавать дополнительные пункты меню из макроса. Чтобы это сделать, используйте свойство com.sun.star.beans.PropertyValue. Например, если вы хотите добавить процедуру showMessage из модуля с именем OOobasic4, можете использовать следующий способ:
MenuItem(0).Name = “CommandURL” MenuItem(0).Value = “macro:///Standard.OOobasic4.showMessage()” MenuItem(1).Name = “Label” MenuItem(1).Value = “Do whatever you want direct from the menu” Menu.insertByIndex( 0,MenuItem)
Чтобы понять, как это работает, взгляните на макрос setUpMenu с нашего диска. Опережаю ваш вопрос: удалять уже существующие пункты меню нельзя, можно только добавлять свои собственные, как элементы в обычных меню OOo.
Разбивайте строки кода
Это совет по улучшению читабельности вашего кода. Читабельность... есть ли такое слово? Короче, вы её улучшите, разбивая длинные строки кода на несколько с помощью символа нижнего подчеркивания. Например,
MenuItem = CreateMenuItem( “macro:///Standard.OOobasic4.showMessage()”, “Show a test message” )
стоит превратить в
MenuItem =_ CreateMenuItem( “macro:///Standard.OOobasic4.showMessage()”,_ “Show a test message” )
На работу кода не влияет, но выглядит лучше – ну, то есть, читабельнее.
Использование нижнего подчеркивания не поможет, если вы попытаетесь расчленить строку вроде этой:
SQL = “select customer.firstname, customer.surname, address.town, address.county, address.postcode where customer.address_id = address.id”
Чтобы разбить её на несколько строк, воспользуйтесь символом «плюс»:
SQL = “select customer.firstname, customer.surname”_ + “, address.town, address.county, address.postcode”_ + “ where customer.address_id = address.id”
Повторюсь: разбиение длинной строки кода на несколько строк никак не повлияет на работоспособность кода, но зато такой код будет проще понять.
Помните о модулях и библиотеках
Вместо того, чтобы сохранять всю свою работу в огромном модуле, попробуйте разбить макросы на отдельные осмысленные функции, запишите их в несколько модулей, а модулям дайте имена, отражающие их суть: Макрос1, Макрос2, Макрос3 и так далее – это, согласитесь, нудно и непонятно. Если вы дадите «говорящие» имена своим макросам (например, назовёте их СоздУчетЗапись или ОбслужитьПокупателя), то в будущем скажете мне спасибо. Но не увлекайтесь – не пытайтесь создать легион модулей, в каждом из которых будет по одному или два макроса.
Когда у вас наберётся много модулей, можете сгруппировать их в библиотеки. Опять-таки, попытайтесь дать им осмысленные имена.
Не скупитесь на комментарии
Когда вы пишете макрос, то думаете, что все понятно и логично. Но когда вы вернетесь к нему через полгода-год, изрядно подзабыв, что, собственно, делали, код может показаться непонятным. Я бы пореко- мендовал вам по ходу работы делать заметки – просто объясните, чего вы пытаетесь достичь. Как добавить комментарий? Для этого начните строку со слова REM или одиночной кавычки: REM Это комментарий ‘ И это А это уже не комментарий Вы также можете добавить комментарий в конце строки кода msgbox “Это сообщение” ‘а это комментарий С другой стороны, не пытайтесь закомментировать всё, не то ваш код затеряется в пояснениях: REM Цель данной куска кода состоит в том, REM чтобы сообщить пользователю информацию. В небольшом окне отобразится текстовое сообщение REM Пользователь должен подтвердить, что он прочел сообщение. REM В противном случае выполнение программы REM продолжено не будет. msgbox “Ну здравствуй!”
Используйте встроенные диалоговые окна
Совершенно незачем делать всю работу по созданию диалоговых окон – лучше позаимствовать уже встроенные в OpenOffice.org решения. Предположим, вы хотите, чтобы пользователь выбрал папку для сохра- нения результатов. Все, что вам надо – это диалог FolderPicker: Dim FolderDialog, UserFolder FolderDialog = CreateUnoService(“com.sun.star.ui.dialogs. FolderPicker”) UserFolder = FolderDialog.Execute() Чтобы узнать, какие ещё предлагаются диалоги, проконсультируй- тесь на сайте OpenOffice.org или загляните на http://snipurl.com/rh5z. На этой странице вы найдете подробное описание каждого из диалогов. Их немного, но из них можно извлечь немалую пользу и сберечь свое время. Раз уж зашла речь о com.sun.star... На самом деле это набор встроенных модулей OOo. Вы, несомненно, заметили, что используя какой-либо объект OOo, мы всегда применяем следующий формат: MyObject = CreateUnoService(“com.sun.star.foo.bar.object”) Это довольно просто, но иногда случается, что вы не можете опре- делить, какие именно еще объекты вам пригодятся. Снова, вы найдёте всю дополнительную информацию о списке модулей в com.sun.star на странице, посвященной OpenOffice.org, по адресу http://snipurl. com/rh61.
Форматируйте отчеты
За последние месяцы мы увидели, как писать в Writer, считать в Calc и использовать данные из баз данных. Вы также можете использовать макрос для того, чтобы сделать вашу работу более презентабельной с минимумом усилий. Представьте, что вы заполнили таблицу из базы данных, выполнили всю необходимую работу (с помощью макроса, конечно), а теперь готовы распечатать свой отчет для менеджера/учи- теля (который уж обязательно повысит вам зарплату/оценку за вашу чудесную работу). Что вы обычно делаете с документом перед тем, как его распечатать? Я предполагаю, что добавляете заголовок, номер стра- ницы, общее число страниц и дату. Это делается просто: oDoc = ThisComponent oPageNumber = oDoc.createInstance( “com.sun.star.text. TextField.PageNumber” ) oPageCount = oDoc.createInstance( “com.sun.star.text. TextField.PageCount” ) oDateTime = oDoc.createInstance( “com.sun.star.text. TextField.DateTime” ) Теперь хорошо бы сделать нижний и верхний колонтитулы: oStyles = oDoc.getStyleFamilies().getByName( “PageStyles” ) oPStyle = oStyles.getByName( “Default” ) oHeader = oPStyle.RightPageHeaderContent oFooter = oPStyle.RightPageFooterContent Вы можете поместить текст в любое место колонтитула: oHeader.getCenterText().setString( “LXF83 Article” ) Однако функции (например, DateTime) обрабатываются по-друго- му, с применением курсора: oCursor = oHeader.getRightText().createTextCursor() oHeader.getRightText().insertTextContent( oCursor, oDateTime, True ) Используя оба этих метода, можете создавать всевозможные вставки: oFooter.getRightText().setString( “Page “ ) oCursor = oFooter.getRightText().createTextCursor() oCursor.gotoEnd( False ) oFooter.getRightText().insertTextContent( oCursor, oPageNumber, True ) oCursor.gotoEnd( False ) oCursor.setString( “ of “ ) oCursor.gotoEnd( False ) oFooter.getRightText().insertTextContent( oCursor, oPageCount, True ) Наконец, необходимо обновить страницу, чтобы новая информация отобразилась: oPStyle.RightPageHeaderContent = oHeader oPStyle.RightPageFooterContent = oFooter
Объединяйте документы
Не просто создавайте новые документы – если у вас их несколько и нужно их скомпоновать, воспользуйтесь курсором для создания еди- ного документа. Такая задача возникает, когда над проектом работает несколько человек: oCursor.gotoEnd(false) oCursor.BreakType = com.sun.star.style.BreakType.PAGE_ BEFORE oCursor.insertDocumentFromUrl(SrcFile, argsInsert()) Очевидно, эти файлы можно брать из какого-то каталога или читать их из таблицы базы данных, а затем с помощью цикла, перебирая каж- дый документ, добавлять его к основному документу. После объединения документов желательно создать раздел Содержание (Content). Это поддаётся автоматизации: oDoc = ThisComponent oCurs = oDoc.getText().createTextCursor() oCurs.gotoStart(False) oDoc.getText().insertTextContent(oCurs, oIndex, False)
Ищите всё, что вам нужно
Может, и не всё, но если хотите посмотреть в алфавитном порядке спи- сок встроенных в OpenOffice.org функций, то отправляйтесь на http:// snipurl.com/rh67. Вы увидите каждую функцию, свойство, сервис и объект, к которому они принадлежат.
Учитесь у других
Хороший способ изучать OOo Basic – это смотреть, как пишут мак- росы другие люди: можете с ними не соглашаться, но возьмите на вооружение полезные идеи. Можно, конечно, запрячь Google, запросив ‘OpenOffice.org macros’, но для начала стоит посмотреть на макросы на странице проекта OOo. Примеры вы найдете на http://codesnippets. services.OpenOffice.org.
На данном уроке мы рассмотрели всего несколько примеров, но я надеюсь, что их достаточно для понимания, как легко делаются эффективные макросы. У вас есть все ресурсы, посвященные OOo, и вы сможете сами создать красивые решения.
ВОЛШЕБНОЕ ТАИНСТВЕННОЕ ПУТЕШЕСТВИЕ ДЖО
Практическое применение макросов OpenOffice.org
Помните, в совете номер один я говорил вам о Джо Твайтсе? Пусть Джо на микроавтобусе совершает объезд потенциальных покупателей. Останавливаясь у очередного дома, он открывает заднюю дверь своего микроавтобуса, чтобы показать последние видеокассеты, DVD и игры. Представьте деревянную панель, встроенную в микроавтобус. Посреди стены стоит 17-дюймовый Flatron, а на нем крутятся сразу три Хроники Нарнии – внимательно всмотревшись, вы увидите под панелью PC с клавиатурой и мышью.
Любопытствуете, что за компьютер? Он работает на Debian 3.1 (благодаря LXF70), для проигрывания DVD используется Kaffeine; и компьютер, и монитор работают через преобразователь Belkin DC-AC.
Мило; но какое это имеет отношение к OpenOffice.org? Хороший вопрос. Перед тем как отправиться на работу, Джо запускает документ OOo Calc с макросом, выполняющимся по событию ‘Open Document’. Этот макрос почти такой же, как разработанная нами процедура connectToDatabase – разница только в том, что в нем стоит обработка ошибок. Зачем? Потому что на этот раз главная база MySQL находится не на PC в автобусе, а на компьютере в доме Джо. Главный компьютер Джо использует беспроводную связь, а PC в автобусе имеет небольшую Wi-Fi антенну. Теперь, если Джо дома, то макрос подсоединится к базе данных; в противном случае Calc просто откроет документ.
Определив доступность базы данных (то есть возможность установления соединения), макрос начинает просмотр листа в Calc (он называется Daily data). Ячейка А1 содержит дату. Если эта дата раньше текущей, макрос переходит ко второму листу и запускает процедуру: uploadYesterdayRoute. Когда этот макрос завершит работу, другой макрос, downloadTodayRoute, опросит базу данных и скачает информацию о сегодняшних адресах, которых надо посетить – эта информация включает в себя видеокассеты, DVD и игры, взятые напрокат клиентами.
Путешествуя по стране, Джо обновляет таблицу Calc, записывая, кто и что у него брал. Если он кого-то не застанет дома, то вызовет другую процедуру, printReminder, которая изменит данные о прокате и перенесёт этот адрес в маршрут следующей поездки. Процедура также распечатает эту информацию на принтере, расположенном в кабине (чтобы оставить ее клиенту). На следующее утро процесс повторяется. Для Джо это значит, что у него имеется полная история всех его клиентов. Более того, он может провести анализ и понять, что для него прибыльнее: например, жители Камбрии любят боевики, и т.д., и ориентироваться на аудиторию, которую собирается посетить в назначенное время.
Ладно, а зачем сюда приплели Джо? Затем, что многие крупные фирмы тратят на разработку систем, подобных придуманной нами для Джо, огромные деньги. А вы можете сделать это бесплатно с помощью Linux и своих знаний.