- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF126:OOo
Материал из Linuxformat.
- OpenOffice.org Открытый офисный пакет для профессионалов
Содержание |
OpenOffice.org: Все по форме
- Дмитрий Попов расскажет, как создать и обработать формы в OpenOffice.org, а также как сохранить добытые данные в виде текста или в базе данных Base.
OpenOffice.org Writer – это не только солидный текстовый редактор. С использованием его возможностей дизайнера форм можно легко генерировать анкеты любого вида, от простых тестов до продвинутых опросников. И хотя создание форм во Writer не отличается сложностью, их обработка и извлечение данных из них – это совсем другое дело. К счастью, OOo сам предлагает инструменты для создания простого, но эффективного решения по обработке форм. С помощью OpenOffice.org Basic можно написать макрос, обрабатывающий форму, а извлеченные данные сохранить в текстовом файле или в базе данных OpenOffice.org Base. Изучая это решение обработки форм, вы узнаете несколько продвинутых технологий OpenOffice.org Basic, способных пригодиться вам в других проектах.
Любой бизнес первым делом требует формы сбора данных. Начнем с простой, для введения имен и фамилий пользователей. Создайте новый документ Writer и выберите Вид > Панели инструментов > Дизайн формы, чтобы появилась панель управления Дизайн формы. Нажмите на Режим проектирования, затем выберите кнопку Текстовое поле и нарисуйте в документе текстовое поле. Дважды щелкните на только что созданном поле, чтобы открылась палитра Свойства, и введите в поле Имя FirstName. С помощью других опций этой палитры можно настроить свойства поля: например, его внешний вид, шрифт и цвет рамки. Таким же образом нарисуйте другое текстовое поле под названием LastName. Сделав это, сохраните полученную форму.
Теперь начнем работать над макросом. Чтобы все было сделано аккуратно, создадим для наших экспериментов отдельную библиотеку. Зайдите в Сервис > Макросы > Управление макросами > OpenOffice.org Basic, нажмите кнопку Управление, переключитесь в раздел Библиотеки и создайте новую библиотеку под названием ProcessForm. Нажмите кнопку Изменить, и откроется редактор OOo Basic. Начнем с написания простого макроса, который инициализирует форму, считывает данные из ее полей и отображает извлеченные значения во всплывающем сообщении.
Создание формы
Для инициализации формы нужны два оператора. Первый велит макросу использовать текущий открытый документ:
Doc=ThisComponent
Второй оператор отыскивает в документе определенную форму по ее индексу. В нашем случае в документе есть только одна форма с индексом, равным нулю, и оператор, инициализирующий переменную Form, имеет вид
Form=Doc.Drawpage.forms.getbyIndex(0)
Извлечение данных из формы – тоже двухшаговый процесс. Во-первых, макрос ищет поле по его имени, используя метод getByName:
TextBox=Form.getByName(“FirstName”)
Найдя поле, макрос извлекает из него текстовые данные следующим оператором:
FirstName=TextBox.String
Точно так же можно взять данные из поля LastName:
TextBox2=Form.getByName(“LastName”) LastName=TextBox2.String
Наконец, чтобы убедиться в правильности работы макроса, добавим оператор, отображающий собранные данные в окне сообщения:
MsgBox FirstName & “ ” & LastName
Вот полный листинг макроса, который нужно ввести в редакторе OOo:
Sub FetchFormData Doc=ThisComponent Form=Doc.Drawpage.forms.getbyIndex(0) TextBox1=Form.getByName(“FirstName”) FirstName=TextBox1.String TextBox2=Form.getByName(“LastName”) LastName=TextBox2.String MsgBox FirstName & “ ” & LastName End Sub
После ввода макроса перейдите в документ, содержащий форму, заполните два поля и сохраните форму. Чтобы запустить макрос, щелкните Сервис > Выполнить макрос... и выберите макрос FetchFormData из библиотеки ProcessForm. Если все работает правильно, вы увидите окно сообщения с данными из полей формы.
Отображение извлеченных данных в окне сообщения демонстрирует нам, что макрос работает; но польза от него пока невелика. Давайте изменим его так, чтобы он записывал значения через запятую (CSV) в текстовый файл, который затем можно импортировать и обработать в Calc или в другом приложении:
Sub WriteToFile() Doc=ThisComponent Form=Doc.Drawpage.forms.getbyIndex(0) TextBox=Form.getByName(“FirstName”) FirstName=TextBox.String TextBox1 = Form.getByName(“LastName”) LastName= TextBox1.String FilePath=“/home/user/formdata.csv” f1=FreeFile() Open FilePath For Append Access Read Write Lock Write As #f1 Print #f1, FirstName + “, ” + LastName + Chr(13) Close #f1 End Sub
Определение путей к файлам
Та часть макроса, что записывает извлеченные данные в текстовый файл, начинается с оператора FilePath=“/home/user/formdata.csv”. Как вы, наверное, уже догадались, этот оператор определяет целевой текстовый файл. Вместо того, чтобы прописывать путь к файлу в макросе вручную, воспользуйтесь процедурой InputBox — пусть его определит пользователь:
FilePath=InputBox(“Введите путь к файлу”, “Внимание”)
Альтернатива – обратиться к службе com.sun.star.util.PathSubstitution, чтобы узнать путь к каталогу настроек пользователя OOo (например, /home/user/.openoffice.org/3/user) и применить его в качестве местоположения текстового файла. Как видно из названия, эта служба заменяет определенную переменную на путь. В нашем случае мы используем переменную $(user), и служба возвратит путь к каталогу настроек пользователя:
SubstService=CreateUnoService(“com.sun.star.util.PathSubstitution”) UserPath=SubstService.substituteVariables(“$(user)”, true)
Теперь используем полученное имя каталога для задания имени файла:
FilePath=UserPath + “/formdata.csv”
Неважно, какой из этих вариантов вы выберете: способ, которым макрос будет записывать данные, останется тем же. Чтобы открыть файл, макрос определяет уникальное число, часто называемое номером файла или каналом данных. Это делается с помощью функции FreeFile, которая возвращает номер файла для использования в макросе:
f1=FreeFile()
Затем макрос открывает файл командой Open:
Чтобы скопировать данные из базы в электронную таблицу Calc, щелкните правой кнопкой по нужной таблице и выберите Копировать. Переключитесь в Calc, выберите Правка > Вставить. И все!
Open FilePath For Append Access Read Write As #f1
Режим For Append создает новый файл или же открывает существующий и помещает курсор в его конец; иными словами, наш макрос будет дописывать данные. Режим Access определяет права доступа; в нашем случае макрос может читать и изменять файл. Чтобы ограничить доступ к файлу на время его использования, макрос применяет режим Lock. Когда текстовый файл открыт, макрос записывает в него данные из полей формы и закрывает файл:
Print #f1, FirstName + “, ” + LastName + Chr(13) Close #f1
Обратите внимание на Chr(13) в конце оператора Print. Это символ возврата каретки, чтобы следующая строка, которую будет записывать макрос, начиналась с новой строки.
Сохранение данных в базе
Данные в текстовом файле можно импортировать и обрабатывать любой программой, поддерживающей формат CSV, но есть и возможность сохранять обработанные данные непосредственно в базе, минуя стадию промежуточных файлов. Для этого зайдите в Файл > Создать > Базу данных..., выберите пункт Создать новую базу данных и нажмите Далее. Выберите Да, зарегистрируйте базу данных и отметьте Открыть базу для редактирования, затем нажмите на кнопку Готово. Сохраните созданную базу данных под именем FormDB.odb. Перейдите в раздел Таблицы и нажмите на Создать таблицу в режиме дизайна.
В таблицу следует внести три поля. Начнем с ID, оно будет ключевым полем таблицы. Введите ID в столбце Название поля, а в выпадающем списке Тип поля выберите Целое [Integer]. Щелкните правой кнопкой мыши по зеленому маркеру рядом с именем поля и выберите опцию Первичный ключ. Наконец, установите опцию Автозначение на Да и введите 10 в поле Длина. Добавьте поля FirstName и LastName, установите им тип Текст [Varchar] и задайте для каждого длину. Сохраните полученную таблицу как Table1, и ваша новая база данных готова.
Вы уже знаете, как извлекать данные из полей формы; осталось написать код, сохраняющий полученные значения в базе данных. Первым делом макрос должен установить связь с базой данных FormDB.odb, используя службу com.sun.star.sdb.DatabaseContext:
DBContext=createUnoService(“com.sun.star.sdb. DatabaseContext”) DataSource=DBContext.getByName(“FormDB”) DB=DataSource.GetConnection (“”,“”)
Чтобы этот код заработал, база данных FormDB.odb должна быть зарегистрирована OOo в качестве источника данных. Если, создавая базу, вы выбрали опцию Да, зарегистрировать базу данных, то вам ничего больше делать не нужно; а если нет, потребуется зарегистрировать базу данных вручную. В OOo зайдите в Сервис > Параметры, там выберите раздел База данных OpenOffice.org > Базы данных. Нажмите Создать..., выберите файл FormDB.odb, убедитесь, что в поле Зарегистрированное название стоит FormDB, и нажмите OK.
Для управления данными, содержащимися в Base, OOo Basic применяет SQL-запросы, и для сохранения данных формы в таблицу Table1 базыданных FormDB понадобится команда SQL INSERT INTO. Запрос имеет следующий формат:
INSERT INTO таблица (“Поле1”, “Поле2”) VALUES (‘Значение1’,‘Значение2’)
Вот как должен выглядеть оператор, вставляющий значения FirstName и LastName в поля таблицы Table1:
SQLQuery=”INSERT INTO “”Table1”” (“”FirstName””,“”LastName””) VALUES “ + “(‘” + FirstName + “’,’” + LastName + “’)”
Наконец, макрос выполняет указанный SQL-запрос и закрывает соединение с базой данных:
SQLStatement=DB.createStatement Result=SQLStatement.executeQuery (SQLQuery) DB.close DB.dispose()
Вот полный текст макроса для ознакомления:
Sub SaveInDB() Doc=ThisComponent Form=Doc.Drawpage.forms.getbyIndex(0) TextBox1=Form.getByName(“FirstName”) FirstName=TextBox1.String TextBox2=Form.getByName(“LastName”) LastName=TextBox2.String DBContext=createUnoService(“com.sun.star.sdb. DatabaseContext”) DataSource=DBContext.getByName(“Basket”) ConnectToDB=DataSource.GetConnection (“”,“”) SQLQuery=”INSERT INTO “”Table1”” (“”FirstName””, “”LastName””) VALUES “ + “ (‘” + FirstName + “’,’” + LastName + “’)” SQLStatement=ConnectToDB.createStatement Result=SQLStatement.executeQuery (SQLQuery) ConnectToDB.close ConnectToDB.dispose()
End Sub
Выпадающие списки
Теперь, зная, как извлекать данные из текстовых полей, можете оживить вашу форму, включив в нее выпадающие списки и группы опций. Например, если нужно спросить пользователей, какой именно текстовый процессор они предпочитают, добавьте выпадающий список с перечнем приложений.
В первую очередь определите источник данных, связанный со списком. В базе данных FormDB.odb создайте новую таблицу, содержащую первичный ключ – поле ID и текстовое поле ListItem. Сохраните ее как Table2, откройте и сделайте в ней три записи, соответствующих трем текстовым процессорам.
Следующий шаг – связать нашу форму с базой данных FormDB. Выберите Вид > Панели инструментов > Дизайн формы, и в появившейся панели Дизайн формы нажмите кнопку Навигатор форм. На палитре Навигатор форм перейдите к разделу Данные и в поле Источник выберите файл FormDB.odb. В выпадающем списке Тип содержимого источника укажите Таблица, а в списке Содержимое – Table2. Нажмите на кнопку Выпадающий список [Combo Box] на панели Элементы управления и нарисуйте на форме выпадающий список. Откроется мастер, где можно определить его параметры. Убедитесь, что у вас отмечено правильное поле (ListItems), и выберите опцию Нет, Сохранить значение только в форме. Нажмите Готово, и список готов к использованию.
Извлечение значения из этого компонента просто и требует всего лишь две строки кода. Сначала надо отыскать спи сок по его имени, а потом запросить значение:
ComboBox = Form.getByName(“ComboBox”) ComboBoxValue = ComboBox.CurrentValue
Добавление группы кнопок-переключателей к форме так же просто, однако следует помнить, что:
- Все переключатели в группе должны иметь одно и то же имя.
- Для задания описания каждого переключателя следует использовать поле Метка в палитре Свойства.
Например, для выбора возможного ответа на вопрос «Как часто вы пользуетесь OpenOffice.org?» можно создать три кнопки-переключателя: «Ежедневно», «Раз в неделю» и «Раз в месяц».
Определение того, какая из кнопок активна в текущий момент, требует нескольких шагов. Во-первых, макрос должен найти все кнопки в указанной группе:
OptionGroup=Form.getGroupByName(“Options”, Opt())
Затем макрос должен в цикле For … Next пройти через все пункты массива, от наименьшего (LBound) до наибольшего (Ubound), и определить состояние (State) каждой кнопки. Если свойство State возвращает True (это значит, что кнопка активна), макрос запрашивает ее значение Label:
For i=LBound(Opt) to UBound(Opt) If Opt(i).state Then OptionGroupValue=Opt(i).label End If Next
Обратите внимание, что все кнопки-переключатели в группе хранятся в массиве Opt(), который следует объявить в самом начале макроса с помощью оператора Dim Opt(). Вот как будет выглядеть полный макрос:
Sub WhichRadioButton Dim Opt() Doc=ThisComponent Form=Doc.Drawpage.forms.getbyIndex(0) OptionGroup=Form.getGroupByName(“Options”, Opt()) For i=LBound(Opt) to UBound(Opt) If Opt(i).state Then OptionGroupValue=Opt(i).label End If Next MsgBox OptionGroupValue End Sub
Настройка макросов
Созданные макросы вполне пригодны к применению, однако небольшая настройка способна облегчить их использование. Для извлечения данных из формы нужно запускать макрос вручную, через Сервис > Макросы > Выполнить макрос... и последующий выбор нужного макроса. Это не самый эффективный способ работы, но горю помочь легко: добавьте на форму кнопку Submit и свяжите ее с макросом. Для этого щелкните компонент Кнопка в панели Элемент управления и нарисуйте на форме кнопочку. В палитре Свойства переключитесь в раздел События и свяжите макрос с событием Нажатие клавиши мыши. Готово!
Теперь другая проблема: вы заметили, что форму надо сохранять перед тем, как макрос будет извлекать из нее данные? Если пользователь этого не сделает, макрос вернется с пустыми руками, или сохранит ранее введенные сведения. Чтобы предотвратить это, выполните проверку наличия в документе изменений с помощью свойства isModified. Если возвращаемый результат равен True, макрос сохраняет документ:
DocURL=Doc.getURL() If Doc.isModified Then Doc.storeAsURL(DocURL, Args) End If
И, наконец, после извлечения данных можно очистить все поля формы. Это упростит следующему пользователю ввод сведений и предотвратит чтение того, что ранее вводил другой пользователь. Для этого напишем простой макрос и свяжем его с кнопкой очистки на форме:
Sub ResetForm Doc = ThisComponent Form = Doc.Drawpage.forms.getbyIndex(0) Form.Reset() End Sub
Вместо этого также можно добавить оператор Form.Reset() в конец макроса, который извлекает данные из формы.
Проверка SQL-запросов
Прежде чем добавлять в ваш код какой-либо SQL-запрос, неплохо было бы посмотреть, работает ли он, в редакторе SQL. Для этого выберите в главном окне открытой базы данных Сервис > SQL, введите SQL-запрос в поле Команда [Command To Execute] и нажмите кнопку Execute. После этого вы увидите и результат, и объяснение возможных ошибок в поле Состояние [Status]. Эта возможность особенно полезна при отладке громоздких SQL-скриптов. LXF