Распечатать страницу

Окружение данных в Visual FoxPro

« Назад

Объект

DataEnvironment

образуется при создании формы, набора форм или отчета. Объект функционирует как контейнер таких объектов, как Cursor, CursorAdapter и Relation, ассоциированных с формой, набором форм или отчетом.

Объект Cursor образуется при добавлении в DataEnvironment таблицы, вида или курсора. Объект Relation отображает отношение между двумя таблицами. CursorAdapter – это буферизованный курсор, представляющий данные одного или нескольких источников. В качестве таковых могут браться таблицы VFP, представления удаленных данных (ODBC-курсоры), ActiveX-источники данных и XML-данные.

Во время исполнения могут быть установлены только следующие свойства объекта DataEnvironment: DataSource, DataSourceType, InitialSelectedAlias, Name, OpenViews и Tag. Чтобы новое значение свойства имело действие, необходимо вызвать методы CloseTables и OpenTables объекта DataEnvironment. Попытка изменить другие свойства объекта приведет к генерации ошибки.

На базе класса DataEnvironment может быть определен подкласс, например:

define class DtEnv as DataEnvironment

&& …

endDefine

Интерактивно объект DataEnvironment создается в проектировщике окружения Data Environment Designer, который доступен при разработке формы, набора форм или отчета. С набором форм ассоциируется один объект DataEnvironment, ссылку на который содержит одноименное свойство формы.

Находясь в проектируемой форме, окружение данных может быть сохранено в виде библиотеки класса – VCX-файла путем выполнения команды меню File – Save As Class – DataEnvironment. Все свойства, события и методы DataEnvironment отобразятся в окне свойств объекта после открытия этого файла в проектировщике классов Class Designer.

В форму (набор форм) можно добавить объект класса DataEnvironment, пользуясь, например, методом AddObject. Однако VFP не рассматривает этот объект как собственное окружение формы, ссылку на которое хранит свойство DataEnvironment формы.

Также на этапе проектирования можно использовать свойства DEClass и DEClassLibrary формы, чтобы задать и загрузить внешний класс DataEnvironment, например:

define class SomeForm as Form

DEClassLibrary = "MyProgram.prg"

DEClass = "MyDE"

endDefine

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

Замечание. Описание свойств, методов и событий объекта DataEnvironment см. в справке VFP, тема DataEnvironment Object.

Пример. Создается форма, содержащая 2 элемента управления Grid (Сетка) соответственно с именами Grid1 и Grid2. Первый отображает список авторов, второй – книги выбранного автора и в качестве источника данных используют таблицу BooksAuthors.

Определим прежде объекты DataEnvironment. Для представления данных об авторах и их книгах нам в соответствии с приведенной в разд. 2.2 моделью данных понадобятся таблицы Authors и Books, содержащие соответственно списки авторов и их книг, и таблица и BooksAuthors, связывающая эти два списка. Таблица BooksAuthors в чистом виде не отображается, но снабжает сетку Grid2 названиями книг выбранного автора. Все таблицы входят в базу данных HomeLibrary.

Создадим новую форму, например d:\SomeForm.scx; откроем проектировщик DataEnvironment (команда меню View – DataEnvironment или контекстное меню формы), добавим в окружение упомянутые таблицы (команда меню DataEnvironment – Add). Далее установим связь между таблицами Authors и BooksAuthors так, как это показано на рис. 10.5 (чтобы установить связь, нужно захватить мышью поле AuthorId таблицы Authors и перетащить его к одноименному полю таблицы BooksAuthors).

159.1.-Окружение-формы-SomeForm

Рис. 10.5. Окружение формы SomeForm

После выполнения описанных действий объект DataEnvironment будет содержать 3 курсора, по умолчанию получившие имена Cursor1, Cursor2 и Cursor3, и отношение с именем Relation1. Отношение Relation1 обеспечивает отображение в сетке Grid2 названий книг автора, выбранного в сетке Grid1. Иных записей сетка Grid2 не показывает.

Имена курсоров, как и значения других свойств, можно изменить в окне редактирования свойств после выбора соответствующего объекта.

Сохраним форму SomeForm и запустим ее на исполнение. В окне Data Session отобразятся открытые таблицы и установленное отношение (рис. 10.6).

159.2.-Окно-Data-Session-после-открытия-формы-SomeForm

Рис. 10.6. Окно Data Session после открытия формы SomeForm

Добавленные в окружение данных формы SomeForm таблицы открываются при запуске формы, поскольку свойство AutoOpenTables окружения равно .T.

После открытия формы имена имеющихся в ее окружении объектов выведет следующий код:

do form d:\SomeForm noShow

