Как стать автором
Обновить

Программирование LibreOffice Base. Часть 3

Open source *
Tutorial
Сегодня мы рассмотрим использование диалоговых окон при редактировании данных в LibreOffice Base (OpenOffice Base). Как мы выяснили в предыдущих сообщениях, Форма LibreOffice Base (OpenOffice Base) — это фактически экземпляр текстового редактора LibreOffice (OpenOffice) Writer. Для организации оконного интерфейса внутри Формы используется Диалоги — которые удобно создаются во встроенным визуальном интерфейсе, но не имеют поддержки для связи с таблицами базы данных. Эту связь будем организовывать макросами OO Basic.

Начнем по-порядку. Создадим две таблицы в базе данных:

products
— id (целое, первичный ключ)
— name (строка)

orders
— id (целое, первичный ключ)
— productId (целое)
— count (целое)
— date (тип данных Дата)

Создадим форму orders, добавим в форму элемент Form с именем orders. А также Table Control с источником данных orders. Как это сделать рассматривалось в Части 2 серии сообщений.

При задании свойств колонки date обратите, пожалуйста, внимание на отмеченные на рисунке стрелками свойства, которые позволяют отображать данные в нужном формате и использовать выпадающий календарь для выбора конкретной даты.

Рисунок
image

Теперь прямо в таблице можно добавлять и изменять данные. До определенного момента это удобно, похоже на привычную работу клиента с табличным процессором. Но в какой-то момент начинаются проблемы, также характерные для работы с табличными процессорами. Данные можно изменить случайно, даже не заметив этого. А заметив невозможно откатить все как было. Места для новых колонок мало, и может образоваться неприятная горизонтальная прокрутка. Заголовки колонок также имеют ограничение по размеру (иначе не поместятся по горизонтали), и это не позволяет дать подробное описание данных.

В качестве полумеры можно рядом с таблицей разместить обычные поля для ввода данных (Text Control, Numeric Control и т.д.). В качестве источника данных задать соответствующие поля таблицы orders и все будет работать. При навигации по набору данных будут меняться данные в полях ввода. При изменении данных в полях ввода будут меняться данные в таблице базы данных. Но выглядеть это решение будет не очень красиво.

Поэтому реализуем такой функционал при помощи Диалогов. У Диалогов есть одно существенное ограничение. Поля ввода Диалогов не связаны с таблицей базы данных. Поэтому заполнение полей ввода Диалога из таблицы базы данных, и сохранение полей ввода в таблицу базы данных нужно будет делать макросом OO Basic. Впрочем, это и хорошо, т.к. позволяет рассмотреть возможности программирования OO Basic (до этого в моих сообщениях была описана работа только со средой, но все это было подготовкой к сегодняшнему сообщению).

Чтобы вызвать на экран редактор Диалогов, необходимо выбрать в меню Tools->Macros->Organize Macros->LibreOffice Basic->Organizer->Dialog->New|Edit|Delete. Хотелось бы иметь более быстрый способ добраться до этого редактора. После чего откроется редактор диалога (увы, не самый удобный), в котором мы создадим поля с именами полей таблицы базы данных. Как Вы помните Диалоги не связываются автоматически с таблицами базы данных поэтому мы напишем макрос, который сделает это. И в качестве соглашения об именовании определим имена полей ввода и полей таблицы базы данных одинаковыми.

Редактор с готовой формой будет выглядеть примерно так:

Рисунок
image

Далее, добавим в Диалог две кнопки. Имена кнопкам дадим произвольные, но начинающиеся с подчеркивания, чтобы отличить их от полей базы данных. Каждой кнопке в палитре свойств можно задать действие. Зададим одой кнопке действие OK — она закроет Диалог с подтверждением действия. А второй — Cancel — она закроет диалог без подтверждения действия.

Закроем редактор Диалогов, и вернемся в редактор Формы. Создадим кнопку, вызывающую диалог и назначим ей процедуру-обработчик Order_Edit, в которой будем заполнять Диалог из таблицы базы данных FromBaseToDialog(oForm, oDialog), и сохранять данные из Диалога таблицу базы данных FromDialogToBase(oDialog, oForm).

Sub Order_Edit(Event)
 Dim oDialog As Object
 Dim orders As Object
 orders = Thiscomponent.DrawPage.Forms.GetByName("orders")
 DialogLibraries.LoadLibrary("Standard")
 oDialog = CreateUnoDialog(DialogLibraries.Standard.dialogOrder)
 FromBaseToDialog(orders, oDialog)
 If oDialog.Execute() = 1 Then
   FromDialogToBase(oDialog, orders)
   orders.UpdateRow()
 End If
End Sub

Sub FromBaseToDialog(oForm, oDialog)
 Dim I
 Dim sName As String
 For I = 0 To Ubound(oDialog.Model.ElementNames)
  sName = oDialog.Model.ElementNames(I)
  If Mid(sName, 1, 1) <> "_" And Mid(sName, 1, 5) <> "Label" Then
   ODialog.GetControl(sName).SetText(oForm.Columns.GetByName(sName).String)
  End If
 Next I
End Sub

Sub FromDialogToBase(oDialog, oForm)
 Dim I
 Dim sName As String
 For I = 0 To Ubound(oDialog.Model.ElementNames)
  sName = oDialog.Model.ElementNames(I)
  If Mid(sName, 1, 1) <> "_" And Mid(sName, 1, 5) <> "Label" Then
   oForm.Columns.GetByName(sName).UpdateString(Trim(oDialog.GetControl(sName).GetText()))
  End If
 Next I
End Sub

Предполагается, что Диалог был сохранен в библиотеке Standard под именем dialogOrder. Естественно, Вы можете выбрать другие имена. Имена контролов, начинающиеся с подчеркивания пропускаются и не обрабатываются. Также не обрабатываются имена, начинающиеся с Label, которые используются для текстовых заголовков полей.

Вызов oDialog.Execute() = 1 отображает Диалог внутри окна Формы и приостанавливает работу макроса до нажатия кнопки OK или Cancel. При нажатии на кнопку OK выполнится равенство возвращаемого значения единице.
Теги:
Хабы:
Всего голосов 7: ↑6 и ↓1 +5
Просмотры 7.3K
Комментарии 4
Комментарии Комментарии 4