dtEnv = SomeForm.DataEnvironment

for each ob in dtEnv.Objects

                                            ? ob.Name

endFor

Возможный результат:

Cursor1

Cursor2

Cursor3

Relation1

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

Значения свойств AutoOpenTables и AutoCloseTables могут быть изменены только на этапе проектирования.

Добавим теперь, используя иконку  панели управления Form Controls, в форму элемент управления Grid (сетка), установив его размеры достаточно большими для отображения полей Author и InputDate таблицы Authors. По умолчанию добавленная сетка получит имя Grid1.

Далее выберем эту сетку, откроем при помощи контекстного меню построитель сетки (Builder), выберем на его вкладке Grid Items ранее открытую базу данных HomeLibrary, таблицу Authors и ее поля Author и InputDate (рис. 10.7).

159.3.-Фрагмент-вкладку-Grid-Items-построителя-сетки

Рис. 10.7. Фрагмент вкладку Grid Items построителя сетки

Отредактируем на вкладке Layout заголовки столбцов сетки и их размеры, приведя внешний вид объекта в соответствие с рис. 10.8.

159.4.-Форма-SomeForm

Рис. 10.8. Форма SomeForm

Вторую сетку (Grid2), предназначенную для отображения книг выбранного автора, создадим без употребления построителя сетки по той причине, что в качестве источника данных ее столбца будет использовано выражение

LookUp(Books.Book, BooksAuthors.BookId, Books.BookId, 'BookId')

позволяющее взамен кода книги, хранящегося в поле BooksAuthors.BookId, выводить ее название.

Определить такой источник данных в построителе сетки нельзя. Поэтому, добавив сетку в форму, приведем ее размеры в соответствие с рис. 10.8; остальные свойства сетки Grid2 и ее компонентов зададим программно, разместив в обработчике события Init формы следующий код:

with ThisForm.Grid2

&& Источник данных сетки

.RecordSource = "BooksAuthors"

&& Число столбцов сетки

.ColumnCount = 1

&& Источник данных столбца сетки

.Column1.ControlSource = "LookUp(Books.Book, ;

  BooksAuthors.BookId, Books.BookId, 'BookId')"

&& Выравнивание в столбце сетки

.Column1.Alignment = 0

&& Ширина столбца сетки

.Column1.Width = ThisForm.Grid2.Width

&& Заголовок столбца сетки

.Column1.Header1.Caption = "Книги автора"

endWith

Кроме того, в этот же обработчик добавим еще одну WITH-команду, обеспечивающую отображение сеток Grid1 и Grid2 без нижних полос прокрутки.

with ThisForm

.Grid1.ScrollBars = 2

.Grid2.ScrollBars = 2

endWith

Замечание. В этом обработчике вместо ссылки ThisForm можно употребить и ссылку This: обе ссылки указывают на один и тот же объект – форму.

Установим, употребив иконку  панели управления Form Designer, следующий порядок обхода элементов управления формы: Grid1 – 1, Grid2 – 2 и "Закрыть" – 3.

При таком порядке во вновь открываемой форме будет выбираться сетка Grid1, а в ней – первая запись таблицы Authors. Если теперь употребить Ctrl+Tab, активизируется элемент Grid2. Находясь на кнопке "Закрыть", для перехода на Grid1 нужно уже нажать не Ctrl+Tab, а просто Tab.

Обработчик события Click кнопки "Закрыть" содержит один закрывающий форму оператор:

ThisForm.Release

Запустим форму и просмотрим результат (рис. 10.9).

159.5.-Форма-SomeForm-сразу-после-открытия

Рис. 10.9. Форма SomeForm сразу после открытия

Замечание. В приведенных сетках допускается непосредственное редактирование данных любого поля. В реальных приложениях такая ситуация недопустима.

Пример 2. Создается форма d:\NextForm.scx с одной сеткой, использующей в качестве данных курсор-адаптер.

Курсор-адаптер добавим в окружение формы, выполнив команду меню DataEnvironment – Add CursorAdapter. Далее, выбрав в контекстном меню курсора-адаптера команду Builder, откроем построитель курсора-адаптера. Вкладку Properties объекта определим в соответствии с рис. 10.10.

159.6.-Вкладку-Properties-курсора-адаптера-CursorAdapter1

Рис. 10.10. Вкладку Properties курсора-адаптера CursorAdapter1

Тип источника данных Native означает, что данные будут извлекаться из таблиц VFP.

На вкладке Data Access разместим в том числе и приведенные на рис. 10.11 данные.

159.7.-Фрагмент-вкладки-Data-Access

Рис. 10.11. Фрагмент вкладки Data Access

Остальные, не отображенные на рис. 10.11 поля вкладки, задающие параметры доставки данных (Data fetching), способ буферизации, значение флажка Break on error, оставим без изменений.

Запрос Select command сформирован частично при помощи построителя запроса, открываемого по кнопке Build… вкладки. Запишем его более наглядно:

select ;

Authors.Author, BooksAuthors.AuthorId, BooksAuthors.BookId, Books.Book, Books.Price ;

from Authors ;

    inner join BooksAuthors on Authors.Authorid = BooksAuthors.AuthorId ;

    inner join Books on BooksAuthors.BookId = Books.BookId ;

order by Authors.Author

На вкладке Auto-Update активизируем флажок Auto-update и активизируем в соответствии с рис. 10.12 флажки рядом с именами полей Book и Price.

159.8.-Фрагмент-вкладки-Auto-Update

Рис. 10.12. Фрагмент вкладки Auto-Update

При этом поле Book отметим и как обновляемое и как ключевое. Тогда изменения в сетке формы значений полей Book и Price приведет к аналогичным изменениям соответствующих полей источника данных – таблицы Books.

Остальные, не приведенные на рис. 10.12 элементы управления вкладки, такие, как переключатели групп Update using и SQL WHERE clause includes и др., оставим без изменений.

Замечание. Смысл определяемых при задании курсора-адаптера данных см. в описании функции CURSORSETPROP( ) (разд. 15.13) и частично в разд. 15.14 и 20.6. Порядок организации запросов см. в описании команды SELECT – SQL.

В качестве источника данных (свойство RecordSource) единственной сетки формы укажем созданный курсор-адаптер Cursoradapter1 (рис. 10.13).

159.9.-Задание-источника-данных-сетки-Grid1

Рис. 10.13. Задание источника данных сетки Grid1

Использовать построитель сетки с таким источником данных нельзя, поэтому выполним ее настройку, устанавливая интерактивно соответствующие значения свойств сетки и ее столбцов. Заголовки столбцов сетки, а также значение ее свойства ScrollBars изменим программно, включив в обработчик события Init формы следующий код:

with This.Grid1

.Column1.Header1.Caption = "Автор"

.Column2.Header1.Caption = "Книга"

.Column3.Header1.Caption = "Цена"

&& Отказываемся от горизонтальной полосы прокрутки

.ScrollBars = 2

endWith

Свойство ScrollBars сетки, если оно установлено в 2, обеспечивает отображение только вертикальной полосы прокрутки объекта Grid1.

Перейдем теперь к интерактивному заданию свойств. Выберем элемент управления Grid1 и в окне Properties установим на вкладке Layout значение свойства ColumnCount (число столбцов сетки) в 3.

Откроем далее раскрывающийся список объектов формы и выберем в нем элемент Column1 (рис. 10.14) и установим его свойство ControlSource (источник данных) в соответствии с рис. 10.15.

159.10.-Активизируем-объект-Column1-сетки-Grid1

Рис. 10.14. Активизируем объект Column1 сетки Grid1

159.11.-Задание-источника-данных-для-Column1-сетки-Grid1

Рис. 10.15. Задание источника данных для Column1 сетки Grid1

Аналогичным образом установим ControlSource для Column2 и Column3 соответственно в CursorAdapter1.Book и CursorAdapter1.Price.

Изменим, оперирую мышью, ширину столбцов сетки, принимая во внимание размеры выводимых в них значений. Такие изменения выполняются в режиме редактирования столбцов. Смена столбца производится после позиционирования мыши на одной из строк столбца и нажатия на правую кнопку мыши; выбор заголовка столбца осуществляется аналогичным образом после позиционирования мыши на заголовке.

Замечание. Перейти к редактированию свойств столбцов и их заголовков можно и иным способом, – выбрав в контекстном меню сетки пункт Edit.

Теперь, когда заданы свойства формы, сетки и ее столбцов, внесен код в обработчики событий Init формы и Click кнопки "Закрыть", запустим форму и просмотрим приведенный на рис. 10.16 результат.

159.12.-Первый-запуск-формы-NextForm

Рис. 10.16. Первый запуск формы NextForm

Если после открытия формы ее сетка не активизируется, то изменим в проектировщике форм порядок обхода ее элементов управления, назначив первый номер элементу Grid1. Такой же эффект будет получен, если в обработчик события Init формы добавить две следующие строчки:

ThisForm.Grid1.TabIndex = 1

ThisForm.Command1.TabIndex = 2         && Кнопка "Закрыть"

Впрочем, в рассматриваемом случае вторая добавленная строка может быть опущена.