Вы находитесь на странице: 1из 465

УДК 681.3.068+800.

92Visual FoxPro
ББК 32.973.26-018.1
Ш24

Шапорев Д. С.
Ш24 Visual FoxPro. Уроки программирования. — СПб.: БХВ-Петербург,
2005. - 480 с: ил.
ISBN 5-94157-627-7
В виде уроков, в форме веселого диалога с читателем рассмотрены ос­
новные приемы работы с СУБД Visual FoxPro — от способов запуска про­
граммы и описания пользовательского интерфейса до создания собственной
компьютерной игры. Описаны разработка и особенности работы с основ­
ными объектами Visual FoxPro, такими как классы, таблицы, запросы,
формы, представления и отчеты. Уделено внимание внедрению OLE-объ­
ектов, использованию компонентов ActiveX и библиотек классов, а также
экспорту и импорту данных в другие приложения. Показано, как создавать
справочную систему, установочный диск приложения. Рассмотрено приме­
нение методов объектно-ориентированного программирования в Visual FoxPro:
разработка экранных форм и собственной панели инструментов на основе
пользовательских классов, создание компьютерных игр и др. Книга сопро­
вождается большим количеством примеров и полезных советов.

Для начинающих программистов


УДК 681.3.068+800.92Visual FoxPro
ББК 32.973.26-018.1
Группа подготовки издания:

Главный редактор Екатерина Кондукова


Зам. главного редактора Игорь Шишигин
Зав. редакцией Григорий Добин
Редактор Екатерина Капалыгина
Компьютерная верстка Ольги Сергиенко
Корректор Зинаида Дмитриева
Дизайн обложки Игоря Цырульникова
Зав. производством Николай Тверских

Лицензия ИД № 02429 от 24.07.00. Подписано в печать 22.04.05.


Формат 70x100Vie. Печать офсетная. Усл. печ. л. 38,7.
Тираж 3000 экз. Заказ No 1002
"БХВ-Петербург", 194354, Санкт-Петербург, ул. Есенина, 5Б.
Санитарно-эпидемиологическое заключение на продукцию
№ 77.99.02.953.Д.006421.11.04 от 11.11.2004 г. выдано Федеральной службой
по надзору в сфере защиты прав потребителей и благополучия человека.
Отпечатано с готовых диапозитивов
в ГУЛ "Типография "Наука"
199034, Санкт-Петербург, 9 линия, 12

I S B N 5-94157-627-7 © Шапорев Д. С, 2005


О Оформление, издательство ' БХР-нетероург , 2005
Оглавление

Введение 9
Для чего я написал эту книгу? 9
Немного истории, или рождение старого лиса 10
Что нового в СУБД Visual FoxPro? 11

ЧАСТЬ I. ПРОЦЕДУРНОЕ ПРОГРАММИРОВАНИЕ


В VISUAL FOXPRO 13

Урок 1. Начинаем работать! 15


Что такое база данных? 15
Таблицы 16
СУБД 18

Урок 2. Запуск Visual FoxPro 19

Урок 3. Главное окно Visual FoxPro 24


Заголовок 24
Главное (системное) меню Visual FoxPro 25
А как выполнить команду меню? 33
Как отменить выполнение команды меню? 34
Панель инструментов 34
Рабочий стол 36
Командное окно 36
Строка состояния 38

Урок 4. Знакомство с диспетчером проекта 40

Урок 5. Первое приложение 45

Урок 6. Экранная форма. Первое знакомство 55


Окно конструктора форм (Form Designer) 56
Окно свойств (Properties) 60
Конструирование экранной формы 63
4 Оглавление

Размещение элементов управления в экранной форме 66


Операторы 75
"Украшение" формы 77
Запуск формы на выполнение 78

Урок 7. Использование переменных 81


Практическое использование переменных 83

Урок 8. Массивы 88

Урок 9. Добавление записей в таблицу 90

Урок 10. Перемещение по записям таблицы 97


Использование построителя для объекта CommandGroup 97
Удаление записей 102
Создание экранной формы с использованием мастера Form Wizard 105
Создание экранной формы с использованием мастера AutoForm Wizard 109

Урок 11. Создание отчетов 111


Окно конструктора отчетов 111
Размещение в отчете элементов управления 114
Размещение в отчете полей 117
Формат данных 118
Определение условий печати 120
Размещение в отчете линий и контуров 122
Заголовок отчета и итоговые значения 122
Изменение цвета объектов в отчете 125
Размещение в отчете изображений 125
Просмотр отчета 126
Печать отчетов 128
Создание отчетов с использованием мастера Report Wizard 131
Вызов отчета из формы 136

Урок 12. Компиляция проекта 139

Урок 13. Работа с базой данных 143


Конструктор базы данных 143
Индексы 146
Простые индексы 147
Составные индексы 147
Создание постоянных отношений 149
Referential Integrity Builder 152
Идентификаторы 154
Хранимые процедуры 157
Триггеры 159
Практическое использование триггеров 160
Контроль достоверности ввода данных 165
Оглавление 5

Урок 14. Экранная форма. Продолжение знакомства 167


Объект ListBox 167
Пример использования 168
Раскрывающийся список (ComboBox) 172
Переключатели (OptionGroup) 173
Контейнер (Container) 176
Счетчик (Spinner) 176
Группа вкладок (PageFrame) 177
Флажок (Checkbox) 179
Линия (Line) 180
Контур (Shape) 182
Изображение (Image) 183
Таблица (Grid) 183

Урок 15. Выборка, упорядочение и просмотр данных 197


Команда LOCATE. Поиск записей 198
Команда SEEK. Поиск по значению индекса 199
Команда SET FILTER TO. Выбор группы записей 199
Сортировка данных в таблицах 200

Урок 16. Создание и использование запросов 203


Конструктор запросов (Query Designer) 203
Типы внешних объединений 209
Использование в запросе фильтров с несколькими условиями 212
Вывод результатов запроса 216
Курсор 217
Таблица 217
График 218
Экран 220
Отчет 221
Этикетка (почтовая наклейка) 222
HTML 227
SQL-инструкция SELECT или как все это сделать "вручную"? 230
Подзапросы 233
Использование HAVING 236
Использование переменных в SQL-инструкциях SELECT 236
Построение перекрестых таблиц 237
Использование SQL-инструкций в программах 243

Урок 17. Использование представлений данных (видов) 244


Создание нового представления данных 244
Параметры представления данных 251
Использование представления данных в отчете 253

Урок 18. Внедрение OLE-объектов 257


Внедрение нового OLE-объекта 260
Связывание OLE-объекта 263
6 Оглавление

Удаление OLE-объекта 265


Использование функций GETDIRQ, GETFILEO и команда APPEND GENERAL 265

Урок 19. Использование компонентов ActiveX и библиотек классов 268


Использование библиотек классов 268
Компоненты ActiveX 272
Использование календаря 279

Урок 20. Экспорт и импорт данных 280


Лис и Excel 280

Урок 21. Наборы форм 293

Урок 22. Создание меню приложения 296


Использование конструктора меню 299
Command (Команда) 30 J
Submenu (Подменю) 302
Определение клавиш быстрого доступа 303
Определение параметров меню 305
Генерация меню 306
Запуск меню 306
Запуск меню в экранной форме 308
Создание Shortcut-меню 309

Урок 23. Создание справочной системы 311


Создание предметного указателя 321
Создание контекстно-зависимых разделов справки 324
Кнопка What's This?. 326

Урок 24. Создание ЕХЕ-приложения 328


Параметры проекта 328
Установка основной программы 329
Опция Exclude 330
Построение исполняемого файла 330

Урок 25. Создание установочных дисков 334

ЧАСТЬ И. ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ
ПРОГРАММИРОВАНИЕ 343

Урок 26. Объекты 345


Классы 346
Композитные классы 349

Урок 27. Создание классов в Class Designer 352


Пример 1 — калькулятор 354
Оглавление 7

Пример 2 — Puzzle 359


Другие полезные примеры 369

Урок 28. Использование таймера 380

Урок 29. Создание экранных форм на основе пользовательских классов 388

Урок 30. Создание панели инструментов 397

Урок 31. Управление классами 401


Class Browser 401
Информация о классе и пиктограмма класса 404
Урок 32. Фундаментальные классы Visual FoxPro 407

Урок 33. Галерея компонентов (Component Gallery) 414


Панель инструментов Component Gallery 416
Работа с галереей компонентов 420
Использование галереи компонентов для создания приложения 421

Заключение 423

ПРИЛОЖЕНИЯ 425

Приложение 1. Настройка параметров конфигурации Visual FoxPro 427

Приложение 2. Возможные значения различных параметров 453


Использование диалоговых окон типа MessageBox 456

Приложение 3. Полезные советы 459


Экранные формы 459
Объект Grid 461
Добавление и удаление колонок в объекте Grid без использования Grid
Builder 461
"Полосатый" Grid 462
Элемент управления TextBox 462
Элементы управления ListBox и СотЬоВох 462
Как скрыть специфичные колонки в СотЬоВох или ListBox 462
Программное раскрытие списка СотЬоВох 463
Подсказки в ListBox 463
Сохранение в списке СотЬоВох DropDown новых строк, введенных
пользователем 463
Запуск других приложений из Visual FoxPro 464
Меню 464
Расширь свое системное меню 465
Панели инструментов 466
Шифрование пароля 466
Предметный указатель 467
"Никто не может бегать как лиса".
Fox Software

Введение

Здесь мы очень кратко поговорим о том, для кого и для чего предназначена
эта книга, дадим небольшую историческую справку о возникновении и раз­
витии Microsoft. Visual FoxPro, а также о различиях между современными и
устаревшими версиями данного программного продукта.

Для чего я написал эту книгу?


Для того чтобы Вы, уважаемый читатель, научились полноценно использо­
вать один из самых популярных программных продуктов — Microsoft Visual
FoxPro.
Читая эту книгу, Вы совершите экскурсию в удивительный мир программи­
рования, познакомитесь с базами данных и способами управления ими, по­
лучите основные понятия о принципах и методах объектно-ориентиро­
ванного визуального программирования.
А теперь перейдем на "ты"? По-моему, так будет удобнее: я думаю, что оба
мы относительно молоды, к чему нам излишняя официальность! Согласен?
Ну и прекрасно.
В общем, я гарантирую — руководствуясь этой книгой, ты не сможешь:
• "взломать" банкомат на соседней улице;
• отменить старт "Atlantis";
• читать электронную почту Президента;
• совершать подобные противоправные действия.
Ничему такому ты здесь не научишься, и в тюрьму тебя не посадят.
Зато ты будешь уметь:
• работать с Visual FoxPro;
• создавать таблицы, базы данных, экранные формы, отчеты и т. д.;
10 Введение

• программировать в терминах классов и работать с библиотеками классов;


• создавать свои собственные приложения — их сложность будет зависеть
только от поставленной перед тобой задачи и твоей фантазии;
• у тебя будет твердая пятерка (догадываешься, по какому предмету?), что
весьма полезно в жизни.
Как, заманчивая перспектива? То-то же! Ты спрашиваешь, что тебе для это­
го нужно?
Отвечаю: твое желание и эта книга. Еще, конечно, компьютер и непосред­
ственно сам "виновник торжества" — Microsoft Visual FoxPro. Где его взять?
Ну, друг мой, я не знаю... А если серьезно, то среда программирования
Visual FoxPro является довольно распространенным программным продук­
том, и уж его-то купить не проблема, поверь мне.
Мы будем считать, что Visual FoxPro уже установлен на твоей машине, ма­
шина находится в "здравом уме и твердой памяти", сам ты бодр, весел и го­
тов ринуться на покорение баз данных. Ура! Но не торопись хвататься за
мышь, потому что сейчас мы немного отвлечемся на историю создания это­
го замечательного программного продукта.

Немного истории,
или рождение старого лиса
История умалчивает о точной дате рождения FoxPro, но известно, что наш
Лис, как и положено всем нормальным лисам, развивался путем эволюции.
В 70-х годах прошлого века для управления базами данных наряду с други­
ми СУБД использовался язык программирования dBase. Вот из него-то и
"вышло" в середине 80-х годов детище компании Fox Software, окрещенное
как FoxPro. "Никто не может бегать как лиса" — таким был девиз разработ­
чиков, имеющих в виду скорость обработки данных.
От своего прародителя Лис отличался, как бронепоезд от дрезины (как по
скорости, так и по "комфорту" работы) — ибо он уже имел нормальный
GUI (Graphic User Interface, графический интерфейс пользователя). Но
главным все же у "ребенка" был не этот самый GUI — главным была ско­
рость! Основатели компании Fox Software демонстрировали многочисленной
аудитории, как FoxPro за считанные секунды находил нужную запись в базе
данных, содержавшей несколько сотен тысяч записей! Мир вздрогнул, а
присутствовавший при этом зрелище народ ахнул от восторга, тем самым
выписав путевку в жизнь нашему приятелю Лису.
В последующие годы развитие FoxPro обеспечивала компания Microsoft,
выкупившая этот программный продукт у Fox Software. Наряду с версией
FoxPro 2.5 for DOS вышла в свет FoxPro for Windows, затем уже появилась
Введение 11

первая "визуальная" версия — Visual FoxPro 3.0, после нее Visual FoxPro 5.0,
Visual FoxPro 6.0 (именно ее мы с тобой и будем рассматривать) и наконец,
не так давно нас порадовали выходом в свет новой версии — Visual
FoxPro 8.0 (и даже поговаривают о выпуске девятой версии!).
Так в чем же отличие "визуальных" версий от более ранних? Сейчас я тебе
объясню на примере шестой версии Visual FoxPro. Почему именно шестой,
а не восьмой или пятой? Да просто потому, что абсолютно непринципиаль­
но, на какой конкретной версии данного продукта проходить обучение.
Пусть это будет пятая, седьмая, даже третья версия — это не суть важно.
Важно то, что во всех версиях принципы программирования одинаковы,
используется один и тот же язык и подавляющее большинство команд,
свойств, методов и событий идентичны. Есть, конечно, различия между
третьей и восьмой версиями (более того, существенные различия), но еще
раз повторюсь — это никак не повлияет на твою последующую работу на
ниве программирования. И еще один аргумент — несмотря на выход вось­
мой версии, наиболее популярной все же остается именно шестая.

Что нового в СУБД Visual FoxPro?


Почему, собственно, Visual? Visual — от слова "визуальный", т. е. видимый.
А что это означает? То, что тебе не придется самому писать программный
код (или почти не придется). Проект твоего приложения будет находиться
перед твоими глазами в виде иерархического дерева и ты можешь запросто
переключаться между любыми компонентами. В общем, все, что ты приду­
маешь — то и увидишь на мониторе: это так называемая технология
WYSIWYG (What You See Is What You Get).
А знаешь, как было раньше, в "не визуальную эру"? В тех версиях не было
экранных форм, там использовались "экраны" (screen) и чтобы увидеть что-
нибудь на этом экране, приходилось писать программный код — естествен­
но, "вручную" — и только потом на мониторе появлялось нечто похожее на
то, что ты хотел (и то далеко не всегда). Но мы-то с тобой работаем на
"продвинутом" Visual и подобная ситуация теперь может только присниться.
Наряду со всей этой красотой хочется кратко отметить еще несколько при­
ятных вещей, реализованных в последних версиях Visual FoxPro.
• Усовершенствованный Automation Server — поддерживает технологию
СОМ. Это позволяет использовать возможности Visual FoxPro в других
приложениях, и наоборот.
• HTML-справка. При помощи дополнительной сервисной программы
HTML Help Workshop ты сможешь разработать для своего приложения
справочную систему в формате HTML.
• Большое количество построителей (Builder) и мастеров (Wizard) — их
использование способно здорово облегчить нелегкую жизнь программиста.
12 Введение

• Галерея компонентов позволит тебе организовывать и группировать раз­


личные объекты (формы, классы и т. д.).
• Поддержка форматов JPEG, GIF — можешь украсить приложение кар­
тинками и анимацией.
• Поддержка дат после 2YK (2000 г.) — правда, нам это уже не грозит.
• Улучшенный графический интерфейс пользователя — тот самый GUI,
про который ты уже слышал.
• Технология активных документов — у тебя есть возможность просмот­
реть не HTML-документ в браузере Internet Explorer.
• Поставляемая совместно с Visual FoxPro программа создания установоч­
ных дисков для распространения создаваемых приложений.
Это, как ты понимаешь, лишь некоторые новые "фишки" Visual FoxPro, пе­
речислять подробно все нововведения можно очень долго. Если в процессе
создания наших приложений встретится что-нибудь необычное — я обяза­
тельно расскажу о нем подробнее.
Прочитав эти страницы, ты узнал с "кем" тебе придется иметь дело, и те­
перь мы переходим к первой части нашей книги.
ЧАСТЬ I
Процедурное программирование
в Visual FoxPro
В части I нашей книги мы познакомимся с основами процедурного или мо­
дульного программирования в СУБД Visual FoxPro. Мы начнем с самого
простого: научимся определять структуру свободной таблицы, познакомим­
ся с диспетчером проекта, экранной формой, отчетом и т. д. Научимся ис­
пользовать различные элементы управления, освоим приемы работы с раз­
личными мастерами (Wizard) и построителями (Builder). Затем мы перейдем
к работе с базой данных, научимся создавать запросы и представления дан­
ных и создадим полностью работающее учебное приложение.
УРОК 1

Начинаем работать!

Начинать-то начинаем, но ведь у тебя уже, наверняка, возникли некоторые


вопросы. Что такое СУБД? А где я возьму базу данных?
Я думаю, что тебе уже приходилось слышать про базы данных, а когда ты
услышал про них, то подумал: "Это точно не для меня, ведь этим могут за­
ниматься только крутые программисты-профессионалы или уж совсем
злобные хакеры". Что тут сказать? Ты прав, приятель, а чтобы убедить тебя
окончательно, приведу несколько мало кому известных фактов из своей
собственной биографии:
• когда я был маленьким, вместо погремушек я играл дискетами с файла­
ми баз данных;
• свою первую Нобелевскую премию я получил в 10 лет;
• по ночам (особенно в полнолуние) я люблю взламывать компьютерные
сети.
Не веришь? Вот и молодец, потому что на самом деле ситуация несколько
иная:
• я такой же "профи", как и ты;
• я понятия не имею о технологии "взлома";
• я белый и пушистый;
• я боюсь всего этого больше, чем ты (если только ты не думаешь, что я
каждый день пишу новую книгу о программировании).
Так что не отчаивайся, дружище — сейчас я прочту тебе небольшую лек­
цию, и мы все разберем по порядку.

Что такое база данных?


С базами ты сталкиваешься почти каждый день. Вот ты идешь в банк, что­
бы снять энную сумму (для покупки Visual FoxPro). А ты видел, чтобы one-
16 Часть I. Процедурное программирование в Visual FoxPro

ратор, заметив тебя, начинал лихорадочно перебирать какие-нибудь бумаги,


гроссбухи и подобные вещи, чтобы определить, кто ты такой и сколько там
у тебя на счету? Конечно же, нет.
У оператора стоит компьютер, в который занесена информация о всех кли­
ентах банка, и он за секунду узнает о тебе все, что ему нужно. При этом все
данные в его компьютере хранятся в виде базы данных. Это только один
пример, а вообще, при наличии воображения, в виде базы данных можно
представить все, что угодно. Ну, или почти все. Телефонный справочник —
база данных? Еще какая! Паспорт — тоже база данных, правда, очень ма­
ленькая, всего с одной записью. Расписание твоих уроков, календарь, днев­
ник — все это можно представить в виде базы данных. А если мы заглянем
в какую-нибудь бухгалтерию или, например, в налоговую инспекцию (Боже
упаси!) — вот где огромное количество различных баз данных! Именно
в таких местах наш Лис чувствует себя, как рыба в воде.
Очевидно, что базы данных занимают отнюдь не последнее место в нашей
деловой, да и в повседневной жизни. Так что же это такое?
С точки зрения Visual FoxPro база данных — это файл с расширением dbc,
который может содержать такие объекты, как:
• Tables (таблицы);
• views (виды, или представления данных: они подразделяются на локаль­
ные Local Views И удаленные Remote Views);
• Connections (связи);
• stored Procedures (хранимые процедуры).
Помимо баз данных, источником данных для Visual FoxPro могут служить
свободные таблицы и запросы.

Таблицы
Таблица в FoxPro хранится в файле с расширением dbf. Представим про­
стейший пример (табл. 1.1).

Таблица 1.1. Таблица Pasport

Фамилия Имя Отчество Дата рождения

Шапорев Дмитрий Сергеевич 22.08.1972

Ясно видно, что таблица — это двумерный набор строк и столбцов.


В FoxPro столбцы таблиц называются полями (Field — англ. "поле"), а стро
ки — записями (Record ~ англ. "запись") — табл. 1.2.
Урок 1. Начинаем работать! 17

Таблица 1.2. Пояснение к определению таблицы

Field 1 Field2 Field n


Record 1
Record2

Record n

Каждое поле имеет свое имя, тип, размер, и в нем содержится информация
о данных какой-либо одной категории. В таблице pasport.dbf поле имя со­
держит строку СИМВОЛОВ Дмитрий (ТИП Character), а поле Дата рождения —
дату 22.08.1972 (тип Date). Попытка записать в поле дата рождения строку
символов обречена на неудачу, т. к. данное поле имеет тип Date, а поля это­
го типа могут содержать только дату и ничего кроме этого. Существует еще
несколько других типов полей, используемых в таблицах, в дальнейшем мы
их подробно рассмотрим.
Таблица в Visual FoxPro может быть представлена как в виде свободной таб­
лицы, так и в виде таблицы базы данных.
Таблица базы данных аналогична свободной таблице, но для нее в базе дан­
ных может храниться дополнительная информация, такая как:
• длинное имя;
• комментарии для полей;
• первичные индексы;
• заголовки полей;
• правила контроля при изменении или добавлении данных;
• триггеры;
• виды (представления данных).
Все это называется словарем данных таблицы базы данных.
Я уже говорил о том, что и просто свободная таблица, и таблица базы дан­
ных хранится в файлах с расширением dbf (Data Base File), а вот сама база
данных — в файле с расширением dbc (Data Base Container). Подобное раз­
деление началось с выходом версии Visual FoxPro 3.0, в предыдущих верси­
ях все таблицы назывались базами данных и имели расширение dbf.
Базы данных могут иметь различные размеры, я имею в виду количество
записей — от простейшей, состоящей из одной таблицы с одной записью до
довольно "крутых" конструкций с десятками, а то и сотнями связанных таб­
лиц, каждая из которых может содержать, допустим, до миллиона записей!
Как ты считаешь, сколько тебе понадобится времени, чтобы найти нужные
18 Часть I. Процедурное программирование в Visual FoxPro

данные, просматривая, скажем, 8 424 659 записей? Я думаю, до пенсии точ­


но хватит...
Именно на этот случай (быстрый поиск, редактирование данных) и были
созданы программы, которые называются СУБД или Системы Управления
Базами Данных.

СУБД
Если тебе где-нибудь встретится аббревиатура СУРБД, то знай, что это то
же самое — только на нормальный язык переводится как Система Управле­
ния Реляционными Базами Данных. Слово "реляционные" означает, что
данные в таблицах каким-то образом связаны между собой. Visual FoxPro
также можно определить как СУРБД.
В настоящее время существует огромное количество различных систем
управления данными. Наиболее распространены такие, как Oracle, SQL
Server, Microsoft Access, Clipper и др. Все они. как и все в этом мире, имеют
свои преимущества и свои недостатки. Наш друг Лис также не идеален, но
он является достойным конкурентом в данной категории профаммного
обеспечения, т. к. изначально был задуман именно как средство управления
базами данных и ничто другое.
На этом наша короткая лекция заканчивается, и если ты еще не заснул, то
наш хитрый Лис давно уже смотрит сны — пора его будить, чем мы и зай­
мемся.
УРОК 2

Запуск Visual FoxPro

Ты, наверное, уже не раз запускал на своей машине различные програм­


мы — Word, Excel, Internet Explorer, еше какие-нибудь, — поэтому для тебя
не секрет, что способов запустить Windows-приложение — "вагон и малень­
кая тележка". Visual FoxPro в этом отношении ничем не отличается от дру­
гих программ, и также имеется несколько способов его активизации. Рас­
смотрим некоторые из них.
• Запуск с использованием кнопки Пуск (Start).
Когда ты устанавливал Visual FoxPro на свой компьютер, инсталлятор
создал новую программную группу Windows, которая называется
Microsoft Visual FoxPro. Нажми кнопку Пуск (Start), расположенную на
рабочем столе твоей машины, в появившемся меню выбери пункт Про­
граммы (Programs). Раскроется еще одно меню, в котором тебе нужно
выбрать пункт Microsoft Visual FoxPro, при этом появится еше одна
"менюшка" — вот за ней-то и спрятался наш рыжий друг. (Одно "но" —
если ты используешь не шестую, а. скажем, восьмую версию, то допол­
нительное меню не появится). Если что-то не понятно, посмотри
рис. 2.1.
• Запуск c использованием командной строки.
Нажми опять же кнопку Пуск, выбери пункт Выполнить. В появившем­
ся окне нажми кнопку Обзор. Найди каталог, в котором находится
Visual FoxPro и укажи файл vfp6.exe (он имеет пиктограмму с изображе­
нием забавной рыжей мордочки), нажми кнопку Открыть, а затем в ок­
не Запуск программы щелкни по кнопке ОК (рис. 2.2).

На заметку
Название исполняемого файла зависит от используемой версии Visual FoxPro
Например, в шестой версии он называется vfp6.exe, а в восьмой — соответст­
венно vfp8.exe.
20 Часть I. Процедурное программирование в Visual FoxPro

Рис. 2.1. Запуск с использованием кнопки Пуск

Рис. 2.2. Запуск с использованием командной строки

• Запуск с использованием Проводника Windows.


Нажимаем кнопку Пуск, выбираем пункт Программы, затем Проводник.
В открывшемся окне находим каталог с Visual FoxPro, ставим указатель
мыши на файл Vfp6.exe, теперь просто делаем двойной шелчок левой
кнопкой мыши (Double Click) и, как говорится, дело в шляпе (рис. 2.3).
А можно и без двойного щелчка — устанавливаем мышь на Vfp6.exe и
нажимаем правую кнопку. В появившемся контекстном меню выбираем
Урок 2. Запуск Visual FoxPro 21

пункт Открыть. К такому же результату приведет щелчок на пункте ме­


ню Файл и выбор соответствующего пункта Открыть.
• Запуск с использованием ярлыка.
По-моему, это самый удобный способ, особенно если каждый день ра­
ботаешь с Visual FoxPro. Все очень просто: находим файл Vfp6.exe, ука­
зываем на него мышью и нажимаем правую кнопку. Появляется меню,
в котором выбираем пункты Отправить | Ярлык на рабочий стол. Все.
На рабочем столе появится "Ярлык для Vfp6.0". Теперь не нужно нажи­
мать разные кнопки, запускать проводники и т. д. — для запуска мы
просто шелкаем по ярлыку. Дешево и сердито. (Ярлык по желанию
можно переименовать — щелкаем правой кнопкой мыши и выбираем
соответствующий пункт.)

Рис. 2.3. Запуск с использованием программы Проводник

Можно, конечно, привести еще пару-другую способов открытия программ


Windows, но цель данной книги не в этом — в конце концов, запуск нужно­
го приложения дело сугубо личное, кому как удобнее... Нам важно, что
получится после запуска. А получится вот какая штука (рис. 2.4).
То, что ты сейчас видишь, называется главным окном, внутри которого от­
крывается небольшое окно команд (Command Window). Если ты запустишь
22 Часть I. Процедурное программирование в Visual FoxPro

\\ HUM
Рис. 2.4. Главное окно Visual FoxPro

Visual FoxPro сразу после его установки на свой компьютер, то после запус­
ка появится экран-заставка (рис. 2.5), содержащий пять опций:
• Open the new Component Gallery to organize your Visual FoxPro com­
ponents — открыть новую галерею компонентов для объединения компо­
нентов Visual FoxPro;
• Discover programming solutions by exploring sample applications — посмот­
реть программные решения из примеров приложений;
• Create a new application — создать новое приложение;
• Open an existing project — открыть существующий проект;
• Close this screen — закрыть этот экран.
В нижней части экрана-заставки расположен флажок Don't display this
Welcome screen again (He показывать этот экран при следующих запусках).
Большинство из программистов именно его и устанавливают. Мы поступим
таким же образом (щелкнув на нем мышью), и при следующем запуске сра­
зу окажемся в главном окне Visual FoxPro, минуя экран-заставку.
Урок 2. Запуск Visual FoxPro 23

Рис. 2.5. Экран-заставка Visual FoxPro


УРОК 3

Главное окно Visual FoxPro

Этот объект можно разбить на шесть основных частей:


• строка заголовка (Caption);
• строка главного меню (System menu);
• панель инструментов (Toolbar);
• рабочая область или рабочий стол (Desktop);
• командное окно (Command window);
• строка состояния (Status bar).
Я понимаю твое нетерпение — все это пока кажется довольно скучным, но
согласись, что нельзя выезжать на новом автомобиле, не узнав назначение
тех или иных элементов управления, не так ли? Все отдают себе отчет,
к чему могут привести подобные эксперименты... Поэтому стоит уделить
этому уроку немного своего драгоценного времени — мы кратко рассмот­
рим каждую часть главного окна.

Заголовок
Заголовок, как известно, для того и существует, чтобы на нем было что-
нибудь написано. А там и написано: Microsoft Visual FoxPro. Но, в отличие
от обычных заголовков, заголовки окон Windows имеют еще и некоторые
дополнительные функции. Например, щелкни мышью по значку пикто­
граммы, расположенному слева от надписи заголовка. Откроется системное
меню, позволяющее тебе манипулировать главным окном Visual FoxPro.
Приведем пункты системного меню в табл. 3.1.
Так, что там у нас еще?
Справа расположены три кнопки. Первая, с чертой внизу — Свернуть —
сворачивает главное окно до размера пиктограммы и помешает его на Па-
Урок 3. Главное окно Visual FoxPro 25

нель задач Windows. При этом Visual FoxPro не прекращает своей работы.
Вторая кнопка — Развернуть — разворачивает главное окно. И наконец,
третья кнопка Закрыть — закрывает главное окно, тем самым прекращая
работу Visual FoxPro.
Закрашенная в синий цвет часть заголовка также имеет свои функции:
О можно щелкнуть на ней мышью и, удерживая нажатой левую кнопку,
перетащить главное окно в любое место экрана;
О выполнив двойной щелчок мышью в этой области, можно развернуть
главное окно или восстановить его предыдущие размеры.

Ha 3 a м е т к у
Синий цвет, установленный по умолчанию, можно запросто изменить — за это
отвечают элементы управления из Панели управления Windows (Панель
управления | Экран).

Таблица 3.1. Команды системного меню

Команда Описание

Restore (Восстановить) Восстанавливает предыдущий размер окна после того,


как ты его свернул или развернул
Move (Переместить) Передает фокус главному окну Visual FoxPro (активизи­
рует его) и позволяет тебе двигать его по всему экрану,
используя клавиатуру

Size (Размер) Активизирует главное окно и позволяет менять размеры


его границ, используя клавиатуру (клавиши управления
курсором)
Minimize (Свернуть) Сворачивает главное окно до размеров пиктограммы
Maximize (Развернуть) Разворачивает главное окно "во всю ширину". Размеры
максимальные
Close (Закрыть) Закрывает Visual FoxPro

Главное (системное) меню Visual FoxPro


Вот уж действительно, меню как в ресторане — чего только нет! Будет очень
хорошо, если ты в этот момент начнешь просматривать пункты системного
меню Visual FoxPro на мониторе — наглядный пример очень полезен, по­
верь мне. Бери мышь — и вперед!
Меню File (Файл). При щелчке мышью открывается меню, которое содер­
жит набор команд, связанных с доступом к файлам. С помощью этих ко-
26 Часть I. Процедурное программирование в Visual FoxPro

манд можно создавать, открывать, сохранять, печатать и закрывать файлы


различных типов. Список команд представлен в табл. 3.2.

Таблица 3.2. Команды меню File

Команда Описание

New (Создать новый) Позволяет создавать файлы различных типов


Open (Открыть) Открывает диалоговое окно Open, в котором можно
указать имя и тип файла, а затем открыть указанный
файл
Close (Закрыть) Закрывает активное окно
Save (Сохранить) Сохраняет файл на диске. Если файл только что
создан, то Лис предложит ввести имя этого файла
Save as (Сохранить как) Также сохраняет указанный файл на диске, но пе­
ред сохранением обязательно запрашивает имя
файла. При помощи этой команды можно создать
точную копию данного файла
Save as HTML Позволяет сохранить файл в формате HTML
(Сохранить как HTML)
Revert (Отменить) Позволяет отменить все изменения, выполненные в
текущем сеансе редактирования и вернуть файл к
его "первозданному" виду
Import (Импорт) Импортирует файл из другого приложения, напри­
мер из ранних версий FoxPro
Export (Экспорт) То же самое, что предыдущая команда, только "в
обратную сторону" — из Visual FoxPro в другое при­
ложение
Page Setup Позволяет изменить параметры принтера и макета
(Параметры страницы) страницы
Page Preview Отображает отчеты на экране такими, какими они
(Предварительный просмотр) будут после вывода на печать. Просмотр, в общем
Print (Печать) Печатает содержимое активного окна или буфера
обмена
Send (Отправить) Можно отправить сообщение E-Mail. Учителю ин­
форматики или, например, автору этой книги
Exit (Выход) Выход. Коротко и ясно. Закрывает главное окно и
прекращает работу Visual FoxPro. Как говорится —
аут!

Меню Edit (Редактирование). С помощью команд этого меню осуществля­


ется редактирование файлов (табл. 3.3).
Урок 3. Главное окно Visual FoxPro 27

Таблица 3.3. Команды меню Edit

Команда Описание

Undo (Отменить) Отменяет последнее действие. Щелкнул ты, допустим,


мышью не туда, куда надо, и что-то там изменилось.
Катастрофа?! Нет, конечно. Смело нажимай Undo —
опять все в порядке! Удобная штука
Redo (Повторить) Прямо противоположна предыдущей команде. "Отмена
отмены". А по-русски — снова выполняет отмененное
действие
Cut (Вырезать) Удаляет выделенный текст или объект и помещает его
в буфер обмена (Clipboard)
Сору (Копировать) Создает копию выделенного текста или объекта и также
помещает ее в буфер обмена
Paste (Вставить) Вставляет в указанную тобой позицию содержимое бу­
фера обмена
Paste Special Почти то же, что и Paste, только "круче" — вставляет в
(Специальная вставка) указанную позицию не содержимое буфера обмена, а
объекты из других приложений
Clear (Очистить) Удаляет выделенный текст без копирования его в буфер
обмена
Select All (Выделить все) Выделяет все объекты в текущем окне. Используется
для одновременного перемещения или форматирова­
ния объектов. Очень удобно применять при создании
больших экранных форм и отчетов, да и вообще вещь
хорошая...
Find (Найти) Используется для поиска строк в файле
Find Again (Найти еще) То же самое, что и Find, только поиск ведется не с на­
чала документа, а с указанной позиции
Replace (Заменить) Используется для замены текстовых строк
Go to Line Применяется при отладке программ и позволяет перей­
(Перейти на строку) ти на строку с указанным номером
Insert Object Действует почти как команда Paste Special, но при
(Вставить объект) этом позволяет сразу открыть другое приложение, в
котором можно создать этот самый объект
Object (Объект) Позволяет отредактировать объект OLE
Links (Связи) Редактирование связанных объектов OLE
Properties (Свойства) Настройка редактора и его свойств

Меню View (Вид) — "хитрая штучка". Допустим, когда мы просматриваем


таблицу, меню View содержит команды, связанные с просмотром таблицы.
28 Часть I. Процедурное программирование в Visual FoxPro

Если же в данный момент не открыта ни одна таблица, форма или отчет, то


в этом меню содержится всего одна опция Toolbars (Инструменты или Па­
нели инструментов). При выборе этой опции открывается диалоговое окно
Toolbars (Панели инструментов), в котором перечислены все панели инст­
рументов Visual FoxPro.
Если мы все же просматриваем таблицу либо редактируем экранную форму
или отчет — в этом случае можно пользоваться командами меню View из
табл. 3.4.

Таблица 3.4. Команды меню View

Команда Описание

Edit (Редактирование) Включает режим E d i t для просмотра и редак­


тирования записей. В этом режиме поля таблиц
отображаются вертикально
Browse (Просмотр) Включает режим Browse для просмотра и ре­
дактирования записей. В этом режиме поля
таблиц отображаются горизонтально. Строки
представляют записи

Append Mode (Добавление), Добавляет пустую запись в конец таблицы, при


(Расширенный режим) этом указатель записи устанавливается на ее
первое поле
Design (Конструкторы) Отображает окно Конструктора форм (Form
Designer), или окно Конструктора отчетов
(Report Designer), или окно Конструктора эти­
кеток (Label Designer) — в зависимости от того,
что тебе нужно
Tab Order (Порядок табуляции) Определяет порядок обхода объектов в экран­
ных формах при использовании клавиши <ТаЬ>
Preview Отображает отчеты на экране такими, какими
(Предварительный просмотр) они будут после печати
Data Environment Определяет таблицы и отношения, данные из
(Среда данных) которых будут использованы в экранных фор­
мах и отчетах (этикетках)
Properties (Свойства) Открывает диалоговое окно Properties (Свой­
ства), в котором отражены все свойства экран­
ных форм и элементов управления
Code (Код, программа) Открывает окна программ для редактирования
методов объектов
Form Controls Toolbar (Панель Открывает панель инструментов для разработ­
элементов экранной формы) ки экранной формы во время работы в Конст­
рукторе форм
Урок 3. Главное окно Visual FoxPro 29

Таблица 3.4 (окончание)

Команда Описание

Report Control Toolbar Открывает панель инструментов для разработ­


(Панель инструментов отчета) ки отчета во время работы в Конструкторе отче­
тов

Layout Toolbar (Панель Используя эту панель инструментов, можно


инструментов для макетирования) выравнивать элементы управления в формах и
отчетах

Color Palette Toollbar (Панель Панель палитры цветов позволяет выбирать


палитры цветов) цвет для элементов управления
Report Preview Toolbars (Панель На этой панеле расположены кнопки, которые
предварительного просмотра помогут тебе напечатать отчет, просмотреть его
отчета) страницы или выйти из режима просмотра
Database Designer Открывает окно Database Designer (Конструк­
(Конструктор базы данных) тор базы данных), в котором можно управлять
таблицами, видами и отношениями между таб­
лицами
Grid lines (Линии сетки) Включает и выключает режим отображения
линий сетки

Show Position При выборе этой опции в строке состояния ото­


(Показать позицию) бражаются позиция, высота и ширина объекта

General Options Добавляет код в меню во время работы с Кон­


(Общие параметры) структором меню (Menu Designer)
Menu Options (Опции меню) Добавляет программный код для выбранной
опции меню

Toolbars (Инструменты) Открывает диалоговое окно Toolbars (Инстру­


менты), в котором отображены все панели ин­
струментов Visual FoxPro

Теперь у нас на очереди команды меню Format (Формат). Они применяются


для изменения характеристик шрифта, отступов и интервалов. Заметим, что
при использовании различных конструкторов Visual FoxPro не все команды
доступны — это зависит от конкретного случая. Мы же рассмотрим их все
сразу (табл. 3.5).

Таблица 3.5. Команды меню Format

Команда Описание
Font (Шрифт) Используется для выбора шрифта и его
параметров (размер, цвет и т. д.)
30 Часть I. Процедурное программирование в Visual FoxPro

Таблица 3.5 (продолжение)

Команда Описание

Enlarge Font (Увеличить шрифт) Увеличивает шрифт в текущем окне


Reduce Font (Уменьшить шрифт) Уменьшает шрифт в текущем окне
Single Space (Одинарный интервал) Устанавливает в текущем окне одинарный
интервал для текста
11/2 Space (Полуторный интервал) Устанавливает в текущем окне полуторный
интервал для текста
Double Space (Двойной интервал) Устанавливает в текущем окне двойной
интервал для текста
Indent (Отступ) Устанавливает отступ в текущем окне для
выделенных строк или для текущей строки
Unindent (Отменить отступ) Отменяет отступ в текущем окне для выде­
ленных строк или для текущей строки
Comment (Комментарий) Выделенная строка становится коммента­
рием
Align (Выравнивание) Команды выравнивания объектов
Size (Размер) Команды, влияющие на размер объекта
Horizontal Spacing Команды настройки горизонтального ин­
(Горизонтальный интервал) тервала между выделенными объектами
Vertical Spacing Команды настройки вертикального интер­
(Вертикальный интервал) вала между выделенными объектами
Bring to Front (Вынести вперед) Выделенный объект располагается впереди
всех остальных объектов формы или отчета
Send to Back (Отправить назад) Выделенный объект располагается позади
всех остальных объектов формы или отчета
Group (Группировка) Группирует выделенные объекты и позво­
ляет в дальнейшем обращаться с ними как
с единым объектом
Ungroup (Разбивка группы, Разбивает группы на отдельные элементы
разгруппировка)
Snap to Grid При "переносе" объекта мышью и "сбросе"
(Привязка к линиям сетки) (отпускании кнопки) левая верхняя точка
объекта соединяется с ближайшей точкой
пересечения линий сетки
Set Grid Scale (Масштаб сетки) Настройка расстояния между горизонталь-
ными и вертикальными линиями сетки
Text Alignment (Выравнивание текста) Выравнивает текст в выделенном объекте
Урок 3. Главное окно Visual FoxPro 31

Таблица 3.5 (окончание)

Команда Описание
Fill (Заполнение, заливка) Определяет орнамент и цвет заполнения
для фигур
Реп (Перо) Определяет стиль и размер пера для рисо­
вания линий и фигур
Mode (Режим) Устанавливает режим прозрачности для
заднего плана объекта

В меню Tools (Инструменты) представлен довольно широкий выбор разных


полезных вещей: мастера, отладчики, макросы и прочие "приятности"
(табл. 3.6).

Таблица 3.6. Команды меню Tools

Команда Описание

Wizards (Мастера) Список мастеров Visual FoxPro


Spelling (Орфография) В школе у тебя орфографию проверяли? Вот и здесь
проверят. Проверяется правописание текстовых и Мето-
полей

Macros (Макрос) При помощи этой команды можно создать свои макросы
Class Browser Можно просматривать содержимое любого класса Visual
(Просмотр класса) FoxPro
Component Gallery Эта команда открывает соответствующее окно для рабо­
(Галерея компонентов) ты с Галереей компонентов Visual FoxPro
Coverage Profiler Позволяет просмотреть информацию о выполненной про­
грамме
Beauty (Украсить) Старина Лис тот еще пижон — при помощи этой команды
он переформатирует файл программы, добавляя отступы
и заменяя строчные буквы прописными. Потом попробу­
ем — забавно!
Run Active Document Позволяет выбрать и запустить активный документ
(Активный документ)
Debbuger (Отладчик) Не знаю, как и перевести... Bugs — "жучки". В среде про­
граммистов жучками называются ошибки в программном
коде. А вот этот убойный механизм и позволяет нам их
выловить и безжалостно уничтожить. Отладчик, одним
словом

OPtions (Опции) Доступ к параметрам конфигурации Visual FoxPro


32 Часть I. Процедурное программирование в Visual FoxPro

Пятый пункт линейки системного меню Visual FoxPro — Program (Про­


граммы). Здесь находится всего шесть команд, связанных с запуском, оста­
новкой и компиляцией программ (табл. 3.7).
Таблица 3.7. Команды меню Program

Команда Описание

Do (Выполнить) Запускает программу из диалогового окна

Cancel (Отменить) Отменяет выполнение текущей программы


Resume (Продолжить) Возобновляет выполнение программы, находящейся в
состоянии ожидания. "Довести" программу до такого
состояния очень просто — используйте следующую
команду

Suspend (Приостановить) Приостанавливает выполнение текущей программы


Compile (Компилировать) Компилирует исходный файл в объектный код

Run (Выполнить) Запускает текущую программу

Расположением окон на экране заведует предпоследний пункт главного ме­


ню — Window (Окно) (табл. 3.8).
Таблица 3.8. Команды меню Window

Команда Описание

Arrange All Показывает на экране все открытые окна таким об­


(Расположить все) разом, что они не перекрывают друг друга
Hide (Скрыть) "Прячет" активное окно, но не удаляет его из памяти
Show All (Показать все) Отображает все определенные окна

Clear (Очистить) Стирает текст из активного окна или из главного


окна Visual FoxPro
Cycle (Цикл) Делает активным следующее окно
Command Window Открывает окно для ввода команд
(Командное окно)
Data Session (Сеанс данных) Открывает соответствующее окно, в котором можно
проконтролировать, какие таблицы в каких рабочих
областях открыты. (А областей-то 32 767!)
<Список> Девять ранее определенных пользователем (т. е.
тобой) окон. Если окон больше, появляется пункт
More Windows (Еще окна). Открыть любое из них
можно, щелкнув мышью
Урок 3. Главное окно Visual FoxPro 33

Заключительная опция системного меню — Help (Помощь).


Вот представь: пишешь ты программу, пишешь и вдруг — ПРОБЛЕМА!
И спросить не у кого! И меня рядом нет! Что делать? В англоязычных стра­
нах в таких случаях принято кричать: "Help me! Save me! I'm dying!". А мы
поступаем иначе: щелкаем мышью на соответствующем пункте и изучаем
меню Help (Помощь) — табл. 3.9.

Таблица 3.9. Команды меню Help

Команда Описание

Microsoft Visual Fox Pro Help Topic Открывает окно справочной системы
(Темы справочной системы)
Contents (Содержание) Вкладка Содержание
Index (Указатель) Указатель

Search (Поиск) Поиск


Techical Support Отображает информацию о технической
(Техническая поддержка) поддержке
Microsoft on the Web Открывает меню со ссылками на Web-стра­
(Страничка корпорации Microsoft нички корпорации Microsoft
в Интернете)
About Microsoft Visual Fox Pro В этом окне содержится информация о раз­
(Информация о программе) работчиках, номер версии программы и т. д.

Теперь, когда мы более или менее разобрались с назначением различных


команд меню, самое время для следующего вопроса.

А как выполнить команду меню?


Да запросто! Как и в других приложениях Windows, в Visual FoxPro команды
меню можно выполнять, используя как мышь, так и клавиатуру.
• Использование мыши — устанавливаем указатель на нужный пункт ли­
нейки меню и нажимаем левую кнопку мыши (если ты левша — нажи­
май правую, у тебя мышь другая). В раскрывшемся списке команд меню
выбираем необходимую и опять жмем левую кнопку.
• Использование клавиатуры — сначала нужно активизировать линейку
меню, нажав клавишу <F10> или <Alt>. Затем при помощи клавиш
управления курсором устанавливаем курсор на нужный пункт и нажима­
ем клавишу <Enter>. Аналогичные манипуляции проводим и с раскрыв­
шимся списком команд меню.

2
Зак. 1002
34 Часть I. Процедурное программирование в Visual FoxPro

• Использование "горячих" клавиш ("hot key"). Ты уже заметил, что справа


от большинства команд меню написаны непонятные закорючки типа
Ctrl+O? Вот это и есть эти самые "горячие" клавиши или "клавиши бы­
строго доступа". При комбинации (одновременном нажатии) клавиш
<Ctrl> и указанной буквы выполнится соответствующая команда. В дан­
ном примере откроется диалоговое окно Open. Использование этих соче­
таний клавиш действительно очень удобно, а время, потраченное тобой
на их запоминание, с лихвой компенсируется при разработке приложе­
ния. Да, еще совет — не пытайся нажимать их одновременно, все равно
не получится — просто нажми <Ctrl> и, не отпуская ее, надави нужную
клавишу. Успехов!

Как отменить выполнение команды меню?


Сделать это очень просто:
• при использовании мыши просто щелкнуть в любое свободное место эк­
рана;
• при использовании клавиатуры отмена происходит по нажатию клавиши
<Esc>. Для отмены активизации линейки главного меню необходимо по­
вторно нажать клавишу <F10> или <Alt>.

Панель инструментов
Как я уже говорил, в Visual FoxPro имеется несколько панелей инструмен­
тов, каждая из которых предназначена для выполнения какой-нибудь кон­
кретной задачи — в зависимости от того, что именно мы делаем в данный
момент.
По желанию ты можешь ВСЕ панели инструментов разместить на рабочем
столе, но при этом будет неудобно работать, т. к. экранная площадь значи­
тельно сократится. В процессе построения наших приложений мы подробно
рассмотрим весь этот инструментарий, а пока познакомимся с главной сис­
темной панелью инструментов Visual FoxPro (рис. 3.1) Данная панель инст­
рументов еще называется Standard (Стандартная) и практически всегда при­
сутствует на экране.

Рис. 3.1. Главная панель инструментов

На главной системной панели инструментов расположены двадцать кнопок


и один comboBox (привыкай к терминологии, comboBox — это элемент управ-
Урок 3. Главное окно Visual FoxPro 35

ления, представляющий собой раскрывающийся список). При установке ука­


зателя мыши на любую кнопку отображается окно с подсказкой (TooiTips),
в котором приводится название кнопки. А для того, чтобы узнать, что озна­
чает сие название и что происходит при нажатии этих кнопок, тебе необхо­
димо просмотреть табл. 3.10.

Таблица 3.10. Команды панели инструментов

Название кнопки (команды) Действие

New (Создать новый) Позволяет создавать файлы различных


типов. Тип файла указывается в раскры­
вающемся окне New
Open (Открыть) Открывает диалоговое окно Open, в кото­
ром можно указать имя и тип файла, а за­
тем открыть указанный файл
Save (Сохранить) Сохраняет файл на диске. Если файл толь­
ко что создан, то Лис предложит ввести
имя этого файла
Print One Copy Печатает одну копию активного файла,
(Печать одной копии) содержимое окна Command или буфера
обмена
Print Preview Отображает отчеты на экране такими, ка­
(Предварительный просмотр) кими они будут после вывода на печать
Spelling (Орфография) Запускает механизм проверки орфогра­
фии
Cut (Вырезать) Удаляет выделенный текст или объект и
помещает его в буфер обмена (Clipboard)
Сору (Копировать) Создает копию выделенного текста или
объекта и также помещает ее в буфер об­
мена
Paste (Вставить) Копирует в указанную тобой позицию со­
держимое буфера обмена
Undo (Отменить) Отменяет последнее действие
Redo (Повторить) Снова выполняет отмененное действие
Run (Выполнить) Дает команду на выполнение текущего
файла. Что выполняется? Да все, что угод­
но — программа, форма или отчет
Modify Form Открывает окно Form Designer (Конструк­
(Изменить форму) тор форм) в котором можно модифициро­
вать экранную форму
Раскрывающийся список Databases В нем отображается активная в данный
(Базы данных) момент база данных
36 Часть I. Процедурное программирование в Visual FoxPro

Таблица 3.10 (окончание)

Название кнопки (команды) Действие

Command Window (Командное окно) Управляет отображением на экране окна


для ввода команд
Data Session Window Управляет отображением на экране окна
(Окно сеанса данных) Data Session (Сеанс данных)
Form (Форма) Запускает Form Wizard (Мастер экранных
форм)
Report (Отчет) Запускает Report Wizard (Мастер отчетов)
Auto Form Wizard (Автоматический Для выбранной таблицы запускается по­
построитель экранной формы) строитель, который автоматически строит
экранную форму для данной таблицы
Auto Report Wizard (Автоматический Для выбранной таблицы запускается по­
построитель отчета) строитель, который автоматически строит
отчет для данной таблицы
Help (Помощь) Открывает доступ к разделам справочной
системы

Панели инструментов также можно перемещать по экрану. Для этого нужно


щелкнуть мышью на свободное от кнопок место и, удерживая нажатой ле­
вую кнопку мыши, переместить панель. Размеры панели инструментов тоже
можно изменить, подведя указатель мыши к границам панели инструмен­
тов.

Рабочий стол
Рабочий стол — это такой белый фон, который ты видишь на своем мони­
торе после запуска Visual FoxPro. Дело в том, что наш Лис не может вот так
просто взять и выдать что-нибудь на рабочий стол Windows. Но при вводе
соответствующих команд это "что-нибудь" (конечно, я имею в виду сообще­
ние или результат вычислений) появляется на рабочем столе Visual FoxPro.
Как? Скоро увидим!

Командное окно
Командное окно используется для ввода команд на языке программирова­
ния Visual FoxPro. Его "графическое" поведение полностью аналогично дру­
гим окнам Windows, т. е. его положение и размеры на экране можно менять
способами, применяемыми и для других окон. Как это сделать — описано
ранее.
Урок 3. Главное окно Visual FoxPro 37

Теперь поговорим о вводе команд. Вообще, используя практически любую


версию Visual FoxPro, можно при разработке приложения ни разу не обра­
титься к этому окну и, соответственно, никакие команды в нем не писать.
Но т. к. мы с тобой учимся, мы введем нашу первую команду, а если по
большому счету — напишем программный код на языке программирования
Visual FoxPro. (Музыка, туш!)
Во многих учебниках по различным языкам программирования в качестве
первой программы используется следующий пример — пользователю пред­
лагается поприветствовать мировое сообщество, выдав на экран сообщение
"Hello,World!" He станем изменять традициям: в командном окне набери
следующее — см. рис. 3.2 — и нажми клавишу <Enter>.

Рис. З.2. Ввод команд

Ну и как, впечатляет? Согласен, не очень. Зато ты понял, как работает ко­


мандное окно — набираешь команду, жмешь <Enter> — и результат не за­
ставит себя ждать.
Но это еще не все. Командное окно имеет замечательную особенность, ко­
торой не было в предыдущих версиях FoxPro — теперь в нем можно выпол­
нить многострочный программный код. Набирая следующий пример (лис­
тинг 3.1), не жми клавишу <Enter>, а для перехода на следующую строку
используй клавиши управления курсором.
38 Часть I. Процедурное программирование в Visual FoxPro

Листинг 3.1. Пример многострочного программного кода

cmessage = "Hello, World !"


cname = "My name is ...."
@10,15 SAY cmessage FONT "arial",16
012,15 SAY cname FONT "arial",16

Теперь выдели мышью все эти строки и нажми клавишу <Enter>.


Другой вариант — щелкни правой кнопкой мыши на окно ввода команд и
в появившемся меню выбери пункт Execute Selection (Выполнить выделен­
ное) — рис. 3.3.

Рис. 3.3. Выполнение многострочного кода

Строка состояния
Строка состояния расположена в нижней части главного окна Visual FoxPro.
Этот элемент можно условно разделить на две части: область сообщений и
индикаторы.
Урок 3. Главное окно Visual FoxPro 39

Область сообщений используется различными конструкторами для отобра­


жения позиции расположенных в них объектах. Если же открыта какая-
нибудь таблица, то в области сообщений будут показаны ее параметры.
• Имя таблицы.
• Имя базы данных (в скобках).
• Номер записи.
• Общее количество записей в таблице, а также способ доступа к файлу:
• Exclusive — однопользовательский, или монопольный доступ;
• Record unlocked — запись разблокирована;
• Record locked — запись заблокирована.
Также в этой области могут отображаться различные системные сообщения.
В правой части строки состояния расположены четыре индикатора или ин­
дикаторные поля, причем три из них видны всегда, а вот для отображения
четвертого необходимо ввести соответствующую команду или изменить на­
стройки Visual FoxPro. Как это делается — показано дальше
В первом показано, была ли нажата клавиша <Insert> — в этом случае в
данном индикаторном поле отображаются символы OVR и редактор Visual
FoxPro работает в режиме вставки.
Символы NUM во втором индикаторном поле отображаются, если включе­
на клавиша <NumLock>.
Третий индикатор показывает состояние клавиши <CapsLock> — если она
включена, в данном поле появляется сообщение CAPS.
И наконец, имеется четвертый индикатор, в котором отображается текущее
время. Чтобы его включить, можно ввести в командном окне команду SET
CLOCK STATUS или выбрать в системном меню пункты Tools | Options (Инст­
рументы | Опции) и в диалоговом окне Options (Опции) выбрать вкладку
View (Вид).
Все! Более или менее разобрались с интерфейсом и теперь переходим к сле­
дующему уроку, где узнаем еще очень много полезного.
УРОК 4

Знакомство
с диспетчером проекта
При разработке практически любого приложения используется проект, ко­
торый помогает организовать все файлы на основе их типа, а также объеди­
няет все компоненты приложения для последующей их компиляции и соз­
дания либо исполняемого файла с расширением ехе, либо файла приложе­
ния с расширением арр. Можно еще сделать и файл динамической
библиотеки — dll. Сам файл проекта имеет расширения pjx и pjt.
Для того чтобы создать новый проект, необходимо выполнить одно из сле­
дующих действий:
• в пункте системного меню File (Файл) выбрать команду New (Новый'
файл);
• нажать кнопку New (Новый) на стандартной панели инструментов.
В любом из этих случаев откроется диалоговое окно New (Новый), в кото
ром нужно указать, что именно мы хотим создать (рис. 4.1). Опция Proje
(Проект) уже установлена по умолчанию (что нам и требуется).
Нажмем кнопку New file (Новый файл). Появится диалоговое окно Сгеа
(Создать) (рис. 4.2). В поле Enter project (Введите имя проекта) нужно вве
сти имя нового проекта, также необходимо указать папку, в которой он бу
дет сохранен.
По умолчанию в поле Enter project (Введите имя проекта) уже стоит им
проекта — projl. Его, естественно, можно заменить на другое.
Итак, вводим имя своего приложения и щелкаем кнопку Сохранит
(Save) — файл создан, открывается окно Project Manager (Диспетчер проек
та) (рис. 4.3).
В верхней части этого окна расположено шесть вкладок. В табл. 4.1 поясня
ется их назначение.
Все элементы проекта показываются в виде иерархического списка. Есл
какой-нибудь элемент содержит в себе другие элементы, то слева от это
Урок 4. Знакомство с диспетчером проекта 41

Рис. 4 . 1 . Диалоговое окно


New Рис. 4.2. Диалоговое окно Create

Таблица 4.1. Вкладки окна Project Manager

Наименование Для чего используется

All (Все) Показываются все файлы, включенные в проект


Data (Данные) Базы данных, таблицы, виды, запросы и хранимые про­
цедуры
Documents (Документы) Экранные формы, отчеты, этикетки

Classes (Классы) Классы и библиотеки классов


Code (Программы) Программы, библиотеки
Other (Другие) Текстовые файлы, меню и прочие типы файлов

элемента показан знак "+". Не очень понятно? А ты шелкни, к примеру, на


"плюсик" рядом с элементом Data (Данные). Теперь ясно?
Справа вверху в окне диспетчера проекта расположена кнопка со стрелкой,
при нажатии на которую окно проекта сворачивается (рис. 4.4).
При щелчке на заголовке какой-нибудь вкладки откроется только вкладка,
изображенная на рис. 4.5.
Более того, вкладку можно "ухватить" мышью и переместить в любое место
экрана (рис. 4.6).
42 - Часть I. Процедурное программирование в Visual FoxPro

Рис. 4.З. Окно Project Manager

Рис. 4.4. Свернутое окно Project Manager

Рис. 4.5. Диалоговое окно Project Manager с открытой вкладкой Documents

А обратил ли ты внимание, что при работе с диспетчером проекта в систему


ном меню Visual FoxPro появился еще один пункт — Project (Проект)?
В этом пункте меню содержатся команды, работающие с файлами проек­
та — табл. 4.2. :]
Урок 4. Знакомство с диспетчером проекта 43

Рис. 4.6. Перемещение вкладок по экрану

Таблица 4.2. Команды меню Project

Команда Описание

New File (Новый файл) Создает новый файл, который добавляется


в проект автоматически
Add File (Добавить файл) Добавляет в проект ранее созданный файл
Modify File (Изменить файл) Модифицирует файл, включенный в проект
Browse File (Просмотреть файл) Открывает файл в режиме Browse (таблич­
ный просмотр)
^Rename File (Переименовать) Позволяет переименовать указанный файл
Preview (Просмотр) Предварительный просмотр файла
Remove (Удалить) Удаляет указанный файл из проекта
Exclude (Исключить) Исключает указанный файл из проекта
Set Main (Главная программа) Устанавливает указанный файл в качестве
главной программы проекта
44 Часть I. Процедурное программирование в Visual FoxPro

Таблица 4.2 (окончание)

Команда Описание

Edit Description Открывает окно для редактирования описа­


(Редактировать описание) ния файла
Project Info (Информация о проекте) Информация о проекте
Errors (Ошибки) Показываются ошибки, возникшие при по­
строении проекта
Build (Построить) Перестраивает весь проект
Refresh (Обновить) При выборе данной команды обновляется
вся информация в окне диспетчера проекта
Cleah Up Project (Упаковать) Упаковывает проект, удаляя из него ненуж­
ные файлы

Также в окне диспетчера проекта имеется шесть кнопок (рис. 4.7). Дейст­
вия, происходящие после их нажатия, практически идентичны соответст­
вующим пунктам меню Project (Проект), поэтому мы не будем подробно
останавливаться на их описании.

Рис. 4.7. Кнопки диалогового окна Project Manager


УРОК 5

Первое приложение

Наконец-то! Дождались! Понимаю, понимаю твою радость. Действительно,


наверное, довольно скучно разглядывать всякие таблицы, читать описания
команд, но что поделать... Без этого тебе бы пришлось всю жизнь всем рас­
сказывать, какой ты "крутой" программист. Чтобы такого не случилось, мы
приступаем к практическим занятиям.
Так как основу любой базы данных составляют таблицы, будет вполне ло­
гичным, если мы сначала научимся работать именно с таблицами. Давай
сделаем простенькое приложение, состоящее из одной свободной таблицы,
экранной формы и отчета.
Что бы такое придумать? Возьмем что-либо из школьной программы, на­
пример, сделаем приложение, которое будет решать квадратные уравнения.
Этот пример хорош тем, что позволяет познакомиться с математическими
функциями Visual FoxPro.
Для начала создадим новую папку, где будут храниться наши примеры, и
назовем ее examples.
Теперь запускаем Visual FoxPro и начинаем конструировать новый проект,
используя кнопку New (Новый) на стандартной панели инструментов и ука­
зав опцию Project в диалоговом окне New (Новый). В окне New нажимаем
кнопку New File (Новый файл) и смотрим на монитор (рис. 5.1).
В окне Create (Создать) в поле Enter project (Введите имя проекта) указыва­
ем имя нашего проекта, а используя раскрывающийся список Папка — имя
нашей папки (examples) и нажимаем кнопку Сохранить.
Открывается окно диспетчера проекта (рис. 5.2).
Для того чтобы создать свободную таблицу, нам необходимо перейти на
вкладку Data (Данные), выбрать пункт Free Tables (Свободные таблицы) и
нажать кнопку New, после чего на экране появится окно New Table (Новая
таблица) (рис. 5.3).
46 Часть I, Процедурное программирование в Visual FoxPro

Рис, 5.1. Диалоговое окно Create

Рис. 5.2. Диалоговое окно диспетчера проекта Equation

Рис. 5.З. Диалоговое окно New Table


Урок 5. Первое приложение 47

Что такое Table Wizard (Мастер таблиц), мы рассмотрим далее, а сейчас на­
жмем кнопку New Table (Новая таблица).
Как видишь, открывшееся диалоговое окно Create (рис. 5.4) почти ничем не
отличается от того окна, которое мы видели в самом начале, при создании
проекта.

Рис. 5.4. Диалоговое окно Create

По умолчанию в поле Enter table уже стоит название таблицы tabiei. При
необходимости его можно изменить на любое другое. Вводим имя, напри­
мер, mytab и нажимаем кнопку Сохранить.
На экране появляется окно Table Designer (Конструктор таблиц). Там рас­
положено три вкладки:
• Fields (Поля) — используется для определения полей таблицы;
П Indexes (Индексы) — для определения индексов;
П Table (Таблица) — отображает информацию о таблице.
По умолчанию открыта вкладка Fields (Поле), и теперь самое время погово­
рить об именах полей и их типах.
Имя поля в свободной таблице не может состоять из более чем 10 сим­
волов. В имени поля можно применять буквы, цифры и знак подчеркива­
ния. Использование знаков препинания, специальных символов и пробелов
в имени поля не рекомендуется. Также имя поля не должно начинаться
с
цифры или знака подчеркивания. Пример допустимых имен: Abed,
F
i r s t _ N a m e , Fox 6.
48 Часть I. Процедурное программирование в Visual FoxPro

Рис. 5.5. Диалоговое окно Table Designer

В Visual FoxPro ровно "чертова дюжина типов" полей — 13.


На з а м е т к у
В старших версиях Visual FoxPro, например в восьмой версии, есть еще один
тип поля — Integer (Autolnc).

Рассмотрим их подробнее.
Поля типа character являются одними из наиболее распространенных типов
полей в таблицах. Они могут содержать от 1 до 254 символов — буквы, чис­
ла, пробелы, знаки препинания. Поля данного типа имеют фиксированную
длину. Например, если у тебя есть поле размером в 10 символов, то оно и
будет занимать ровно 10 символов, независимо от того, что в нем записано.
Что это значит? А то, что если ты изменишь длину символьного поля в таб­
лице с данными, например уменьшишь ее, то все данные в полях character
будут усечены до указанного размера.
В полях типа character можно хранить не только символьные выражения,
но и числа. Например, почтовый индекс или номер телефона. Для чего это
делать? Во-первых, если число 000458 поместить в поле типа Numeric, то
Лис уберет ведущие нули и получится 458. Во-вторых, чтобы не возникло
"соблазна" произвести с ними какие-нибудь вычисления. Ну ты сам поду­
май, что хорошего получится, если мы по ошибке начнем складывать между
собой номера телефонов и делить их на почтовые индексы?
В общем, здесь рекомендация такая: если числа будут участвовать в матема­
тических вычислениях — смело помещаем их в поле Numeric. Если нет —
в ы б и р а е м ТИП C h a r a c t e r .
Тип currency — поля данного типа используются для записи значений, вы­
ражающих денежные суммы. Максимальное допустимое значение находится
Урок 5. Первое приложение 49

где-то в районе 922 триллионов. Не плохая цифра, правда? Дядюшка


Скрудж из диснеевского мультика просто бы умер от зависти, узнай он про
нашего дядюшку Лиса. Ну а если ты тоже любишь считать денежки, вот
тебе точный диапазон допустимых значений поля типа currency:
от -922 337 203 685 477,5807 до 922 337 203 685 477,5807
Тип Date — для работы с датами. Даты могут принимать значения от
1 января 01 года (от Рождества Христова) до 31 декабря 9999 года (это уж
точно конец света...).
Тип DateTime — почти то же, что и Date, только еще позволяет хранить по­
мимо дат время в диапазоне от 12,00,00 am до 11,59,59 р т .
Тип Logical — информация, хранимая в этих полях, может принимать
только два значения — .Т. (True) (Истина) или .F. (False) (Ложь). Исполь­
зуется для указания наличия или отсутствия каких-нибудь свойств, призна­
ков. Например, выражение типа "кошка/собака" может принимать только
одно значение, потому что собака не может быть одновременно и собакой и
кошкой.
Тип Memo — для символьных данных большого объема. А что такое "боль­
шой объем"? Принцип следующий: если информация не помещается в поле
C h a r a c t e r , Т. е. б о л ь ш е 2 5 4 СИМВОЛОВ — ИСПОЛЬЗуеМ ПОЛе Memo.

Тип character (binary) используется в тех случаях, когда нам не требуется


для отображения данных учитывать кодовую страницу.
Тип integer используется для хранения целых чисел. Возможный диапазон
значений от -2 147 483 547 до 2 147 483 547.
Тип General — поля данного типа предназначены для хранения изображе­
ний и другой информации в двоичном виде. Можно сказать, что это спе­
циализированное поле Memo.
ТИПЫ N u m e r i c И F l o a t ИСПОЛЬЗУЮТСЯ ДЛЯ р а б о т ы С ЧИСЛОВЫМИ ДЭННЫМИ И
отображают числа в диапазоне от -0,9999999999*1019 до 0,9999999999*Ю20.
Тип Double применяется для хранения данных с высокой точностью:
от 4,94065658541247*10324 до 1,79769313486232*10308.
Перед тем как начать конструировать нашу таблицу, необходимо опреде­
лить, данные какого типа будут храниться в полях таблицы, и, соответст­
венно, назначить типы полей.
Насколько я помню, один из способов решения квадратного уравнения
имеет примерно такой вид:
ах2 + Ьх+с=0
d = b2- 4ас
xl=(-b+sqrt(d)/2*a
x2=(-b-sqrt(d)/2*a
50 Часть I. Процедурное программирование в Visual FoxPro

здесь sqrt (d) не что иное, как просто квадратный корень из d. Я специаль­
но записал это выражение именно так, чтобы сразу познакомить тебя с
функцией FoxPro, которая возвращает значение квадратного корня.
Итак, для решения нашей задачи нам понадобятся поля типа Numeric, в ко­
торых мы будем хранить значения а, ъ, с, d, xi и х2, одно символьное поле
типа character и возьмем, пожалуй, еще поле типа Date.
Начинаем определять структуру таблицы mytab.
Для этого на вкладке Fields (Поля) окна Table Designer (Конструктор таб­
лиц) имеется несколько "столбцов" (рис. 5.6).

Рис. 5.6. Определение структуры таблицы mytab

Первый столбец, Name (Имя), используется для ввода имени поля, причем
имя не должно повторяться, иначе Лис "обидится" и выдаст соответствую­
щее сообщение о недопустимости ввода двух полей с одинаковым именем.
Вводим имя нашего первого поля, пусть это будет first_a. Введя хотя бы
один символ, мы уже видим, что столбец Туре (Тип) принял вид раскры­
вающегося списка, из которого можно выбирать соответствующие значения,
щелкая мышью на нужной строчке. По умолчанию стоит тип character. Так
как мы будем иметь дело с числами, необходимо установить тип Numeric.
При нажатии клавиши <ТаЬ> фокус получает следующий столбец — Width
(Ширина), в котором указывается размер поля. Значения можно вводить с
клавиатуры, а можно использовать счетчик, т. к. данный элемент представ­
ляет собой объект spinner (Поле ввода со счетчиком). Просто нажми
мышью на нужную кнопку счетчика справа от поля ввода и все. Счетчик
сначала будет работать довольно медленно, но затем раскрутится почти до
космических скоростей. Главное здесь — вовремя остановиться.
Урок 5. Первое приложение 51

Следующий столбец вкладки Fields — Decimal (Десятичные знаки). Данная


опшя доступна только для полей типа Numeric и позволяет задать количест­
во знаков в числе после запятой. Надо учитывать, что количество знаков не
добавляется к общему размеру поля, а выделяется из него, т. к. общий раз­
мер определяется параметром Width.
Столбец Index используется для того, чтобы определить порядок отображе­
ния записей — по возрастанию (Ascending) или по убыванию (Descending).
Если индекс (о них разговор пойдет далее) не определен, то Visual FoxPro
при помощи данной опции автоматически его создаст.
И последний столбец этой вкладки NULL устанавливает, допустимы ли для
данного поля значения NULL.
После определения имен и типов полей наша табличка примет вил, пока­
занный на рис. 5.7.

Рис. 5.7. Мы закончили определение структуры таблицы

Маленькие кнопки, расположенные слева от имен полей, служат для изме­


нения порядка отображения полей при просмотре таблицы. Можешь смело
менять их местами, это никак не повлияет на результат вычислений.
После всех этих несложных манипуляций необходимо сохранить плоды на­
шей титанической работы. Для этого нажмем кнопку ОК. Да, я же не рас­
сказал о назначении кнопок в окне конструктора таблиц! Действия этих
элементов управления нехитрые:
• ОК — сохраняет структуру таблицы;
• Cansel — отмена проведенных изменений;
• Insert — вставка нового поля;
• Delete — удаление указанного поля.
52 Часть I. Процедурное программирование в Visual FoxPro

Итак, мы только нажали кнопку ОК, а хитрющий Лис уже интересуется,


будем ли мы вводить записи в нашу таблицу прямо сейчас (рис. 5.8).

Рис. 5.8. Запрос на ввод записей

Совершенно необязательно сразу после создания таблицы приступать к вво­


ду значений. Но мы все же ответим Yes (Да) и нажмем соответствующую
кнопку в диалоговом окне запроса. После этого наша таблица откроется в
режиме добавления записей (Append Mode), и мы введем наши первые дан­
ные (рис. 5.9).

Рис. 5.9. Таблица в режиме ввода данных

Ввод данных осуществляется с клавиатуры, а для перехода к следующему


полю можно использовать клавиши управления курсором. Вообще же пере­
ход происходит автоматически: заносим данные, нажимаем <Enter> и указа­
тель устанавливается на следующее поле. В данном режиме поля показаны
"столбиком", т. е. вертикально. Для разделения записей используется тонкая
пунктирная линия. После заполнения первой записи указатель автоматиче­
ски устанавливается на следующую, и мы можем продолжить ввод данных.
Урок 5. Первое приложение 53

В нашем случае нет необходимости заполнять все поля и поэтому мы, введя
единственную запись (см. рис. 5.9), закрываем это окно. Для закрытия ис­
пользуем стандартные методы Windows: щелкаем на кнопку с крестиком в
правом верхнем углу окна или используем соответствующую команду меню,
щелкнув на пиктограмме в левом верхнем углу. Также для закрытия этого
окна можно воспользоваться комбинацией клавиш <Ctrl>+<W>.
Давай теперь посмотрим на диалоговое окно диспетчера проекта (Project
Manager) (рис. 5.10). Видно, что наша таблица автоматически добавлена в
проект, ее имя находится в разделе Free Tables вкладки Data. Слева от име­
ни расположены два значка: перечеркнутый кружок и знак +. Если мы на­
жмем на знак +, то увидим список полей нашей таблицы.

Р И С . 5.10. Таблица добавлена в проект

Перечеркнутый кружок означает, что при компиляции проекта данный


файл компилироваться не будет. Внизу, под надписью Description (Описа­
ние) указан полный путь (Path) к нашему файлу.
Просмотреть и отредактировать данные в таблице можно, нажав кнопку
Browse (Просмотр) (рис. 5.11).
С данными мы более или менее разобрались, таблица готова и пришло вре­
мя заняться непосредственно интерфейсом нашего приложения, для чего
мы переходим к следующему уроку, где начнем создавать экранные формы.
54 Часть I. Процедурное программирование в Visual FoxPro

Рис. 5.11. Таблица в режиме просмотра


УРОК 6

Экранная форма.
Первое знакомство
Любое серьезное приложение просто "обязано" иметь как минимум одну
экранную форму, потому что именно экранная форма является тем основ­
ным средством, которое позволяет пользователю взаимодействовать с дан­
ными.
Каждая экранная форма может состоять из неограниченного числа объек­
тов. Любой объект экранной формы имеет свои, присущие данному классу
объектов свойства, которые мы можем редактировать. Также мы можем ука­
зать объекту действия, которые он будет выполнять при наступлении опре­
деленных событий.
В общем, весь процесс создания экранной формы сводится к следующему:
выбираем необходимые нам объекты, размещаем их в форме, определяем их
свойства и задаем, какие действия они будут выполнять.
Создать новую экранную форму можно различными способами: используя,
в частности, Form Wizard или Form Designer.
"Кто" такие эти загадочные Wizard, уже дважды нам встретившиеся, узнаем
дальше, а пока будем "делать" экранную форму, используя Form Designer
(Конструктор форм).
Открыть окно конструктора форм можно различными способами.
• Выполнить команду New (Новый) из меню File (Файл) и в открывшемся
диалоговом окне New (Новый) нажать кнопку New File (Новый файл),
предварительно установив опцию Form (Форма).
• Нажать кнопку New (Новый) на стандартной панели инструментов.
Дальнейшие действия, как в предыдущем способе.
А спрашивается, к чему нам лишние движения мышью? В окне диспетчера
проекта есть кнопка New (Новый), которая также позволяет создать новый
файл, который к тому же будет автоматически добавлен в проект. Нужно
только указать, какой именно файл мы хотим создать.
56 Часть I. Процедурное программирование в Visual FoxPro

Рис. 6.1. Диалоговое окно New Form

Для создания файла новой экранной формы необходимо перейти на вклад­


ку Documents (Документы) в окне диспетчера проекта, отметить пункт
Forms (Формы) и нажать кнопку New (Новый).
Открывается диалоговое окно New Form (Новая форма) (рис. 6.1), в кото­
ром услужливый Лис опять предлагает для создания формы воспользоваться
мастером экранных форм (Form Wizard). Но мы с тобой уже договорились,
что использование мастеров рассмотрим позднее, поэтому мы нажмем
кнопку New Form (Новая форма), после чего перед нами во всей красе от­
кроется окно конструктора форм.

Окно конструктора форм (Form Designer)


В окне конструктора форм (рис. 6.2) содержатся следующие объекты:
• макет экранной формы (по умолчанию он назван Forml);
• панель инструментов Form Controls (Элементы управления);
• панель Color Palette (Палитра цветов);
• панель Layout (Расположение);
• окно редактирования Properties (Свойства);
• окно среды данных (Data Environment).
Отобразить эти объекты на экране, или наоборот, скрыть их можно, устано­
вив либо сняв соответствующие флажки в меню View (Вид).
Кратко рассмотрим функции этих объектов.
• Панель Color Palette (Палитра цветов) управляет цветом фона экранной
формы, а также цветом элементов формы.
• Панель Layout (Расположение) управляет размерами и размещением объ-1
ектов в экранной форме.
• Окно Data Environment (Среда данных) отображает элементы среды дан­
ных (таблицы, виды), с которыми работает экранная форма.
• Окно Properties (Свойства) содержит все свойства, методы и события,
связанные с объектами формы, и позволяет их редактировать.
Урок 6. Экранная форма. Первое знакомство 57

• Панель Form Controls {Элементы управления), несомненно, является ос­


новной панелью инструментов в окне Form Designer, поэтому ее необхо­
димо рассмотреть подробнее (рис. 6.3). Описание кнопок этой панели
приведено в табл. 6.1.

Рис. 6.2. Диалоговое окно Form Designer

Рис. 6.3. Панель инструментов Form Controls

Таблица 6.1. Кнопки панели Form Controls


58 Часть I. Процедурное программирование в Visual FoxPro

Таблица 6.1 (продолжение)


Урок 6. Экранная форма. Первое знакомство 59

Таблица 6.1 (продолжение)


60 Часть I. Процедурное программирование в Visual FoxPro

Таблица 6.1 (окончание)

Окно свойств (Properties)


Еще одним абсолютно необходимым элементом, используемым при разра­
ботке экранных форм, является окно свойств (Properties) (рис. 6.4).

Рис. 6.4. Диалоговое окно Properties


Урок 6. Экранная форма. Первое знакомство 61

Если данное окно не отображено на экране, его можно вызвать, установив


флажок на соответствующем пункте меню View (Вид), или воспользоваться
командой контекстного меню, которое вызывается нажатием правой кнопки
мыши в любом месте окна конструктора форм (рис. 6.5).

Рис. 6.5. Использование контекстного меню для отображения окна Properties

Также можно воспользоваться кнопкой Properties (Свойства) на стандарт­


ной панели инструментов Visual FoxPro.
Именно используя это окно, мы с тобой можем редактировать свойства,
события и методы экранной формы и ее объектов.
Окно свойств можно условно разделить на две части: в левой, на сером фо­
не, перечислены названия всех свойств, методов и событий объектов (в дан­
ном случае макета формы), а в правой, на белом фоне, — значения этих
свойств (событий, методов). Еще там могут быть надписи типа Default и
User Procedure.
default — это установка по умолчанию, если ты ее изменишь, вместо нее
появится текст User Procedure (Процедура, определенная пользователем).
Если же значение свойства (метода, события) выделено курсивом — Можешь
Не мучаться, ты все равно его не изменишь, потому что курсив в этом случае
62 Часть I. Процедурное программирование в Visual FoxPro

означает, что данное свойство (метод, событие) в режиме разработки дос­


тупно только для чтения.
Также в окне свойств имеется пять вкладок:
О All — отображает все свойства, методы и события для данного объекта
(рис. 6.6);

Рис. 6.6. Вкладка All окна Properties Рис. 6.7. Вкладка Data окна Properties

• Data — отображает только те свойства, которые имеют отношение к дан­


ным (рис. 6.7);
• Methods — отображает все методы и события объекта (рис. 6.8);

Рис. 6.8. Вкладка Methods окна Properties


Урок 6. Экранная форма. Первое знакомство _ _ _ _ _ _ _ _ ^ _ ^ _ 63

П Layout — здесь находятся только те свойства, которые "отвечают" за ото­


бражение объекта на экране (рис. 6.9);
П Other — другие свойства объекта (рис. 6.10).

Рис. 6.9. Вкладка Layout окна Properties Рис. 6.10. Вкладка Other окна Properties

Конструирование экранной формы


Теперь переходим к самому процессу конструирования экранной формы.
Так как источником данных для нашей формы является таблица mytab, пер­
вое, что нам необходимо сделать, — это "указать" форме, что она будет ра­
ботать именно с данной таблицей. Для чего необходимо выполнить сле­
дующее:
1. Открываем диалоговое окно Data Environment (Среда данных), восполь­
зовавшись соответствующим пунктом контекстного меню экранной
формы. Автоматически откроется окно Open (Открыть), в котором мож­
но выбрать таблицу или представление данных.
2. На экране появится окно Add Table or View (Добавление таблицы или
вида) (рис. 6.12), в котором указаны все таблицы, входящие в открытую
в этот момент базу данных. Если нет открытой базы данных (как в на­
шем случае), список Tables in database (Таблицы в базе данных) будет
пустым. Для добавления других свободных таблиц воспользуемся кноп­
кой Other (Другие).
3- Откроется диалоговое окно Open (Открыть) (рис. 6.13), в котором выби­
раем нужную таблицу и нажимаем кнопку ОК — таблица будет добавле­
на в среду данных нашей формы (рис. 6.14).
64 Часть I. Процедурное программирование в Visual FoxPro

Рис. 6.11. Диалоговое окно Data Environment


после выбора таблицы или представления данных

Рис. 6.12. Диалоговое окно Add Table or View

При щелчке на данной таблице правой кнопкой мыши раскрывается кон­


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

I
Урок 6. Экранная форма. Первое знакомство 65

Рис. 6.13. Диалоговое окно Open

Рис. 6.14. Диалоговое окно Data Environment с новой таблицей

Теперь, когда необходимые таблицы добавлены в среду данных, можно за­


крыть диалоговое окно Data Environment (Среда данных) и перейти непо­
средственно к созданию формы.
Так как в форме будут находиться различные объекты, нам необходимо
научиться размещать их в макете формы.

Зак Ю02
66 Часть I. Процедурное программирование в Visual FoxPro

Размещение элементов управления


в экранной форме
Для размещения элемента управления в экранной форме необходимо вы­
брать этот элемент на панели Form Controls, нажав соответствующую кнопку.
Например, начнем с размещения в форме элемента управления типа
TextBox (Поле ввода). Для этого нажмем соответствующую кнопку на пане­
ли Form Controls, а затем, указав мышью в макете формы предполагаемое
место, нажмем левую кнопку мыши. Все, элемент управления размещен в
форме (рис. 6.15).

Рис. 6.15. Размещение элемента управления TextBox в экранной форме

При встраивании элемента управления в форму вокруг этого объекта pacno-


лагаются восемь маленьких черных точек. Их наличие говорит о том, что
объект выделен и в окне Properties (Свойства) будут отображаться свойства,
методы и события, присущие только данному объекту. Более того, при ус-
тановке указателя мыши на любую из этих точек указатель примет вид дву-
направленной стрелки, что позволяет изменять линейные размеры объектам
Это делается путем нажатия и удерживания левой кнопки мыши. А изме-
нить положение всего объекта в форме тоже довольно легко — нужно толь­
ко установить указатель "внутрь" элемента управления и так же, используя
левую кнопку мыши, перетащить его в необходимое место.
Теперь немного поговорим об именах элементов управления. Как ты уже!
заметил, при встраивании элемента управления TextBox он получил имz
Textl. Эти имена Visual FoxPro устанавливает сам, и если мы разместим
в нашей форме еще один объект TextBox, то он будет по умолчанию иметь
имя Text2. Аналогично Лис поступает и с другими элементами управления.
Имена объектов при необходимости можно легко изменить — в окне
Properties данное свойство так и называется Name (Имя).
Урок 6. Экранная форма. Первое знакомство 67

Но следует отметить, что имена типа Texti, Text2 и т. д. Visual FoxPro при­
сваивает в том случае, когда мы для размещения объектов в форме исполь­
зуем панель Form Designer. Если же мы размещаем объекты, в частности
поля таблиц, путем их перетаскивания из окна Data Environment (Среда ок­
ружения), или пользуемся услугами Form Wizard — в этом случае имя объ­
екта будет совпадать с именем поля.
Теперь добавим в нашу форму объект Label (Этикетка), который будет со­
держать текст, и подкорректируем размеры поля ввода Textl (рис. 6.16).

Рис. 6.16. Мы вставили в форму еще один элемент управления (Label)


и изменили некоторые свойства

После вставки в форму объекта Label мы видим, что надпись в этом объекте
совпадает с его именем (Labeli). Нас это не устраивает и мы меняем ее, ис­
пользуя свойство caption (Заголовок) в окне свойств экранной формы. Та­
ким же образом мы корректируем некоторые другие свойства объектов:
• для объекта TextBox устанавливаем свойство FontBoid равным .т. (жир­
ный шрифт), свойство Fontsize (размер шрифта) устанавливаем рав­
ным 22 и немного изменяем его размеры;
• для объекта Label также устанавливаем жирный шрифт, размер шрифта
принимаем равным 26 и используем еше одну установку — свойство
AutoSize (Авторазмер) устанавливаем в .т. — границы объекта "подго­
няются" под размер шрифта и длину заголовка, в противном случае текст
будет обрезан.
Теперь нам необходимо разместить в форме остальные объекты. Чтобы ус­
корить данный процесс, мы воспользуемся кнопками Сору (Копировать) и
68 Часть I. Процедурное программирование в Visual FoxPro

Paste (Вставить), расположенными на стандартной панели инструментов.


Для того чтобы указать Лису, что именно мы будем копировать, нужный
объект должен быть выделен. Выделить объект можно, произведя на нем
щелчок мышью. А если необходимо выделить не один объект, а несколько,
как в нашем случае? Не волнуйся, все предусмотрено! Нужно просто нажать
клавишу <Shift> и, удерживая ее, щелкать мышью на необходимых элемен­
тах управления. Еще способ: нажать левую кнопку мыши в любом свобод­
ном месте макета формы (при этом указатель примет вид руки) и обвести
нужные элементы так, чтобы они оказались внутри пунктирного контура.
После выделения необходимых объектов щелкаем кнопку Сору — наши
объекты окажутся скопированными в буфер обмена. Извлечь их из этого
таинственного буфера можно, используя кнопку Paste на этой же панели
инструментов. Нужно просто указать мышью на предполагаемое место рас­
положения этих объектов и нажать кнопку Paste.
Команды копирования и вставки доступны также из системного меню
Visual FoxPro и из контекстного меню, которое, как ты уже знаешь,
вызывается щелчком на объекте правой кнопкой мыши.
После вставки элементов управления нам остается только подкорректиро­
вать их размеры и изменить необходимые свойства.
Я сделал следующее: элементы управления Text2, Text3, Labei2 и Labei3
разместил с помощью команд копирования и вставки (их можно считать
"клонами" объектов Texti и Labeli), элемент управления Text4 добавил
обычным способом (рис. 6.17).

Рис. 6.17. Размещение элементов управления TextBox и L a b e l в экранной форме

В Visual FoxPro реализован еще один интересный способ размещения эле­


ментов управления, помимо указанных ранее. Оказывается, их можно легко
"перетащить" из окна Data Environment (Среда данных). Для чего нужно от­
крыть это окно, поставить указатель мыши на необходимое поле таблицы и,
удерживая нажатой левую кнопку мыши, просто перетащить его в нужное
место экранной формы. Перенесем таким образом поля xi и х2 из нашей
т а б л и ц ы mytab (рИС. 6.18).
Урок 6. Экранная форма. Первое знакомство 69

Рис. 6.18. Поля xl и х2 мы перетаскиваем на экранную форму


прямо из диалогового окна Data Environment

Несмотря на то, что мы "тащили" одно поле из таблицы, в экранной форме


появляется два объекта: Label и TextBox. Это наш заботливый Лис услужли­
во создал объект Label и даже подписал его, назвав так же, как и имя поля.
А теперь, если интересно, загляни в свойства этих объектов, в частности,
посмотри свойство Name (Имя). Ну, что я говорил?
Продолжаем работу над формой. Теперь, когда у нас есть поля, в которые
мы можем вводить данные, встает вопрос — а что с этими данными, собст­
венно, делать? Нам — ничего! Пусть Лис сам с ними что хочет, то и "дела­
ет", а вот что именно: тут-то мы и должны ему подсказать. Но прежде чем
давать ему советы и инструкции, необходимо связать наши объекты TextBox
с полями таблицы mytab. Выделяем объект Texti и переходим на вкладку
Data (Данные) в окне свойств. Находим свойство controisource (Источник
Данных) и из раскрывающегося списка вверху, в котором перечислены все
поля нашей таблицы, выбираем поле F i r s t a (рис. 6.19).
Таким же образом устанавливаем свойство controisource для остальных
элементов:
• Text2 — mytab.second_b;
• Text3 — mytab.third_c;
• Text4 — mytab.result.
70 Часть I. Процедурное программирование в Visual FoxPro

Рис. 6.19. Устанавливаем источник данных для элемента управления T e x t l

Замечание
Перед именем поля стоит имя таблицы. Это так называемый псевдоним или
a l i a s . Все дело опять же в том, что любая таблица открывается в своей рабо­
чей области и Visual FoxPro может обращаться к ней, используя псевдоним, ко­
торый в данном случае совпадает с именем нашей таблицы.

А ты обратил внимание, что при назначении источника данных я не упомя­


нул объекты txtx1 и txtx2?
Я не забыл про них, просто при размещении этих объектов в экранной |
форме мы использовали метод перетаскивания из окна среды данных, а в
этом случае Visual FoxPro сам назначает источник данных. В этом легко!
убедиться, посмотрев значения свойств в диалоговом окне Properties.

На заметку
Для того чтобы определить значения свойств элементов управления, вовсе не­
обязательно метаться мышью между макетом формы, выделяя в нем нужный |
элемент, и диалоговым окном Properties. Дело в том, что в самой верхней час­
ти диалогового окна Properties имеется раскрывающийся список, в котором пе- j
речислены все объекты, входящие в макет экранной формы. Всего-то и нужно, |
что выбрать необходимый.
Для экономии времени некоторые свойства, например Fontsize и т. п., можно |
установить одинаковыми сразу для нескольких объектов. Для этого нужно про-1
сто выделить группу объектов и установить желаемое значение свойства для j
всей группы. В этом случае в окне свойств вместо имени объекта появится
надпись M u l t i S e l e c t i o n (Множественный выбор).
Урок 6. Экранная форма. Первое знакомство 71

Теперь разместим в нашей форме объекты в виде кнопок (commandButton) и


запрограммируем действия, которые будут происходить после щелчка
мышью на этих элементах управления. Для этого выберем на панели Form
Controls соответствующую кнопку и вставим объекты в экранную форму
(рис. 6.20).

Рис. 6.20. Мы только что разместили на экранной форме два новых элемента управления

Определим значения свойства Caption (Заголовок):


П для элемента управления commandi установим Расчет;
• для элемента управления command2 — выход.
Соответствующие надписи появятся на изображении кнопок. Естественно,
можно изменить размер шрифта, стиль написания и сам шрифт для данных
элементов, редактируя соответствующие свойства.
Давай, например, изменим цвет надписи на кнопке Выход — установим
предупреждающий красный цвет, чтобы невнимательный пользователь не­
нароком ее не "щелкнул".
За цвет надписей отвечает свойство Forecoior. При обращении к этому
свойству в верхней правой части окна свойств появляется кнопка с тремя
точками, по нажатию которой отображается панель Цвет (рис. 6.21). Вы­
бираем нужный и нажимаем кнопку ОК. В данном случае значение свойст­
ва ForeCoior устанавливается равным (255, о, 0), где цифры обозначают со­
отношение красной, зеленой и синей составляющих. Данное свойство мож­
но изменять программно, используя соответствующую функцию RGB.
Также для этой цели можно воспользоваться уже немного знакомой нам
панелью Color Palette (Цвет) (рис. 6.22). В качестве примера установим зе­
леный цвет для надписи в поле txtxi, а цвет фона для этого поля сделаем
Желтым.
О Foreground color — цвет шрифта ( ). Выделяем объект (txtxi), нажима­
ем эту кнопку и выбираем желаемый цвет.
72 Часть I. Процедурное программирование в Visual FoxPro

Рис. 6.21. Изменение цвета надписи на кнопке с использованием окон Properties и Цвет

Рис. 6.22. Панель Color Palette

• Background color — цвет фона . Действия точно такие же.


• Other colors — другие цвета . По нажатию этой кнопки отображает-1
ся уже знакомая нам панель Цвет.
Теперь давай вернем данному объекту первоначальные значения: не стоит
злоупотреблять цветами, раскрашивая формы во все цвета радуги — некото­
рых пользователей это может раздражать, а изменить самостоятельно дан­
ные параметры неподготовленному человеку затруднительно.
Сейчас мы будем программировать те события, которые будут происходить|
при нажатии наших кнопок.
Начнем с кнопки Выход:
1. Выделим этот объект и, перейдя на вкладку Methods (Методы) окна
Properties, установим указатель мыши на свойство ClickEvent.
click, как ты уже догадался, означает щелчок мышью. Для того чтобы |
определить действия, выполняемые нашим приложением при щелчке
Урок 6. Экранная форма. Первое знакомство 73

мышью на данном элементе управления, дважды щелкнем мышью на


имени метода ciickEvent. При этом откроется новое окно, которое назы­
вается окно редактирования (рис. 6.23).

Рис. 6.23. Диалоговое окно редактирования программного кода

2. В раскрывающемся списке Object (Объект) перечислены все элементы


управления, а в списке Procedure (Процедура) — все методы и события
для данного объекта.
Введем в окно редактирования для события click команду
thisform.Release О И закроем его.
Теперь мы определили действия, происходящие при щелчке на кнопке
Выход.
Что же будет происходить? Все просто — форма закроется.
В этой процедуре мы обратились к объекту "форма" (thisform) и предложи­
ли Лису выполнить команду RELEASE для этого объекта.
Но в данном случае просто закроется только экранная форма, а вот для то­
го, чтобы закончить работу с Visual FoxPro, нужно ввести команду QUIT.
Как видишь, программирование в СУБД Visual FoxPro не является чем-то
Уж архисложным — все просто и естественно. Ты спросишь, а где тут про­
граммирование? А чем же ты, уважаемый, занимался в течение последних
Ю минут? Именно программированием!
Кнопка Расчет. Именно при нажатии этой кнопки будет решаться наше
Уравнение. Открываем окно редактирования процедур и пишем программ­
ой код для события click (рис. 6.24).
74 Часть /. Процедурное программирование в Visual FoxPro

Рис. 6.24. Программный код для решения квадратного уравнения

Команды вводятся непосредственно в окно редактирования процедур. При]


вводе команд совершенно не обязательно учитывать регистр букв — нашему;
Лису абсолютно все равно, строчные или прописные буквы мы используем.)
А еще у Visual FoxPro есть интересная особенность: необязательно вводить!
полный текст команды, достаточно первых пяти символов. Например, вме-j
сто Replace вполне достаточно ввести Repia.
Рассмотрим подробнее действие команд.
Программу мы начали с символа * (звездочка). Данный символ указывает,/
что вся следующая за ним строка будет использоваться как комментарий.^
Комментарий служит для подсказки или описания тех или иных действий И)
ни в каких вычислениях, понятно, не участвует. Но символ * используется,
только с начала строки, а если нам нужно поставить комментарий
командой? Все просто: используем символы &&.
Команда Replace заменяет значение поля на указанное выражение, которое;
стоит после слова with. Этим выражением может быть практически все, чт*
угодно: число, строка символов, другое поле или результат какого-нибудг
вычисления. Правда, нужно учитывать тип поля. Например, при попьглс
ввода в поле типа Numeric строки символов FoxPro автоматически сгенери^
рует сообщение об ошибке.
Урок 6. Экранная форма. Первое знакомство 75

Далее следует оператор выбора:


do c a s e &&начало проверки
c a s e <если какое-то условие! верно, выполняем команды>
<список команд>
case <если какое-то условие2 верно, выполняем команды>
<список команд>

endcase &&конец проверки

И наконец, при помощи команды Refresh о перерисовываем окно формы,


тем самым обновляя отображаемую в нем информацию. Все.

Замечание
При обращении к полю таблицы можно обойтись и без указания псевдонима
таблицы, а обращаться непосредственно к именам полей. Так как у нас форма
работает с одной таблицей (до других мы еще не дошли), то естественно, толь­
ко эта таблица будет открываться при вызове формы. Но если в среде данных
экранной формы находится несколько таблиц, то такой "номер" может и не
пройти. Поэтому лучше все-таки обращаться к полям нужной таблицы, исполь­
зуя псевдоним или команду Select.

Пусть тебя не смущает обилие скобок в командах Replace. Они нужны для
того, чтобы расставить "очередность" при математических вычислениях, по­
тому что у Visual FoxPro имеются на этот счет свои правила, о которых мы
и поговорим далее.

Операторы
В Visual FoxPro достаточно большой выбор операторов, позволяющих ма­
нипулировать данными. Можно объединять несколько операций, создавая
тем самым довольно сложные выражения, но следует помнить, что данные
внутри каждого выражения должны быть одного типа.
Опишем операторы, имеющиеся в Visual FoxPro (табл. 6.2—6.6). В таблицах
выражения представлены в порядке расстановки приоритетов, т. е. сначала
будет выполняться действие, занимающее верхнюю строчку, затем следую­
щее и т. д., в порядке убывания приоритета.

Таблица 6.2. Символьные операторы

Оператор Описание

Конкатенация двух символьных строк. Конкатенация — это "по-


научному", а результатом действия этого оператора будет вот что:
"Fox" + " P r o " = "FoxPro"
76 ^ ^ ^ ^ Часть I. Процедурное программирование в Visual FoxPro

Таблица 6.2 (окончание)

Оператор Описание

- Конкатенация с удалением конечных пробелов из первого выражения


$ Поиск одной символьной строки в другой

Таблица 6.3. Арифметические операторы

Оператор Описание

0 Группировка значений для повышения приоритета — сначала выполня­


ется выражение, заключенное в скобки
** или А
Возведение в степень
+ Умножение
/ Деление
% Остаток от деления
+ Сложение
- Вычитание

Таблица 6.4. Операторы операций с датами

Оператор Описание
+ Сложение (результатом будет дата в будущем)
- Вычитание

Таблица 6.5. Операторы отношений (сравнения)

Оператор Описание
< Меньше чем
> Больше чем
= Равно
! = ИЛИ # ИЛИ < > Не равно
<= Меньше или равно
>= Больше или равно ___
== Точно равно (применяется для символьных выражений)
Урок 6. Экранная форма. Первое знакомство ^ 77

Таблица 6.6. Логические операторы

Оператор Описание

0 Группировка значений для повышения приоритета - сначала


выполняется выражение, заключенное в скобки

NOT ИЛИ ! Логическое отрицание

AND Логическое умножение (И)

OR Логическое исключение (ИЛИ)

"Украшение" формы
Теперь, когда у нас все практически готово, осталось навести окончатель­
ный "лоск" в нашей форме и можно запускать ее в "первое плавание".
Чтобы не смущать пользователя невразумительным названием Formi, из­
меним СВОЙСТВО Caption ДЛЯ макета формы: Caption=Решение квадратного
уравнения.
Чтобы пользователь не мог изменять размеры формы (баловство все это!),
установим значение свойства Border style (Стиль обрамления) равным 2
Fixed Dialog (Фиксированная двойная линия).
Свойство AutoCenter (Автоматическое центрирование) установим рав­
ным . т. — наша форма всегда будет располагаться в центре экрана.
Свойство ShowWindow имеет три значения: in screen (В окне Visual FoxPro),
in тор LeveiForm (В форме верхнего уровня) и As Top Level Form (Как фор­
ма верхнего уровня). Значения этих свойств указывают, как будет работать
наша форма: только в главном окне, внутри другой формы или как форма
верхнего уровня. Установим значение As Top Level Form.
У элемента управления Text4 установим свойство Alignment (Выравнивание)
равным 2Center (По центру).
Теперь добавим немного "крутизны", а именно: изменим вид указателя мы­
ши и установим фон для нашей формы.
Свойство Picture (Изображение) позволяет использовать какой-нибудь ри­
сунок в качестве фона экранной формы. Желательно, чтобы все графиче­
ские файлы, которые ты используешь в приложении, находились в одном
с ним каталоге (или подкаталоге).
При нажатии кнопки с тремя точками откроется окно Open (Открыть)
(Рис. 6.25), в котором можно выбрать необходимый графический файл.
Флажок Preview (Просмотр) позволяет предварительно просмотреть изобра-
78 Часть I. Процедурное программирование в Visual FoxPro

жение. (К сожалению, для просмотра доступны файлы не всех графических


форматов.)
Указав нужный файл, нажимаем кнопку ОК.

Рис. 6.25. В диалоговом окне Open выбираем рисунок фона

Теперь выделим наши кнопки Расчет и Выход, и аналогичным способом


выберем изображение, которое будет служить указателем мыши. (Свойство
Mouse icon.) Свойство MousePointer (Указатель мыши) при этом необходимо
установить равным 99 - Custom (Пользовательский).
Ну и последний штрих — свойство Backstyle (Стиль фона) для объектов
Label 1, Labei2 и Labei3 устанавливаем как Transparent (Прозрачный фон).
После того как мы закончим работу в Конструкторе форм, Лис предложит
сохранить новую форму под именем Formi. Что же, пусть будет Forml.

Запуск формы на выполнение


Запуск формы — процедура не сложная. Вот возможные способы:
• кнопка Run на стандартной панели инструментов;
• команда Run Form из меню Form;
• кнопка Run в окне диспетчера проекта;
• ввод в окне Command следующей команды: do form forml.
Запускаем форму и, вводя в поля нужные значения, решаем наши уравне-j
ния. Но решать мы их будем до определенного момента, а именно пока нб|
увидим сообщение, представленное на рис. 6.26.
Урок 6. Экранная форма. Первое знакомство 79

Рис. 6.26. Сообщение о программной ошибке

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


вводе значения ноль в первое поле произойдет сбой, потому что Лис тоже
немного знаком с математикой и знает, что на ноль делить нельзя. А мы
этим и пытаемся его озадачить. Как тут быть? Говорить пользователям, что­
бы не вводили ноль в первое поле? Но это "не есть хорошо", из вредности
(а они такие) — будут вводить. Нет, ничего им говорить не надо, а нужно
сделать так, чтобы его невозможно было ввести! Сказано — сделано. Вы­
делим элемент управления Texti, в окне Properties найдем событие
vaiidEvent, для которого в окне редактирования процедур введем следую­
щие команды:

if this.value=0
this.backcolor = RGB(255,0,0)
return .F.
else
t h i s . b a c k c o l o r = RGB(192,192,192)
endif

Разберем, как все это работает.


Команда if...endif немного похожа на уже знакомую нам docase. Ее син­
таксис следующий:
&&начало проверки
if <условие1>
<список команд1>
else
<список команд2>

endif &&конец проверки

Смысл здесь такой: если <условие1> верно, выполняем <список команд1>,


Иначе ВЫПОЛНяеМ <список команд2>.

Рассмотрим подробно условие:


c
oбъeкт>. <свойство>=<вьражение>
80 Часть I. Процедурное программирование в Visual FoxPro

где <свойство> — в нашем случае это value (значение), <объект> — в данном


случае Texti, т. е. если значение объекта Texti равно 0, то выполняем сле­
дующие команды:
• this.backcoior — устанавливает цвет фона объекта, определяемый функ­
цией RGB о (в данном случае красный цвет);
• return— передает значение .F. свойству ErrorMessage (Сообщение об
ошибке), которое и отображается на экране, если проверка Valid прошла
успешно. Если мы в окне процедур для события ErrorMessage ничего не
введем, то будет выдано сообщение invalidinput (Неверное значение).
Но мы не станем пугать пользователя разными словами типа invalid, мы
сделаем свое сообщение! В окне процедур для события ErrorMessage вводим:
MessageBox ( "Вы ввели неверное значение. Пожалуйста, исправьте.",
"Ошибка ввода данных")

MessageBox — опять что-то новое. Теперь на каждой странице тебе будет


встречаться какое-нибудь незнакомое понятие. Но ты не отчаивайся —
я все объясню. А этот самый messagebox — всего-навсего диалоговое окно
с кнопками (рис. 6.27). Ты их уже видел не один раз.

Рис. 6.27. При вводе недопустимых значений появляется сообщение об ошибке


УРОК 7

Использование переменных

Сейчас мы поговорим об еще одном типе данных, широко используемом в


Visual FoxPro. Это переменные памяти. При их использовании необходимо
соблюдать некоторые правила:
• имя переменной не может содержать более 255 символов;
• имя переменной должно начинаться с буквы;
• в именах переменных не допускается использование пробелов и специ­
альных символов (использование цифр и знаков подчеркивания допус­
тимо);
• имя переменной не должно совпадать с зарезервированными словами
FoxPro. Зарезервированные слова — название команд языка, например
уже знакомая нам replace и т. д.
Да уж, в первом пункте (255 символов) разработчики явно расщедрились.
Вероятно, это сделано специально для фанатов машинописи...
Так что такое переменная памяти?
MyVar =456

где MyVar — это имя переменной. Используя знак равенства, мы присваива­


ем ей значение 456.
В отличие от полей таблиц, нам не нужно заранее определять тип исполь­
зуемых переменных. Дело в том, что переменные в Visual FoxPro имеют
"слабую типизацию". Это означает, что при определенных условиях одна и
та же переменная может использовать данные различных типов. Например:
MyVar = 456 && в этом случае в переменной хранится число 456
MyVar = "Fox Pro" && а теперь в этой же переменной находится
&& строка символов
Хорошо это или плохо? Однозначно ответить трудно. Для разработчиков
Приложений в среде Visual FoxPro это, возможно, удобно — нет необходи-
82 Часть I. Процедурное программирование в Visual FoxPro

мости заранее определять типы переменных, которых может быть довольно


много. Но с другой стороны, возникает проблема совместимости с другими
языками высокого уровня, например в C++ необходимо заранее определить
типы используемых переменных.
Ты спросишь: "И что, одну и ту же переменную можно использовать во
всем приложении?" Не всегда, дружок, не всегда... За это отвечает параметр,
определяющий так называемую область видимости переменной и прини­
мающий следующие значения: Public, Private, Local.
Переменная, объявленная как Public (Глобальная), "видна" в любой про­
грамме приложения. Под программой подразумевается любой файл, входя­
щий в состав проекта.
Переменная с областью видимости Private (Закрытая) используется только
в текущей программе (процедуре, методе).
Переменная Local (Локальная) будет работать только в текущей процедуре.
Объявление области видимости происходит так:
Local MyVar, M y V a r l , . . . , MyVarn

т. е. перед именем переменных указываем необходимый параметр.


Как задать переменной то или иное значение? Можно использовать, как
показано ранее, знак равенства. Но если предполагается использовать не­
сколько переменных с одинаковыми значениями, то удобнее применять
команду STORE. Синтаксис следующий:
STORE 456 ТО MyVar,MyVarl,MyVar2

В случае символьных строк необходимо использовать кавычки:


STORE "Moscow" TO MyCity, MyTown, MyRegion, Adress

В отличие от "долгожителей" — таблиц, переменные памяти "живут" только


во время работы приложения или сеанса Visual FoxPro. Именно поэтому
они в основном используются для промежуточных вычислений, хотя доступ
к ним осуществляется намного быстрее, чем к полям таблиц.
И еще немного об именах переменных и полей таблиц. Конечно, ты мо­
жешь называть их как угодно, главное — соблюдать известные правила. Но
в последнее время среди программистов принято негласное соглашение о
присвоении имен. Все просто — перед именем переменной или поля следу­
ет указывать префикс из двух прописных букв, показывающих область ви­
димости и тип переменной. Например, переменную, объявленную как Local
и хранящую числовые значения, можно назвать как lnMyVar, где i — Local,
a n — Numeric. В табл. 7.1 и 7.2 показаны принятые буквы префиксов и их
описание.
Для чего все это делается? В первую очередь для тебя самого: приложения
могут быть очень большими, содержащими огромное количество различных
Урок 7. Использование переменных 83

переменных, и не исключено, что ты сам в них запутаешься. Во-вторых,


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

Таблица 7.1. Область видимости (первая буква)

Буква Описание
g Public (Global)
i Local

р Private
t Parameter

Таблица 7.2. Тип данных (вторая буква)

Буква Описание
а Array (Массив)
с Character (Символьный)

У Currency (Денежный)
d Date (Дата)
о Object (Объект)
п Numeric (Числовой)
I L o g i c a l (Логический)
f Float (Вещественный)
t DateTime (Дата и время)
b Double (Вещественный с двойной точностью)

Практическое использование переменных


Сейчас рассмотрим, как применить все сказанное ранее на практике. От­
кроем нашу форму (Formi) в окне конструктора форм и, воспользовавшись
командой системного меню File | Save As (Файл | Сохранить как), сохраним
эту форму под другим именем, например FormWithVar. Вызовем окно Data
Environmennt (Среда данных) и удалим из него таблицу mytab, используя
84 Часть I. Процедурное программирование в Visual FoxPro

команду Remove (Удалить) контекстного меню. Теперь у нашей формы от­


сутствует "официальный" источник данных. Он нам и не требуется, потому
что в этом примере мы будем использовать переменные памяти, присваивая
им значения объектов TextBox.
По ходу реализации данной задачи мы познакомимся еще с одним инстру­
ментом, широко используемым при создании приложений. Речь идет о по­
строителе объекта (Builder).
Использование построителей существенно облегчает процесс настройки
свойств объектов. К сожалению, в Visual FoxPro имеются построители не
для всех размещаемых в экранной форме объектов. Мы рассмотрим исполь­
зование большинства из них, а сейчас остановимся на применении по­
строителя для поля ввода.
Вообще, построители можно использовать не только для создания новых
объектов, но и для редактирования свойств уже существующих. Именно
этим мы займемся, и в качестве примера будем "препарировать" объект
T e x t l В ф о р м е FormWithVar.

Для этого выделим объект поле ввода Textl и, нажав правую кнопку мыши,
выберем пункт Builder (Построитель). Откроется диалоговое окно Text Box
Builder (Построитель поля ввода) (рис. 7.1) с тремя вкладками:
• Format (Формат);
• Style (Стиль);
• Value (Значение).

Рис. 7.1. Окно построителя объекта TextBox. Вкладка Format

Вкладка Format (Формат) содержит раскрывающийся список Data Type


(Тип данных), используя который мы можем установить необходимый тип
Урок 7. Использование переменных 85

данных для нашего объекта. Так как значения из нашего примера будут
принимать участие в вычислениях, установим числовой тип Numeric.
Флажки, расположенные на этой же вкладке, имеют следующее назначение:
• Enable at run time (Доступно) — устанавливает, будет ли разрешен доступ
к объекту при запуске формы. Данный флажок связан со свойством объ­
екта Enabled;
• Alphabetic characters only (Только буквы) — при установке данного флаж­
ка в поле можно вводить только буквы алфавита;
• Make read-only (Сделать доступным только для чтения) — при включе­
нии этого флажка пользователь не сможет вводить и редактировать дан­
ные. СВОЙСТВО Readonly;
• Select on entry (Выделять при вводе) — при получении фокуса (установке
курсора) содержимое этого поля будет выделяться целиком;
• Hide selection (Убрать выделение — после перехода курсора на другой
объект (потеря фокуса) выделение будет снято. Свойство HideSeiection;
• Display leading zeros (Показывать ведущие нули) — отображает ведущие
нули при выводе их в поле ввода.
В нижней части находится еще один раскрывающийся список: Input Mask
(Маска ввода или Шаблон). Он предназначен для задания шаблона ввода
данных. Справа от списка находится надпись User-defined mask (Маска, оп­
ределенная пользователем). Это означает, что мы можем как выбирать зна­
чения, так и вводить свои, что и сделаем — введем свой шаблон, например
999.99.
Определившись с вкладкой Format, перейдем к рассмотрению следующей —
Style (Стиль), используя которую можно изменять стиль отображения объ­
екта (рис. 7.2).
Переключатель Special effect (Специальный эффект) содержит две опции:
3D (Трехмерный) и Plain (Плоский). При включенном 3D объект отобража­
ется с эффектом объемности. Это свойство speciaiEffeet.
Переключатель Border (Обрамление) позволяет задать стиль обрамления
объекта: Single (Одинарный) устанавливает стиль обрамления в виде оди­
нарной линии, a None (Нет) показывает объект без обрамления.
Раскрывающийся список Character alignment (Выравнивание) позволяет оп­
ределить, каким образом будет происходить выравнивание данных в объек­
те. Это СВОЙСТВО Alignment.
Флажок Size text box to fit "подгоняет" размер объекта под длину "содержи­
мого".
Вкладка Value (Значение) предназначена для связывания объекта поле ввода
с полем таблицы. В раскрывающемся списке Field name (Имя поля) можно
86 Часть I. Процедурное программирование в Visual FoxPro

выбрать поле, с которым мы хотим связать наш объект (в данном случае


этого делать не нужно — таблицы-то нет). Кнопка с тремя точками позво­
ляет выбрать таблицу, используя диалоговое окно Open (Открыть).

Рис. 7.2. Диалоговое окно построителя элемента управления TextBox. Вкладка Style

Рис. 7.3. Диалоговое окно построителя элемента управления TextBox. Вкладка Value

После установки всех параметров нажимаем кнопку ОК. Расположенная


рядом кнопка Cancel (Отмена) отменяет все изменения и закрывает окно
построителя. Ну а про кнопку Help (Помощь) и говорить не приходится —
Help он и в Африке Help!
Используя построитель, установим такие же параметры для объектов Text2
И Text3.
Урок 7. Использование переменных 87

Теперь осталось изменить программный код для события click кнопки Рас­
чет (листинг 7.1).

Листинг 7.1. Решение уравнения с использованием переменных

note объявляем переменные:


LOCAL lnvara,lnvarb,lnvarc,lnd,lnxl,lnx2,lcresult
* присваиваем переменным значения полей ввода
invara=THISFORM.ТЕХТ1.VALUE
lnvarb =THISFORM.TEXT2.VALUE
lnvarc =THISFORM.TEXT3.VALUE
* вычисляем дискриминант d
* для этого заменяем значение переменной lnd на математическое выражение:
lnd=lnvarb**2 - (4*lnvara*lnvarc)

* проверяем значение d
DO CASE && начало проверки
CASE lnd>0 && если d больше нуля, выполняем команды:
lcresult="ypaBHeHne имеет два корня"
* вычисляем первый корень, присваивая значение переменной lnxl
lnxl=(-lnvarb+sqrt(lnd))/(2*lnvara)
* то же самое для второго корня:
1пх2=(-lnvarb-sqrt(lnd))/(2*lnvara)

CASE lnd=0 && если d равен нулю, то:


lcresult="ypaBHeHne имеет один корень"
lnxl=lnvarb/(2*lnvara)

CASE lnd<0
lcresult = "Уравнение не имеет решения"
*заканчиваем проверку условий:
ENDCASE
*присваиваем значения переменных объектам:
THIS FORM.ТХТХ1.VALUE =lnxl
THISFORM.TXTX2.VALUE = lnx2
THISF0RM.TEXT4.VALUE = lcresult
обновляем информацию в форме:
THISFORM.REFRESH{)

Я использовал в начале программы команду Note — это еще один спо­


соб объявить строку комментарием. В данном примере можно обойтись
и без команд присваивания переменным значений полей ввода
(lnVarA = THISFORM.TEXTI. VALUE и т. д.) — достаточно указать имена этих пе­
ременных в поле Field name (Имя поля) на вкладке Value (Значение) в диа­
логовом окне построителя объекта.
УРОК 8

Массивы

Массивы — это все те же переменные памяти, обращаться к которым мож­


но как к единому целому. Массивы могут быть одномерными и многомер­
ными (например, двумерные).
Одномерный массив представляет собой последовательность переменных па
мяти, имеющих одинаковые имена и различающихся порядковым номером
Например, массив муАггау(З) будет состоять из трех "ячеек", в каждой и
которых может храниться информация: муАггауш, муАггау(2), муАггау(З).
Данные в элементах одного массива могут иметь различный тип.
Двумерный массив можно представить в виде виртуальной таблицы, в мес
тах пересечения строк и столбцов которой и расположены наши "ячейки".
При обращении к элементам двумерного массива необходимо указывать дdf
параметра: номер "строки" и номер "столбца":
My2Darray(5,2)
Пока массив находится в области видимости, можно получить доступ к лю-
бому его члену. Например:
MyArray(l) = 5 2 3
MyArray(2) = 348
МуАггау(З) =* (МуАггау (1)-Муаггау (2) ) *0.5

В результате в элементе МуАггау(З) появится вычисленное значение 87,5.


Теперь попробуем использовать массив в нашем примере, изменив код
в обработке события click (листинг 8.1).

Листинг 8.1. Решение квадратного уравнения с использованием массива

NOTE объявляем массив, используя команду declare:

DECLA myar(7) && массив состоит из семи элементов


* присваеваем элементам массива значения полей ввода
Урок 8. Массивы 89

myar(l)=thisform.textl.value && a
myar(2) -thisform.text2.value && b
myar(3) -thisform.text3.value && с
* вычисляем дискриминант d
* для этого заменяем значение элемента массива на математическое выражение:
myar(4)=myar(2)**2 - (4*myar (l) *myar (3))

* проверяем значение d
DO CASE & начало проверки
CASE myar(4)>0 && если d больше нуля, выполняем команды:
myar(5)="уравнение имеет два корня"
* вычисляем первый корень, присваивая значение переменной lnxl
myar(6)=(-myar(2)+sqrt(myar(4)))/(2*myar(1))

* то же самое для второго корня:

myar(7)=(-myar(2)- sqrt(myar(4)))/(2*myar(1))

CASE myar(4)=0 && если d равен нулю, то:


myar(5)="уравнение имеет один корень"
myar(6)=myar(2)/(2*myar(l))

CASE myar(4)<0
myar(5) = "уравнение не имеет решения"
* заканчиваем проверку условий:
ENDCASE
* присваиваем значения переменных объектам:
THISFORM.TXTX1.VALUE =myar(6)
THISFORM.TXTX2.VALUE = myar(7)
THISFORM.TEXT4. VALUE = myar(5)
* обновляем информацию в форме:
THISFORM.REFRESH()

Теперь, когда мы решили нашу задачу тремя различными способами (кста­


ти, все это можно решить и без использования переменных, таблиц или
массивов — используя прямое обращение к значениям объектов, например
THISFORM.TEXTI.VALUE), ты ясно увидел различия между ними. При исполь­
зовании массивов и переменных памяти мы можем решать только одно
Уравнение, которое к тому же не сохраняется в памяти после закрытия
Формы.
(-охранить результат вычислений мы можем используя таблицу. Но в нашем
примере и в таблице сохраняется только одно какое-то уравнение — ведь
работаем всего с одной записью.
Ответ на твой вопрос: "А как добавлять новые записи в таблицу?" — в сле­
дующем уроке.
УРОК 9

Добавление записей
в таблицу
Существует несколько способов, позволяющих добавлять новые записи в
таблицу. Наиболее распространенным среди неопытных пользователей
является использование команды BROWSE (Просмотр).
Вообще BROWSE используется для просмотра и редактирования данных в таб­
лицах, но при определенной сноровке можно и научиться добавлять новые
записи.
Рассмотрим этот метод.
Добавим в нашу форму еще одну командную кнопку, при нажатии которой
в таблицу будет добавляться запись. Установим свойство caption рав­
ным новая запись, а в обработку события click пропишем команду BROWSE
(рис. 9.1).
Запустив форму и щелкнув на нашей новой кнопке, мы увидим результат
работы команды BROWSE (рис. 9.2).
Так как мы используем команду BROWSE без ключевых слов, "в чистом ви­
де" — открываются все поля таблицы. Это уже нехорошо, потому что поль-
зователю совершенно незачем вводить значения в поля xl, x2, d и Result,
т. к. эти поля являются вычисляемыми и значения в них заносятся про­
граммно. Пользователю даже знать о них не нужно! Желательно всегда ог­
раничивать доступ пользователя к тем полям таблиц, которые используются
приложением, так сказать, для "внутреннего потребления". Речь идет о вы­
числяемых полях, полях, содержащих индексные выражения и уж тем бо­
лее, содержащих значения первичных ключей для связанных таблиц! Пожа-
луйста, отнесись к этому внимательно — немалое количество программных
сбоев происходит именно по вине неосторожных пользователей (что ни
в коей мере не умаляет вину программиста, допустившего пользователя к
этим данным).
Урок 9. Добавление записей в таблицу 91

Рис. 9.1. Для добавления записей мы создали новую кнопку

Рис. 9.2. Таблица в режиме просмотра Browse


92 Часть I. Процедурное программирование в Visual FoxPro

Поэтому мы добавим в BROWSE список полей, к которым пользователь может


быть "допущен":
BROWSE FIELDS first_a :h= "Первая переменная a", second_b :h= "Вторая
^переменная b,third_c :h= "Третья переменная с"

После ключевого слова FIELDS (Поля) мы через запятую перечисляем те по­


ля, которые будут отображаться при просмотре таблицы. Также мы исполь­
зуем ключ :н для создания заголовка поля (рис. 9.3). Дело в том, что при
работе команды BROWSE заголовки полей совпадают с их именами, что не
очень удобно для пользователя — это мы знаем, что такое second_b, а как
об этом догадаться постороннему человеку?

Рис. 9.3. Мы определили список доступных полей и их заголовки

Теперь пользователь может добавлять новые записи, используя комбинацию


клавиш <Ctrl>+<Y>. Согласись, не очень-то удобно для каждой новой
записи постоянно использовать комбинацию клавиш, особенно если прихо­
дится вводить много записей. Опять же необходимо предусмотреть про вер-j
ку первого поля на ноль:
BROW FIELDS f i r s t _ a :Ь="Первый компонент A", second_b :гл.="Второй
•^компонент В", t h i r d _ c :п="Третий компонент С" VALID f i r s t _ a < > 0

VALID — это и есть проверка. Режим просмотра не будет закрыт, пока поль­
зователь не введет корректное значение для поля.
Команду BROWSE необходимо использовать при отладке программ, значение
этого средства трудно переоценить, но вот для ввода записей она не оченН
удобна, хотя можно и ее успешно применять для этой цели.
Урок 9. Добавление записей в таблицу 93

Альтернативой может стать замена BROWSE на команду APPEND.


Посмотрим, что получится, если мы вставим данную команду в процедуру
обработки события click для кнопки Новая запись (рис. 9.4):
Append Fields f i r s t _ a , second_b, third_c

Рис. 9.4. Использование команды APPEND

При использовании этой команды новая запись будет добавляться автома­


тически после заполнения всех полей предыдущей записи. Это, конечно,
удобнее, чем использование комбинации клавиш в случае с BROWSE, но здесь
не удастся просто так задать заголовки полей. И опять же необходимо по­
думать о проверке вносимых значений. Поэтому мы также можем поставить
под сомнение широкое использование данной команды.
Еще один способ — использование команды APPEND BLANK. При этом табли­
ца не будет открываться в режиме просмотра, просто будет добавлена пустая
запись. А т. к. поля таблицы связаны с полями ввода экранной формы, мы
можем заносить новые данные, используя экранную форму. Тем более, что
проверка достоверности данных у нас уже реализована.
Заменим команду в событии click на следующее выражение:
APPEND BLANK
THISFORM.REFRESH{)

Команда REFRESH обновляет информацию в форме, заново ее "перерисовы­


вая" с учетом новых данных (рис. 9.5).
94 Часть I. Процедурное программирование в Visual FoxPro

Рис. 9.5. Мы можем вводить новые значения, используя поля ввода

Казалось бы — вот оно, идеальное решение! Однако и здесь есть свои "под­
водные камни". Представь такую ситуацию: пользователь нажал кнопку Но­
вая запись, а затем передумал вводить значения и закрыл форму. Но запись-
то добавилась!
Хорошо, что современные винчестеры позволяют хранить огромное количе­
ство информации, а вот лет 15 назад руководитель проекта просто застрелил
бы программиста, допустившего такое "использование" дискового простран-
ства. Да дело, собственно, и не в этом. Как ты думаешь, пользователь будет
нервничать, увидев пятьсот пустых строк? То-то и оно...
Выход из этой ситуации есть — можно использовать переменные памяти
Для их создания применяется следующая команда:
SCATTER MEMVAR BLANK MEMO

С помощью этой команды из таблицы создается набор переменных памяти.


Слово MEMO используется для переноса в переменные значения из полей
Memo. В нашем примере его можно не использовать. Для того чтобы редак-
тировать значения этих переменных, создадим еще одну экранную форму
ADDREC (рИС. 9.6).

Рис. 9.6. Мы создали новую экранную форму


для редактирования значений переменных
Урок 9. Добавление записей в таблицу 95

В новой форме расположим три поля ввода и укажем для них в качестве
источника данных переменные, созданные командой SCATTER. При исполь­
зовании данной команды имена переменных будут совпадать с соответст­
вующими именами полей таблицы и, чтобы их не путать, перед именем пе­
ременной ставится префикс т.
Разместим в форме две командные кнопки: Сохранить и Отмена, введем
следующие команды обработки события Click:
О для кнопки Сохранить:
SELECT mytab
APPEND BLANK
GATHER MEMVAR
WAIT WINDOW "Запись добавлена"
THISFORM.RELEASE

О для кнопки Отмена введем одну команду:


THISFORM.RELEASE

Теперь откроем в Конструкторе отчетов форму Formi и для кнопки Новая


запись определим новый код в событии click:
SCATTER MEMVAR BLANK
DO form c:\examples\addrec

Вся эта конструкция работает следующим образом (рис. 9.7).


1. При нажатии кнопки Новая запись создается набор переменных памяти.
В этих переменных нет никаких значений, они "пустые" (результат ис­
пользования в команде SCATTER ключевого слова BLANK).
2. Затем запускается форма ADDREC. Запуск происходит по команде:
DO FORM (<путь>) <имя формы>

Рис. 9.7. Добавление записей в форму


96 Часть I. Процедурное программирование в Visual FoxPro

3. Используя поля ввода формы ADDREC, присваиваем значения связанным с


ними переменным.
4. При нажатии кнопки Сохранить происходят следующие процессы:
• т. к. в среде окружения данной формы таблицы не используются,
необходимо указать нужную таблицу; это делается командой SELECT
<имя_таблиць!>\

• выбрав таблицу, добавляем в нее пустую запись — APPEND BLANK;


• затем команда GATTER MEMVAR заполняет поля соответствующими зна­
чениями, после чего выдается сообщение командой WAIT WINDOW
"Текст сообщения";

• последняя команда (Thisfom.Release) закрывает форму.

Замечание
Форма ADDREC выполняется внутри формы верхнего уровня FORMI (свойство,
ShowWindow=l).

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


и мы без особых хлопот сможем добавлять записи в нашу таблицу.
Но в нашей форме Formi отображается только одна, текущая запись, а как
же быть с остальными? Для этого необходимо узнать, каким образом осу-
ществляется перемещение по записям, а также научиться удалять ненужные)
записи. Всем этим мы и займемся на следующем уроке.
УРОК 10

Перемещение
по записям таблицы
Для перехода от записи к записи в Visual FoxPro используется несколько
команд, некоторые из которых мы рассмотрим.
О Команда SKIP П применяется для перехода на следующую запись, где п —
необязательный параметр, указывающий, на какое число записей пере­
местить указатель. По умолчанию это число равно 1 и для перехода на
следующую запись достаточно просто задать команду SKIP.
О Команда SKIP -l аналогична SKIP, ТОЛЬКО перемещение происходит
"в другую сторону" — на предыдущую запись.
О Команда GO BOTTOM устанавливает указатель на самую последнюю запись
в таблице, а похожая на нее GO TOP — на самую первую.
О Команда GO ИЛИ GOTO осуществляет переход на запись с указанным номе­
ром. Например, GOTO 23 установит указатель на двадцать третью запись
таблицы.
Используя эти команды, можно организовать переход по записям таблицы в
нашем приложении, добавив соответствующие элементы управления и за­
программировав их действия.

Использование построителя
Для объекта CommandGroup
Мы уже познакомились с таким объектом, как простая командная кнопка,
и теперь пришло время научиться работать еще с одной интересной шту­
кой —- группой командных КНОПОК CommandGroup.
Откроем в окне конструктора форм нашу форму Formi. Выбрав на панели
гогщ Controls кнопку Command Group, разместим объект CommandGroup в
Форме. Для данного объекта также имеется свой построитель, и мы можем
вызвать его, используя команду Build контекстного меню (рис. 10.1).
4 з
а к Ю02
98 Часть I. Процедурное программирование в Visual FoxPro

Рис. 10.1. Диалоговое окно построителя Command Group Builder

Окно построителя имеет две вкладки: Buttons (Кнопки) и Layout (Располо-1


жение).
Рассмотрим вкладку Buttons (см. рис. 10.1). Используя поле ввода Number of |
buttons (Количество кнопок) можно изменить число кнопок, установленное |
по умолчанию (2). Ниже расположена таблица, в которой перечислены на­
ши кнопки. Столбец Caption (Заголовок) позволяет задать надписи на
кнопках, а используя кнопку с тремя точками в столбце Graphic (Графиче­
ский стиль), можно выбрать рисунок, который будет размещен на кнопке, j
Давай сначала изменим число кнопок (установим значение равное 6) и вы-|
берем изображение для каждой кнопки. Для этого открывается уже знако-1
мое нам диалоговое окно Open (Открыть), в котором и можно выбрать нуж­
ный файл графического изображения (рис. 10.2).

Рис. 10.2. Диалоговое окно для выбора графического файла


урок Ю- Перемещение по записям таблицы

Теперь перейдем на вкладку Layout (Расположение) (рис. 10.3). Здесь мы


должны определить внешний вид нашей группы командных кнопок.

Рис. 10.3. Вкладка Layout

Пункт Button layout (Расположение кнопок) содержит две опции: Vertical


(Вертикальное), Horizontal (Горизонтальное).
Пункт Spacing between buttons (Расстояние между кнопками) позволяет из­
менять интервал между кнопками. За единицу измерения принят пиксел.
Пункт Border style (Стиль обрамления) нам уже знаком — это стиль обрам­
ления объекта.
Установив необходимые параметры (см. рис. 10.3), нажимаем кнопку ОК.
Должно получиться примерно следующее — рис. 10.4.

Рис. 10.4. Объект CommandGroup размещен в форме


100 Часть I. Процедурное программирование в Visual FoxPro

Возможно, что после завершения работы построителя вид объекта будет еще
далек от желаемого. В этом случае следует произвести необходимые изме-
нения "вручную". Выделим объект commandGroup. Так как данный элемент
управления представляет собой контейнер, то при его выделении будут дос-
тупны только его "контейнерные" свойства. А как забраться "во внутрь"?
Нужно вызвать контекстное меню, нажав правую кнопку мыши, и выбрать
команду Edit (Редактирование). Теперь у нас есть доступ к любому объекту,
и мы можем изменять свойства любого элемента, входящего в состав этого
контейнера. Устанавливаем обработку события Click для кнопок следую-
щим образом:
О кнопка Первая запись:
GO TOP
THISFORM.REFRESH

П кнопка Следующая.
IF ! ВОТ ()
SKIP
THISFORM.REFRESH
ENDIF

• кнопка Предыдущая:
I F ! EOF ()
SKIP -1
THISFORM.REFRESH
ENDIF

• кнопка Последняя запись:


GO BOTTOM
THISFORM.REFRESH

Ну, с первой и последней записями ясно, а вот для чего нужна проверка
для перехода на следующую и предыдущую записи? И что это за EOF()
такая?
EOFо — это функция (End of File), которая проверяет, не стоит ли уже
указатель на последней записи, т. е. в конце файла. Если да, то данная
функция вернет значение .т. (Логическая истина).
Аналогично действует и функция вот о (Begin Of File), единственное от-
личие которой заключается в том, что здесь речь идет о первой записи.
Если исключить указанные ранее проверки и попытаться выполнить,
к примеру, команду SKIP, когда указатель уже стоит на последней записи
бдительный Лис немедленно отреагирует сообщением об ошибке (рис. 10.5).
Урок 10. Перемещение по записям таблицы 101

Рис. 10.5. Сообщение об ошибке (конец файла)

Вот поэтому и используются проверки при перемещениях по записям


таблиц.
Но это еще не все. Мы теперь можем перемещаться по записям таблицы,
выбирая нужную запись и производя расчеты для этой записи. Согласись,
не очень удобно для каждой записи нажимать кнопку Расчет. А ведь можно
сделать так, чтобы при выборе кнопки Расчет решались сразу все наши
уравнения, т. е. обрабатывались все записи таблицы.
Рассмотрим два способа. Первый— использование цикла SCAN. . .ENDSCAN
(листинг 10.1).

Листинг 10.1. Первый способ обработки всех записей сразу

SCAN && н а ч а л о с к а н и р о в а н и я
REPLACE m y t a b . d WITH m y t a b . s e c o n d _ b A 2 - ( 4 * m y t a b . f i r s t _ a * m y t a b . t h i r d _ c )
DO CASE && н а ч а л о п р о в е р к и
CASE d>0 && е с л и d больше н у л я , выполняем команды:
REPLACE m y t a b . r e s u l t WITH " у р а в н е н и е и м е е т д в а к о р н я "
* вычисляем первый корень при помощи команды r e p l a c e , заменяя
значение в поле xl
Replace m y t a b . x l w i t h (-mytab.second_b + s q r t ( m y t a b . d ) ) / ( 2 * f i r s t _ a )
* то же самое для второго корня:
REPLACE mytab.x2 WITH (-mytab.second_b - s q r t ( m y t a b . d ) ) / ( 2 * f i r s t _ a )
CASE d=0 && а если d равен нулю, то:
REPLACE m y t a b . x l WITH ( m y t a b . s e c o n d _ b ) / ( 2 * f i r s t _ a )
REPLACE m y t a b . r e s u l t WITH "уравнение имеет один корень"
Case d<0
REPLA m y t a b . x l WITH 0,mytab.x2 WITH 0 , m y t a b . r e s u l t WITH "уравнение н е ;
имеет решения"
заканчиваем проверку условий:
ENDCASE
ENDSCAN &&конец сканирования - обработаны все записи

Цикл SCAN. . .ENDSCAN используется для обработки всего файла таблицы. При
э
том происходит сканирование таблицы, и указатель записи перемещается
п
° записям "сверху вниз", для каждой выполняя команды, находящиеся ме-
102 Часть I. Процедурное программирование в Visual FoxPro

жду SCAN и ENDSCAN. В команде SCAN можно использовать дополнительные


условия, такие как FOR И WHILE.
Еше один способ — использование уже знакомой нам команды REPLACE С
параметрами ALL И FOR (ЛИСТИНГ 10.2).

I Листинг 10.2. Второй способ обработки всех записей сразу

REPLACE ALL m y t a b . d WITH mytab. second__b A 2 -;


(4*mytab.first_a*mytab.third_c)
<S<S если d больше нуля, выполняем команды:
REPLACE ALL m y t a b . r e s u l t WITH "уравнение имеет два корня" FOR mytab.d>0
REPLACE ALL m y t a b . x l WITH (-mytab.second_b + s q r t ( m y t a b . d ) ) / ( 2 * f i r s t _ a ) ;
FOR y t a b . d > 0
REPLACE ALL mytab.x2 WITH (-mytab.second_b - s q r t ( m y t a b . d ) ) / ( 2 * f i r s t _ a ) ;
FOR y t a b . d > 0
&& а если d равен нулю, т о :
REPLACE ALL m y t a b . x l WITH ( m y t a b . s e c o n d _ b ) / ( 2 * f i r s t _ a ) FOR mytab.d=0
REPLACE ALL m y t a b . r e s u l t WITH "уравнение имеет один корень" FOR mytab.d=0I
*если меньше 0:
REPLA ALL m y t a b . x l WITH 0,mytab.x2 WITH 0 , m y t a b . r e s u l t WITH "уравнение;
не имеет решения" FOR mytab.d<0
REPLA ALL m y t a b . d a t WITH d a t e О

Здесь мы отказались от использования конструкции DO CASE для проверки


значений дискриминанта — используя в команде REPLACE (Заменить) пара-
метр FOR (Для), мы как бы делаем выборку прямо в этой команде. Параметр
ALL (Все) указывает, что будут меняться значения полей для всех тех запи-
сей, которые удовлетворяют условию FOR.
В этом же примере мы заменяем все значения поля Dat на текущую дату с
помощью функции Date о, возвращающей значение сегодняшней даты. Но
если мы откроем нашу таблицу для просмотра, то увидим, что дата отобра-
жается как-то не "по-русски". Дело в том, что в Visual FoxPro поддержива-
ется несколько форматов для отображения данных типа Date, все они опи-
саны в приложении 2. А сейчас мы исправим этот непривычный для нас
формат, введя в метод i n i t экранной формы Formi следующую команду*.
SET DATE TO German

Удаление записей
Довольно часто возникает ситуация, когда пользователю необходимо уда
лить из таблицы какие-нибудь записи. Это можно делать как программно-
так и в интерактивном режиме, используя уже знакомую команду BROWSE
Урок 10. Перемещение по записям таблицы 103

Откроем нашу таблицу для просмотра (рис. 10.6). Крайний левый столбец
называется Delete Mark (Маркер удаления). При щелчке мышью в этом
столбце он закрашивается, что говорит о том, что данная запись помечена
для удаления. Таким образом, пометив необходимые записи, пользователь
может удалить их, используя команду Remove Deleted Records (Удалить
помеченные записи) из пункта Table (Таблица) системного меню Visual
FoxPro.

Рис. 10.6. Удаление записей в режиме просмотра

Но необходимо отметить, что удалить запись возможно только в том случае,


когда таблица открыта с исключительным доступом. Как получить этот са­
мый доступ, описано далее, а сейчас поговорим вот о чем: пользователь,
просматривая таблицу, может совершенно случайно поставить отметку для
удаления на "нужных" записях. Я уже говорил, что не рекомендуется широ­
ко использовать режим просмотра BROWSE В приложениях (по крайней мере,
без использования дополнительных параметров), но если уж это необходи­
мо, тогда для предотвращения случайных удалений нужно использовать
команду BROWSE с опцией NODELETE, которая запрещает ставить метки на
записях.
Установить или снять метку также можно, используя клавиатуру — комби-
Нация клавиш <Ctrl>+<T>.
104 Часть I. Процедурное программирование в Visual FoxPro

Для удаления записей без использования режима просмотра таблиц


(BROWSE), так сказать программно, используются следующие команды:

О DELETE — ставит на записи отметку для удаления. По умолчанию метка


ставится на текущую запись, но в этой команде также можно задать ус­
ловия, используя ключевые слова FOR/WHILE. Команда DELETE ALL помеча­
ет все записи;
О PACK — непосредственное удаление записей, отмеченных командой
DELETE. Эту же команду можно использовать для уменьшения размера
файла, содержащего поля типа Memo, PACK MEMO удалит только неиспользо­
ванное пространство в полях Memo, и при этом даже маркированные
записи не будут "затронуты";
О RECALL — снимает метки с записей.
Но опять же удаление возможно только в таблице, открытой с исключи­
тельным доступом. Как это сделать?
USE — одна из "главных" команд Visual FoxPro. Именно эта команда откры­
вает таблицу и все связанные с ней индексные файлы, если, конечно, по­
следние определены. Данная команда используется с огромным количест­
вом дополнительных параметров, а в самом простом случае имеет такой
вид:
USE (<луть>) <имя_таблиць!>

Почему мы ее не использовали? Да потому, что наша таблица открывается


автоматически при запуске формы. А вот если мы добавим в метод inijl
формы Formi строку
USE C:\Examples\Mytab EXLUSIVE

то наша таблица будет открываться с этим самым исключительным досту­


пом, что сделает возможным удаление записей.
Использование команды USE без параметров и имен приведет к тому, что
будет закрыта таблица в текущей рабочей области.
Определим следующие действия при событии click для объекта command6,
входящего в состав набора кнопок commandGroupi (кнопка Удалить):
DELETE
PACK
THISFORM.REFRESH()

Вот и все — легко и просто.


Урок 10. Перемещение по записям таблицы 105

Создание экранной формы


с использованием мастера Form Wizard
Наш хитрый Лис содержит не одного, а целых двух мастеров экранных
форм — это мастер для создания формы с одной таблицей (Form Wizard) и
мастер для формы, использующей связанные таблицы (One-to-Many Form
Wizard). Мы пока ограничимся первым (Form Wizard) и, выбрав его, на­
жмем кнопку ОК (рис. 10.7).

Рис. 10.8. Диалоговое окно New Form


Рис. 10.7. Диалоговое окно выбора мастера для запуска мастера

Form Wizard ("Волшебник", "Колдун") используется для быстрого построе­


ния экранной формы. Но сразу предупреждаю — не стоит обольщаться,
мастер не может учитывать все твои желания и поэтому он "наколдует" тебе
простенькую формочку с минимальным набором элементов управления. Да
что говорить, давай посмотрим.
В диалоговом окне NewForm (Новая форма) нажмем кнопку Form Wizard
(рис. 10.8).
Вся работа с мастером сводится к тому, что нужно шаг за шагом отвечать на
его вопросы, появляющиеся в соответствующих диалоговых окнах. Вот оно,
началось!
На первом шаге работы (рис. 10.9) мастер просит указать имя свободной
таблицы или таблицы базы данных, которая будет использована в экранной
форме. Кнопка с точками открывает уже знакомое нам диалоговое окно
Open (Открыть), в котором можно выбрать необходимую таблицу. После
выбора таблицы наименования всех ее полей отображаются в списке Avail­
able fields (Имеющиеся поля). Используя кнопки со стрелками справа от
списка, нужно перенести наименования тех полей, которые будут приме­
няться в форме, в список Selected fields (Выбранные поля). Для перехода к
106 Часть I. Процедурное программирование в Visual FoxPro

следующему шагу необходимо нажать кнопку Next (Следующий), а для воз­


врата к предыдущим шагам используется кнопка Back (Назад).

Рис. 10.9. Первый шаг работы мастера

Рис. 10.10. Второй шаг работы мастера

На втором шаге работы (рис. 10.10) мастер просит выбрать стиль для буду-1
щей формы. Доступные стили отображены в списке Style (Стиль). Выбрав!
Урок 10. Перемещение по записям таблицы 107

желаемый, можно тут же посмотреть примерный вид формы в окне про­


смотра, расположенном в верхнем левом углу. Переключатель Button type
(Тип кнопок) имеет 4 опции:
О Text buttons (Кнопки с надписями);
О Picture buttons (Кнопки с изображением);
О No buttons (Нет кнопок);
О Custom (Пользовательский) — здесь можно выбрать тип кнопки из рас­
положенного ниже списка.
На третьем этапе (рис. 10.11) можно указать, по каким полям будет проис­
ходить упорядочение записи и порядок сортировки записей (по возраста­
нию — Ascending или по убыванию — Descending).

Рис. 10.11. Третий шаг работы мастера

И, наконец, на последнем — четвертом шаге работы мастера (рис. 10.12)


предлагается ввести заголовок для формы (поле Type a title for your form) и
выбрать вариант сохранения формы:
• Save form for later use (Сохранить форму для последующего использова­
ния) — при этом форма не будет сразу запушена;
• Save and run form (Сохранить и запустить форму) — форма сохраняется и
сразу же запускается на выполнение;
• Save form and modify it in the Form Designer (Сохранить и изменить форму
в Конструкторе форм).
108 Часть I. Процедурное программирование в Visual FoxPro

Рис. 10.12. Заключительный этап работы мастера

Рис. 10.13. Предварительный просмотр формы


Урок 10 Перемещение по записям таблицы 109

При установке флажка Add pages for fields that do not fit будут созданы до­
полнительные вкладки для полей, которые не поместились в форму.
Кнопка Preview (Просмотр) используется для предварительного просмотра
результатов работы мастера. Посмотрим — рис. 10.13.
И вот что мы имеем в результате: поля ввода и группу кнопок, позволяю­
щих перемещаться по записям, добавлять или удалять записи, осуществлять
поиск и закрывать форму. Большая кнопка Return to Wizard (Вернуться к
Мастеру) позволяет закрыть режим просмотра и вернуться к последнему
этапу работы мастера. Ясно, что ни о каком решении уравнения здесь не
может быть и речи, но мы можем сохранить эту форму и изменить дейст­
вия, происходящие при нажатии кнопок в окне Конструктора форм. Есте­
ственно, там же можно добавить или удалить необходимые элементы управ­
ления, да и вообще отредактировать всю форму по своему вкусу.

Установив необходимые параметры при последнем шаге работы мастера,


нажмем кнопку Finish (Завершить), после чего запустится процесс генера­
ции формы и через несколько секунд наша форма будет готова.

Создание экранной формы


с использованием мастера AutoForm Wizard
Почти такого же результата можно добиться, используя мастер AutoForm
Wizard (Мастер автоформы). Этот мастер выполняет автоматическое по­
строение экранной формы для выбранной таблицы. Для его запуска нужно
выбрать на вкладке Data (Данные) окна диспетчера проекта необходимую
таблицу и нажать кнопку мастера на стандартной панели инструментов
(кнопка AutoForm Wizard). При этом сразу откроется диалоговое окно Save
As (Сохранить как), которое позволяет сохранить форму (рис. 10.14). По
умолчанию имя экранной формы совпадает с именем таблицы.
После закрытия этого окна запускается процесс генерации, и через пару
секунд экранная форма появляется на экране (рис. 10.15).
Конечно, разработчики Visual FoxPro не могли включить в данный про­
граммный продукт такое количество мастеров, которое удовлетворяло бы
все потребности и желания программистов. Но, несмотря на кажущуюся
простоту созданных форм, использование мастеров может оказать сущест­
венную помощь при разработке элементов приложений. Ведь созданные
ими формы можно редактировать в Конструкторе, а это значит, что из не­
приглядной серенькой формы, созданной мастером, можно соорудить нечто
такое, ну очень красивое и сложное!
110 Часть I. Процедурное программирование в Visual FoxPro

Рис. 10.14. Диалоговое окно Save As

Рис. 10.15. Форма, созданная мастером автоформ


урок 11

Создание отчетов

Наше приложение, можно сказать, почти готово, но не кажется ли тебе, что


в нем явно чего-то не хватает? Правильно, пока у нас нет возможности по­
лучить распечатку! Я думаю, излишне говорить, для чего они нужны... Ре­
альность такова, что со времен Древнего Египта люди (чуть не сказал поль­
зователи), предпочитают хранить информацию на надежном, проверенном
веками носителе — бумаге. Их стремление к этому можно понять — жизнь
полна сюрпризов, и кто знает, вдруг ты сойдешь с ума, изучая программи­
рование по этой книге, или в твой компьютер влетит шаровая молния... Как
в таком случае потомки узнают о наших с тобой подвигах на ниве програм­
мирования? Конечно, все это шутка, но в ней есть доля правды — делопро­
изводство еще не отменили и отчеты находят широчайшее применение в
нашей деловой и повседневной жизни.
В Visual FoxPro имеются довольно мощные средства для создания разных
отчетов — от мастера отчетов Report Wizard до конструктора отчетов Report
Designer.
Создать сложный отчет при помощи мастера отчетов вряд ли удастся и, хотя
отчет, который мы будем делать для нашей программы, никак нельзя отне­
сти к "сложным", все равно изучение этой темы мы начнем со знакомства
с конструктором отчетов Report Designer.

Окно конструктора отчетов


Открыть окно конструктора отчетов можно различными способами:
О выбрать в пункте File (Файл) системного меню команду New (Новый) и
в открывшемся диалоговом окне New (Новый) нажать кнопку New File
(Новый файл), предварительно указав опцию Report (Отчет);
О нажать кнопку New (Новый) на стандартной панели инструментов.
Дальнейшие действия как в предыдущем пункте;
112 Часть I. Процедурное программирование в Visual FoxPro

Рис. 11.1. Диалоговое окно New Report

• нажать кнопку New (Новый) в окне Project Manager (Диспетчер проек­


та), отметив пункт Reports (Отчеты) на вкладке Documents (Документы).
После этого откроется диалоговое окно New Report (Новый отчет) (рис. 11.1).
Выберем кнопку New Report (Новый отчет), a Report Wizard оставим "на
десерт". Появится окно конструктора отчетов Report Designer (рис. 11.2).
Для работы могут быть использованы следующие панели инструментов:
G Report Controls (Элементы управления отчетом);
• Color Palette (Палитра);
• Layout (Расположение).

Рис. 11.2. Окно Report Designer


Урок 11. Создание отчетов 113

Отобразить или, наоборот, убрать эти панели с экрана можно, поставив со­
ответствующие флажки в меню View (Вид), или воспользовавшись еще од­
ной панелью инструментов, которая называется Report Designer (Конструк­
тор отчета) (рис. 11.3).

Рис. 11.3. Панель Report Designer

"Главной" панелью, конечно, является панель Report Controls — именно


с ее помощью мы будем размещать в отчете те или иные объекты. На пане­
ли имеется восемь кнопок, рассмотрим их назначение (табл. 11.1).

Таблица 11.1. Кнопки панели Report Controls

Помимо панелей инструментов, окно конструктора отчетов содержит сле­


дующие объекты: непосредственно сам макет отчета (белый фон) и три по-
114 Часть I. Процедурное программирование в Visual FoxPro

лосы, которые ограничены своего рода планками. Три полосы установлены


по умолчанию, всего их семь, и при использовании в отчете группировки
данных, титула и итоговых значений появляются дополнительные полосы.
Любая из этих полос или областей может содержать объекты: поля таблиц,
текст, линии и т. д. Описание типов полос представлено в табл. 11.2.

Таблица 11.2. Типы полос

Полоса Описание

Title (Титул) Информация из этой полосы печатается только на


первой странице отчета и может служить в качест­
ве заголовка отчета или титульного листа
Page Header Данные из этой полосы печатаются вверху на каж­
(Заголовок страницы дой странице отчета. Здесь можно поместить та­
или верхний колонтитул) кую информацию, как дата, номер страницы и т. д.
Group Header При использовании группировки данных в отчете
(Заголовок группы) информация из этой области печатается перед
печатью самой группы данных. В общем, это про­
сто заголовок для группы
Detail (Детали) В этой полосе содержатся данные полей таблиц и
прочая информация
Group Footer (Итог по группе) Итоги по группе при использовании группировки
данных
Page Footer Здесь могут находиться номер страницы, а также
(Нижний колонтитул страницы, итоговые значения для данной страницы отчета
или "подвал")
Summary (Итоги) Информация из этой полосы печатается один раз
и содержит итоговые значения по всему отчету

Итак, приступим. Для отчета, как и для экранной формы, необходимо оп­
ределить среду данных. Для этого можно воспользоваться пунктом контек­
стного меню, вызываемого нажатием правой кнопки мыши, или воспользо­
ваться командой Data Environment (Среда данных) из пункта View (Вид)
системного меню. Откроется уже знакомое диалоговое окно Data Environ­
ment. Все действия по добавлению в среду окружения отчета таблиц или
видов полностью аналогичны тем, которые мы выполняли для создания
среды данных для экранной формы.

Размещение в отчете
элементов управления
Начнем с размещения простого текста. Для этого на панели инструментов
Report Controls (Элементы управления отчетом) выберем кнопку Label
Урок 11. Создание отчетов 115

(Текст) и, указав предполагаемое место расположения объекта, нажмем ле­


вую кнопку мыши. Все, объект вставлен в отчет, и теперь можно набрать
текст с клавиатуры.
разместим наш первый текст в области Page Header (Верхний колонти­
тул) — рис. 11.4.

Рис. 11.4. Мы разместили текст в отчете

Теперь мы можем изменить размер шрифта, сам шрифт и цвет объекта. Для
этого выберем его, щелкнув мышью, и воспользуемся пунктом Font
(Шрифт) из меню Format (Формат) — рис. 11.5.
Но здесь нужно учесть следующее обстоятельство: не рекомендуется ставить
экзотические" шрифты — на машине пользователя их может не оказаться,
и в результате вместо красивого отчета может получиться набор непонятных
закорючек". Лучше ограничиться стандартным "джентльменским" набором
Шрифтов — Times New Roman, Courier, Arial — они установлены практиче­
ски у всех.
А вот при двойном щелчке на тексте открывается диалоговое окно Text
(Текст) — рис. 11.6.
116 Часть I. Процедурное программирование в Visual FoxPro

Рис. 11.5. Диалоговое окно Шрифт

Рис. 11.6. Диалоговое окно Text

В данном окне можно разместить комментарии для объекта и задать усло-j


вия печати (кнопка Print When), а группа переключателей Object position|
(Позиция объекта) позволяет определить расположение объектов:
• Float — при изменении размеров или положения соседних объектов по­
ложение данного объекта также изменится;
• Fix relative to top of band — объект "прикрепляется" к верхней границе
полосы;
• Fix relative to bottom of band — объект "прикрепляется" к нижней границе
полосы.
Урок 11. Создание отчетов 117

Размещение в отчете полей


Теперь будем размещать объекты в полосе Detail (Детали). Именно здесь
нам необходимо разместить поля из нашей таблицы (ты не забыл добавить
ее в среду данных?). Поля можно просто перетаскивать в любую полосу из
среды данных, а можно опять же воспользоваться панелью инструментов
Report Designer.
Выберем кнопку Field (Поле) и щелкнем мышью в полосе Detail (Детали).
Появится диалоговое окно Report Expression (Выражение отчета) (рис. 11.7).
Данное окно позволяет задать выражение, которое будет вычисляться перед
печатью и результат которого будет отображаться в отчете, определить фор­
мат отображения данных, задать условия печати и установить расположение
объектов в отчете.

Рис. 11.7. Диалоговое окно Report Expression

Поля таблицы или выражение задаются в поле ввода Expression (Выраже­


ние), а формат данных — в поле Format (Формат). Данные в поле Expression
можно как ввести с клавиатуры, так и воспользоваться диалоговым окном
Expression Builder (Построитель выражения), которое вызывается при нажа­
тии кнопки, расположенной справа от этого поля ввода.
Определение выражений мы рассмотрим, когда начнем работать с базой
Данных, а пока просто познакомимся с диалоговым окном Expression Builder
(Рис. 11.8).
В списке Fields (Поля) отображаются поля всех таблиц, включенных в среду
Данных отчета. Список Variables (Переменные) содержит системные пере­
менные Visual FoxPro, но также может содержать и переменные, определен-
118 Часть I. Процедурное программирование в Visual FoxPro

ные пользователем. В области Functions (Функции) находится четыре рас­


крывающихся списка, в которых перечислены строковые, математические,
логические функции FoxPro, а также функции даты и времени.

Рис. 11.8. Диалоговое окно Expression Builder

Так как мы договорились, что пока не будем использовать выражения, ог-


раничимся тем, что просто перенесем необходимое поле из таблицы в поле)
ввода Expression for Field on Report (Выражение для поля отчета). Для этого,
достаточно просто дважды щелкнуть на имени поля в списке Fields. Поле
переносится в область Expression for Field on Report, и мы можем смело на
жать кнопку ОК. Смело потому, что мы в принципе не могли ошибиться,
ведь выражение как таковое отсутствует, мы просто занесли сюда имя поля,
здесь и проверять нечего. А вот при формировании какого-нибудь сложного
выражения будет весьма полезно сначала нажать кнопку Verify (Проверка).
Если в выражение что-то неверно, будет выведено сообщение об ошибке.

Формат данных
Диалоговое окно Format (Формат) (рис. 11.9) вызывается нажатием кноп­
ки, расположенной справа от поля ввода Format окна Report Expression
(см. рис. 11.7).
Формат отображения поля при печати можно и не задавать, воспользовав-
шись установками по умолчанию, но при работе с этим диалоговым окном
можно, например, перевести все строчные символы в прописные, показати
Урок 11. Создание отчетов 119

в числах десятичные запятые, преобразовать формат даты и сделать многое


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

Рис. 11.9. Диалоговое окно Format

Флажки, расположенные в данном окне, позволяют задать параметры, опи­


санные в табл. 11.3—11.5.

Таблица 11.3. Параметры для символьных выражений

Флажок Описание

То upper case Преобразует все строчные символы в прописные


(К верхнему регистру)
Set Date format Данные отображаются в виде даты, определенной
(Установить формат даты) К о м а н д о й SET DATE

Ignore input mask На экране данные отображаются, но в заданном


(Игнорировать маску ввода) формате сохранены не будут
Left justify (Сдвиг влево) Информация в поле будет выровнена по левой гра­
нице поля
Right justify (Сдвиг вправо) Информация в поле будет выровнена по правой гра­
нице поля
_Center justify (По центру) Информация в поле располагается по центру

Таблица 11.4. Параметры для числовых данных

Флажок Описание
Left justify (Сдвиг влево) Информация в поле будет выровнена по левой гра­
нице поля
120 Часть I. Процедурное программирование в Visual FoxPro

Таблица 11.4 (окончание)

Флажок Описание

Blank if zero При печати нуль не будет выводиться


(Пусто, если нуль)
(Negative) Если число отрицательное, оно заключается в скобки
(Отрицательное значение)

SET DATE format Данные отображаются в виде даты, определенной


(Установить формат даты) командой SET DATE

British date (Европейская Данные отображаются в виде даты в европейском


дата) формате (British)
CR if positive (Кредит, если Если число положительное, то в этом случае после
положительное значение) числа ставится CR (Кредит)
DB if negative (Дебет, если Если число отрицательное, то в этом случае после
значение отрицательное) числа ставится DB (Дебет)
Leading zeroes Отображаются все ведущие нули
(Ведущие нули)
Currency (Денежный) Данные отображаются в формате денежной едини­
цы (Команда SET CURRENCY)

Scientific Число отображается в экспоненциальной форме


(Экспоненциальный)

Таблица 11.5. Параметры для данных типа Date

Флажок Описание

Set Date format Данные отображаются в виде даты, определенной


(Установить формат даты) КОМаНДОЙ SET DATE

British Date Данные отображаются в виде даты в европейском


(Европейская дата) формате (British)

Определение условий печати


Чтобы определить, при выполнении каких условий данные будут выведен»
на печать, используется диалоговое окно Print When (Условия печатй|
(рис. 11.10), вызываемое нажатием кнопки Print When в окне Яероц
Expression (см. рис. 11.7).
Чтобы запретить вывод на печать повторяющихся значений полей, необхб|
димо установить переключатель Print repeated values (Печать повторяющие
Урок 11. Создание отчетов 121

ся значений) в положение No (Нет). При установке по умолчанию — Yes


(Да) — печатаются все значения поля.

Рис. 11.10. Диалоговое окно Print When

Область Also print (А также печатать) содержит следующие флажки:


• In first whole band of new page/column — печать на первой полосе сле­
дующей страницы или колонки;
• When this group changes — поле будет печататься при изменении указан­
ной группы. Группа указывается в раскрывающемся списке;
• When detail overflows to new page/column — печать при переходе полосы
Detail (Детали) на новую страницу/колонку.
При установке флажка Remove line if blank из отчета будут удалены пустые
строки.
В поле Print only when expression is true задается выражение, которое вычис­
ляется перед выводом отчета на печать. Если данное выражение верно
(true) — значение поля выводится на печать.
Такое количество параметров в одном только окне Report Expression (Выра­
жение отчета) (см. рис. 11.7) способно испугать хоть кого... Но не так стра­
шен черт, вполне вероятно, что о некоторых из них ты никогда и не вспом­
нишь, успешно обходясь без их использования.
Продолжая создавать наш первый отчет, ты уже можешь для размещения
полей использовать построитель выражений, но т. к. последние фактически
отсутствуют, можно просто перетащить мышью поля из среды окружения и
Добавить остальные необходимые объекты. Кстати, границы полос можно
Ле
гко изменять, также их перетаскивая.
•эким образом, научившись размещать в отчете некоторые объекты, по­
смотрим, что получится — рис. 11.11.
122 Часть I. Процедурное программирование в Visual FoxPro

Рис. 11.11. Поля таблицы добавлены в отчет

Замечание
Любое поле можно редактировать с помощью диалогового окна Report Expres­
sion, дважды щелкнув мышью на этом поле.

Размещение в отчете линий и контуров


Для размещения в отчете таких объектов, как линии и контуры, также ис-
пользуется панель инструментов Report Controls (Элементы управления от­
чета). Для размещения линии необходимо выбрать соответствующую кнопку
и, указав мышью положение начальной точки, просто "протащить" линию
необходимой длины. В случае размещения в форме объектов в виде прямо­
угольников действия аналогичные: указав начальную точку, "рисуем" контур-.

Заголовок отчета и итоговые значения


Для размещения в отчете заголовка необходимо воспользоваться командой
меню Report ( Title/Summary (Отчет | Титул/Итоговые значения).
Урок 11. Создание отчетов 123

Рис. 11.12. Диалоговое окно Title/Summary

Появится диалоговое окно Title/Summary (рис. 11.12), в котором для раз­


мещения в отчете полосы заголовка Title отметим флажок Title band, а для
размещения полосы итоговых значений, соответственно, Summary band.
Зададим для нашего отчета заголовок и разместим в нем объект в виде пря­
моугольного контура (рис. I I.J3).

Рис. 11.13. Полоса Title

Используя команду Fill (Заливка) из меню Format (Формат), мы можем вы­


брать стиль заполнения объекта. Но при этом может получиться, что наш
текст или другие объекты будут скрыты за контуром. Исправить это
"безобразие" можно, воспользовавшись командой Send To Back (Поместить
на задний план) все того же меню Format.
За атрибуты контуров и линий отвечают параметры, определяемые при вы­
зове меню Реп (Перо) (табл. 11.6).

Таблица 11.6. Параметры атрибутов контуров и линий

Параметр Атрибут

Hairline (Тонкая линия) Ширина линии — один пиксел


1 Point (Один пункт) Ширина линии — один пункт
2 Point (Два пункта) Ширина линии — два пункта
4 Point (Четыре пункта) Ширина линии — четыре пункта
124 Часть I. Процедурное программирование в Visual FoxPro

Таблица 11.6 (окончание)

Параметр Атрибут

6 Point (Шесть пунктов) Ширина линии — шесть пунктов


None (Нет) Контур не имеет обрамления
Dotted (Пунктир) Обрамление в виде пунктирной линии
Dashed (Штрих) Обрамление в виде чередующихся штрихов
Dash-dot (Штрих-точка) Обрамление типа "штрих-точка"
Dash-dot-dot (Штрих-точка-точка) Обрамление типа "штрих-точка-точка"

Итоговые значения мы разместим в полосе Summary, хотя для этого можно


использовать любую полосу отчета. Воспользовавшись командами копиро­
вания (Сору) и вставки (Paste), скопируем в буфер обмена любое поле из
области Detail и вставим его в полосу Summary. Дважды щелкнув мышью на
вставленном объекте, откроем уже знакомое диалоговое окно Report Expres­
sion и нажмем кнопку Calculations (Вычисления), после чего появится диа­
логовое окно Calculate Field (Вычисляемое поле) (рис. 11.14).

Рис. 11.14. Диалоговое окно Calculate Field

Теперь мы можем определить, какая операция будет проводиться с данным |


объектом, установив соответствующую опцию (табл. 11.7).

Таблица 11.7. Возможные операции с объектом

Опция Описание
Nothing (Ничего) Никакие вычисления не производятся
Count (Количество) Вычисляется количество обращений Visual FoxPro
к данному объекту при формировании отчета 1
Урок 11. Создание отчетов 125

Таблица 11.7 (окончание)

Опция Описание

Sum (Сумма) Сумма значений элемента


Averange (Среднее значение) Среднее значение
Lowest (Минимальное значение) Минимальное значение из всех
Highest (Максимальное значение) Максимальное значение из всех
Standard deviation Страшно даже сказать: это "квадратный корень
(Стандартное отклонение) из дисперсии значений"
Variance (Дисперсия) Статистическая величина отклонений значений
от среднего значения

Для подсчета количества уравнений установим опцию Count (Количество).


Раскрывающийся список Reset (Сброс) позволяет определить, когда про­
изойдет обнуление итоговых значений:
• End of Report (Конец отчета) — именно ее и выберем;
• End of Page (Конец страницы).

Изменение цвета объектов в отчете


Для изменения цвета объекта можно использовать уже встречавшуюся нам
панель инструментов Color Palette (Палитра цветов).
Действия здесь точно такие же, как при "раскраске" объектов экранной
формы, поэтому мы не будем подробно останавливаться на этом пункте. Да
и вообще, прежде чем этим заниматься, неплохо бы поинтересоваться:
а есть ли у заказчика цветной принтер?

Размещение в отчете изображений


В отчетах можно размещать различные изображения, как из файлов, так и
из таблиц, содержащих поля General. Для этого нужно выбрать соответст­
вующую кнопку на панели инструментов Report Controls и щелкнуть
мышью в предполагаемом месте отчета. При этом откроется диалоговое ок­
но Report Picture (Изображение в отчете), в котором можно указать источ­
ник данных и настроить параметры изображения (рис. 11.15).
Источник данных указывается в области Picture from (Откуда картинка? Из
Файла, вестимо...).
Ьсли тебе известен полный путь к графическому файлу, можешь просто
в
вести его в поле ввода File (Файл). Если же сомневаешься, нажми кнопку
126 Часть I. Процедурное программирование в Visual FoxPro

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


(Открыть).
В поле ввода Field (Поле) указывается поле таблицы типа General.

Рис. 11.15. Диалоговое окно Report Picture

Параметры, устанавливаемые в разделе If picture and frame are different sizes


(Если картинка и рамка имеют различные размеры) имеют следующие зна-
чения:
• Clip picture (Обрезать изображение) — рисунок сохраняет первоначаль-
ные размеры;
• Scale picture, retain shape (Изменить масштаб, сохраняя форму) — рису­
нок заполнит всю рамку, сохраняя свои пропорции;
• Scale picture, fit the frame (Изменить масштаб, сохраняя рамку) — рису-
нок заполнит всю рамку, но при этом может быть искажен.
Примерный вид готового отчета в окне конструктора представлен на
рис. 11.16.

Просмотр отчета
Для просмотра отчета используется команда Preview (Просмотр) из контек-
стного меню или одноименная кнопка на стандартной панели инструмен-
Урок 11. Создание отчетов 127

Рис. 11.16. Готовый отчет в окне конструктора отчетов

Рис. 11.17. Отчет в режиме предварительного просмотра


128 Часть (. Процедурное программирование в Visual FoxPro

тов. При выборе данной команды отчет открывается для предварительного


просмотра — рис. 11.17.
Когда отчет открывается в режиме просмотра, на экране автоматически по~
является еще одна панель Print Preview (Предварительный просмотр отчета)
(рис. 11.18).
Кнопки, расположенные на данной панели, позволяют осуществлять нави­
гацию по страницам отчета, изменять масштаб отображения страниц, рас­
печатать отчет на принтере и закрыть окно предварительного просмотра.

Рис. 11.18. Панель Print Preview

Печать отчетов
Ты, наверное, уже привык к тому, что для выполнения какой-либо опера­
ции Visual FoxPro предоставляет в наше распоряжение минимум три раз-
личных способа. Вывод отчетов на печать не является исключением.
• Команда Print (Печать) из системного меню File (Файл).
П Команда Print (Печать) из контекстного меню.
• Команда Run Report (Запуск отчета) из меню Report (Отчет).
• Кнопка Print One Copy (Печать одной копии) на стандартной панели
инструментов.
• Комбинация клавиш <Ctrl>+<P>.
Результатом выполнения любой из этих операций является окно Print (Пе-
чать).
Расположенный в верхней части диалогового окна раскрывающийся список
Name (Имя) содержит имена всех доступных принтеров.
Установка переключателя в области Print range (Область печати) в положе­
ние All (Все) приведет к тому, что будут распечатаны все страницы отчета, Я
вот выбор Pages (Страницы) позволяет задать номера печатаемых страниц'-
from (от), to (до).
Используя счетчик Number of copies (Количество копий), можно задать ко-
личество печатаемых экземпляров.
При нажатии кнопки Properties (Свойства) можно настроить параметры
принтера, вид появляющегося при этом диалогового окна зависит от прин-
тера, установленного в системе (рис. 11.20).
Урок 11. Создание отчетов 129

Рис. 11.19. Диалоговое окно Print

Рис. 11.20. Диалоговое окно Свойства

Впрочем, принтер можно настроить и заранее, используя Панель управле-


н
ия Windows.
Кнопка Options (Параметры) из окна Print (см. рис. 11.19) позволяет вы­
полнить дополнительную настройку принтера (рис. 11.21).

Зак Ю02
130 Часть I. Процедурное программирование в Visual FoxPro

Рис. 11.21. Диалоговое окно Print Options

В области Print what (Что печатать) находится раскрывающийся список Туре


(Тип), в котором можно указать тип печатаемой информации. В поле File
(Файл) указан полный путь доступа к файлу.
Флажки имеют следующее назначение:
• Line numbers (Номера строк) — используется для печати в отчете нумера­
ции строк. Доступен при печати содержимого командного окна или фай-
ла;
• Page eject before (Прогон страницы перед печатью) — перед печатью от-
чета дает принтеру команду перехода на новую страницу;
• Page eject after (Прогон страницы после печати) — осуществляет перехс
на новую страницу после окончания печати;
• Restore environment (Восстановить среду данных) — эта "фишка" исполь-
зуется для совместимости со старыми версиями FoxPro.
Как ни странно, и в этом окне есть кнопка, также называемая Options (Па-
раметры). Используя данную кнопку, мы можем задать условия выборки
записей, предназначенных для вывода на печать. По нажатию этой кнопки
на экран выводится диалоговое окно Report and Label Print Options (Пара-
метры для печати отчетов и этикеток) (рис. 11.22), в котором можно задать
следующие параметры печати:
• Scope (Диапазон значений) — в этом списке выбирается диапазон печа-
таемых записей;
• For (Для) — запускается построитель выражений, в котором можно за-
дать логическое выражение. При этом будут печататься только те записи,
для которых значение этого выражение будет равным .Т. (Истина);
• While (Пока) — все, как в предыдущем пункте, но в отличие от него пе-
чать отчета будет прекращена как только встретится первая запись, ДЛЯ
которой значение этого выражения будет равным .F. (Ложь).
Урок 11. Создание отчетов 131

Рис. 11.22. Диалоговое окно Report and Label Print Options

Создание отчетов
с использованием мастера Report Wizard
Для запуска Report Wizard (Мастер отчетов) также имеется несколько спо­
собов — все они аналогичны тем, которые мы использовали при запуске
Form Wizard (Мастер экранных форм).
Независимо от способа запуска на экране появится первое диалоговое окно
мастера (рис. 11.23).

Рис. 11.23. Диалоговое окно Wizard Selection


132 Часть I. Процедурное программирование в Visual FoxPro

В этом окне опять, как и при использовании мастера форм, предлагается


сделать выбор мастера:
• One-to-Many Report Wizard — этот мастер создает отчет для связанных
таблиц;
О Report Wizard — простой отчет для одной таблицы.
Первый шаг работы мастера отчетов полностью идентичен первому шагу
работы мастера экранных форм — здесь мы выбираем таблицу и необходи­
мые поля (рис. 11.24).

Рис. 11.24. Первый шаг работы мастера отчетов

На втором шаге работы мастера (рис. 11.25) можно задать поля, по которым
будет производиться группировка данных в отчете. Поддерживается от од-]
ной до трех групп данных. Параметры группировки задаются так: в раскры­
вающемся списке указываем имя поля, а затем, нажимая кнопку Grouping]
options (Параметры группировки), задаем интервал группировки в диалого­
вом окне Grouping Intervals (рис. 11.26).
В раскрывающемся списке Grouping intervals (Интервал группировки) мож­
но выбрать следующие значения:
О Entire Field — полностью значение поля;
О 1st Letter — по первой букве;
• 2, 3, 4, 5 Initial Letters — по первым двум, трем и т. д. буквам.
Кнопка Summary Options (Итоговые значения) вызывает диалоговое окно
Summary Options, в котором можно сформировать итоговые значения ДЛЯ
каждого поля (рис, 11.27).
Урок 11. Создание отчетов 133

Рис. 11.25. Второй шаг — группировка данных

Рис. 11.26. Диалоговое окно Grouping Intervals

В расположенной в этом окне таблице выбираем имя поля и ставим "птич-


К
У" в нужном столбце.
Значения столбцов:
О Field — имя поля;
^ Sum — сумма значений;
134 Часть I. Процедурное программирование в Visual FoxP/qj

Рис. 11.27. Диалоговое окно Summary Options

• Avg — среднее значение;


• Count — число строк;
• Min — минимальное значение;
• Мах — максимальное значение.
Переключатели, расположенные под таблицей, управляют отображением
в отчете полос.
На третьем шаге выбирается стиль отчета (рис. 11.28).

Рис. 11.28. Третий шаг работы мастера отчетов

Шаг четвертый (рис. 11.29) — указывается положение страницы:


• Portrait — книжное расположение страницы на экране;
• Landscape — альбомное расположение страницы.
к 11. Создание отчетов 135
ш

Рис. 11.29. Четвертый шаг работы мастера отчетов

Рис. 11.30. Заключительный шаг работы мастера отчетов


136 Часть I. Процедурное программирование в Visual FoxPro

Также здесь указывается порядок размещения полей с помощью группы


переключателей Field Layout (Расположение поля).
Шестой и последний шаг мастера отчетов (рис. 11.30) аналогичен такому же
шагу мастера экранных форм.
Откроем предварительный просмотр, нажав кнопку Preview (Просмотр) —
рис. 11.31.

Рис. 11.31. Отчет, созданный мастером отчетов

Ну и что получилось? Применительно к нашей задаче — ничего хорошего^


Но зато мы познакомились с работой мастера отчетов, использование KOTOJ
рого в других приложениях может стать более чем оправданным. Мы еше]
вернемся к этому инструменту при работе с базой данных.
Использование дополнительных инструментов для создания отчетов, такЖ
как AutoReport Wizard и Quik Report, также будет изучено при создании на-j
шего следующего приложения.

Вызов отчета из формы


Теперь, когда мы узнали, как вывести отчет на печать, неплохо бы сделать
так, чтобы отчет печатался при нажатии на определенную кнопку экранно)
формы.
Урок 11. Создание отчетов 137

Откроем окно конструктора форм и определим действия, происходящие


при наступлении события click для кнопки Печать.
Вывод отчета на принтер выполняет следующая команда:
REPORT FORM (Путь) Имя_Отчета ТО PRINTER

Но при этом вывод информации может происходить как на принтер, так и


в окно экранной формы. Чтобы запретить вывод на экран, следует в данной
команде указать параметр NOCONSOLE:
REPORT FORM C:\EXAMPLES\REPORTl ТО PRINTER NOCONSOLE

Для открытия окна предварительного просмотра можно применить такую


конструкцию:
REPORT FORM C:\EXAMPLES\REPORTl PREVIEW

А еще можно поместить наш отчет в текстовом файле:


REPORT FORM C:\EXAMPLES\REPORTl ТО FILE TXT1.TXT ASCII

Но при этом все графические элементы отчета будут проигнорированы.


Преимуществом является то, что отчет в виде файла можно просматривать в
любом текстовом редакторе, например, используя даже встроенный редак­
тор текста в Norton Comander или Блокнот Windows (рис. 11.32).

Рис. 11.32. Просмотр отчета в виде текстового файла в Блокноте

А вот результат работы нашей кнопки Печать, в которой использована


команда REPORT FORM C:\EXAMPLES\REPORTI PREVIEW, показан на рис. 11.33.
Отчет находится в границах формы, потому что мы используем форму верх­
него уровня. Для перемещения по странице используются горизонтальная и
вертикальная линейки прокрутки.
о конструкции REPORT FORM... можно также задать условия для выборки
записей. Например, для того чтобы просмотреть или распечатать только те
Уравнения, которые имеют два корня, достаточно ввести следующую команду:
REPORT FORM REPORTI PREVIEW FOR D>O
138 Часть I. Процедурное программирование в Visual FoxPro

Рис. 11.33. Режим просмотра включается из нашей формы


УРОК 12

Компиляция проекта

Теперь, когда практически все готово, можно перейти к созданию испол­


няемого приложения. Для формирования файла приложения с расширени­
ем арр или исполняемого файла, имеющего расширение ехе, достаточно
щелкнуть на кнопке Build (Построить) в диалоговом окне Project Manager.
Но прежде необходимо отметить главный файл, который будет использо­
ваться в качестве первого файла при генерации проекта. Главный файл ус­
танавливается при помощи команды Set Main (Установить главным) пункта
Project (Проект) линейки системного меню или одноименной команды кон­
текстного меню, вызываемого нажатием правой кнопки мыши. Файл, отме­
ченный как главный, выделяется полужирным шрифтом. Обычно в качестве
главного файла выступает меню, но таким элементом может быть практиче­
ски любой файл проекта. В нашем случае применим команду Set Main
к файлу нашей экранной формы Formi (рис. 12.1).
После нажатия кнопки Build открывается диалоговое окно Build Options
(рис. 12.2).
Используя группу переключателей Action (Действия) мы указываем те дей­
ствия, которые будут происходить при запуске процесса компиляции:
• Rebuild Project (Перестроить проект) — при выборе этой опции файл
проекта полностью заново перестраивается, при необходимости вновь
добавленные в проект файлы компилируются;
• Build Application (Создать приложение) — создается файл приложения с
расширением арр. Приложение будет работать только на тех компьюте­
рах, на которых установлен полный пакет Visual FoxPro;
• Build Executable (Создать исполняемый файл) — а вот это уже всем зна­
комый "ЕХЕ-шник"! В общем, все операции, происходящие при форми­
ровании данного файла, аналогичны тем, которые происходят при фор­
мировании файла приложения арр, но при этом еще добавляются при­
сущие ЕХЕ-файлам элементы: загрузчик и заголовок файла. Для работы
140 Часть I. Процедурное программирование в Visual FoxPro

данного файла также требуется наличие необходимых библиотек Visual


FoxPro (Vfp6renu.dll и Vfp6r.dll);
• Build COM DLL (Создать библиотеку) — создается файл с расширение
dll (Dynamic Link Library, динамически подключаемая библиотека).
Параметры, устанавливаемые в группе Options диалогового окна Buil
Options, имеют следующее назначение:
О Recompile All Files (Перекомпиляция всех файлов проекта) — заново
компилируются все включенные в проект файлы, независимо от времени
их создания;

Рис. 12.1. С помощью команды контекстного меню устанавливаем главный файл приложения

Рис. 12.2. Диалоговое окно Build Options


Урок 12. Компиляция проекта 141

О Display Errors (Просмотр ошибок) — вся информация об ошибках, воз­


никающих при компиляции приложения, заботливо складывается Лисом
в одном файле — этот файл имеет расширение err. При установке данно­
го флажка после завершения процесса компиляции ERR-файл будет от­
крыт для просмотра;
О установка флажка Run After Build (Запуск после создания) приведет к
тому, что после завершения компиляции приложение будет сразу запу­
щено на выполнение;
О при установке флажка Regenerate Component IDs (Перестроить иденти­
фикаторы компонентов) происходит установка и регистрация Auto­
mation-серверов, которые могут содержаться в проекте. Данный флажок
доступен при установленной опции Build COM DLL или Build Executable.
Для того чтобы включить файл проекта в процесс компиляции, или, наобо­
рот, исключить — используются команды контекстного меню Include
(Включить) и Exclude (Исключить). Исключенные файлы отображаются ря­
дом с перечеркнутым кружком.
Тебя, вероятно, уже насторожили фразы о том, что для работы твоего при­
ложения на "чужом" компьютере необходимо присутствие на нем Visual
FoxPro: "Это что же творится, люди добрые?! Ночами не спишь, создаешь
приложения, а потом еще на каждый компьютер своего Лиса ставить?!"
Не все так трагично, дружок. Дело в том, что состав Visual FoxPro входит
замечательное средство — Setup Wizard, с помощью которого ты за шесть
секунд создашь фирменную программу установки, в которую будут входить
как твое приложение, так и необходимые для его работы "фоксовские" фай­
лы. И все всегда везде и у всех будет работать.
Ну а теперь давай построим наше первое приложение, пусть это будет файл
с расширением арр. Установив необходимые параметры, нажмем кнопку
Build диалогового окна Project Manager. В открывшемся диалоговом окне
Save As (Сохранить как) укажем имя приложения и папку, в которой оно
будет сохранено, после чего запустится процесс генерации приложения.
Через несколько секунд компиляция будет закончена, и в строке состояния
появится сообщение "Build application completed", после чего можно закон­
чить работу с Visual FoxPro и запустить приложение (рис. 12.3).

Замечание
При создании нашей экранной формы мы определили ее как форму верхнего
уровня, поэтому для того чтобы она выполнялась не в окне FoxPro, а прямо на
рабочем столе Windows, можно перед началом компиляции включить в свойст­
во i n i t следующую команду:
SCREEN.VISIBLE=.F.
142 Часть I. Процедурное программирование в Visual FoxPro

Рис. 12.3. Приложение выполняется на Рабочем столе Windows


урок 13

Работа с базой данных

Что такое база данных? В начале книги было дано определение базы дан­
ных, так сказать, с "обывательской" точки зрения. А вообще под базой дан­
ных в Visual FoxPro подразумевается совокупность таблиц, которые могут
каким-то образом быть связанными между собой. А могут быть и не свя­
занными. А можно вообще обойтись без использования баз данных, успеш­
но применяя для решения поставленных задач свободные таблицы.
Так для чего тогда усложнять себе жизнь? Все дело в том, что использова­
ние баз данных не усложняет, а, наоборот, значительно упрощает работу с
данными. Это происходит потому, что именно в базе данных реализованы
мощные и полезные функции, используемые при работе с таблицами.
Создать новую базу данных можно так же, как и любой другой файл Visual
FoxPro. Мы уже подробно рассматривали процесс создания новых файлов,
повторяться не будем. Действия полностью аналогичны, за исключением
того, что в открывающихся диалоговых окнах необходимо указать опцию
Database (База данных). При использовании командного окна применяется
следующая команда:
CREATE DATABASE <имя_файла>

При работе с использованием окна диспетчера проекта (Project Manager)


Для создания новой (кнопка New) или модификации существующей базы
Данных (кнопка Modify) применяется конструктор базы данных — Database
Designer.

Конструктор базы данных


В окне конструктора базы данных (рис. 13.1) расположена панель управ­
ления Database Designer. Назначение кнопок данной панели описано в
табл. 13.1.
144 Часть I. Процедурное программирование в Visual FoxPro

Рис. 13.1. Окно конструктора базы данных с панелью инструментов Database Designer

Таблица 13.1. Кнопки панели Database Designer


Урок 13. Работа с базой данных 145

Таблица 13.1 (окончание)

Сейчас мы начнем создавать новое приложение, в котором рассмотрим ас­


пекты работы с базой данных. Назовем его отель Старый Лис. Вряд ли это
приложение (по крайней мере, именно в таком виде) найдет применение в
практической жизни, но это и не особо важно. Наша цель — познакомиться
с принципами работы с базой данных, с остальными элементами управле­
ния экранных форм и т. д.
Но, прежде чем приступить к работе, поговорим о следующем: как нам ор­
ганизовать файлы? Когда мы делали наше самое первое приложение, мы
располагали все файлы в одной папке. Так можно делать, если файлов не
очень много. А если их сотни, тысячи? Тут необходимо их как-то рассорти­
ровать по типам: формы в одной папке, отчеты в другой и т. д. Уловил
мысль? Обычно в основном каталоге (папке), где "лежит" твое приложение,
создается несколько подкаталогов, например: Database, Forms, Menus, Progs,
Images, Others и т. д. И теперь всем, а тебе в первую очередь, ясно, где ка­
кой файл находится. Все это не догма, можешь делать, как хочешь, но
предложенный способ, несомненно, поможет придать твоему приложению
более стройный вид.
Начнем с того, что создадим новую таблицу базы данных. Нажав кнопку
New (Новая) на панели инструментов Database Designer и указав в открыв­
шемся диалоговом окне Create (Создать) имя новой таблицы, мы увидим
уже знакомое окно Table Designer (Конструктор таблицы) (рис. 13.2).
Окно вроде как бы знакомое, да что-то не то, не правда ли? Мы видим, что
Данный инструмент "обзавелся" дополнительными возможностями.
О Формат данных и маска ввода (поля ввода Format и Input mask) позво­
ляют задать формат представления значений поля и маску ввода.
О Заголовок поля (поле ввода Caption). По умолчанию при просмотре таб­
лиц в режиме BROWSE в качестве заголовка поля FoxPro использует имя
поля. Теперь мы можем изменить эту ситуацию, вводя для каждого поля
его заголовок в поле ввода Caption.
Q Контроль данных на уровне поля. Условие или правило можно как вве­
сти непосредственно в поле ввода Rule (Правило), так и используя уже
146 Часть I. Процедурное программирование в Visual FoxPro

знакомое нам диалоговое окно Expression Builder (Построитель выраже­


ния), нажав для его вызова расположенную справа от поля кнопку с тре­
мя точками.
• В поле ввода Message (Сообщение) можно задать сообщение, которое
будет отображаться на экране при несоблюдении условия, указанного в
поле Rule.
• Для любого поля можно задать значение по умолчанию, например, сис­
темную дату (Default value).

Рис. 13.2. Диалоговое окно Table Designer

Поле Field comment (Комментарий для поля) используется для ввода ком­
ментария для данного поля. Длина комментария может быть произвольной,
т. к. этот элемент представлен в виде поля Memo.

Индексы
Индексы используются для сортировки записей и организации связей меж­
ду таблицами, а также для ускорения доступа к данным. Индексы в Visual
FoxPro хранятся в файлах, имеющих расширение cdx — это так называемые
составные индексные файлы. В ранних версиях использовалось расширение
idx, или простой индексный файл, который мог содержать только одно ин­
дексное выражение.
Урок 13. Работа с базой данных 147

Простые индексы
Простые индексы, состоящие из одного индексного выражения, использо­
вались в FoxBase — предшественнике Visual FoxPro. В те древние времена
для каждого индексного выражения использовался отдельный индексный
файл. Вот и приходилось почти всегда при открытии таблиц специально
открывать вместе с таблицей и все ее индексы. Для чего это делалось? Все
просто — если не открыть необходимый индексный файл, Лис не сможет
его модифицировать при добавлении или удалении записей из таблицы —
он просто его не "увидит", ведь не могут все индексные файлы иметь имена,
совпадающие с именем таблицы!
В настоящее время уже как бы принято за правило использовать составные
или структурные индексы.

Составные индексы
Никто не запрещает использовать в приложениях простые индексы с рас­
ширением idx, но применение составных индексов кажется более предпоч­
тительным и вот почему:
• в один индексный файл можно включить несколько индексных выраже­
ний;
• если индексному файлу присвоить имя таблицы, то он всегда будет от­
крываться вместе с таблицей — потерять такой файл невозможно;
• структурный индекс всегда автоматически привязывается к "своей" таб­
лице.
Из чего состоит индексный файл? Файлы данного типа могут содержать
один или несколько тегов. Тег (Tag) — это и есть индексное выражение.
Чтобы узнать, какие именно теги используются в индексе, можно восполь­
зоваться функцией TAG о, которая возвращает имя тега. А вот сколько этих
самых тегов — подскажет функция TAGCOUNT (). Узнать имя самого индекс­
ного файла можно, применив функцию CDX () или аналогичную ей MDX ().
В Visual FoxPro имеется четыре типа индексов:
О Primary (Первичный). В таблице может быть только один первичный ин­
декс (иногда его называют первичным ключом), который позволяет вво­
дить только уникальные значения данного поля;
О Candidat (Кандидат или потенциальный). Также позволяет вводить толь­
ко уникальные значения поля, но в отличие от индекса Primary таблица
может иметь несколько индексов такого типа;
О Regular (Регулярный или простой). Данный индекс может быть создан
для любого значения поля;
148 Часть I. Процедурное программирование в Visual FoxPro

• Unique (Уникальный). Может быть создан только для неповторяющихся


значений поля. Как и Regular, данный индекс широко применялся в[
ранних версиях FoxPro.
Теперь перейдем к практике и создадим в нашей базе данных три таблицы.
Для этого откроем окно конструктора базы данных и, воспользовавшись
кнопкой New Table (Новая таблица) панели Database Designer, создадим
таблицу Countries.dbf со структурой, отображенной в табл. 13.2.

Таблица 13.2. Countries.dbf

Тип поля Имя поля Заголовок

Integer (4) IDcountry Идентификатор


Character (10) cCountry Страна

Таким же образом создадим таблицы Cities.dbf (табл. 13.3), Streets.dbf


(табл. 13.4).

Таблица 13.3. Cities.dbf

Тип поля Имя поля Заголовок


Integer (4) Idcountry Идентификатор
Character (30) CCity Город
Integer (4) idcity Идентификатор города

Таблица 13.4. Streets.dbf

Тип поля Имя поля Заголовок


Integer (4) Idcity Идентификатор города
Character (10) cStreet Улица

И проиндексируем их следующим образом:


• таблица Countries.dbf:
TAG: Idcountry Primary INDEX ON : idcountry
TAG: country Regular INDEX ON: country

• таблица Cities.dbf:
TAG: idcountry Regular INDEX ON: Idcountry
TAG: ccities Regular INDEX ON: ccities
TAG: idcity Candidate INDEX ON: idcity
Урок 13. Работа с базой данных 149

0 таблица Streets.dbf:
TAG : i d c i t y Regular INDEX ON : i d c i t y
TAG: s t r e e t Regular INDEX ON: s t r e e t

Рассмотрим подробно процесс индексации на примере создания индексов


для таблицы Countries.dbf. В окне конструктора таблиц (Table Designer) пе­
рейдем на вкладку Indexes (Индексы). В поле Name вводим имя индекса, а
из раскрывающегося списка Туре (Тип) выберем необходимый тип. Затем,
нажав кнопку справа от поля ввода Expression (Выражение), вводим значе­
ние индексного выражения в окне построителя выражений. Но в данном
примере мы не будем применять сложные выражения и просто зададим
имена полей (рис. 13.3).

Рис. 13.3. Создание индексов в окне конструктора таблиц

Вот теперь, когда созданы таблицы и соответствующие индексные файлы,


можно перейти к следующему шагу.

Создание постоянных отношений


Отношения (Relation) могут быть временными и постоянными. Вся разница
состоит во времени "жизни" и способа их создания.
150 Часть I. Процедурное программирование в Visual FoxPro

Временные отношения создаются командой SET RELATION (имеющей много


дополнительных параметров) и существуют только в текущем сеансе Visual
FoxPro. После завершения работы созданные таким образом отношения
"приказывают долго жить". Такого же результата можно добиться, введя
команду SET RELATION без параметров.
Постоянные же отношения создаются в конструкторе базы данных и сохра­
няются после сеанса работы.
Для создания отношений между таблицами (а говоря проще, для того чтобы
связать их) необходимо, чтобы таблицы были соответствующим образом
проиндексированы. Это, как ты уже догадался, обязательное условие! Также
нужно соблюдать еще одно правило: таблица, с которой начинаем установку
отношений, должна иметь индекс типа Primary или candidate, потому что
никак не получится создать отношение, начав с регулярного индекса.
Теперь от слов переходим к делу: открой конструктор базы данных
(рис. 13.4). На каждой из трех таблиц после списка полей изображены име­
на индексов. Таблица countries содержит рядом с именем индекса изобра­
жение ключика. Вот это и есть так называемый первичный ключ, именно
с него мы начнем связывать таблицы.
Процесс создания отношений довольно прост — щелкаем мышью на имени |
индекса и тащим его к индексу в другой таблице (в нашем случае к cities).
Все, отношение установлено. Таким же образом свяжем таблицу cities]
С таблицей s t r e e t s .

Рис. 13.4. Установка отношений между таблицами

Таблица countries является родительской таблицей (parent table) по отно­


шению к таблице cities, которая, в свою очередь, является дочерней (child
table) по отношению к таблице countries. Но таблица c i t i e s является одно­
временно и родительской по отношению к таблице streets. Сложно? А ты
как думал! Здесь только три таблицы, а если бы их было сто тридцать три,
знаешь, какое можно "генеалогическое дерево" нарисовать!
Итак, шутки в сторону, что мы имеем? Таблицы связаны, связи отобража­
ются линиями, заканчивающимися тремя штрихами. Эти штрихи показы-
Урок 13. Работа с базой данных 151

вают, что в данном случае имеет место связь "один-ко-многим" (one-to-


many).
Что же будет происходить, когда мы начнем перемещаться по записям таб­
лицы countries? При этом "на другой стороне" отношения, в таблице горо­
дов cities, будут отображаться только те города, которые относятся к стра­
не, выбранной в таблице countries. А это и определяется значением индек­
са idcountry. Так как в любой стране имеется как минимум два города,
в данном случае применяется именно отношение "один-ко-многим".
Ты спрашиваешь, какие еще бывают отношения? Еще есть отношение
"один-к-одному". При таком виде связи указатель в дочерней таблице оста­
новится на первой встретившейся записи, имеющей такое же значение ин­
декса, что и запись в родительской таблице. Связь типа "один-к-одному"
установится в том случае, если мы будем связывать таблицы по их первич­
ным ключам, которые имеют уникальные, неповторяющиеся значения. Во
всех остальных случаях будет автоматически установлено отношение "один-
ко-многим".
Для редактирования связей между таблицами используется диалоговое окно
Edit Relationship (Редактирование отношений) (рис. 13.5). Для его вызова
достаточно дважды щелкнуть на линии, отображающей отношение, или
воспользоваться соответствующей командой контекстного меню.

Рис. 13.5. Диалоговое окно Edit Relationship

Ну вот, все готово и можно с удовлетворением вздохнуть. Ан нет, не все


спокойно в мире! Попробуй, измени значение поля idcountry для какой-
нибудь записи в таблице countries (теоретически, записей пока нет). Что же
тогда произойдет с записями в связанной с ней таблицей cities? В физиче­
ском смысле — ничего с ними не случится, а вот что касается отношений —
здесь нас поджидает неприятность — Лис просто не найдет эти записи.
Чтобы избежать подобной ситуации, необходимо каким-то образом сделать
т
ак, чтобы при изменении значений индексов в родительской таблице авто­
матически обновлялись соответствующие индексы в дочерних таблицах.
Другими словами, необходимо обеспечить ссылочную целостность базы
Данных.
152 Часть I. Процедурное программирование в Visual FoxPro

Для этой цели в Visual FoxPro имеется инструмент, называемый Referential


Integrity Builder (Построитель ссылочной целостности).

Referential Integrity Builder


Для вызова Referential Integrity Builder достаточно щелкнуть правой кнопкой
мыши на линии, отображающей связь между таблицами, и выбрать команд
контекстного меню Edit Referential Integrity (Редактировать ссылочную це
лостность).
После выбора данной команды открывается окно построителя (рис. 13.6).

Рис. 13.6. Диалоговое окно Referential Integrity Builder

В данном окне есть три вкладки: Rules for Updating (Правила при обновле**
нии), Rules for Deleting (Правила при удалении) и Rules for Inserting (Пра-y
вила при вставке).
Внизу расположена таблица, в которой перечислены все отношения. В пер^
вом столбце этой таблицы указано имя родительской таблицы, а во вто*|
ром — дочерней. В трех следующих столбцах указаны правила соблюдение
1
ссылочной целостности для каждого конкретного случая: Update (Обновле*]
ние), Delete (Удаление), Insert (Вставка). В двух последних столбцах указа^
ны теги.
По умолчанию в трех столбцах (Update, Delete, Insert) установлено значенЖ
Ignore (Игнорировать) и никакая ссылочная целостность, естественно, пок
не соблюдается.
При щелчке мышью в любом из этих столбцов появляется меню, содержу
шее допустимые варианты поведения.
Урок 13. Работа с базой данных 153

Существуют следующие правила поведения, которые могут быть использо­


ваны при изменении значений индекса в родительской таблице:
О Cascade (Каскадное изменение) — при изменении значения ключа в ро­
дительской таблице произойдет каскадное обновление соответствующих
индексов и в дочерней таблице. Это как раз тот случай, который мы рас­
сматривали ранее;
П Restrict (Ограничить) — обновление значений ключа в родительской таб­
лице невозможно, если имеются соответствующие значения в записях
дочерних таблиц;
О Ignore (Игнорировать) — правила ссылочной целостности не соблюдают­
ся и возможны любые изменения в значениях индексов.
Мы рассмотрели правила при обновлении, правила при удалении записей
полностью аналогичны.
А вот правила при вставке (Insert) следующие:
• Restrict (Ограничить) — не удастся вставить в дочернюю таблицу записи
в том случае, если в родительской таблице нет записей с таким же зна­
чением ключа;
О Ignore (Игнорировать) — разрешена вставка записей, ссылочная целост­
ность соблюдаться не будет.
В верхней части построителя расположена группа переключателей, при по­
мощи которых также можно реализовать все сказанное ранее.
Что же, давай разрешим обновление значений индекса в таблице c i t i e s
в случае обновления соответствующего индекса в родительской таблице
countries и обновление в таблице streets при изменении значений в таб­
лице cities.
Установив необходимые правила для соблюдения ссылочной целостности,
закроем диалоговое окно построителя, воспользовавшись кнопкой ОК. При
этом появится диалоговое окно, в котором Лис спросит, действительно ли
мы хотим сохранить произведенные изменения (рис. 13.7).

Рис. 13.7. Сохранение произведенных изменений

Ответим Да и после генерации соответствующего кода процесс определения


ссылочной целостности будет завершен.
Теперь, прежде чем приступить к заполнению наших таблиц, необходимо
Рассмотреть следующий важный вопрос — что такое идентификаторы?
154 Часть I. Процедурное программирование в Visual FoxPro

Идентификаторы
Практически любая таблица имеет поле, специально выделенное для хране­
ния значения, которое однозначно идентифицирует каждую запись. Вот это
и есть идентификатор, он же "первичный ключ" (primary key). Например,
в нашей таблице countries значение в поле idcountry соответствует назва­
нию страны. Значения в этом поле должны быть уникальными, неповто­
ряющимися — не может быть двух стран с одинаковым названием. В даль­
нейшем мы рассмотрим вопрос, каким образом можно реализовать автома­
тическую генерацию значений ключа при добавлении записей в таблицу, а
теперь поговорим вот о чем: значение идентификатора нежелательно ника­
ким образом связывать со значениями других полей. Что это значит? На­
пример, не нужно в качестве идентификатора фирмы использовать ее на­
звание: во-первых, оно может со временем измениться, а во-вторых, может
быть несколько компаний с одинаковыми названиями. Также нежелательно
в качестве идентификатора человека использовать номер его паспорта — та
же причина (человек существо беспокойное, он с легкостью может сменить
паспорт, герб, флаг и даже пол...).
В общем, идентификатор должен быть абсолютно абстрактной величиной,,
не подверженной никаким внешним воздействиям. Займись на досуге буд­
дизмом!
Теперь перед нами встает следующий вопрос: какого типа должны быть
идентификаторы: символьного или числового?
Рассмотрим и те и другие.
Преимущества числовых идентификаторов:
• всегда точное сравнение, не зависящее от длины поля;
• для получения нового значения идентификатора достаточно произвести
одну-единственную математическую операцию — "сложение", и не нуж­
но "выдумывать" никаких специальных функций.
Их недостатки:
• можно по неосторожности включить их в какие-то вычисления.
Преимущества символьных идентификаторов:
П они никогда не могут быть использованы в математических вычисле-!
ниях;
• использование в идентификаторе сочетания цифровых и алфавитных
символов значительно повышает его "емкость".
Их недостатки:
• для генерации нового значения необходимо использовать специальные
функции, здесь не удастся обойтись "простыми" математическими опера­
циями;
/
Урок 13. Работа с базой данных 155

- необходимо всегда точное сравнение значений (они могут занимать не


все поле целиком), как следствие, необходимо повсеместно использовать
функцию ALLTRIMO, которая убирает из выражения начальные и конеч­
ные пробелы.
Как видно, недостатки идентификаторов одного типа являются преимуще­
ствами другого, и наоборот.
Теперь обсудим такой вопрос: как произвести генерацию неповторяющихся
значений? Первое, что приходит на ум — метод последовательного увеличе­
ния. Просто берем последнее значение и увеличиваем его на какую-то ве­
личину. Обычно используется два варианта:
- в таблице находится последнее значение (максимальное) и вычисляется
следующее;
- последнее значение хранится в отдельной таблице. Просто берем его от­
туда и на его основе вычисляем следующее.
Рассмотрим первый вариант, когда последнее значение идентификатора на­
ходится непосредственно в таблице. Допустим, у нас есть форма с кнопкой,
при нажатии которой происходит добавление записи в таблицу. Код для
события click будет выглядеть примерно так, как описано в листинге 13.1.

Листинг 13.1. Первый вариант вычисления значения идентификатора

*переходим в рабочую о б л а с т ь , в которой открыта наша таблица


SELECT C o u n t r i e s
*проверяем, есть ли хотя бы одна запись. Функция RECCOUNT() возвращает
количество записей в таблице
IF RECCOUNT()=0
*если записей нет, добавляем новую запись и вводим первое значение
идентификатора
APPEND BLANK
REPLACE Idcountry WITH 1
ELSE
*если записи есть, переходим на последнюю
GO RECCOUNTO
*присваиваем значение идентификатора переменной
Lastid = Idcountry
Добавляем запись и устанавливаем новое значение идентификатора
APPEND BLANK
REPLACE Idcountry WITH Lastid +1
ENDIF

Спрашивается, почему для перехода на последнюю запись мы использовали


Go RECCOUNTO? Есть же команда GO BOTTOM! А все дело в том, что функция
156 Часть I. Процедурное программирование в Visual FoxPro

RECCOUNTO возвращает количество физических записей в таблице, в то время


как GO BOTTOM подвержена влиянию команд SET ORDER TO (порядок отобра­
жения индексированных записей) и SET FILTER TO (отображение записей,
удовлетворяющих условию). А посему при применении GO BOTTOM нам при­
шлось бы где-то запомнить значение тегов и фильтра, "снять" их, а после
перехода опять восстановить эти значения. А к чему нам лишние пробле­
мы? При использовании же данного метода максимальное значение иден­
тификатора всегда будет находиться в последней записи, его и искать не
надо.
Недостатком этой процедуры является то, что пользователь может удалить
какие-то записи, а затем при добавлении новых окажется, что данное зна-
чение идентификатора уже использовалось ранее. И если не задать условия
сохранения ссылочной целостности — сам понимаешь, к чему это может
привести.
Второй вариант: последнее значение идентификатора хранится в единст­
венной записи дополнительной таблицы, пусть это будет Myjast_id.dbf с
полем iast_id (integer) и одной пустой записью (листинг 13.2).

Листинг 13.2. Второй вариант вычисления значения идентификатора

SELECT Countries
APPEND BLANK
REPLA Idcountry WITH my__last_id . Last_id+1
SELECT My_Last_Id
REPLA Last_Id WITH countries . Idcountry
SELECT Countries

В этом случае мы можем не беспокоиться о том, что после удаления запи-|


сей из основной таблицы и последующем добавлении новых нам может
встретиться уже применявшееся ранее значение идентификатора.
Недостатком является то, что, применяя этот метод, так сказать, "в чистом]
виде", нам придется создавать для каждой таблицы свою дополнительную
таблицу, хранящую последнее значение идентификатора.
Никто, конечно, так не делает — все гораздо проще: просто нужно слегка)
"модернизировать" таблицу My_iast_id, добавив в нее поля с названиями,
совпадающими с псевдонимами всех необходимых таблиц, а потом изме--
нить код указанной ранее процедуры для каждой таблицы. В этом случае в
каждом поле будет находиться значение идентификатора только для "своей"
таблицы.
А если таблиц очень много, то для каждой писать почти одинаковый код?
Это "не есть хорошо!" А если приложение в процессе работы создаст новые
таблицы, например, используя команду COPY? А если...
Урок 13. Работа с базой данных 157

Да, вопросов может возникнуть множество. Поэтому вот тебе, дружок, поч­
ти универсальный рецепт на все случаи жизни.
Создаем дополнительную таблицу Lastid.dbf со следующей структурой —
табл. 13.5.

Таблица 13.5. Lastid.dbf

Тип поля Имя поля


Integer (4) lastid
Character (20) alias

И ПИШем ФУНКЦИЮ M y l a s t i d (ЛИСТИНГ 13.3).

Листинг 13.3. Функция M y l a s t i d

FUNCTION M y l a s t i d
PARAMETER a l i a s
IF TYPE ("Myalias")#"C".OR.EMPTY("Myalias")
Myalias=ALIAS()
ENDIF
SELECT Lastid
LOCATE FOR Lastid.Alias=Myalias
IF FOUND()=.T.
REPLACE Lastid.Lastid WITH Lastid.Lastid+1
ELSE
APPEND BLANK
REPLA Lastid.Alias WITH Myalias,Lastid.Lastid WITH 1
ENDIF
SELECT SMyalias
RETURN Lastid.Lastid

Вот и все! Теперь у нас есть всего одна таблица, которая хранит значения
идентификаторов для любого количества таблиц. Более того, данную функ­
цию мы запишем как хранимую процедуру, входящую в состав нашей базы
Данных.

Хранимые процедуры
Хранимая процедура — это программа или функция, которая определяется
Пользователем, т. е. тобой, и хранится в контейнере базы данных.
Создать хранимую процедуру можно так: выбрать в окне диспетчера проекта
баз
У данных, перейти в группу Stored Procedures (Хранимые процедуры)
158 Часть I. Процедурное программирование в Visual FoxPro

(рис. 13.8) и нажать кнопку New (Новая). После этого откроется окно ре­
дактирования хранимых процедур, в котором могут содержаться как про­
цедуры, созданные тобой ранее, так и автоматически сгенерированные Vis­
ual FoxPro. (Лис автоматически создает процедуры и функции при опреде­
лении условий ссылочной целостности базы данных.)

Рис. 13.8. Группа Stored Procedures содержит хранимые процедуры

Как записать свою процедуру? Очень просто — если окно редактирования)


хранимых процедур пустое, просто бери и пиши в нем свой код. А если там
уже есть ранее определенная процедура? Тогда просто "пролистай" все нахо­
дящиеся в этом окне процедуры и функции (используя вертикальную
линейку прокрутки) и пиши свой код после них, на свободном месте
(рис. 3.9).

Рис. 13.9. Окно редактирования хранимых процедур


Урок 13. Работа с базой данных /59

Совет
Никогда не изменяй те функции, которые получены путем автоматической гене­
рации при определении условий ссылочной целостности — к чему могут при­
вести эти изменения, одному Лису известно...

Теперь для таблиц, входящих в состав базы данных, нужно определить триг­
геры (правила).

Триггеры
Триггер INSERT определяет действия, которые будут выполняться после до­
бавления в таблицу новой записи.
Триггер UPDATE — то же самое, только после изменения записи.
Триггер DELETE определяет действия, которые будут выполняться после уда­
ления записи из таблицы.
На вкладке Table окна Table Designer имеется группа Triggers (Триггеры),
в которой расположены три поля ввода: Insert Trigger, Update Trigger, Delete
Trigger. Вот в эти-то поля и заносится вызов хранимой процедуры, логиче­
ское выражение или операторы сравнения — в общем, любое допустимое
выражение. И если результатом вычисления данного выражение будет .Т.
(True) —- все в порядке! В противном случае нашего уважаемого пользовате­
ля ждет сообщение об ошибке.
Вызов триггеров происходит в следующих случаях:
• триггер UPDATE — при любом изменении значения поля, а также при вы­
полнении команд REPLACE, REPLACE FROM ARRAY, UPDATE-SQL, GATHER;
• триггер DELETE — при установке на записи метки на удаление в режиме
просмотра или/и при выполнении команды DELETE;
• триггер INSRET — при вводе новой записи в режимах BROWSE ИЛИ EDIT, a
также при выполнении команд APPEND FROM, APPEND FROM ARRAY, APPEND
BLANK, IMPORT, RECALL, INSERT-SQL И П р и СНЯТИИ ОТМеТКИ об у д а л е н и и
записи в режиме просмотра.
Но при использовании триггеров имеются и ограничения: если ты пометил
запись для удаления, а потом вдруг начал ее же модифицировать — тригге­
ры вызываться не будут.
Убрать" триггер из таблицы проще простого — нужно очистить соответст­
вующее поле ввода или использовать команду DELETE TRIGGER.
Как все это претворить в жизнь? Сначала о хранимой процедуре (рис. 13.10):
открой окно конструктора таблиц (Table Designer) с таблицей countries и
в поле Default value (Значение по умолчанию) введи следующее выражение:
m y l a s t i d ("countries")
160 Часть I. Процедурное программирование в Visual FoxPro

Рис. 13.10. Вызов хранимой процедуры

А вот теперь попробуй ввести несколько значений. Ну как, получается?,


А ты как думал!
Эта же функция может успешно применяться и в других таблицах, напри-1
мер в таблице cities. В поле ввода Default value для этой таблицы следует
указать myiastid ("cities") и вперед! А что у нас в таблице lastid? Смоге
рим на рис. 13.11.

Рис. 13.11. В таблице l a s t i d хранятся последние значения идентификаторов

Практическое использование триггеров


Да, признаюсь, здесь я не оригинален — подобный пример использования
триггеров встречается во многих учебниках по программированию. Суть та-
Урок 13. Работа с базой данных jgj

кая: неплохо бы вести какой-нибудь учет, например, сколько ты ввел новых


записей, допустим, сегодня — кто знает, вдруг ты действительно отель от­
кроешь? Но сначала доведем "до ума" нашу базу данных, создав новые таб­
лицы со следующей структурой — табл. 13.6.
В этой таблице будет храниться информация о клиентах, которые прожива­
ют в нашем отеле в настоящее время.

Таблица 13.6. Names.dbf

Поля Описание
Idcountry (i4) Идентификатор страны
Idcity (i4) Название города
Ccountry (c30) Название страны
Ccity (c30) Название города
CFirstname (c30) Имя
CSecondname (c30) Фамилия
CLastname (c30) Отчество
DBirthday (d8) Дата рождения
CStreet (c30) Улица
CHome (c5) Дом
CRoom (c5) Квартира
GPhoto (g) Фотография
Csex (clO) Пол
Darrdate (d8) Дата приезда
Ddepdate (d8) Дата отъезда
Idroom (i4) Номер в отеле
MDescr (Memo) Дополнительные сведения

А в таблице Depclients.dbf будет храниться информация обо всех клиентах,


когда-либо проживавших в отеле (табл. 13.7). При "выписке" клиента дан­
ные о нем будут скопированы в эту таблицу из таблицы Clients.dbf.

Таблица 13.7. Depclients.dbf

Поля Описание
Idcountry (i4) Идентификатор страны
Ccountry (сЗО) Название страны

6
Зак Ю02
162 Часть I. Процедурное программирование в Visual FoxPro

Таблица 13.7 (окончание)

Поля Описание
Ccity (сЗО) Название города
Idcity (i4) Идентификатор города
CFirstname (сЗО) Имя
CSecondname (сЗО) Фамилия
С Lastname (сЗО) Отчество
DBirthday (d8) Дата рождения
CStreet (сЗО) Улица
CHome (c5) Дом
CRoom (c5) Квартира
GPhoto (g) Фотография
Csex (clO) Пол
Darrdate (d8) Дата приезда
Ddepdate (d8) Дата отъезда
Ndays Время проживания
Ncost Стоимость проживания
Idroom (i4) Номер в отеле
MDescr (Memo) Дополнительные сведения

В таблице Rooms.dbf— информация о номерах нашего отеля (табл. 13.8).

Таблица 13.8. Rooms.dbf

Поля Описание
Idroom (Integer) Номер (идентификатор гостиничного номера)
Idfloor (Integer) Идентификатор этажа
Nprice (Numeric) Стоимость проживания в сутки
Nplaces (Numeric) Количество мест в номере
Ltv (Logical) Наличие телевизора
Lphone (Logical) Наличие телефона

В таблице Floors.dbf, как видно из ее названия, хранится информация об|


этажах (табл. 13.9).
Урок 13. Работа с базой данных 163

Таблица 13.9. Floors.dbf

Поля Описание
Idfloor (Integer) Идентификатор этажа
Cfloor (Character) Описание этажа (первый, второй и т. д.)

А вот в таблице Todayrecords.dbf мы и будем вести ежедневный учет при­


бывших постояльцев (табл. 13.10).

Таблица 13.10. Todayrecords.dbf

Поля Описание
Icounter (i4) Счетчик
DToday (d8) Дата

После определения соответствующих индексов и установки отношений на­


ша база данных будет выглядеть примерно так, как показано на рис. 13.12.

Рис. 13.12. База данных Oldfox


164 Часть I. Процедурное программирование в Visual FoxPro

Так, на чем мы остановились? А, использование триггера... Выбрав таблицу


names, откроем окно Table Designer и перейдем на вкладку Table. Затем в
поле ввода Insert trigger введем вызов функции newrecordso — рис. 13.13.

Замечание
В таблице todayrecords должна быть одна пустая запись.

Рис. 13.13. Использование триггера

Откроем окно редактирования хранимых процедур и введем следующий


текст:
PROCEDURE Newrecords
SELECT Todayrecords
REPLACE Icounter WITH Icounter+1
REPLACE Dtoday WITH DATE()
SELECT Todayrecords
RETURN .T.

Теперь посмотрим, как это все работает: переходим в рабочую область,


в которой открыта таблица todayrecords, увеличиваем значение поля icounte
на единицу, а в поле dtodae ставим текущую дату, используя функцию
DATE (). Все просто, не так ли?
Урок 13. Работа с базой данных 165

Контроль достоверности ввода данных


На вкладке Fields (Поля) диалогового окна Table Designer имеется область
Field validation (Проверка ввода).
В поле ввода Rule (Правило, условие) вводится логическое выражение, и
если его результатом вычисления будет False (Ложь) — появляется выраже­
ние, указанное в поле Message (Сообщение).
Например, при вводе значения в поле dbirthday (Дата рождения) таблицы
names необходимо следить за тем, чтобы введенная дата не была больше да­
ты сегодняшней: действительно, новорожденные еще "туда сюда", но к чему
нам "гости из будущего"?!
Так вот (рис. 13.14): переходим на вкладку Fields, указываем поле dbirthday
и в поле ввода Rule пишем dbirthday < DATE о, а в поле Message вводим
текст с о о б щ е н и я Дата рождения не может быть датой из будущего! Все, на­
жимаем ОК.

Рис. 13.14. Определение условий достоверности ввода данных на уровне поля

Точно так же (с небольшими изменениями) можно задать хранимые про­


цедуры, триггеры и правила проверки и для других таблиц и полей.
Ты спрашиваешь, для чего их вообще использовать? Ведь все эти проверки
и прочее можно организовать, используя экранные формы? Естественно,
166 Часть I. Процедурное программирование в Visual FoxPro

можно. Но в этом случае мы ничего не сможем поделать с теми пользовате­


лями, которые решат редактировать данные в таблицах, минуя экранные
формы — например, используя BROWSE ИЛИ командное окно. А используя эти
функции, мы в любом случае сможем обеспечить ссылочную целостность.
И еще: никто тебя не заставляет писать собственные процедуры (как было
показано ранее). Referential Integrity Builder достаточно мощное и удобное
средство, в большинстве случаев его применение более чем оправданно и
достаточно. Но если ты решишь обрабатывать изменения данных не так,
как это предусмотрено по умолчанию в Visual FoxPro — пожалуйста, как ты
уже убедился, в этом нет ничего сложного.
А теперь мы ненадолго оставим нашу базу данных и продолжим знакомство
с экранной формой. Пусть тебя не удивляет такая "непоследовательность",
действительно, во многих учебниках главы построены таким образом, что
полностью раскрывают какую-то определенную тему. Но я считаю, что тебе
будет понятней рассматривать процесс построения приложения именно так,
максимально приблизившись к "боевым" условиям. Да и врачи советуют,
что лучший вид отдыха — это смена вида деятельности.

/
УРОК 1 4

Экранная форма.
Продолжение знакомства
На данном уроке мы продолжим знакомство с элементами управления
экранных форм, рассмотрим их назначение и свойства, научимся работать
с различными построителями элементов управления.

Объект ListBox
List в переводе с английского список. Источником данных для этого эле­
мента управления могут быть значения полей, элементы массивов, пункты
меню, список значений и т. д. Всем этим хозяйством управляет свойство
RowSourceType (Тип источника данных), возможные значения которого при­
ведены в табл. 14.1.

Таблица 14.1. Значения свойства RowSourceType

Значение Тип источника данных

0 (None) Значение определяется программно


1 (Value) Список значений задается в виде строки, элементы которой
отделяются друг от друга запятыми
2 (Alias) Источник данных — таблица
3 (SQL-Statement) Источник данных — результат SQL-оператора
4 (Query) Источник данных — результат запроса
5 (Array) Источник данных — массив
6 (Fields) Значения элементов списка являются значениями полей
таблицы
7 (Files) Значения элементов списка — перечень файлов
8 (Structure) Источник данных — структура таблицы
9 (Popup) Источник данных — пункты Рорир-меню
168 Часть I. Процедурное программирование в Visual FoxPro

Пример использования
Создадим новую форму, в которой расположим объект ListBox, воспользо­
вавшись для этого панелью Form Controls (рис. 14.1).

Рис. 14.1. Экранная форма с размещенным в ней объектом L i s t B o x

При создании или редактирования объекта ListBox можно использовать по-|


строитель (Builder), вызываемый нажатием кнопки на соответствующей
команде контекстного меню.
Рассмотрим этот вопрос более подробно (рис. 14.2).

Рис. 14.2. Вкладка List Items окна построителя List Box Builder
Урок 14. Экранная форма. Продолжение знакомства 169

На вкладке List Items (Список объектов) необходимо задать тип источника


данных для заполнения списка. Тип источника указывается в раскрываю­
щемся списке Fill the list with, в котором доступны следующие значения:
• Fields from a table or view (Поля из таблицы или представления данных);
• Data entered by hand (Источником данных является список значений);
• Values from an array (Источником данных является массив).
Мы будем использовать первое значение, и при этом в списке Databases and
tables (Базы данных и таблицы) нужно указать таблицу, поля которой будут
являться источником данных.
Выбрав таблицу, мы увидим список ее полей в списке Available fields
(Имеющиеся поля). При помощи кнопок со стрелками перенесем необхо­
димые поля в область Selected fields (Выбранные поля).
А вот в том случае, когда мы укажем в качестве источника данных массив,
внешний вид вкладки List Items изменится (рис. 14.3).

Рис. 14.3. Вкладка List Items окна построителя


при установленном значении Values from an array

В поле ввода Array Name указывается имя массива. Если массив использует­
ся не весь — ставим переключатель в положение Range of the array и указы­
ваем диапазон значений.
Вернемся к нашему случаю. После задания необходимых параметров на
вкладке List Items перейдем к следующей вкладке — Style (Стиль) (рис. 14.4).
Здесь мы видим две группы переключателей:
• Three-dimensional (Трехмерный) — позволяет придать объекту эффект
объемности;
• Plain (Плоский) — объект отображается плоским;
170 Часть I. Процедурное программирование в Visual FoxPro

• Yes, enable incremental searching (Да, возможен поиск) — означает, что


при вводе каждой буквы будет осуществляться поиск подходящего зна­
чения из списка;
• No, don't enable incremental searching (Нет, поиск не возможен) — при
вводе букв никакого поиска, соответственно, не будет.

Рис. 14.4. Вкладка Style окна построителя List Box Builder

Счетчик Rows to display (Отображение строк) позволяет задать количество


одновременно показываемых значений списка.
Разобравшись с этой вкладкой, двигаемся дальше на вкладку Layout (Распо­
ложение) (рис. 14.5).

Рис. 14.5. Вкладка Layout окна построителя List Box Builder


Урок 14. Экранная форма. Продолжение знакомства у 77

Расположенный на данной вкладке флажок Adjust the width of the list box to
display all columns автоматически увеличивает ширину списка для отображе­
ния всех колонок.
Ширину каждой колонки можно изменить вручную, установив мышь на
границу между ними и "растянув" колонку до необходимого размера.
И, наконец, последняя вкладка нашего построителя — Value (Значение)
(рис. 14.6).

Рис. 14.6. Вкладка Value окна построителя List Box Builder

Эта вкладка используется для того, чтобы задать источник данных. В окне
Properties (Свойства) за это отвечает свойство controisource.
Закончив "строительство", нажмем ОК и вернемся к Конструктору форм.
Выделим наше поле ввода Texti, а в окне свойств дважды щелкнем на ме­
тоде Keypress (Нажатие клавиши), после чего в открывшемся окне редакти­
рования процедур напишем следующий код — рис. 14.7.
nKeycode — это параметр, передаваемый методу Keypress (Нажатие клави­
ши). Если нажата клавиша <Enter> (13 — это ее код), выполняется провер­
ка, не является ли значение данного поля ввода пустой строкой — функция
EMPTY о возвращает истину, если в данном поле нет данных. Если условие
верно, в таблицу добавляется новая пустая строка и заполняется значения­
ми поля ввода формы. Затем поле ввода снова очищается. Таким образом,
Мы можем заполнять наш справочник, вводя название стран в соответст­
вующее поле ввода и нажимая клавишу <Enter>.
По умолчанию в объекте ListBox отображается восемь значений, а если их
будет больше — в нем появится линейка прокрутки.
172 Часть I. Процедурное программирование в Visual FoxPro

Рис. 14.7. Код для заполнения таблицы

Раскрывающийся список (ComboBox)


Этот элемент мы уже видели в главном окне Visual FoxPro, именно в нем
отображается открытая база данных. Данный элемент управления часто
применяется в экранных формах, и, естественно, мы никак не можем щ
обратить внимание на сей объект.
Можно сказать, что ComboBox является более "продвинутым" братом-близ-
неиом объекта ListBox — так много у них общего.
Данный объект, как и обычный список, имеет собственный построитель
(Builder) для определения и редактирования источника данных и других
свойств. Использование построителя для раскрывающегося списка практи­
чески идентично использованию построителя для обычного списка, поэтому
мы не будем на нем останавливаться. Вместо этого мы определим свойства
данного элемента управления с помощью окна Properties (Свойства).
Давай откроем форму, на которой у нас размещен ListBox, выделим его и
удалим, нажав клавишу <Delete>. Вместо него поместим на форму элемент
управления в виде раскрывающегося списка (рис. 14.8).
В окне Properties перейдем на вкладку Data для определения типа источни­
ка данных. Значения свойства RowSourceType точно такие же, как и объекта
ListBox. Так как мы используем в качестве источника данных значение поля
таблицы, нам необходимо установить значение 6. В раскрывающемся спи­
ске для свойства RowSource укажем поле нашей таблицы, то же самое уста-
новим и для свойства controisource (Источник данных).
Стиль отображения объекта на экране можно задать, установив соответст-
вующие значения для свойств, расположенных на вкладке Layout.
Запустим форму на выполнение — рис. 14.9.
Урок 14. Экранная форма. Продолжение знакомства 173

Рис. 14.8. Мы заменили в форме Рис. 14.9. Форма


простой список на раскрывающийся с раскрывающимся списком

Видишь, нам даже не пришлось изменять код для события Keypress для по­
ля ввода новых значений. Это наглядно демонстрирует сходство между
ComboBox И ListBox.
Теперь рассмотрим тот случай, когда в качестве источника данных выступа­
ет не таблица, а список значений. Уберем таблицу из среды данных (Data
Environment) нашей формы. Свойство RowSourseType определим равным i
(Value, Значение). Свойство Controisourse примем равным None (Нет).
А вот в RowSourse занесем через запятую список значений.

Переключатели (OptionGroup)
Эти элементы называются переключателями, потому что они могут прини­
мать только одно из нескольких значений поля или переменной. То есть
когда один из них включен, другие, входящие в эту группу переключателей,
выключены. Их еще иногда называют радиокнопками — раньше на старых
радиоприемниках применялись подобные устройства, правда, механические.
Объект OptionGroup является контейнером, т. е. состоит из нескольких эле­
ментов, обладающих определенными свойствами.
Создадим новую экранную форму и разместим на ней элемент управления
OptionGroup, воспользовавшись соответствующей кнопкой на панели Form
Controls (рис. 14.10).

Рис. 14.10. По умолчанию объект O p t i o n G r o u p состоит из двух элементов


174 Часть I. Процедурное программирование в Visual FoxPro

Вызовем контекстное меню для этого элемента управления и посмотрим,


как работает построитель для группы переключателей — рис. 14.11.

Help I OK Cancel |
Рис. 14.11. Вкладка Buttons окна построителя Option Group Builder

Счетчик Number of buttons определяет количество элементов в группе пере­


ключателей.
Переключатели Standard и Graphical позволяют определить "внешний вид"
элементов. Standard (Стандартный) — обычный для этого объекта вид (см.
рис. 14.10), Graphical (Графический) — элементы отображаются в виде кно-|
пок.
В расположенной ниже таблице можно определить надпись для каждого
элемента (Caption) и, если нужно, изображение (Graphic).
Теперь перейдем на вторую вкладку окна Option Group Builder — Layout
(Расположение), которая позволяет задать параметры отображения объектов
(рис. 14.12):
• Button layout (Vertical, Horizontal) — отвечает за расположение элементов
в группе: вертикально (по умолчанию) или горизонтально;
• Spacing between buttons (in pixels) — определяет расстояние между эле­
ментами в пикселах;
• Border style (Single, None) — определяет, будет ли группа переключателей
иметь обрамление в виде одинарной линии (Single) или вообще обрамле­
ния не будет.
На последней, третьей вкладке Value (Значение) можно определить таблицу
и поле, в которое будут заноситься значения элементов. В окне свойств j
Properties за это отвечает свойство controisource (Источник данньгх).
Урок 14. Экранная форма. Продолжение знакомства 175

Рис. 14.12. Вкладка Layout окна построителя Option Group Builder

Рис. 14.13. Вкладка Value окна построителя Option Group Builder

В качестве примера давай создадим группу переключателей, состоящую из


четырех элементов, и таблицу, поле которой может принимать одно из че­
тырех значений (рис. 14.14).
При выборе одного из элементов соответствующее значение будет занесено
в поле таблицы.
А вот на рис. 14.15 приведен пример графического стиля отображения эле­
мента OptionGroup.
Естественно, все эти свойства, а также и другие (цвет и т. д.) доступны в
°кне Properties (Свойства). Для того чтобы "добраться" к элементам данного
176 Часть I. Процедурное программирование в Visual FoxPro

объекта, необходимо щелкнуть на нем правой кнопкой мыши — только так


ты получишь доступ к его "внутренностям". Это относится и к другим объ­
ектам-контейнерам.

Рис. 14.14. Использование O p t i o n G r o u p Рис. 14.15. Использование O p t i o n G r o u p


для занесения значения в таблицу Для занесения значения в таблицу
(режим Standard) (режим Graphical)

Контейнер (Container)
А вот и сам контейнер. Как ясно из названия, перед нами самый настоя-
щий контейнер, в который можно включать различные элементы управле­
ния. Данный объект очень широко используется при создании классов — на
его основе можно соорудить такие элементы, как группа командных кно-
пок, progressBar (Индикатор) и многое другое. В экранных формах он так­
же частенько применяется, например, на рис. 14.16 представлен фрагмент
экранной формы с тремя контейнерами. Свойство speciaiEffect у первого
равно 2 (Плоский), у второго — 1 (Утопленный), у третьего — о (Выпук­
лый).

Рис. 14.16. Фрагмент экранной формы стремя контейнерами

Счетчик (Spinner)
Счетчик применяется для ввода числовых значений. К сожалению, для него
не предусмотрен построитель, поэтому для определения его свойств тебе
придется часа четыре двигать мышью (шутка).
Поместив объект на форме, открываем окно Properties (Свойства) и начи^
наем творить:
1. Используя уже знакомое нам свойство controisource (Источник данных)
определяем поле, для которого, собственно, и нужен счетчик. Смотри,
поставь поле Character!
Урок 14. Экранная форма. Продолжение знакомства 177

2. Теперь необходимо задать максимальное и минимальное значения для


с ч е т ч и к а — с о о т в е т с т в е н н о с в о й с т в а SpinnerHighValue И SpinnerMinValue.

3. В предыдущем пункте мы определили максимальное и минимальное


допустимые значения, которые вводятся с использованием стрелок счет­
чика. Но значения можно вводить и с клавиатуры, поэтому для та­
кого случая определим дополнительно значения следующих свойств —
KeyboardHighValue И KeyboardMinValue.

4. Определим шаг, с которым изменяется значение поля, воспользовавшись


СВОЙСТВОМ I n c r e m e n t .

Но счетчик, кстати, можно использовать и для других целей. Например,


пользователь не может изменить размер кнопок, а ему это ну очень надо!
Так сделай ему счетчик рядом с кнопкой, определи максимально допусти­
мые значения, допустим, для ширины кнопки, а для события
interactiveChange запиши следующее:
THISFORM.Commandl.WIDTH=THIS.VALUE
THISFORM.Commandl.REFRESH()

Вот и пусть изменяет...


Пошутили, расслабились — поехали дальше!

Группа вкладок (PageFrame)


Вкладки используются в основном тогда, когда на форме предполагается
разместить большое количество объектов и каким-то образом их сгруппи­
ровать.
Создадим новую форму, которая будет входить в состав нашего приложе­
ния, и разместим на ней три вкладки. Вкладки располагают на форме сле­
дующим образом: выбирается соответствующая кнопка на панели Form
Controls, затем мышью обводится контур необходимого размера. По умол­
чанию при встраивании вкладок в экранную форму их число равняется
Двум. Вкладки не имеют своего построителя, и вся настройка осуществляет­
ся при помощи окна Properties (Свойства). Более того, объект PageFrame
также является контейнером и содержит в контекстном меню пункт Edit
(Редактировать).
Разместив в нашей форме вкладки, увеличим их число до трех, изменив
значение свойства PageCount в окне Properties (рис. 14.17).
Как видишь, у нас появились три вкладки, имеющие заголовки Pagel,
Page2, Page3. Кстати, эти объекты имеют и такие же имена. Изменим заго­
ловки вкладок — для этого щелкнем правой кнопкой на объекте PageFramel
178 Часть I. Процедурное программирование в Visual FoxPro

и выберем пункт Edit контекстного меню. После этого станет возможным


переключение между вкладками и определение свойств для каждой из них.
Первое, что мы сделаем — изменим значение свойства caption (рис. 14.18).

Рис. 14.17. Размещение вкладок на форме

Рис. 14.18. Изменение заголовков вкладок

Теперь поговорим о размещении объектов на вкладках. Правило здесь та-


кое — не забывать включать режим Edit из контекстного меню, иначе раз­
мещаемый объект "вставится" не на нужную вкладку, а на сам объект;
PageFrame.
Урок 14. Экранная форма. Продолжение знакомства 179

Вот и давай разместим на первой вкладке три "утопленных" контейнера.


Для этого в режиме Edit перейди на первую вкладку (если она не открыта —
это происходит по умолчанию) и размести необходимые объекты. Можешь
поставить туда только один контейнер, определить необходимые свойства, а
затем, воспользовавшись командами копирования и вставки, добавить ос­
тальные (рис. 14.19).

Рис. 14.19. Размещение объектов на вкладках

Флажок (CheckBox)
Элемент управления в виде флажка используется, когда значение поля мо­
жет иметь только одно из двух значений. Ты догадался, о чем это я говорю?
Ну конечно, речь идет о полях типа Logical, ведь именно они могут иметь
только два возможных значения — "Истина" (True) и "Ложь" (False). При
Установке флажка значение в поле будет "Истина", а при сбросе — "Ложь",
'фоцесс размещения данного объекта в форме сводится к следующему:
'• Размещаем его на форме, воспользовавшись соответствующей кнопкой
на панели Form Controls.
180 Часть I. Процедурное программирование в Visual FoxPro

2. Определяем источник данных controisource — понятно, что это должно


б ы т ь ПОЛе L o g i c a l
3. Определяем надпись для данного элемента — свойство Caption.
Пример объекта спесквох, помещенного на форму, представлен на рис. 14.20.

Рис. 14.20. Пример объекта CheckBox

Линия (Line)
Ну, линия — она и есть линия. Объект, скажем прямо, декоративный. Для)
размещения линии в форме нужно воспользоваться соответствующей кно...|
Слушай, тебе не надоело читать каждый раз про кнопку? Я думаю, ты уже и
так на всю жизнь запомнил, как "вставить" в форму тот или иной объект.
В общем, переходим сразу к сути: устанавливаешь указатель мыши в начало
линии и тащишь на необходимое расстояние. В Paint рисовал? Вот-вот,
почти то же самое. А когда линия уже нарисована, определяем ее свойства: |
• толщина линии определяется значением Borderwdth;
• ц в е т о м "заведует" B o r d e r C o l o r ;
• чтобы более точно задать длину линии, используется свойство width для|
горизонтальной линии и Height — для вертикальной. Они же "регулиру­
ют" угол наклона линии;
• стиль отображения указывается с помощью свойства Borderstyle, кото­
рое может иметь значения, перечисленные в табл. 14.2.

Таблица 14.2. Значения свойства Borderstyle

Значение Borderstyle Стиль

0 — Transparent Прозрачная линия


1 - Solid (Default) Просто тонкая линия
2 - Dash Штрих
3-Dot Пунктир
4 — Dash-Dot Штрихпунктир
5 - Dash-Dot-Dot Штрих-двойной пунктир
6 — InsideSolid Непрерывная линия /
Урок 14. Экранная форма. Продолжение знакомства 181

Но т. к. наш Лис является натурой творческой — было бы наивно думать,


что его "художества" ограничиваются только рисованием примитивных ли­
ний. Нет! Немного фантазии, и Лис запросто выдаст нечто в стиле "матема­
тического сюрреализма". Делаем простейшую форму с двумя полями ввода
и двумя кнопками. В коде события click одной из кнопок пропишем сле­
дующий код — листинг 14.1.

Листинг 14.1. Событие C l i c k

DECIA X ( 4 0 0 ) , Y ( 4 0 0 )
FOR I = 1 TO 360
FOR K=l TO 200
Z=6.6832*1/360
X ( I ) = 120+90*SIN(5*Z)*COS(THISFORM.TEXT1.VALUE*Z)
Y d ) = 120+90*COS(5*Z)*SIN(THISFORM.TEXT2.VALUE*Z)
THISFORM.CURRENTX=X(I)
THISFORM.CURRENTY=Y(I)
THISFORM.PRINT ( " ( ( * ) ) " )
ENDFOR
ENDFOR

Задавая в полях ввода различные значения, рисуем "картинки" (рис. 14.21 и


14.22).

Рис. 14.21. Лис в качестве художника Рис. 14.22. Лис в качестве художника
(значения 60, 1) (значения 5, 1)
182 Часть I. Процедурное программирование в Visual FoxPro

Контур (Shape)
Расположив в необходимом месте экранной формы контур, настраиваем его
свойства:
• цвет ф о н а — BackColor;

• Прозрачность — BackStyle;

• СТИЛЬ рамКИ — B o r d e r S t y l e ;

• эффект объемности — SpecialEffeet;


• изгиб — curvative (значения от 1 до 99);
• цвет узора — Fiilcoior;
• сам узор, заполнение — свойство Fiiistyie, которое может принимать)
несколько значений (табл. 14.3).

Таблица 14.3. Значения свойства Fiiistyie

Значение F i i i s t y i e Узор
0 - Solid Сплошная заливка

1 — Transparent(Default) Без заливки

2 — Horizontal Line Горизонтальная штриховка

3 — Vertical line Вертикальная штриховка

4 — Upward Diagonal Штриховка по диагонали слева направо

5 — Downward Diagonal Штриховка по диагонали справа налево

6 — Cross Крестик (горизонтально-вертикальная штриховка)

7 — Diagonal Cross "Косой" крестик

Пример объекта shape, помещенного на форму, представлен на рис. 14.23.

Рис. 14.23. Пример объекта Shape


Урок 14. Экранная форма. Продолжение знакомства 183

Изображение (Image)
Элемент управления image предназначен для размещения в экранной форме
изображений (рис. 14.24). Непосредственно за само изображение отвечает
свойство Picture, в котором нужно указать путь к графическому файлу.
Помнишь, мы использовали данное свойство для экранной формы? Разме­
щаем объект, указываем путь к файлу и производим настройку других
свойств, а именно свойства stretch, которое может принимать следующие
значения:
О Clip (Обрезать) — картинка сохраняет свои размеры;
О Isometric (Изменить, сохранив форму) — картинка занимает весь объект
image, причем пропорционально изменяет свои размеры;
О Strech (Изменить, заполнив рамку) — картинка занимает весь объект
image, но размеры не меняет.

Рис. 14.24. Размещение изображения в форме

Таблица (Grid)
Объект Grid используется для отображения данных в табличной форме.
С первого взгляда он похож на таблицу в режиме просмотра Browse, но это
только с первого. Данный элемент управления представляет собой объект-
контейнер, включающий в себя несколько объектов. Об объектах, входящих
в состав Grid, поговорим позже, а сейчас начнем создавать этот элемент
при помощи построителя.
Откроем в окне конструктора форм нашу форму с вкладками. Разместим
при объекта Grid в ранее созданных контейнерах. Но начнем, естественно,
с одного.
184 Часть /. Процедурное программирование в Visual FoxPro

После расположения его внутри первого контейнера выберем команду


Builder контекстного меню (рис. 14.25). Ну и как всегда в таких случаях,
происходит запуск построителя (рис. 14.26).

Рис. 14.25. Размещение в форме объекта G r i d и вызов построителя

Окно Grid Builder (Построитель таблицы) содержит четыре вкладки, первую


из которых мы и видим в данный момент. Она называется Grid Items (Эле-
менты) и здесь мы можем сформировать список полей, которые будут раз­
мещены в нашем объекте. Для этого в раскрывающемся списке Databases
and tables (Таблицы и базы данных) укажем нашу базу данных oidFox, после
чего внизу отразится список имеющихся в базе данных таблиц. Выбрав не­
обходимую таблицу, мы увидим список полей данной таблицы в области
AvaiJables fields (Имеющиеся поля). При помощи кнопок со стрелками пе­
ренесем те поля, которые мы хотим разместить в Grid, в область Selectee
fields (Выбранные поля). На этом работу с первой вкладкой построителе
можно считать законченной, и мы переходим ко второй — Style (Стиль)
(рис. 14.27).
Данная вкладка используется для задания стиля отображения данных в таб-
лице. Всего имеется пять различных стилей. Рядом расположено окно npeк-
варительного просмотра. Выбрав желаемый, переходим к третьей вкладке
Layout (Расположение) (рис. 14.28).
Урок 14. Экранная форма. Продолжение знакомства 185

Рис. 14.26. Первый шаг работы построители Grid Builder

Рис. 14.27. Вторая вкладка построителя Grid Builder

По умолчанию заголовки столбцов совпадают с их именами. Ясно, что это


н
е всегда удобно. Для переопределения заголовка используется поле ввода
Caption (Наименование). Раскрывающийся список Control type (Тип эле­
мента управления) содержит список объектов, которые могут отображаться
в
этом столбце. Некоторые из них в данный момент недоступны — это за-
в
исит от типа поля.
186 Часть I. Процедурное программирование в Visual FoxPro

Рис. 14.28. Третья вкладка построителя Grid Builder

Открываем последнюю, четвертую вкладку построителя — Relationship (От­


ношения).

Рис. 14.29. Четвертая вкладка построителя Grid Builder

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


индекс подчиненной (дочерней). Это, как ты уже догадался, применяется
при создании объекта Grid для многотабличных форм.
Закончив манипуляции с построителем, разместим на вкладке нашей фор-
мы надписи и поле ввода для добавления записей в таблицу, расположив
его ниже объекта Grid (рис. 14.30).
Урок 14. Экранная форма. Продолжение знакомства 187

Рис. 14.30. Мы расположили в форме справочник стран в виде объекта G r i d

Для события Keypress объекта Text 11 запишем код из листинга 14.2.

Листинг 14.2. Добавление записей в таблицу

LPARAMETERS N k e y c o d e , N s h i f t a l t c t r l
IF N k e y c o d e = 1 3 && ЭТО КОД КЛАВИШИ ENTER
DO CASE
CASE EMPTY ( T h i s . V a l u e ) = . F .
SELECT C o u n t r i e s
APPEND BLANK
REPLACE C c o u n t r y WITH T h i s . V a l u e
This.Value=""
_SCREEN.ACTIVEFORM.REFRESH()
ENDCASE
ENDIF

Теперь рассмотрим создание объекта Grid "вручную", без использования по­


строителя. Сделаем Grid, отображающий справочник городов. Для этого от­
кроем нашу форму в конструкторе форм, щелкнем мышью на объекте
p
ageFramei, и войдем в режим редактирования, воспользовавшись соответст­
вующей командой контекстного меню (Edit). Выбрав на панели инструмен­
тов кнопку Grid, разместим наш объект во втором контейнере (рис. 14.31)
и начнем настройку его свойств, используя окно Properties (Свойства).
Перейдем на вкладку Layout окна Properties. За отображение числа столбцов
(Column) отвечает свойство coiumncount. По умолчанию данное свойство
имеет значение -1 (поэтому в таблице поначалу как бы ничего и нет). Так
как нам нужен всего один столбец, в котором будут отображаться только
названия городов, мы установим данное свойство равным единице. Источ­
ником данных для нашего объекта будет таблица со списком городов
cities. Для того чтобы определить источник данных, перейдем на вкладку
Data окна Properties и зададим значение для свойства RecordSource (Источ-
ник данных) (рис. 14.32).
188 Часть I. Процедурное программирование в Visual FoxPro

Рис. 14.31. Мы встроили в экранную форму Рис. 14.32. Определение источника данных
еще один G r i d для объекта G r i d

Как я уже и говорил, объект Grid включает в себя несколько объектов, т. e.j
является контейнером. Нажми на кнопку в раскрывающемся списке окна
Properties и ты увидишь, какие именно объекты входят в состав нашего Grid]
(рис. 14.33).

Рис. 14.33. В состав G r i d входит несколько объектов

Column — это столбец. Кроме уже известного нам Coiumncount, данный объ-|
ект имеет множество других свойств. Рассмотрим некоторые из них:
• controisource — определяет источник данных для столбца;
• Alignment — выравнивает информацию в столбце;
• coiumnOrder — определяет порядок отображения столбцов;
• Backcolor — определяет цвет фона.
Используя эти, а также и другие свойства, можно для всего столбца зада
цвет фона, цвет шрифта, размер шрифта и прочие параметры. /
урок 14. Экранная форма. Продолжение знакомства 189

Объект Header — это не что иное, как заголовок столбца. По умолчанию он


называется так же, как и соответствующее поле таблицы, но заголовок
можно легко изменить, задав значение свойства caption.
Объект Text — это тот элемент управления, который определяет, в каком
виде будет выводиться информация. В данном случае это обычное поле
ввода. В Grid для отображения информации могут использоваться такие
элементы управления, как счетчик (spiner), флажок (checkbox), поле редак­
тирования (EditBox), раскрывающийся СПИСОК (ComboBox).
Таким образом, настроив необходимые свойства для нашего второго объек­
та Grid, добавим в форму поле ввода, с помощью которого будем добавлять
в справочник городов новые наименования. Код для события Keypress будет
такой же, как и в предыдущем случае (см. листинг 14.2), только вместо таб­
лицы стран нужно указать таблицу городов cities и, соответственно, изме­
нить название поля в команде Replace.
А теперь самостоятельно добавь в третий контейнер экранной формы еще
один Grid, в котором будет располагаться справочник улиц. Также не забудь
добавить поле для ввода нового значения. После того как ты это сделаешь,
посмотри на рис. 14.34. Именно такая форма (или почти) у тебя может по­
лучиться, если добавишь еще несколько объектов.

Рис. 14.34. Первая вкладка формы для ввода данных


190 Часть I. Процедурное программирование в Visual FoxPro

Ну и что теперь делать? Как все это будет работать? Сейчас разберем.
Во-первых, для полей ввода, отвечающих за ввод фамилии, имени, отчест­
ва, даты рождения и дополнительной информации о клиенте, необходимо в
качестве источника данных назначить соответствующие переменные памя­
ти. Их имена будут совпадать с именами полей таблицы Names.dbf за одним
лишь исключением — перед именем поля необходимо ставить префикс т.
А вот в качестве источника данных для полей, указывающих страну, город и
улицу, укажем не переменные памяти, а сами имена полей из соответст­
вующих таблиц. Да еще и сделаем данные поля доступными только для чте-
НИЯ (ReadOnly=.T.).
Посмотрим, как будет работать форма на этом этапе? Давай только еще не­
много отредактируем свойства наших элементов Grid. Конкретно нас инте­
ресует событие AfterRowCoichange, которое наступает после того, как мы пе-
рейдем на другую строчку Grid. Так вот, в первом объекте Grid (где страны)
для данного события пишем следующий код:
THISFORM.REFRESH() && после перехода на другой ряд Grid
&& форма просто перерисовывается с новыми данными.

Для второго Grid (Города):


THISFORM.PAGEFRAME1.PAGE1.ТЕХТ5.REFRESH()

То есть во втором случае мы только обновляем информацию для поля ввода


Text5.
Ну и почти то же самое для третьего Grid:
THISFORM.PAGEFRAME1.PAGE1.TEXT6.REFRESH()

А сейчас мы сделаем программу, которая будет запускать наше будущее


приложение. Для этого в окне диспетчера проекта перейди на вкладку Code
(Код) и выбери пункт Programs (Программы). Нажми кнопку New (Новая).
В открывшемся окне напиши код из листинга 14.3.

Листинг 14.3. Программа для запуска

SET TALK OFF


SET ECHO OFF
SET DATE TO GERMAN
SET PATH TO C:\OLDFOX\
OPEN DATABASE Oldfox
USE Names IN 1 EXCLUSIVE
USE Depclients IN 2 EXCLUSIVE
DO FORM Main && Main - это название файла нашей формы
Урок 14. Экранная форма. Продолжение знакомства 191

Вот и все. Сохрани эту программу под любым именем, и теперь можешь
попробовать запустить форму на выполнение и позаполнять наши справоч­
ники. Сначала заполняется справочник стран — тут все просто, в поле вво­
да набираешь название и нажимаешь <Enter>. Затем, указав в этом Grid
нужную страну, также заносишь данные в справочник городов для этой
страны. Указав город, заносим название улиц этого города.
Таким образом, у нас уже имеется форма с тремя связанными и, что совсем
уже удивительно, работающими объектами Grid.
Ну а как же все-таки добавлять записи в таблицу names, где у нас "фамилии,
пароли, явки" и т. д.?
Кнопка Новая запись может иметь примерно такой программный код для
события click — листинг 14.4.

Листинг 14.4. Код события C l i c k для кнопки Новая запись

SELECT names && переходим в рабочую область с таблицей names.dbf


SCATTER MEMVAR BLANK && создаем переменные памяти
THISFORM.REFRESH() && обновляем информацию в экранной форме

Ничего сложного. Немного сложнее с кнопкой Сохранить (листинг 14.5).

Листинг 14.5. Код события c l i c k для кнопки Сохранить

SELE Names
APPEND BLANK
GATHER MEMVAR
REPLACE I d c o u n t r y WITH C o u n t r i e s . I d c o u n t r y ;
Ccountry WITH C o u n t r i e s . C c o u n t r y
REPLACE C s t r e e t WITH S t r e e t s . S t r e e t
REPLACE I d c i t y WITH C i t i e s . I d c i t y , C c i t y WITH C i t i e s . C c i t y
REPLACE Idrooms WITH Rooms.Idroom
I
E THISFORM.Pageframel.Pagel.Optiongroupl.Optionl.Value=l
REPLACE Csex WITH "M"
ELSE
UEPLACE Csex WITH "Ж"
ENDIF

Но очевидно, что здесь необходимо каким-то образом предотвратить воз­


можность ввода пустых записей в таблицу names. Один из вариантов — про­
­­­ить значения полей ввода. Например, вот так — листинг 14.6.
192 Часть I. Процедурное программирование в Visual FoxPro

Листинг 14.6. Проверка значения полей ввода

IF EMPTY(THISFORM.Pageframel.Pagel.Textl.Value)
-> = MESSAGEBOX("УКАЖИТЕ ФАМИЛИЮ КЛИЕНТА", "ОШИБКА...")
ELSE
... <приведенный ранее код>...
END IF

Как ты уже догадался, здесь Лис проверяет — а не забыл ли пользователь]


ввести фамилию клиента? Аналогичным способом можно осуществить про­
верку и других полей.
На второй вкладке нашей формы мы расположим информацию о тех кли4
ентах, которые проживают в нашем отеле в настоящий момент (рис. 14.35).

Рис. 14.35. Вторая вкладка нашей формы

На третьей вкладке мы поместим информацию о клиентах, которые выех<


из нашего отеля. Здесь мы можем расположить как общий список клиенте
так и некоторую дополнительную информацию: номер, в котором клие |
жил, даты прибытия и выезда, стоимость проживания. Возможно, это 6yJ
выглядеть так — рис. 14.36. /
Урок 14. Экранная форма. Продолжение знакомства 193

Рис. 14.36. Третья вкладка экранной формы

по нас в данный момент интересует совсем Другое обстоятельство — а от­


куда взялись записи в таблице с выбывшими клиентами (Depclients.dbf)?
па второй вкладке нашей экранной формы есть кнопка Удалить запись.
о нашем случае это будет означать, что при щелчке на этой кнопке запись
о клиенте удаляется из таблицы names (клиент выехал) и добавляется в ар­
хив — таблицу depciients (листинг 14.7).

Листинг 14.7. Код заполнения таблицы d e p c i i e n t s

Объявляем локальную переменную (стоимость проживания в номере за сутки)


LOCAL Nroomprice
*переходим в рабочую область с таблицей rooms
SELЕСТ Rooms
* в таблице rooms переходим на запись с тем номером, где проживает клиент
LOCАТЕ FOR Idroom=Names.Idrooms
* присваиваем соответствующее значение нашей переменной
Nroomprice=Rooms .Nprice
* т е п е р ь переходим в таблицу names
SELECT Names
194 Часть I. Процедурное программирование в Visual FoxPro

* создаем переменные памяти, в которых находится вся информация о текущей


записи
SCATTER MEMVAR MEMO
* помечаем запись на удаление
DELETE
* переходим в рабочую область с таблицей depclients
SELECT Depclients
* добавляем пустую запись
APPEND BLANK
* заполняем ее значениями из таблицы names
GATHER MEMVAR MEMO
* производим замену значения даты выезда на сегодняшнюю дату
REPLACE Ddepdate WITH DATE()
* вычисляем количество прожитых в номере дней
REPLACE Ndays WITH Ddepdate-Darrdate
* вычисляем полную стоимость проживания
REPLACE Ncost WITH Ndays*Nroomprice
* опять переходим в область с таблицей names
SELECT Names
* удаляем запись
PACK
* обновляем информацию в экранной форме
THISFORM.REFRESH()

Тут поневоле вспоминаются триггеры и хранимые процедуры — ведь весь


этот код можно было (с небольшими изменениями) занести в контейнер
базы данных в виде триггера удаления. И еще одно дополнение — данный
метод подходит в том случае, когда нам нужно "выселить" клиента раньше
срока, ну допустим, кому-то срочно нужно выехать домой. А как быть с ос­
тальными? Не искать же по всей базе данных (а в твоем пятизвездочном
отеле уже ежедневно проживает по 15 тыс. человек) тех, у кого дата предпо­
лагаемого выезда совпадает с сегодняшним числом! Конечно, нет. Доста­
точно немного изменить код и наша программа сама при каждом запуске
будет удалять из базы данных необходимые записи (листинг 14.8).
%

Листинг 14.8. Измененный код заполнения таблицы d e p c l i e n t s

SELECT Names
SCAN FOR Ddeptdate=DATE ()
LOCAL Nroomprice
SELECT Rooms
LOCATE FOR Idroom=Names.Idrooms
Nroomprice=Rooms.Nprice
Урок 14. Экранная форма. Продолжение знакомства 195

SELECT Names
SCATTER MEMVAR MEMO
DELETE
SELECT Depclients
APPEND BLANK
GATHER MEMVAR MEMO
REPLACE Ndays WITH Ddepdate-Darrdate
REPLACE Ncost WITH Ndays*Nroomprice
SELECT Names
ENDSCAN
PACK
THISFORM.REFRESH ()

А если этот код еще и поместить в метод i n i t нашей формы, то все полу­
чится именно так, как мы задумали. Но при этом есть и грустный мо­
мент — посмотри теперь на нашу форму (рис. 14.37).

Рис. 14.37. Вид формы изменился при модификации кода приложения

Что случилось? Почему вместо Grid мы теперь видим какую-то белую "ды-
ру? А это результат использования команды PACK. Более того, я тебя сейчас
196 Часть I. Процедурное программирование в Visual FoxPro

еще обрадую — тот же эффект мы будем наблюдать каждый раз, когда бу!
дем удалять записи из таблицы, являющейся источником данных для объек-3
та Grid. Избежать этого довольно просто, нужно сделать следующее: перед
использованием команды удаления необходимо "очистить" источник данных
для Grid, а потом восстановить его (листинг 14.9).

Листинг 14.9. Очистка и восстановление G r i d

SELECT Names
THISFORM.Pageframel.Page2.Gridl.Recordsource=.NULL.
PACK
THISFORM.Pageframel.Page2.Gridl.Recordsource="NAMES"

И еще одно замечание по этому поводу: в восстановленном объекте Gril


столбцы будут отображаться в том порядке, в котором были расположена
поля при создании таблицы. Отсюда вывод — если порядок отображения нА
соответствует желаемому, можно модифицировать таблицу, изменив поря­
док следования полей. Если же это невозможно, то следует назначать ис­
точник данных не для всего Grid, а отдельно для каждого столбца.

/
урок 15

Выборка, упорядочение
и просмотр данных
Итак, что мы имеем? У нас есть база данных, есть несколько таблиц, есть
экранная форма и, наконец, есть сами данные. А что мы умеем? Мы умеем
заносить в базу данных новые записи и, соответственно, удалять какие-
нибудь из них. Что ж, для начала не так уж и плохо. Но ведь мы знаем, что
основное назначение системы управления базами данных — это быстрый
поиск и предоставление пользователю тех записей, которые удовлетворяют
заданным условиям. Вот именно этому, читая данную главу, мы сейчас и
будем учиться.
Для того чтобы из таблицы выбрать данные, ее сначала нужно открыть. Каж­
дая таблица, независимо от того, входит ли она в контейнер базы данных
или является свободной таблицей, открывается в своей рабочей области.
Принято считать, что в Visual FoxPro имеется 32 627 рабочих областей, в
каждой из которых может храниться таблица и соответствующие ей индек­
сы. И что все эти таблицы можно открыть одновременно. Это так, но на
самом деле рабочих областей еще больше. Дело в том, что если мы будем
использовать приватные сеансы данных (private data session), то
32 627 рабочих областей будут доступны в каждом сеансе!
Открыть таблицу (а сейчас мы говорим о свободных таблицах) можно, ис­
пользуя команду USE. Например, вот так: USE ROOMS. При этом таблица rooms
будет открыта в первой рабочей области. После применения USE FLOORS В
первой области у нас окажется таблица floors, a rooms соответственно будет
закрыта. А как их использовать одновременно? Для этого в команде USE
необходимо указать, в какой именно рабочей области будет открыта таб­
лица:
USE ROOMS IN 1
USE FLOORS IN 2

Вот и все. Теперь для перехода к нужной таблице достаточно использовать


уже знакомую нам команду SELECT и указать номер рабочей области:
198 Часть I. Процедурное программирование в Visual FoxPro

SELECT 2
BROWSE

Но гораздо удобнее использовать не номер рабочей области, а псевдоним


или алиас (alias) таблицы. Псевдоним всегда совпадает с именем таблицы, а
читаемость программного кода при его использовании заметно улучшится.
SELECT FLOORS
BROWSE

Этот пример полностью идентичен предыдущему.


Таблицы, входящие в состав базы данных, открываются так же, но перед их
открытием необходимо открыть саму базу данных:
OPEN DATABASE OLDFOX
USE ROOMS IN 1
USE FLOORS IN 2

Открывать базу данных необходимо потому, что связанные таблицы могут


иметь длинные имена, триггеры и тому подобные вещи, присущие базе
данных.
Ну и конечно, в состав этих команд можно включить указание пути:
OPEN DATABASE C:\OLDFOX\OLDFOX
USE C:\OLDFOX\ROOMS EXCLUSIVE

А можно и не включать, но в этом случае путь необходимо заранее указать:


SET PATH TO C:\OLDFOX

Команда LOCATE. Поиск записей


С помощью данной команды мы можем отыскать записи, удовлетворяющие
заданному условию. При этом совершенно безразлично, в каком месте таб­
лицы эти записи расположены, потому что LOCATE всегда начинает поиск с
первой записи и последовательно просматривает все записи до конца таб­
лицы, пока не найдет ту, которая соответствует заданному условию. В на­
шей экранной форме есть кнопка Найти и поле ввода Поиск по фамилии.
Допустим, нам нужно найти всех клиентов, фамилия которых начинается с
букв ИВ. В поле ввода заносим соответствующие буквы и нажимаем кноп-
ку, которая в событии click имеет следующий набор команд:
SELECT NAMES
LOCATE FOR CSECONDNAME=THISFORM.PAGEFRAME1.PAGE1.TEXT1.VALUE
THISFORM.REFRESH()
Урок 15. Выборка, упорядочение и просмотр данных 199

Если найдена запись, удовлетворяющая заданному условию, то указатель


записей на ней и остановится. Но что делать, если у нас несколько таких
записей, например, трое Ивановых, пятеро Ивиных и один Иванченко?
Первое, что приходит в голову, — это запустить LOCATE еще раз. Но здесь
скрывается небольшая проблема — LOCATE всегда начинает поиск с первой
записи и завершает на найденной (а если не найдет, то на последней) и по­
этому, сколько бы ты раз ее не запускал — столько раз она тебе и покажет
того же самого Иванова. Выход следующий: нужно совместно с LOCATE ис­
пользовать еще одну команду — CONTINUE, которая продолжает поиск не с
начала файла, а с уже найденной записи. В нашем случае можно для собы­
тия Rightciick (Щелчок правой кнопкой мыши) кнопки Найти назначить
выполнение этой команды. Теперь, если мы при помощи LOCATE найдем
требуемую запись, для проверки наличия остальных достаточно несколько
раз щелкнуть правой кнопкой мыши.

Команда SEEK.
Поиск по значению индекса
Некоторой альтернативой команды LOCATE является команда SEEK, НО ДЛЯ ее
использования необходимо наличие индекса. Если открыто несколько ин­
дексов, то нужно перед использованием данной команды "выбрать" какой-
то один, т. к. команда работает с одним индексом. Установить индекс мож­
но при помощи команды SET ORDER TO, использование которой будет рас­
смотрено далее. Попробуем найти запись в таблице rooms, значение индекса
которой равно 202.
SELECT ROOMS
SET ORDER TO IDROOM
SEEK 202

Вот и все. Синтаксис команды очень прост, но необходимо помнить, что


тип задаваемого значения должен совпадать с типом данных текущего ин­
декса. То есть если индексируемое поле имеет тип character, то задаваемое
в команде значение нужно заключить в кавычки.

Команда SET FILTER TO.


Выбор группы записей
Для того чтобы выбрать группу записей, удовлетворяющих заданному усло­
вию или условиям, можно использовать команду SET FILTER TO. В рассмот­
ренном ранее примере мы искали тех клиентов, у которых фамилия начи­
нается на ИВ, и при этом последовательно перебирали записи, используя
200 Часть I. Процедурное программирование в Visual FoxPro

"спарку" LOCATE и CONTINUE. А используя SET FILTER то, мы можем сразу ого-
бразить все необходимые записи:
SELECT NAMES
SET FILTER TO CFIRSTNAME="MB"
BROWSE

Команда SET FILTER TO также позволяет выбрать записи, удовлетворяющие


нескольким условиям. Простой пример: отель твой процветает, дела идут
"в гору" и тебе просто необходим надежный и верный помощник. В общем,
ты решил жениться! И причем невесту ты собираешься выбрать среди по­
стояльцев своего отеля. Но не бегать же по этажам, в самом деле! Зачем то-
гда СУБД? Ищем невесту:
SELECT NAMES
SET FILTER TO UPPER(СЗЕХ)="Ж".AND.DBIRTHDAY<=CTOD("01.01.1986");
.AND.DBIRTHDAY>=CTOD("01.01.1983")
BROWSE

Пожалуйста, выбирай — рис. 15.1.

Рис. 15.1. Результат работы команды SET FILTER TO

Сортировка данных в таблицах


Прежде чем приступить к сортировке записей, нам необходимо выяснить:
какие вообще существуют способы сортировок данных. Основных способа
два, и они принципиально отличаются друг от друга. Первый способ — фи-
зическая или постоянная сортировка записей. Второй способ — виртуальная
сортировка или временная.
Постоянная сортировка. Ее суть заключается в том, что данные в таблице
располагаются в строго установленном порядке. Для ее выполнения доста-
точно просто перезаписать существующую таблицу в нужном порядке. А что
делать, если требуется другой порядок записей? Ведь очевидно, что в одной
таблице нельзя иметь несколько порядков сортировки. В этом случае нужно
еще раз перезаписать таблицу, т. е. создать еще одну копию. Да уж, для по-
Урок 15. Выборка, упорядочение и просмотр данных 201

вседневного использования этот способ является, мягко говоря, не совсем


удобным. Но, тем не менее, знать и уметь это будет полезно. Создаем по­
стоянную сортировку, используя команду SORT:
USE NAMES
SORT TO NEWNAMES ON CFIRSTNAME

После выполнения данной команды будет создана новая копия таблицы


names (она будет иметь имя newnames), но записи в этой таблице будут рас­
полагаться В Отсортированном ВИДе ПО ПОЛЮ cfirstname.
Виртуальная сортировка. Для ее выполнения необходимо наличие соответ­
ствующих индексов. Что такое индексы, мы с тобой уже рассматривали.
Допустим, нам нужно отобразить записи из таблицы names отсортирован­
ными по фамилиям клиентов, то бишь по алфавиту. Для этого необходимо
создать соответствующий индекс, используя либо конструктор базы данных
для модификации таблицы, либо введя следующую команду:
USE NAMES
INDEX ON ALLTRIM (CFIRSTNAME) TAG FIRSTN

А теперь достаточно выполнить команду SET ORDER TO FIRSTN И все, записи


упорядочены (рис. J 5.2).

Рис. 15.2. Сортировка записей в таблице

А если нам нужно, помимо сортировки по фамилиям, упорядочить записи


еще и по именам клиентов? В этом случае необходимо использовать состав­
ной индекс:
INDEX ON ALLTR(CFIRSTNAME)+ALLTR(CSECONDNAME) TAG FIRSTN
202 Часть I. Процедурное программирование в Visual FoxPro

При этом Лис сообщит, что индекс с таким именем уже существует и спро-
сит, не желаем ли мы его перезаписать? Чтобы он не спрашивал, а индекс
переписывался автоматически, нужно добавить в нашу команду еще одно
ключевое слово ADDITIVE:
USE NAMES
INDEX ON ALLTRIM (CFIRSTNAME) TAG FIRSTN ADDITIVE

Для отмены сортировки используется команда SET ORDER TO без дополни-


тельных параметров.
УРОК 16

Создание и использование
запросов
На твой вопрос: "Что такое запрос?" — отвечаю: "Запрос — это вопрос".
Красиво сказано, не правда ли? А ведь в этой шутке есть доля правды, по­
тому что запрос это действительно вопрос, с которым пользователь обраща­
ется к базе данных. Применительно к нашему случаю.
• Сколько клиентов из России проживало в нашем отеле за период
с 1 сентября по 26 октября?
• В каком из номеров предпочитали останавливаться клиенты за все время
существования отеля?
• Сколько клиентов на сегодняшний день живут в номерах третьего этажа,
оборудованных телефоном?
• Какой номер самый рентабельный?
Список, как ты понимаешь, может быть бесконечным. Ты скажешь: "Ну и
что? Я только что научился находить, выбирать, сортировать данные и при
помощи определенных команд легко отвечу на эти вопросы!" Не спорю, от­
ветишь. Количество дополнительных условий, используемых в SET FILTER
то, LOCATE, SCAN и т. д., практически не ограничено. Но ты ответишь на эти
вопросы сегодня, а завтра и послезавтра возникнут другие. Ты захочешь
снова переписывать свою программу? Да и вообще, ведь все вопросы преду­
смотреть нельзя (если ты, конечно, не ясновидящий). Вот для того, чтобы
пользователь мог найти ответ практически на любой вопрос, и существуют
такие хитрые и очень мощные "штуковины", как запросы (Query). Еще есть
п
°хожие на них виды или представления данных, но о них разговор будет
Позже.

Конструктор запросов (Query Designer)


Для создания запросов в среде Visual FoxPro используется конструктор за­
просов или Query Designer. Запустить этот "механизм" можно так же, как и
все остальное: используя соответствующий пункт системного меню. Выбери
204 Часть I. Процедурное программирование в Visual FoxPro

пункты File | New (Файл | Новый). В диалоговом окне New выбери опцию
Query (Запрос) и нажми кнопку New file (Новый файл) (рис. 16.1).

Рис. 16.2. Диалоговое окно


Рис. 16.1. Диалоговое окно New Add Table or View

Как видишь, сразу после выполнения команды меню Лис открывает диало-
говое окно, в котором спрашивает: "А какие таблицы или представления
данных будут добавлены в создаваемый запрос?" (рис. 16.2). Выберем для
начала две таблицы, cities и streets, закроем диалоговое окно, используя
кнопку Close (Закрыть), и поближе познакомимся с конструктором запро­
сов (рис. 16.3).
Конструктор запросов содержит панель инструментов Query Designer
(рис. 16.4), описание кнопок которой приведено в табл. 16.1.

Таблица 16.1. Кнопки панели Query Designer

Кнопка Описание

Добавляет в запрос новую таблицу

Add Table (Добавить таблицу)


Удаляет таблицу из запроса

Remove Table (Удалить таблицу)


Задает условия объединения таблиц

Add Join (Добавить объединение)


Урок 16. Создание и использование запросов 205

Таблица 16.1 (окончание)

Кнопка Описание

Открывает окно с SQL-оператором, со­


ответствующим данному запросу
View SQL (Показать SQL)

Раскрывает панель отображения таблиц


во весь экран
Maximize The T^ble View
(Максимизировать панель отображения)
Открывает диалоговое окно, в котором
можно указать, куда выводить результа­
Query Destination (Результат запроса) ты запроса

Рис. 16.3. Окно конструктора запросов, вкладка Fields

Рис. 16.4. Панель инструментов Query Designer

Мы видим, что на рис. 16.3 между добавленными таблицами изображена


соединительная линия, которая показывает, что между полями этих таблиц
существует связь. Связь действительно есть, в базе данных эти таблицы свя-
206 Часть I. Процедурное программирование в Visual FoxPro

заны по полю idcity, и на вкладке Join (Объединение) конструктора запро­


сов показано условие объединения этих таблиц (рис. 16.5).

Рис. 16.5. Окно конструктора запросов, вкладка Join

Сейчас мы подробно, на примере, разберем, что же это такое — условие


объединения. Допустим, цель нашего запроса — отобразить все города на
шей базы данных, кроме тех, названия которых начинаются на М. Также
мы включим в результат запроса улицы этих городов, да еще и в алфавит
ном порядке.
Прежде чем начать формировать условия запроса, необходимо выбрать из
таблиц те поля, значения записей которых будут включены в результат за­
проса. Это делается на вкладке конструктора запросов Fields (Поля) (см.
рис. 16.3). На этой вкладке мы видим два списка: Availabe fields (Доступные
поля) и Selected fields (Выбранные поля). Поначалу список Selected fields
пуст. Чтобы добавить в него поле, нужно выделить его в списке доступных
полей и нажать кнопку Add (Добавить). А можно просто перетащить его
мышью на список выбранных полей. Для добавления сразу всех полей
можно щелкнуть кнопку Add All (Добавить все). Действия при удалении по-­
лей из списка выбранных прямо противоположны указанным ранее -
кнопки Remove (Удалить) и Remove All (Удалить все). Маленькие кнопочки
со стрелками позволяют изменить порядок отображения полей.
Для описания условия запроса используется вкладка Filter (Фильтр)
(рис. 16.6).
Урок 16. Создание и использование запросов 207

Рис. 16.6. Окно конструктора запросов, вкладка Filter

В раскрывающемся списке Field Name (Имя поля) отображены имена полей


из соответствующих таблиц, включенных в запрос, а в списке Criteria (Кри­
терий) — условие отбора записей:
• = — действует так же, как и обычный знак равенства;
• Like (Такой как) — посимвольное сравнение выражения, стоящего спра­
ва от оператора Like, с выражением, стоящим слева;
• = = — создает более ограниченное сравнение (точно равно);
• < и > — можно определить как "больше чем" и "меньше чем";
• >= и <= — определяется как "больше или равно" и "меньше или равно";
• Between (Между) — выбираются записи, значения которых попадают в
указанный диапазон.
С помощью кнопки Not (He) можно инвертировать заданное выражение. Не
очень понятно, что такое "инвертировать"? Да не расстраивайся, это просто
обозначает "наоборот". Вот в нашем примере при помощи этой кнопки мы
и
задаем условие такого "неравенства". А если бы мы ее не нажали, то на­
оборот выбрались бы все города, названия которых начинаются на букву М.
Нажатие кнопки Case (Регистр) позволяет игнорировать регистр символь­
ных строк.
Следующая вкладка конструктора запросов — Order By (Порядок отображе­
ния) (рис. 16.7). Именно здесь мы можем задать желаемый порядок отобра­
жения записей, иначе говоря, произвести их сортировку. На данной вкладке
208 Часть I. Процедурное программирование в Visual FoxPrci\

также отображены два списка: Selected fields (Выбранные поля) и Ordering


criteria (Критерий упорядочения). Добавление полей в список Ordering criteria
происходит таким же способом, как и на вкладке Fields. Сам же критерии
упорядочения задается выбором соответствующих опций переключателя
Order options: Ascending — по возрастанию, Descending — по убыванию.

Рис. 16.7. Окно конструктора запросов, вкладка Order By

Рис. 16.8. Результат выполнения запроса


Урок 16. Создание и использование запросов 209

Теперь осталось только запустить наш запрос в "первое плавание" и по­


смотреть, что из этого выйдет. Запустить запрос на выполнение проще про­
стого:
1. Выбрать команду Run Query из пункта системного меню Query (Запрос).
2. Нажать кнопку Run на стандартной панели инструментов.
3. ВЫПОЛНИТЬ Команду DO QUERY <имя_запроса>.
Выполнив любое из этих действий, ты увидишь результат своего запроса на
экране (рис. 16.8).
Ты спросишь: "А как же обещанное разъяснение про условие объединения
таблиц?" А я и не забыл про него, мы собственно и выполнили наш первый
запрос для того, чтобы понятнее и нагляднее объяснить, что это такое.

Типы внешних объединений


Существует четыре типа объединений: внутреннее, левое внешнее, правое
внешнее, полное внешнее. Чтобы нагляднее разъяснить тебе разницу между
ними, обратимся к нашим таблицам (рис. 16.9 и 16.10).

Рис. 16.9. Таблица Cities Рис. 16.10. Таблица Streets

Посмотри, в таблице cities имеется несколько записей (например, Екате­


ринбург и Самара), для которых нет соответствующих записей в таблице
s t r e e t s . А В таблице s t r e e t s , наоборот, имеется запись (ул. Цветочная), ДЛЯ
210 Часть I. Процедурное программирование в Visual FoxPro

которой нет соответствующей записи в таблице с названиями городов. Не


стоит удивляться, как такое могло случиться — мы специально ввели эти
лишние записи в качестве "наглядного пособия". Теперь вернемся к конст­
руктору запросов и установим на вкладке Join внутреннее объединение
(Inner Join). В этом случае результат нашего запроса будет содержать толь­
ко те записи из двух таблиц, которые отвечают критерию объединения
(рис. 16.11).

Рис. 16.11. Результат внутреннего объединения

Действительно видно, что в итоговую таблицу не попали ни Екатеринбург,


ни Самара, ни улица Цветочная. Догадался, почему? Совершенно верно,
эти записи не соответствуют критерию объединения — у них не совпадает
значение поля idcity.
Теперь установим в условие объединения как левое внешнее (Left Outer
Join). При таком объединении в результат запроса будут включены все
записи из таблицы слева и только те записи из таблицы справа, которые
отвечают условию объединения (рис. 16.12).
Установив правое внешнее объединение (Right Outer Join), мы добьемся
следующего результата — в итоговую таблицу попадут все записи из табли­
цы справа и записи, отвечающие условию объединения из левой таблицы
(рис. 16.13).
И наконец, рассмотрим полное внешнее объединение (Full Outer Join), при
котором в результат запроса попадают все записи из обеих таблиц
(рис. 16.14).
Урок 16. Создание и использование запросов 211

Рис. 16.12. Результат левого Рис. 16.13. Результат правого


внешнего объединения внешнего объединения

Рис. 16.14. Результат полного объединения

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


• В определении критерия фильтра не следует заключать символьные
строки в кавычки — они будут добавлены автоматически.
• Если критерий имеет логическое значение, его необходимо заключить
в точки ( . F . ) , (.т.).
212 Часть I. Процедурное программирование в Visual FoxPro

• Не нужно использовать функцию CTODO при вводе дат. Просто введи


дату в обычном формате — например, 01/01/2001.

Использование в запросе фильтров


с несколькими условиями
В этом примере мы выполним запрос, используя несколько условий в
фильтре. Задача следующая: мы знаем, сколько получили прибыли на сего­
дняшний день — в день отбытия клиент рассчитывается, а данные и о нем
самом и о сумме оплаты заносятся в таблицу depciients. Но нам интересно,
есть ли среди живущих в нашем отеле клиентов те, которые уже на сегодня
"должны" нам с тобой, ну скажем, сумму больше 36 500 руб. Почему имен­
но такую? Да не важно, это просто для примера. Усложним задание: клиен­
ты должны быть из России и более того, нам интересно видеть конкретную
сумму по каждому. Каким же образом все это узнать, хотя бы про суммы —
ведь в таблице с записями о проживающих (names) нет соответствующего
поля? Тем не менее конструктор запросов позволяет легко решить данную
задачу, потому что помимо использования фильтра с несколькими условия-
ми, у нас еще есть возможность создавать с помощью построителя выраже-
ний вычисляемые поля и включать их в итоговую таблицу.
Для построения нашего нового запроса нам потребуются три таблицы
с записями о проживающих в данный момент (names), с записями о стоимо
сти проживания в номере (rooms), справочник стран (countries). (Хотя
справочник стран в данном случае можно и не использовать, ведь записи
стране есть и в таблице names.)
Для того чтобы узнать сумму по каждому клиенту, воспользуемся построи
телем выражений. Чтобы его открыть, нужно щелкнуть на области поля
Fields Name вкладки Fields и перейти к его самому последнему элементу Ex-­
pression. При щелчке на данном элементе откроется построитель выражений
(Expression Builder) — а с помощью этой "хитрой штуки" можно создать лю­
бое выражение на языке программирования Visual FoxPro (рис. 16.15).
Что ж, приступим. Чтобы узнать сумму оплаты, нам сначала необходимо
знать, сколько дней человек пребывал в нашем отеле — от сегодняшней да­
ты отнимаем дату приезда. Затем умножаем полученное значение на стои­
мость проживания в номере за сутки. Практически все изложенное ранее
выполняется следующим образом: в раскрывающемся списке From table (Из
таблицы), в котором перечислены все "участвующие" в запросе таблицы,
выбираем необходимую — в данном случае это таблица names. При этом в
списке Fields (Поля) будут отображены поля указанной таблицы. Для того
чтобы перенести их в поле Expression (Выражение), где собственно и проис­
ходит построение выражения, необходимо дважды щелкнуть по выбранном»
полю. Если в выражении участвуют какие-либо функции, то их можно пи-
сать как вручную, так и выбирать из раскрывающихся списков в областя
Урок 16. Создание и использование запросов 213

Functions (Функции). После построения выражения его необходимо прове­


рить, щелкнув по кнопке Verify, и сохранить, нажав кнопку ОК. Сохранив
полученное выражение, его можно добавить в список Selected fields конст­
руктора запросов.
Построим еще одно выражение — объединим в одном поле фамилию, имя
и отчество клиента (рис. 16.16).

Рис. 16.15. Окно построителя Expression Builder

Рис. 16.16. Мы построили еще одно выражение, которое также будет включено в запрос
214 Часть I. Процедурное программирование в Visual FoxPro

Рис. 16.17. Определение условий фильтра

Теперь обратимся к вкладке Filter, на которой и определим условия фильтра]


(рис. 6.17).
В данном случае мы установили значение логического оператора (Logical)
как AND (Логическое И). Смысл показанного на рисунке выражения можно
объяснить так: показать записи, для которых результат первого выражения
будет больше 36 500, и те записи, для которых значение второго выражения
совпадет с условием фильтра. Результат запроса показан на рис. 16.18.
А что будет, если мы изменим значение логического оператора, и вместо
AND поставим OR? Давай посмотрим — рис. 16.19.
Здесь видно, что в результат запроса попали как клиенты, прибывшие из
России, так и те люди, что проживают в других странах. Более того, мы ви­
дим записи, как удовлетворяющие первому условию (сумма больше 36 500),
так и записи, не "прошедшие" проверку. Почему так произошло? А все дело
в том, что при добавлении оператора OR В набор условий происходит разде-
ление выражения на две части: до OR И после. Они выполняются независимо
друг от друга, и что самое интересное, оба работают правильно. Посмотри
повнимательней — результатом работы первого выражения являются все
записи с суммами больше указанной. Верно? Верно. Ты спросишь, а почему
попали "иностранцы"? А где в первом условии упоминание о стране? ТаМ
ведь речь идет только о суммах, вот наш дядюшка Лис их аккуратно и вы-
брал. Но опять же, есть запись с меньшей суммой. А это уже результат pa-
боты второго условия. Страну "заказывали"? Заказывали. Есть записи с этой
страной? Есть. Вот и ладненько. Примерно так рассуждает наш изворотлив
Урок 16. Создание и использование запросов 215

вый Лис, и он прав, потому что для него главное синтаксис критериев, а
смысл этих критериев ему безразличен. За смыслом выражений должны
следить, естественно, мы с тобой. Вот еще один наглядный пример, на этот
раз с использованием логического оператора AND (рис. 16.19а).

Рис. 16.18. Результат запроса с AND

Рис. 16.19. Результат запроса с OR


216 Часть I. Процедурное программирование в Visual FoxPro

Рис. 16.19а. Установка значения AND

Что мы видим? С первого взгляда все выглядит вполне нормально. Но дан­


ный запрос никогда не даст результата, потому то не может быть в одной
записи двух указанных значений. В данном случае необходимо использовать
логический оператор OR.
Ну и как тебе работа с конструктором запросов? Возможности действитель­
но впечатляют. Помнишь, как мы вычисляли сумму счета для выбывших
клиентов? Писали программный код, использовали SCAN, REPLACE И другие
команды... А здесь мы обошлись без каких-либо вычислений и легко полу­
чили желаемый результат. Но на этом возможности конструктора запросов
не ограничиваются, в чем мы и убедимся, изучив следующие разделы дан­
ной главы.

Вывод результатов запроса


То, в каком виде результаты запроса предстанут перед пользователем, мож­
но определить, воспользовавшись диалоговым окном Query Destination (На­
значение запроса) (рис. 16.20).
Всего имеется семь различных режимов для вывода результатов (табл. 16.2)-
По умолчанию стоит режим BROWSE И именно его мы использовали в преды­
дущих примерах. Данный режим применяется в основном при разработке
приложений, для быстрого просмотра данных.
Урок 16. Создание и использование запросов 217

Таблица 16.2. Режимы отображения результата

Режим отображения результата Описание

BROWSE (Окно просмотра Browse) Результат выводятся в режиме BROWSE


CURSOR (Временная таблица) Результат помещается во временную таблицу
TABLE (Таблица) Результат помещается в постоянную таблицу

GRAPH (График) Результат используется для построения


графика
SCREEN (Экран) Результат выводится на экран
REPORT (Отчет) Результат представляется в виде отчета
LABEL (Этикетка) Результат представляется в виде этикетки

Рис. 16.20. Диалоговое окно Query Destination

Курсор
Курсор — это не только указатель мыши. В Visual FoxPro курсором
называется временная таблица, которая будет создана для хранения резуль­
татов запроса. Данные в курсоре можно только просматривать, нельзя их ни
Добавлять, ни модифицировать, ни удалять. Курсор "живет" только в теку­
щем сеансе, при завершении работы Visual FoxPro он будет удален. Знаешь,
почему он так интересно называется? Да потому, что его название как нель­
зя точно определяет его суть — CURSOR (Current Set Of Records, текущий
набор записей).

Таблица
Результаты запроса записываются в новую таблицу. Это обычная таблица,
записи которой можно удалять, добавлять, модифицировать. В отличие от
218 Часть I. Процедурное программирование в Visual FoxPro

своего временного собрата курсора таблица остается на диске и после за­


вершения сеанса работы Visual FoxPro.

График
Результаты запроса можно отобразить в графическом виде. Для построения
графиков у Лиса имеется свой "чертежник" — Graph Wizard (Мастер графи­
ков). Чтобы наглядно проследить за его работой, давай запустим на выпол­
нение наш запрос, предварительно установив опцию Graph в диалоговом
окне Query Destination.

Рис. 16.21. Выбор данных для графика

На данном этапе мастер предлагает выбрать данные, которые будут отобра­


жены в виде графика (рис. 16.21). Мы будем использовать значения нашего»
вычисляемого поля в рядах данных, а поле с фамилией клиента — в катего­
риях диаграммы.
На следующем шаге будет предложено выбрать стиль диаграммы (рис. 16.22).
И наконец, последний шаг (рис. 16.23), на котором предлагается задать за­
головок для будущего графика (Type a title for your graph), выбрать режим
отображения нулевых значений (Show null values) и легенды (Add a legend to
the graph). Воспользовавшись кнопкой предварительного просмотра Preview,
мы можем посмотреть на результат работы мастера (рис. 16.24).
После просмотра можно вернуться назад и выбрать другой стиль диаграмм
мы. Определившись со стилем окончательного варианта, график необходи-
Урок 16. Создание и использование запросов 219

мо сохранить. Сохранен он будет в виде экранной формы, которую затем


можно использовать в приложении. Более того, форму можно модифициро­
вать (в данном случае это не помешало бы, видишь, как отобразились
надписи в легенде (см. рис. 16.24)).

Рис. 16.22. Третий шаг работы мастера

Рис. 16.23. Заключительный этап работы мастера


220 Часть I. Процедурное программирование в Visual FoxPro

Рис. 16.24. Просмотр результата работы мастера графиков

Экран
При выборе данного режима результат запроса будет выводиться просто над
экран Visual FoxPro, но, используя некоторые дополнительные опции, мож-|
но указать еще и дополнительный "пункт назначения" (рис. 16.25).

Рис. 16.25. Диалоговое окно Query Destination, р е ж и м SCREEN

Для назначения дополнительного способа вывода используются переключа-j


тели в области Secondary output (Вторичный вывод):
Урок 16. Создание и использование запросов 221

• None — вторичный вывод отсутствует;


• To printer — происходит вывод как на экран, так и на принтер;
• То text file — вторичный вывод в текстовый файл.
Имя файла можно как задать в поле ввода, так и выбрать из созданных ра­
нее, воспользовавшись кнопкой с таким же названием.
Ниже расположена группа флажков:
• Suppress column headings — не выводить заголовки столбцов;
• Pause between screens — приостанавливать вывод по мере заполнения эк­
рана.
С первым флажком все ясно, а зачем нужен второй? Затем, что если данных
много, а второй флажок не установлен — все, пиши пропало: записи проне­
сутся по экрану так, что ты и моргнуть не успеешь!

Отчет
При выборе этого режима результаты запроса будут представлены в виде
отчета (рис. 16.26).

Рис. 16.26. Диалоговое окно Query Destination, режим REPORT

Используя данный режим, мы можем поместить данные как в созданный


Ранее макет отчета, так и создать совершенно новый. Для вывода результа­
тов в уже существующий отчет необходимо щелкнуть на кнопке Open
222 Часть I. Процедурное программирование в Visual FoxPro

Report (Открыть отчет). Если же имя отчета известно, то достаточно просто


указать его в поле ввода. При этом диалоговое окно Open открыто не будет.
Расположенная справа от поля ввода кнопка с изображением волшебной
палочки предназначена для вызова Report Wizard (Мастер отчетов). Распо­
ложенные ниже флажки имеют следующее назначение:
• Page preview — предварительный просмотр отчета;
• Console on — позволяет разрешить/отменить вывод результатов запроса
в текущее окно;
• Eject page before report — прогон страницы перед печатью.
Также можно указать и вторичный приемник результатов запроса (см. ранее).

Этикетка (почтовая наклейка)


Этикетка, или почтовая наклейка, может использоваться как по своему,
прямому назначению, так и для других целей — например, для рассылки
информации рекламного характера и т. д. Допустим, мы решили подгото-
вить и отправить кое-кому из наших клиентов приглашения на празднич-
ный вечер. Используя данный режим вывода, мы можем без особых хлопот
это проделать. Далее представлено диалоговое окно Query Destination с оп-
циями, используемыми для вывода этикеток (рис. 16.27).

Рис. 16.27. Диалоговое окно Query Destination, режим LABEL

Так как опции данного диалогового окна аналогичны опциям для вывода
отчетов, мы не будем останавливаться на этом вопросе, а сразу обратимся к
Label Wizard — мастеру почтовых наклеек (в "арсенале" у Лиса и такое чудо
Урок 16. Создание и использование запросов 223

имеется). В первом диалоговом окне мастера предлагается выбрать источ­


ник данных (рис. 16.28).

Рис. 16.28. Первый шаг работы мастера

Рис. 16.29. Второй шаг работы мастера

На втором шаге (рис. 16.29) мастер предлагает выбрать из списка готовых


этикеток наиболее подходящую. В столбце Avery (Наименование) отобра-
22Л Часть I. Процедурное программирование в Visual FoxPro

жаются наименования этикеток, а в столбце Dimensions (Размерность) пока­


заны размеры этикетки. Количество колонок, помещаемых на одной стра­
нице, указано в столбце Columns (Колонки). Размеры указаны в дюймах, но
их легко можно перевести в миллиметры, включив опцию Metric (Метри­
ческая).
Щелкнув на кнопке New Label (Новая этикетка), мы можем задать свои раз­
меры для этикетки (рис. 16.30).

Рис. 16.30. Диалоговое окно Custom Labels

После нажатия кнопки New (Новая) мы можем приступить к процессу oп-


ределения размеров нашей будущей этикетки, в чем нам поможет соответ--]
ствующее диалоговое окно (рис. 16.31).
Для изменения ранее созданной пользователем почтовой наклейки исполь­
зуется кнопка Edit (Редактирование) диалогового окна Custom Labels (Поль­
зовательские этикетки).
На третьем шаге работы мастера (рис. 16.32) необходимо перенести соответ-
ствующие поля из списка Available fields (Имеющиеся поля) в список Se-
lected fields (Выбранные поля). Но здесь, в отличие от других диалоговых
окон, необходимо сразу задать тип разделителя между полями. Типы разде
лителей изображены на кнопках, расположенных между этими двумя спи-
сками. Для вставки между полями пробела используй кнопку Space (Про­
бел), а для расположения поля на следующей строке необходимо нажать
кнопку с изображением кривой стрелки (как на клавиатуре клавиша
<Enter>). Размер и стиль шрифта можно изменить, щелкнув на кнопке Font
(Шрифт).
Разместив необходимые поля, переходим к следующему этапу, на которому
определим порядок сортировки записей (рис. 16.33).
Созданную этикетку можно модифицировать в окне Label Designer (Конст
руктор этикеток) (рис. 16.34).
Урок 16. Создание и использование запросов 225

Рис. 16.31. Диалоговое окно для определения размеров


и прочих параметров создаваемой этикетки

Рис. 16.32. Третий шаг работы мастера

I002
226 Часть I. Процедурное программирование в Visual FoxPro

Рис. 16.33. Четвертый шаг работы мастера

Рис. 16.34. Наша этикетка в окне конструктора этикеток


Урок 16. Создание и использование запросов 227

Обрати внимание на выражение, расположенное выше выбранных нами


полей. Там используется незнакомый тебе оператор IIF. Синтаксис этого
выражения следующий:
IIF(Names.cSex= " м " , "Уважаемый", "Уважаемая")

т. е. если первое выражение возвращает логическую истину (верно) — вы­


полняется следующее за запятой выражение. Если же нет — выполняется
последнее выражение. Этот оператор очень удобен потому, что в нем можно
использовать любые команды, а также поддерживается выполнение не­
скольких вложенных условий IIF.
Полюбовавшись на творение рук своих (рис. 16.35), нам остается только
удовлетворенно вздохнуть и рассмотреть еще один способ сохранения ре­
зультатов запросов — в формате HTML.

Рис. 16.35. Наша этикетка в окне предварительного просмотра

HTML
Visual FoxPro может сохранять некоторые файлы в данном формате, и таб­
лицы не являются исключением. Для представления результатов запроса в
формате HTML, их (результаты) сначала нужно представить в табличной фор­
ме (CURSOR или BROWSE). После этого необходимо в системном меню File
(Файл) выбрать пункт Save As HTML (Сохранить как HTML) (рис. 16.36).
228 Часть I. Процедурное программирование в Visual FoxPro

Рис. 16.36. Диалоговое окно Save As HTML

В открывшемся диалоговом окне можно выбрать любую из трех опций:


• Save file for later use — сохранить файл для последующего использо­
вания;
• Save and edit file — сохранить файл и открыть окно для его редактиро­
вания;
• Save file and view in web browser — сохранить файл и открыть браузер для
просмотра данного файла.
При выборе второго пункта диалогового окна Save As HTML (Сохранить
как HTML) мы получим возможность просмотреть и отредактировать
HTML-код нашего файла (рис. 16.37).

Рис. 16.37. Окно редактирования

При выборе последнего пункта диалогового окна мы можем просмотреть


результаты запроса в окне Web-браузера (рис. 16.38).
Рассмотрев режимы вывода результатов запросов, перейдем на последнюю
вкладку конструктора запросов — Miscellaneous (Разное), которая содер­
жит опции для задания дополнительных критериев для выборки записей
(рис. 16.39).
Урок 16. Создание и использование запросов 229

Рис. 16.38, Результат запроса в окне Opera

Рис. 16.39. Окно конструктора запросов, вкладка M i s c e l l a n e o u s


230 Часть I. Процедурное программирование в Visual FoxPro

Флажок No duplicates (Без дубликатов) позволяет предотвратить или, наобо­


рот, разрешить вывод в результирующий запрос повторяющихся значений.
Установка флажка Cross tabulate (Перекрестная таблица) позволяет предста­
вить результаты запроса в виде перекрестной таблицы. Счетчик Number of
records (Количество записей) позволяет указать количество выводимых в
результат запроса записей. При установленном флажке All (Все) будут выве­
дены все записи. На этом мы на время оставим конструктор запросов и пe-
рейдем к следующему разделу.

SQL-инструкция SELECT
или как все это сделать "вручную"?
Что такое SQL-инструкция SELECT? ЭТО как раз то, написанием чего мы за­
нимались всю предыдущую главу. Ты спросишь: "Как же так? Ведь мы за­
нимались построением запросов с помощью Query Designer, и никаких та-
ких непонятных инструкций видеть не видели, и знать не знаем..." Про
"знать не знаем" пока согласен, а вот насчет остального... Щелкни-ка
мышью по кнопке SQL, которая расположена на панели инструментов
Query Designer (рис. 16.40).

Рис. 16.40. SQL-инструкция SELECT

Вот это и есть SQL-инструкция SELECT. А кто написал весь этот программ-)
ный код? Да ты сам, кто же еще. Вернее не ты, а Лис, но с твоей помощью.
А вот прочитав эту главу, ты вполне сможешь научиться писать SQL-
инструкции самостоятельно и затем использовать их как подпрограммы или
фрагменты программ в своих приложениях.
Урок 16. Создание и использование запросов 231

Что же это такое? Очевидно, что SQL-инструкция SELECT представляет со­


бой набор операторов, предназначенных для выборки из таблиц определен­
ных данных, удовлетворяющих заданным условиям. Простыми словами —
эта "штука" используется для создания запросов.
Простейший запрос может иметь такой вид:
USE C:\OLDFOX\OLDFOX
SELECT * FROM OLDFOX!NAMES

В данном случае в наш запрос попадут все поля и все записи из таблицы
names, входящей в состав базы данных oidfox, и все это будет отображено
в окне Browse. А где в приведенном примере команда BROWSE? А нигде —
режим отображения BROWSE установлен по умолчанию.
Если нам нужны не все поля, можно просто указать необходимые:
SELECT Cfirstname, Csecondname, Dbirthday FROM OLDFOX!NAMES

В любом случае инструкция всегда начинается с ключевого слова SELECT, за


которым следует перечисление включаемых в результат запроса полей. Если
используется таблица, входящая в состав базы данных (как в нашем случае),
то перед именем таблицы необходимо указать имя базы данных и разделить
их восклицательным знаком. Если же таблица не входит в состав базы дан­
ных, т. е. является свободной, — указывается только ее имя. На рис. 16.40
видно, что перед именами полей стоят псевдонимы таблиц. В принципе,
псевдонимы можно и не указывать, но для улучшения "читаемости" все-
таки лучше их использовать. Более того, псевдонимы просто необходимы в
том случае, если таблицы, включаемые в запрос, имеют одинаковые имена.
Разобравшись с самыми основными понятиями, переходим к практическим
занятиям: помнишь, мы искали с помощью команды LOCATE фамилии, кото­
рые начинаются на ИВ? Попробуем сделать то же самое с использованием
SQL-инструкции:
SELECT * FROM OLDFOX!NAMES WHERE Cfirstname="MB"

Вот даже на этом простейшем примере ты можешь оценить возможности


SQL: вспомни-ка код, написанный для использования LOCATE. А здесь всего
одна строка, в которой оператор WHERE действует точно так же, как FOR В
других командах.
Для того чтобы отобразить записи в упорядоченном виде, в SQL-инструк-
Цию SELECT необходимо включить ключевое слово ORDER BY (аналог коман­
ды SET ORDER TO <имя_ПОЛЯ>)
SELECT * FROM OLDFOX! NAMES WHERE Cfirstname="MB";
ORDER BY Cfirstname

Теперь вернемся к вопросу о твоей невесте — ты ведь все еще не женился


(рис. 16.41)?
232 Часть I. Процедурное программирование в Visual FoxPro

SELECT Cfirstname AS Фамилия, Csecondname AS Имя;


DBIRTHDAY AS День_Рождения;
YEAR (DATE ()) -YEAR(Dbirthday) AS Возраст;
FROM OLDFOX! NAMES WHERE Csex=")K".AND. YEAR(Dbirthday) <«1986;
.AND. YEAR (Dbirthday) >=1983 ORDER BY Cfirstname

Рис. 16.41. Мы изменили заголовки полей в результате запроса

Здесь мы включили в нашу инструкцию еще несколько ключевых слов и


сейчас проанализируем, как это все работает. Ключевое слово AS позволяет
изменить имя поля, причем кавычки ставить не нужно. Единственное усло­
вие — название должно состоять из одного слова. Функция YEAR о возвра-
щает значение года из выражения, имеющего формат Date. Используя две
этих функции, мы вычисляем возраст твоей невесты. (Правда приблизи­
тельно, потому что для точного вычисления возраста используется несколь-
ко другой алгоритм.) Затем, опять же используя функцию YEARO, задаем
критерий отбора записей.
Данную инструкцию можно упростить, применив еще одно ключевое сло­
во — BETWEEN, которое позволяет выделить диапазон значений:
SELECT CFIRSTNAME AS ФАМИЛИЯ, CSECONDNAME AS ИМЯ;
DBIRTHDAY AS ДЕНЬ_ РОЖДЕНИЯ;
YEAR(DATE(>) -YEAR(DBIRTHDAY) AS ВОЗРАСТ;
FROM OLDFOX!NAMES WHERE CSEX=">K";
.AND.YEAR(DBIRTHDAY) BETWEEN 1983 AND 1986 ORDER BY CFIRSTNAME

Для фильтрации отбираемых значений можно применить ключевое слово|


IN. Допустим, нужно показать записи о всех клиентах, прибывших из горо-|
дов Москва, Красноярск и Санкт-Петербург. Без использования члена IN
инструкция может выглядеть таким образом:
SELECT * FROM OLDFOX!NAMES;
WHERE ССГГС="Санкт-Петербург";
OR CCITY="MocKBa";
OR CCITY="Красноярск"

А вот та же инструкция с использованием слова IN:


SELECT * FROM OLDFOX!NAMES;
WHERE CCITY IN ("Красноярск","Москва","Санкт-Петербург")
Урок 16. Создание и использование запросов 233

Для того чтобы запретить вывод повторяющихся значений, необходимо до­


бавить в SQL-инструкцию еще одно ключевое слово — DISCTINCT (аналог
флажка No duplicates на вкладке Miscellaneous). Если мы захотим узнать,
какие города есть в таблице names, нам достаточно написать простенькую
инструкцию:
SELECT CCITYAS ГОРОД FROM OLDFOX! NAMES

и посмотреть результат — рис. 16.42.

Рис. 16.42. Список городов Рис. 16.43. Результат запроса


из таблицы names с использованием слова DISCTINCT

Мы видим, что в этом случае значения записей повторяются. На рис. 16.43


показан результат работы инструкции
SELECT DISCTINCT CCITY AS ГОРОД FROM OLDFOX!NAMES

Единственное условие — DISCTINCT в инструкцию нужно включать перед


именами выбранных полей.

Подзапросы
Применяя SQL-инструкции, разрешается использовать до десяти вложен­
ных запросов. Конструкция, имеющая вложенные запросы, называется под­
запросом. Допустим, нам понадобилось узнать, какой была максимальная
заплаченная сумма за проживание в нашем отеле, а также выбрать клиен-

I
234 Часть I. Процедурное программирование в Visual FoxPro

тов, которые заплатили больше половины от максимальной. Зачем нам это


нужно в реальной жизни, я не знаю, но в данном случае инструкция SQL
будет иметь следующий вид:
SELECT Cfirstname AS ФАМИЛИЯ;
Csecondname AS ИМЯ;
Ncost AS СУММА;
FROM OLDFOX! DEPCLIENTS;
WHERE Ncost > (SELECT MAX (Ncost) * 0,5 FROM DEPCLIENTS)

Результат выполнения этого подзапроса показан на рис. 16.44.

Рис. 16.44. Результат подзапроса 1

Изменив условие отбора


WHERE NCOST < (SELECT MAX (NCOST) * 0,5 FROM DEPCLIENTS)

получим прямо противоположный результат — рис. 16.45.


При построении данной инструкции мы использовали функцию МАХ(), КО-
торая определяет максимальное значение поля. В SQL-инструкциях можно
применять некоторые математические функции (табл. 16.3).
Все эти функции можно использовать как при написании SQL-инструкции,
так и при работе с конструктором запросов — в этом случае они находятся
в раскрывающемся списке Math (Математические) в группе Function
(Функции) окна построителя выражений (Expression Builder).
Урок 16. Создание и использование запросов 235

Таблица 16.3. Математические функции, доступные в SQL-инструкциях

Функция Описание
COUNT() Подсчитывает количество записей
SUM() Суммирует значения
AVG() Вычисляет среднее значение
MIN() Определяет минимальное значение
МАХО Определяет максимальное значение
COUNT(DISTINCT) Подсчитывает количество неповторяющихся записей
SUM(DISTINCT) Суммирует значения неповторяющихся записей
AVG(DISTINCT) Вычисляет среднее значение среди неповторяющихся записей

Рис. 16.45. Результат подзапроса 2

При использовании сложных выражений в инструкции необходимо указы­


вать тип объединения между таблицами:
SELECT (DATE()-NAMES.DARRDATE)*ROOMS.NPRICE; NAMES.CFIRSTNAME;
FROM OLDFOX!COUNTRIES INNER JOIN OLDFOX!NAMES;
INNER JOIN OLDFOX!ROOMS;
ON ROOMS.IDROOM = NAMES.IDROOMS;
ON COUNTRIES.IDCOUNTRY = NAMES.IDCOUNTRY;
236 Часть I. Процедурное программирование в Visual FoxPro

WHERE (DATE()-NAMES.DARRDATE)*ROOMS.NPRICE > 36500;


AND COUNTRIES.CCOUNTRY = "Россия"

Так как в данном примере условие выборки состоит из двух условий, необ­
ходимо дважды указать тип объединения:
INNER JOIN OLDFOX'NAMES;
INNER JOIN OLDFOX!ROOMS;
ON ROOMS.IDROOM = NAMES.IDROOMS;
ON COUNTRIES.IDCOUNTRY - NAMES.IDCOUNTRY;

Использование HAVING
Ключевое слово HAVING имеет тот же смысл, что и слово WHERE, но в то вре­
мя как WHERE используется для выборки отдельных строк, удовлетворяющих
условию, HAVING "работает" с группами записей. Определим города, из кото-
рых в наш отель прибыло по два постояльца:
SELECT CCITY FROM OLDFOX!NAMES;
GROUP BY CCITY;
HAVING COUNT (*)>2

Использование переменных
в SQL-инструкциях SELECT
До сих пор мы сами задавали условия для выборки тех или иных данных из
таблиц. Но для того чтобы значения критериев отбора мог задавать конеч­
ный пользователь, необходимо использовать переменные:
nMYCOST=12000
SELECT CFIRSTNAME, CSECONDNAME, NCOST FROM OLDFOXiDECLIENTS;
WHERE NCOST=NMYCOST

Рассмотрев данный пример, нетрудно догадаться, каким образом можно ор­


ганизовать работу пользователя с запросом. Правильно, можно использо­
вать экранную форму, в полях ввода которой пользователь и будет задавать
те или иные значения для формирования критерия отбора записей. А как
будет выполняться запрос? Да запросто: сохраняем нашу инструкцию в виде
файла с расширением prg и назначаем команду
DO <имяг_нашей_программы>

для события click какого-нибудь элемента экранной формы.


По умолчанию результат работы SQL-инструкции SELECT выводится в окно.
Browse. "Пункт назначения" можно изменить, добавив в инструкцию кля
чевое слово INTO:
Урок 16. Создание и использование запросов 237

nMYCOST=12000
SELECT CFIRSTNAME, CSECONDNAME, NCOST FROM OLDFOX!DECLIENTS;
WHERE NCOST=NMYCOST;
INTO CURSOR MYQWERY

В данном случае результат будет помещен в курсор MYQWERY. А вот и таблица


с допустимыми значениями оператора INTO — табл. 16.4.

Таблица 16.4. Значения оператора INTO

Значение Описание

INTO ARRAY <имя_массива> Результат запроса выводится в массив


INTO CURSOR <имя_курсора> Результат запроса выводится в курсор
INTO TABLE <имя_таблицьО Результат запроса выводится в таблицу
TO PRINTER Результат запроса выводится на принтер
TO SCREEN Результат запроса выводится на экран
TO FILE <имя_файла> Результат запроса выводится в указанный файл

Построение перекрестых таблиц


В некоторых случаях удобнее просматривать данные в виде перекрестной
таблицы. Например, нам необходимо провести небольшой анализ— в ка­
ком из номеров нашего отеля чаще всего предпочитали останавливаться
клиенты и от каких клиентов (имеется в виду город постоянного прожива­
ния), мы получили наибольшую прибыль — во как закрутили, скоро дейст­
вительно аудиторами станем!
Нам не составит труда "соорудить" соответствующий запрос и получить же­
лаемый результат (рис. 16.46).
Как говорится, что хотели, то и получили. Действительно, мы видим и го­
рода, и номера апартаментов, и уплаченные суммы. Но для проведения ана­
лиза такой режим отображения данных не совсем удобен, и поэтому мы
примем решение вывести результат нашего запроса в виде перекрестной
таблицы. Но сначала дадим определение — что же это такое?
Перекрестная таблица (Cross-Tab) представляет собой такой вид запроса,
в котором определяются заголовки столбцов и строк таблицы, а затем вы­
числяются результаты ячеек, находящихся на пересечении соответствующих
столбцов и строк.
Для представления данных в виде перекрестной таблицы сохраним резуль­
тат нашего запроса в отдельной таблице:
238 Часть I. Процедурное программирование в Visual FoxP,

SELECT DEPCLIENTS.CCITY, DEPCLIENTS.NCOST, DEPCLIENTS.IDROOMS;


FROM OLDFOX! C I T I E S , OLDFOX!DEPCLIENTS;
INTO TABLE QUERY2.DBF

Рис. 16.46. Результат запроса

Существует два способа для построения перекрестной таблицы — использо-


вание мастера Cross-Tab Wizard и использование соответствующей SQL-
инструкции. Рассмотрим процесс создания перекрестной таблицы с по­
мощью мастера, который можно вызвать следующим образом:
1. Любым из уже известных нам способов вызываем диалоговое окно New
Query (Новый запрос) (рис. 16.47).
2. Нажав кнопку Query Wizard, выбираем мастер перекрестных таблиц.
(рис. 16.48).

Рис. 16.47. Диалоговое окно New Query Рис. 16.48. Диалоговое окно Wizard Selection
Урок 16. Создание и использование запросов 239

На первом этапе работы мастера необходимо указать поля, значения кото­


рых будут выведены в перекрестную таблицу (рис. 16.49).

Рис. 16.49. Первый шаг работы мастера перекрестных таблиц

Выбрав необходимые поля, переходим ко второму шагу работы мастера


(рис. 16.50).

Рис. 16.50. Второй шаг работы мастера перекрестных таблиц


240 Часть I. Процедурное программирование в Visual FoxPro

На данном этапе предлагается определить строки, столбцы и значения по­


лей (необходимые поля просто перетаскиваются мышью).

Рис. 16.51, Третий шаг работы мастера перекрестных таблиц

На третьем шаге работы мастера (рис. 16.51) можно установить опции


позволяющие вычислять групповые значения по полю (табл. 16.5).

Таблица 16.5. Возможное итоговое значение

Опция Назначение
Sum Итоговые значения равны сумме значений
Count Итоговые значения равны количеству значений
Average Итоговые значения равны среднему значению
Max Итоговые значения равны максимальному значению
Min Итоговые значения равны минимальному значению

В перекрестную таблицу можно добавить итоговый столбец и установить


для него определенное значение (табл. 16.6).

Таблица 16.6. Значения итогового столбца

Опция Назначение
Sum of data В итоговом столбце — сумма значений текущей
строки
Урок 16. Создание и использование запросов 241

Таблица 16.6 (окончание)

Опция Назначение

Number of cells containing data В итоговом столбце — количество ячеек текущей


строки, содержащих данные
Percentage of the table total В итоговом столбце — процент значений текущей
строки по отношению к итоговой сумме
None Итоговый столбец отсутствует

Рис. 16.52. Заключительный этап работы мастера

На заключительном этапе (рис. 16.52) мастер спрашивает, что делать с по­


лученным результатом — табл. 16.7.
Таблица 16.7. Назначение опций мастера перекрестных таблиц

Опция Назначение

Save cross-tab query Сохранить созданный запрос

Save and run cross-tab query Сохранить созданный запрос и запустить его
на выполнение
Save cross-tab query and modify Сохранить созданный запрос и открыть его в
in the Query Designer окне конструктора запросов для модифика­
ции
242 Часть I. Процедурное программирование в Visual FoxPro

Флажок Display null values позволяет отображать или, наоборот, скрывать


нулевые значения.
Что же, пора посмотреть, чего мы там натворили — рис. 16.53.

Рис. 16.53. Перекрестная таблица

Теперь посмотрим, как будет выглядеть код для инструкции SQL. Самый
простой способ — модифицировать полученный запрос в конструкторе и
"подсмотреть" SQL-оператор, сгенерированный Visual FoxPro (рис. 16.54).

Рис. 16.54. Этот SQL-оператор — результат работы мастера перекрестных таблиц


Урок 16. Создание и использование запросов 243

Этот фрагмент кода можно скопировать в буфер обмена и затем использо­


вать в своих приложениях.
Обрати внимание, каким образом происходит построение перекрестной
таблицы: DO (_GENXTAB) WITH. .. Для этого используется специальная про­
грамма _GENXTAB, входящая в состав Visual FoxPro. Для ее корректной рабо­
ты необходимо определение специальных параметров — табл. 16.8.

Таблица 16.8. Параметры, передаваемые программе _GENXTAB

Номер Значение
Назначение
параметра по умолчанию
1 Имя выходного файла или курсора Xtab.dbf
2 Создание только курсора .Т.

3 Закрывать таблицу при выходе из программы .Т.

4 Отображать индикатор работы программы .т.


5 Номер поля, являющегося строкой перекрестной 1
таблицы
б Номер поля, являющегося столбцом перекрестной 2
таблицы
7 Номер поля, являющегося полем данных для пере­ 3
крестной таблицы
8 Будет формироваться итоговое поле .F.

9 Тип вычислений в итоговом поле: 0 — сумма, 0


1 — количество, 3 — процент

Изменяя эти параметры, можно менять режим отображения перекрестной


таблицы.

Использование SQL-инструкций
в программах
Так как инструкция сохраняется в виде файла с расширением qpr, для ее
выполнения достаточно использовать простую команду:
DO <имя файла>.qpr
УРОК 17

Использование
представлений данных (видов)
Как всегда, возникает самый главный вопрос — а что это такое? Отвеча-
ем — почти то же, о чем мы читали в предыдущей главе. Почему почти?
А вот это и есть самый важный вопрос, потому что между этими двумя поч-
ти эквивалентными понятиями есть различия и они принципиальны.
• Запросы хранятся в отдельных файлах с расширением qpr, а представле-
ния данных — в самой базе данных.
• Самое главное — представления позволяют обновлять данные.
• С помощью представления можно обновлять данные, сохраняемые в не-
скольких связанных файлах.
• Созданное представление данных можно использовать как обычную таб-)
лицу в отчетах, формах, запросах.
• С помощью представления данных можно ограничить доступ пользовате-
ля к отдельным записям.

Создание нового представления данных


Создание нового представления в принципе не отличается от создания лю-
бого нового элемента приложения:
• выберите в системном меню команду File J New | View (Файл | Новый )
Вид);
• в окне диспетчера проекта: вкладка Data (Данные), элемент Local Views
(Представление локальных данных);
• в окне Command (Команда): команда Create View (Создать представление
данных).
Независимо от того, какой способ выбран, на экране появится диалоговое
окно New Local View (Новое представление данных) (рис. 17.1).
Урок 17. Использование представлений данных (видов) 245

Рис. 17.1. Диалоговое окно New Local View

Как всегда в таких случаях, Лис предлагает воспользоваться либо услугами


мастера, либо построить новый вид самостоятельно, используя конструктор.
Мы с тобой трудностей не боимся, поэтому выбираем конструктор (рис. 17.2).

Рис. 17.2. Диалоговое окно View Designer

Конструктор данных почти полностью идентичен конструктору запросов (за


исключением новой вкладки Update Criteria), поэтому мы не будем подроб­
но останавливаться на его описании, а сразу перейдем к делу.
Задача следующая: нам необходимо знать, на каком этаже живет тот или
иной клиент, а также сумму, которую он должен уплатить на сегодняшнюю
дату.
Для создания данного представления нам потребуются три таблицы:
Floors.dbf, Rooms.dbf и Names.dbf. Воспользовавшись кнопкой Add Table
246 Часть I. Процедурное программирование в Visual FoxPro

(Добавить таблицу), расположенной на панели управления View Designer


(Конструктор представлений данных), добавим в наше представление ука­
занные таблицы (рис. 17.3).

Рис. 17.3. Добавление таблиц в представление данных

Теперь необходимо указать поля, которые будут "участвовать" в представле-


нии данных. Здесь нет ничего сложного, и как это сделать — описано ранее
при изучении конструктора запросов. Единственное, что может вызвать за­
труднение, — это создание вычисляемого поля (с суммами оплаты). Но ин
здесь, оказывается, никаких проблем не возникает: в конструкторе можно
воспользоваться построителем выражений, в котором можно написать лю-
бое выражение на языке FoxPro. Вот и напишем:
rooms.nprice*(date() - names.arrdate)

и включим это выражение в наше представление.


Как и в конструкторе запросов, в конструкторе представлений можно задать
условия объединения таблиц — вкладка Join (Объединение) (рис. 17.4).
А для задания условий выборки данных можно воспользоваться вкладкой
Filter (Фильтр) (рис. 17.5).
За порядок отображения записей "отвечает" вкладка Order By (Сгруппиро­
вать по) (рис. 17.6).
А теперь запустим наше представление в "первое плавание" (рис. 17.7).
урок 17. Использование представлений данных (видов) 247

Рис. 17.4. Условия объединения таблиц

Рис 17.5. Условие выборки данных


248 Часть I. Процедурное программирование в Visual FoxPro

Рис. 17.6. Порядок отображения записей

Рис. 17.7. Представление данных

Таким образом, созданные представления можно просматривать, как обыч­


ные таблицы, использовать их в качестве источника данных для экранных
форм, отчетов и т. д. Как и при работе с обычными таблицами, при работе
Урок 17. Использование представлений данных (видов) 249

с представлениями вполне допустимо использование соответствующих


команд: USE, BROWSE И т. д.
Более того, сами записи в представлении данных можно редактировать —
в этом-то и состоит главное отличие представления от запроса.
В конструкторе представлений имеется вкладка Update Criteria (Критерии
обновления), которая и содержит опции, связанные со способностью пред­
ставлений обновлять (редактировать) входящие в них данные (рис. 17.8).

Рис. 17.8. Опции вкладки Update Criteria

По умолчанию, изначально, обновление данных в таблицах, входящих в со­


став представления, запрещено. Чтобы разрешить обновление записей, не­
обходимо указать таблицу, к которой эти записи принадлежат — это делает­
ся с помощью раскрывающегося списка Tables (Таблицы).
При выборе необходимой таблицы ее поля (не все, а только те, которые
включены в представление данных) будут отображены в списке Field name
(Имя поля). Если таблица имеет первичный ключ (индекс), то в первой ко­
лонке, где изображен ключик, появится галочка. Мы можем изменить зна­
чение первичного ключа только в том случае, если поле, содержащее его,
входит в набор полей, включенных в наше представление данных.
Кнопка Reset Key (Сброс ключа) позволяет вернуть первоначальное значе­
ние ключа.
Кнопка Update All (Обновить все) позволяет установить, какие именно поля
будут обновляться. Но даже если указать, что разрешено обновление всех
250 Часть I. Процедурное программирование в Visual FoxPro

полей, все равно никакого обновления не получится, если ты забудешь при


этом отметить галочкой флажок Send SQL updates (Отправлять обновления).
Так что отметь его, не забудь. Разрешив обновления, нужно выбрать одну
из четырех опций, перечисленных в табл. 17.1.

Таблица 17.1. Опции вкладки Update Criteria

Опция Описание

Key fields only В поиске записей, которые следует обновить


(Только ключевые поля) в исходных таблицах, используется только
значение ключевого поля
Key and updatable fields В поиске записей, которые следует обновить
(Ключи и обновляемые поля) в исходных таблицах, используются значения
ключевого поля и всех обновляемых полей
Key and modified fields В поиске записей, которые следует обновить
(Ключи и модифицированные поля) в исходных таблицах, используются значения
ключевого поля и модифицированных полей
Key and timestamp На локальных станциях эта опция недоступ­
(Ключи и временная метка) на. А вообще это — запрет всех обновлений,
если было изменено ключевое поле или вре­
менная метка. Используется в сетевых вер­
сиях

Рис. 17.9. Пример критерия отбора записей


Урок 17. Использование представлений данных (видов) 251

Последние две опции на этой вкладке позволяют определить, каким же


именно способом обновить записи: либо удалить исходные и затем вставить
новые (SQL DELETE then INSERT), либо просто обновить существующие
(SQL UPDATE).
Ну вот, более или менее разобрались с представлениями данных, но возни­
кает одно но: а как сделать так, чтобы пользователь мог сам определять ус­
ловия для отбора записей?
Простой пример — рис. 17.9.
В данном случае в представление данных войдут те фамилии из таблицы
names, которые начинаются на букву А — рис. 17.10.

Рис. 17.10. Результат отбора записей — вид

Но мы можем позволить пользователю самому определить условия выборки,


и делается это с использованием параметров представления.

Параметры представления данных


Если задать эти самые параметры, то они будут запрашиваться при откры­
тии представления. Для определения параметров используется команда View
Parameters (Параметры представления) из меню Query (Запрос) (рис. 17.11).
В открывшемся диалоговом окне мы можем задать список параметров, оп­
ределив для каждого тип и имя. Теперь для определения условия выборки
Данных достаточно на вкладке Filter (Фильтр) указать имя необходимого
параметра (рис. 17.12).
252 Часть I. Процедурное программирование в Visual FoxPro

Рис. 17.11. Диалоговое окно для определения параметров

Рис. 17.12. Использование параметра для определения условия выборки данных

Имя параметра указывается в поле ввода Example (Пример) и перед ним


ставится знак вопроса, который является признаком использования napa-
метра.
Параметров может быть несколько, и при этом для задания значения каж,
дого из них будет открываться отдельное окно. А вот так будет работать на
ше модифицированное представление:
1. Задаем значение параметра (рис. 17.13).
2. Получаем результат (рис. 17.14).
Но очевидно, что использование данной технологии не очень удобно для
конечного пользователя — не будет он разбираться во всяких меню, команд-
Урок 17. Использование представлений данных (видов) 253

дах и т. п.! Это я тебе точно говорю. А выход очень простой — использовать
в качестве параметров все те же переменные памяти, значения которым
пользователь может присваивать с помощью полей ввода в экранной форме.
Вот и все. Все довольны! Более того, при этом окна для ввода значения па­
раметров открываться не будут.

Рис. 17.13. Значение параметра

Рис. 17.14. Результат

Замечание
В представление данных, помимо обычных полей, можно включать и поля типа
Memo. Включать-то можно, да вот беда — обновляться (см. ранее) они не будут
ни при каких условиях. Се ля ви, что тут поделать.

Использование представления данных


в отчете
Как уже было сказано, представления могут быть использованы при созда­
нии отчетов. Например, нам нужно получить отчет, содержащий данные
254 Часть I. Процедурное программирование в Visual FoxPro

всех трех указанных ранее таблиц. Можно, воспользовавшись конструкто­


ром отчетов, назначить в качестве источника данных сами таблицы, но то­
гда придется конструировать многотабличный отчет со связями между таб­
лицами типа "один-ко-многим". Можно воспользоваться мастером (One-To-
Many Report Wizard), но этот мастер работает только с двумя связанными
таблицами. Наиболее рациональным вариантом является именно использо­
вание представления в качестве источника данных. Давай попробуем соз-
дать такой отчет в конструкторе.
Как обычно, назначаем источник данных для нашего отчета, указав в диа-|
логовом окне опцию Views (Представления данных) (рис. 17.15).

Рис. 17.15. В качестве источника данных мы выбираем не таблицы,


а наше представление

Для группировки данных в нашем отчете воспользуемся соответствующим


пунктом меню Report (Отчет) (рис. 17.16). На экране появится диалоговое
окно Data Grouping (Группировка данных) (рис. 17.17).
В данном окне мы можем задать условие группировки данных, причем
можно как просто указать поле, так и написать какое-нибудь выражение (на
языке Visual FoxPro, естественно).
В нашем случае данные будут представлены в виде групп, заголовком кото-
рых будет являться номер этажа. Более того, мы можем получить итоговые
значения как по каждому этажу (поместив соответствующее выражение в
область отчета Group Footer), так и итоги по всему отчету, воспользовав-
шись командой Report | Title | Summary.
В конструкторе наш отчет будет выглядеть примерно так, как на рис. 17.18.
При запуске данного отчета на выполнение появится окно для ввода пара-
метров, после чего отчет будет выполнен (рис. 17.19).
Урок 17. Использование представлений данных (видов) 255

Рис. 17.16. Группировка данных

Рис. 17.17. Диалоговое окно Data Grouping


256 Часть I. Процедурное программирование в Visual FoxPro

Рис. 17.18. Макет нашего отчета в окне конструктора

Рис. 17.19. Наш отчет в режиме предварительного просмотра

Ну и как, удобно использовать представления? За три минуты мы получили


отчет с данными из трех таблиц, да еще и возможность самим задавать
условия отображения записей. Что ж, перейдем к следующему уроку.
УРОК 18

Внедрение OLE-объектов

Для начала короткая справка, дающая ответ на твой вечный вопрос: "А это
еще что такое?!" В твоем приложении может быть сколь угодно этих самых
OLE-объектов, и несмотря на то, что созданы они не средствами Visual
FoxPro, они являются полноценными членами твоего приложения. В об­
щем, можно дать такое "примитивное" определение для OLE-объекта — эта
штука создана в какой-либо программе Windows (не Visual FoxPro), но так­
же может использоваться в другой, не "родной" программе, например в
Visual FoxPro. В таблицах Visual FoxPro могут храниться как сами OLE-
объекты, так и связи с этими объектами. И вот именно от этого будет зави­
сеть, каким образом будет запоминаться и обновляться информация о дан­
ном объекте после того, как он будет помещен в таблицу.
При внедрении объекта в таблице Visual FoxPro хранится сам объект. Если
дважды щелкнуть на таком объекте, то откроется приложение, в котором
данный объект был создан. При этом, используя данное приложение, объ­
ект можно редактировать, после чего все внесенные в него изменения будут
сохранены в таблице.
Несколько иная ситуация возникает при связывании объекта — в таблице
хранится только ссылка о месте расположения исходного файла, а сами
данные хранятся в этом файле. Данные будут обновлены только в случае
обновления исходного файла.
Приложение, в котором объект был создан, называется приложение-сервер, а
приложение, в которое данный объект внедряется — приложение-клиент.
Так что же мы можем назвать OLE-объектом? Я думаю, что в свете изло­
женного ранее нетрудно догадаться, что этим самым объектом может быть
практически любой объект, созданный в приложениях Windows, поддержи­
вающих технологию OLE. Например, документ Word или электронная таб­
лица Excel. Файл звукозаписи или видеоизображение. Точечный рисунок,
наконец. Вот в качестве примера использования OLE-объектов мы и рас­
смотрим внедрение и связывание рисунков в наши таблицы. В качестве ри­
сунков у нас будут выступать фотографии постояльцев отеля Old Fox Hotel.
258 Часть I. Процедурное программирование в Visual FoxP.

OLE-объекты в таблицах хранятся в полях типа General и только там. Если


мы откроем такую таблицу в режиме просмотра, мы увидим, что в полях
данного типа стоит пометка gen или Gen. Что сие означает? Очень просто —
если поле пусто, то при просмотре стоит gen, а если поле содержит OLE-
объект, то метка будет выглядеть как Gen (рис. 18.1).

Рис. 18.1. Таблица, содержащая поля G e n e r a l

Для вставки нового объекта в поле General необходимо дважды щелкнуть


мышью на пометке gen, после чего откроется окно редактирования данного
поля (рис. 18.2).
Для вставки нового объекта необходимо выбрать пункт Insert Object (Встав­
ка объекта) из меню Edit (Редактирование), после чего откроется вот такое
диалоговое окно — рис. 18.3.
Как видно, данное окно содержит две опции: Создать новый и Создать из
файла.
При установке Создать новый необходимо в списке Тип объекта указать
сервер, который мы хотим использовать для создания объекта, и нажать
кнопку ОК. После этого будет запущено указанное приложение, с помощью
которого мы и создадим наш новый объект.
При установке Выбрать из файла внешний вид диалогового окна изменится,
и мы можем найти уже готовый файл для использования его в качестве
OLE-объекта.
Все это теория, а вот теперь переходим к практике.
Урок 18. Внедрение OLE-объектов 259

Рис. 18.2. Окно редактирования поля типа G e n e r a l

Рис. 18.3. Диалоговое окно Вставка объекта


260 Часть I. Процедурное программирование в Visual FoxPro

Внедрение нового OLE-объекта


Открываем таблицу, содержащую поля типа General, в режиме просмотра
Browse. Ставим курсор на необходимую запись и дважды щелкаем мышью
на пометке gen. После открытия диалогового окна укажем в нем Paintbrush
Picture (Рисунок Paint) и выполним команду Insert Object (Вставить объект).
После этого откроется указанное приложение, в котором можно создать
изображение. Чтобы никого не обидеть, проведем данный эксперимент на
авторе (рис. 18.4).

Рис. 18.4. Это автор

Чтобы отредактировать изображение, а в данном случае это просто необ­


ходимо, нужно выбрать команду Точечный рисунок Object из меню Editj
(рис. 18.5).
Эта команда имеет подменю, в котором есть два пункта: Изменить и От-
крыть. Какой выбрать? Да любой, вся разница в том, что при выборе пункта
Изменить системное меню приложения-сервера (в нашем случае Paint) будет|
встроено в меню Visual FoxPro, а при выборе Открыть откроется приложе-
ние-сервер.
Мы рассмотрели процесс создания нового объекта, а как быть, если объек-
ты уже существуют (созданы ранее)? В этом случае в диалоговом окне
Урок 18. Внедрение OLE-объектов 261

Вставка объекта нужно вместо опции Создать новый указать опцию Создать
из файла. При этом диалоговое окно Вставка объекта примет такой вид —
рис. 18.6.

Рис. 18.5. Редактировать объект

Рис. 18.6. Диалоговое окно Вставка объекта


при установленной опции Создать из файла
262 Часть I. Процедурное программирование в Visual FoxPro

Рис. 18.7. Диалоговое окно Обзор


Урок 18. Внедрение OLE-объектов 263

Для выбора необходимого файла необходимо воспользоваться кнопкой Об­


зор, после чего откроется одноименное диалоговое окно, в котором можно
выбрать необходимый файл (рис. 18.7).
А вот и результат — рис. 18.8.

Связывание OLE-объекта
При связывании объекта в таблице Visual FoxPro хранится только ссылка на
данный объект, а сам объект располагается в другом месте. Для того чтобы
связать OLE-объект с его основной копией, можно воспользоваться уже
знакомой командой Insert Object или Paste Special (Специальная вставка).
Рассмотрим оба варианта, а ты уж сам решай, какой предпочтительней.
Открой приложение-сервер и выполни для связываемого объекта команды
Выделить все и Копировать. Этим самым ты поместишь объект в буфер об­
мена. Теперь открой в таблице окно редактирования для поля General и вы­
полни команду Paste Special (Специальная вставка) (рис. 18.9).

Рис. 18.9. Диалоговое окно Специальная вставка

Ссылка на указанный объект будет запомнена в соответствующем поле


General. При изменении файла-источника будет автоматически обновлен и
объект в Visual FoxPro.
Для связывания объекта с помощью команды Insert Object необходимо
в диалоговом окне Вставка объекта установить флажок Связь (рис. 18.10).
Если объект размещен со связью, то связь можно отредактировать или вовсе
Удалить с помощью диалогового окна Связи (рис. 18.11).
Кнопки, расположенные в данном окне, описаны в табл. 18.1.
264 Часть I. Процедурное программирование в Visual FoxPro

Рис. 18.10. Установка связи в диалоговом окне Вставка объекта

Рис. 18.11. Диалоговое окно Связи

Таблица 18.1. Кнопки окна Связи

Кнопка Описание

Обновить сейчас Обновляет связь


Открыть источник Открывает исходный файл
Сменить источник Заменяет исходный файл
Разорвать связь Разрывает связь. После этой процедуры, естественно,
ни о каком обновлении объекта не может быть и речи
Урок 18. Внедрение OLE-объектов 265

Удаление OLE-объекта
Ну, как говорится, ломать — не строить. Единственная команда меню Edit
(Редактирование) — Clear (Очистить) и все, объект "приказал долго жить".

Использование функций GETDIR(), GETFILE()


и команда APPEND GENERAL
Вот опять перед нами возникает та же проблема: как все это растолковать
конечному пользователю? Да в принципе, это ему и не нужно: я имею в
виду Insert Object, Paste Special и т. д. Тем более, вряд ли у него будет воз­
можность при работе с готовым приложением "проникнуть" в системное
меню Visual FoxPro. А пользователь требует, чтобы все было легко и понят­
но. Что же, пользователя надо любить, и поэтому мы предоставим ему воз­
можность самостоятельно выбирать и вставлять в приложение OLE-
объекты. Применительно к нашему случаю, рассмотрим внедрение изобра­
жений.
Создадим новую экранную форму с двумя кнопками: Выбрать и Вставить
(рис. 18.12).

Рис. 18.12. Экранная форма для выбора графического файла

Для кнопки Выбрать напишем следующий код в событии click:


PUBLIC Myfile
GETDIR ()
Myfile=GETFILE ("BMP")

А для кнопки Вставить напишем следующее:


APPEND GENERAL Gphoto FROM SMyfile
Вот и все. Запускаем на выполнение и обсуждаем, как вся эта система будет
Работать. При нажатии кнопки Выбрать происходят следующие процессы:
создается глобальная переменная Myfile — в ней будет храниться имя вы­
бранного файла. Далее "срабатывает" функция GetDirO, которая позволяет
выбрать каталог (рис. 18.13).
266 Часть I. Процедурное программирование в Visual FoxPro

Рис. 18.13. Диалоговое окно Select Directory

После выбора каталога в работу включается функция GetFileO, которая


позволяет выбрать необходимый файл. У данной функции есть несколько
параметров, один из них — расширение файла. В нашем примере мы указа­
ли bmp, и поэтому данная функция будет отображать только файлы с ука­
занным расширением (рис. 18.14).

Рис. 18.14. Диалоговое окно Open


Урок 18. Внедрение OLE-объектов 267

Если применить данную функцию без параметров, в диалоговом окне будут


отображены все имеющиеся в данном каталоге файлы.
Файлы выбраны, и остается только вставить их в соответствующую таблицу
с помощью следующей команды:
APPEND GENERAL Gphoto FROM SMyfile

После команды APPEND GENERAL следует указать имя поля General, а после
ключевого слова FROM пишут имя файла, можно с указанием пути. Но мы в
данном случае не стали явно прописывать имя, а, воспользовавшись макро­
подстановкой (&), передали в данную команду значение переменной
&Myfile.
Конечно, здесь еще нужно предусмотреть, чтобы объект "попал" в нужную
таблицу и в нужную запись, но это, как говорится, уже "дело техники".
УРОК 19

Использование
компонентов ActiveX
и библиотек классов
До сих пор мы использовали только те элементы управления, которые дос­
тупны из различных панелей управления Visual FoxPro. Это, так сказать,
стандартные элементы управления, входящие в состав Visual FoxPro. Но,
как часто бывает в жизни, здесь мы с тобой видим только надводную часть
"айсберга", а все остальное пока от нас скрыто... Улавливаешь, о чем это я?!
Правильно, кроме уже известных нам элементов управления существует
множество других, как входящих в состав Visual FoxPro, так и разработан­
ные сторонними фирмами. Те элементы управления, которые входят в со­
став Visual FoxPro, находятся в специальных каталогах, которые называются
библиотеками классов. В Visual FoxPro эти библиотеки объединены под об­
щим названием — Visual FoxPro Foundation Classes (Основные классы Visual
FoxPro). Для чего это вообще все нужно? Для того чтобы облегчить нам с
тобой процесс создания приложений, и сейчас мы разберем, каким же обра­
зом это происходит.

Использование библиотек классов


Чтобы добраться до необходимой нам библиотеки, воспользуемся уже хо­
рошо знакомой нам панелью инструментов Form Controls, а именно кноп­
кой View Classes (Просмотр классов) (рис. 19.1).
При нажатии этой кнопки мы увидим меню, содержащее три пункта: Add
(Добавить), Standard (Стандартные), ActiveX Controls (Элементы управления
ActiveX).

Рис. 1 9 . 1 . Нам нужна ЭТА кнопка!


Урок 19. Использование компонентов ActiveX и библиотек классов 269

По умолчанию галочкой отмечен пункт Standard (Стандартные), и на пане­


ли Form Controls отображены стандартные элементы управления, которыми
мы уже пользовались. Чтобы добавить внешнюю библиотеку классов, необ­
ходимо выбрать пункт меню Add (Добавить). При этом откроется диалого­
вое окно Open (Открыть), в котором нам нужно указать файл необходимой
библиотеки. Библиотеки классов имеют расширение vex. В данном случае
нас будет интересовать каталог classes, в котором "лежат" четыре библиотеки
классов Visual FoxPro (рис. 19.2).

Рис. 19.2. Диалоговое окно Open.


Именно в нем мы можем выбрать необходимую библиотеку

Укажем библиотеку buttons.vcx. Она содержит кнопки, которые могут ис­


пользоваться для перемещения по записям таблиц. После выбора необхо­
димой библиотеки в меню кнопки View Classes (Просмотр классов) на па­
нели Form Controls (Элементы управления формы) будет добавлен пункт с
названием выбранной библиотеки, а стандартные элементы управления бу­
дут заменены на элементы управления данной библиотеки (рис. 19.3).

Рис. 19.3. Измененная панель Form Controls


270 Часть I. Процедурное программирование в Visual FoxPro

Рассмотрим элементы управления, входящие в состав библиотеки классов


buttons.vcx — табл. 19.1.
Таблица 19.1. Элементы управления библиотеки buttons.vcx

Элемент Описание

С помощью этой кнопки можно отправить данные по электрон­


mailbtn ной почте
Группа кнопок для перемещения по записям таблицы
vcr

cmdok Кнопка ОК
Кнопка Help
cradhelp

Кнопка Cancel
cmdcancel

Все эти элементы можно размещать в экранных формах точно так же, как и
стандартные элементы управления (рис. 19.4).

РИС. 19.4. Фрагмент нашей экранной формы

Все, элемент управления добавлен в форму, и что самое интересное, он


полностью "готов к употреблению". Попробуй, пощелкай по кнопкам. Все
работает, происходит перемещение по записям таблицы и обновление эк­
ранной формы. И ничего выдумывать не надо!
Еще один способ использования внешних библиотек и элементов управле­
ния — применение галереи компонентов, в которой "собраны" все эти са­
мые основные классы (Foundation Classes).
Открыть галерею компонентов можно, воспользовавшись пунктом систем­
ного меню Tools | Component Gallery (рис. 19.5).
Для добавления необходимого элемента в экранную форму нужно нажать
правую кнопку мыши и выбрать пункт контекстного меню Add To Form
Урок 19. Использование компонентов ActiveX и библиотек классов 271

(Добавить в форму). Можно также просто "ухватить" его мышью и перета­


щить на экранную форму. '
Еше одним способом размещения в форме элементов управления из внеш­
них библиотек классов является использование Class Browser (Браузер клас-

Рис. 19.5. Диалоговое окно Component Gallery

Рис. 19.6. Диалоговое окно Class Browser


272 Часть I. Процедурное программирование в Visual FoxPro

сов) (рис. 19.6). Открыть его можно, воспользовавшись одноименным пунк­


том меню Tools (Инструменты).
Перенести выбранный элемент в экранную форму можно точно так же, как
и при использовании галереи компонентов.

Компоненты ActiveX
Компоненты ActiveX представляют собой объекты, включающие в себя дан-
ные и код. Их можно использовать так же, как и элементы управления
Visual FoxPro. Единственное их отличие от базовых компонентов Visual
FoxPro состоит в том, что они создаются не в среде FoxPro, а с помощью
других средств разработки, например Visual C++. А главным преимущест-
вом является то, что их много] Их разработкой занимаются все, кому не
лень — как коммерческие организации, так и программисты. Точное ко-
личество существующих компонентов ActiveX, наверное, одному Богу из­
вестно...
Ладно, лирику в сторону, переходим к практике. Для выбора необходимых
компонентов ActiveX необходимо воспользоваться пунктом ActiveX Controls
(Элементы управления ActiveX) из контекстного меню кнопки View Classes
(Просмотр классов) панели Form Controls (Элементы управления), после
чего появится вот такое сообщение — рис. 19.7.

Рис. 19.7. Предупреждающее сообщение

Ничего страшного, просто наш Лис просит указать, какие именно элементы
управления мы собираемся использовать, и просит воспользоваться пунктом
Options (Опции) из системного меню Tools (Инструменты) для выбора ком­
понентов. Что ж, так и поступим — рис. 19.8.
В списке Selected мы видим все доступные на нашем компьютере компо­
ненты ActiveX. Для того чтобы подключить дополнительные компоненты,
скажем, с компакт-диска, необходимо воспользоваться кнопкой Add (Доба­
вить). А для выбора уже имеющихся элементов достаточно отметить их кре­
стиками в списке Selected и нажать кнопку ОК.
После этой процедуры мы без хлопот можем добавить наши элементы на
панель Form Controls. Вот и давай выберем несколько наиболее часто при-
Урок 19. Использование компонентов ActiveX и библиотек классов 273

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


использовать следующие компоненты (рис. 19.9):
• Точечный рисунок;
• Документ Word;
• Презентацию Power Point;
• Microsoft Slider Control;
• Microsoft ProgressBar Control;
• Calendar Control.

Рис. 19.8. Диалоговое окно Options. Вкладка Controls

Рис. 19.9. Мы разместили необходимые элементы на панели Form Controls

Начнем с первых трех. Для этого создадим новую экранную форму с тремя
вкладками (рис. 19.10).
Разместив на первой вкладке компонент точечный рисунок, вызовем контек­
стное меню, в котором выберем пункт Точечный рисунок Object, а затем оп­
цию Открыть или Изменить
274 Часть I. Процедурное программирование в Visual FoxPro

Рис. 19.10. Форма стремя элементами ActiveX

При выборе пункта Открыть запустится приложение-сервер (в данном слу­


чае Paint), в котором откроется созданный рисунок. Если же выбрать опцию
Изменить, то к панелям инструментов Visual FoxPro добавятся панели инст-|
рументов Paint, и можно приступить к редактированию или созданию ри­
сунка.
Точно такие же манипуляции можно проделать и с остальными элементами
на вкладках нашей формы (рис. 19.11, 19.12).
Теперь рассмотрим использование остальных объектов ActiveX.
Элемент ProgressBar предназначен для визуального отображения какого-
нибудь процесса. Например, происходит сканирование большой таблицы, в
ходе которого с данными выполняются какие-либо действия. Процесс мо­
жет занимать довольно долгий промежуток времени, и для того чтобы поль­
зователь мог следить за ходом выполнения данного процесса, можно ис-
пользовать этот элемент. Создадим новую таблицу с одним полем и запол­
ним ее следующим образом:
SELECT Table1
FOR 1=1 ТО 10000
APPEND BLANK
REPLACE Nnumeric WITH RECNO()
ENDFOR
Урок 19. Использование компонентов ActiveX и библиотек классов 275

Рис. 19.11. Работа с Word

Рис. 19.12. Работа с PowerPoint


276 Часть I. Процедурное программирование в Visual FoxPro

Теперь создадим новую экранную форму и назначим эту таблицу в качестве


источника данных. Разместим в форме наш элемент ActiveX и обычную
командную кнопку (рис. 19.13).

Рис. 19.13. Пример использования элемента P r o g r e s s B a r

Если щелкнуть на данном элементе правой кнопкой, откроется контекстное


меню, в котором можно настроить некоторые свойства данного компонента
(рис. 19.14, 19.15).

Рис. 19.14. Контекстное меню для настройки свойств элемента P r o g r e s s B a r

В окне свойств элемента ProgressBar мы можем установить такие парамет­


ры, как: максимальное и минимальное значения, вид указателя мыши|
стиль отображения объекта и т. д.
В событии click для кнопки Сканировать напишем следующее:
SELE TABLE1
THISFORM.OLEC0NTROL1.MAX=RECCOUNT()
SCAN
REPLA NNUMERIC WITH NNUMERIC+1
THISFORM.OLECONTROL1.VALUE=RECNO()
ENDSCAN

Нетрудно догадаться, что oiecontroii не что иное, как имя нашего объекта
ProgressBar. На этом простом примере видно, каким образом можно ис-
пользовать данный компонент для визуализации тех или иных процессов.
Урок 19. Использование компонентов ActiveX и библиотек классов 277

Рис. 19.15. Диалоговое окно настройки свойств Рис. 19.16. Форма с элементом
элемента P r o g r e s s B a r Slider

Компонент ActiveX, именуемый как slider, представляет собой шкалу с


двигающимся маркером. Обычно он используется в различных программах-
плеерах для регулировки уровня громкости, в эквалайзерах и т. д. Но, тем
не менее, мы также можем использовать его в своих формах. Давай обра­
тимся к нашей новой форме, удалим из нее предыдущий компонент и доба­
вим элемент slider и объект Grid (рис. 19.16).
Теперь обратимся непосредственно к самому ActiveX-компоненту: в свойст­
ве mit данного объекта пропишем:
THIS.MIN-1
THIS.MAX=RECCOUNT()

В СОбыТИИ CHANGE:

MYREC=THIS.VALUE
SELE TABLE1
GO MYREC
THISFORM.REFRESH()

Запускаем форму (рис. 19.17).


А вот еще один (шуточный) пример использования slider — мы располо­
жим на форме три таких элемента и будем с их помощью изменять пара­
метры отображения объекта Grid (рис. 19.18).
В данном случае в событии change мы пишем следующий код:
• для первого:
THIS FORM.GRIDl.BACKCOLOR=RGB(THIS.VALUE,THIS.VALUE,THIS.VALUE)
278 Часть I. Процедурное программирование в Visual FoxPro

• для второго:
THISFORM.GRID1.FORECOLOR=RGB(THIS.VALUE,THIS.VALUE, THIS.VALUE)

• для третьего:
THISFORM.GRIDl.FONTSIZE=THIS.VALUE

Более того, для двух первых объектов необходимо установить свойство


Мах=255, а ДЛЯ т р е т ь е г о Мах=70, Min=8.

Рис. 19.17. Перемещение по записям с помощью элемента S l i d e r

Рис. 19.18. С помощью компонентов ActiveX пользователь


настраивает параметры отображения данных
Урок 19. Использование компонентов ActiveX и библиотек классов 279

Использование календаря
Одним из интересных примеров применения объектов ActiveX является ис­
пользование календаря. С помощью данного элемента мы можем вводить
даты в наши таблицы. Создадим новую форму, источником данных для ко­
торой будет являться таблица names, и добавим в нее указанный компонент
ActiveX (рис. 19.19).

Рис. 19.19. Форма со встроенным календарем

Указав в качестве источника данных соответствующее поле, можно вводить


даты с помощью календаря.
УРОК 20

Экспорт и импорт данных

В современном делопроизводстве широчайшее распространение получили


такие офисные приложения, как Word и Excel. Наш приятель Лис также
шагает в ногу со временем и умеет передавать данные из своих таблиц в
другие приложения, а также принимать данные из некоторых приложений. I

Лис и Excel
Самый простой способ передать данные из Visual FoxPro в Excel — восполь­
зоваться командой Export (Экспорт) из системного меню File (Файл)
(рис. 20.1).

Рис. 20.1. Для передачи данных используется соответствующий пункт системного меню

После выполнения данной команды мы увидим диалоговое окно Export


(Экспорт) (рис. 20.2).
Урок 20. Экспорт и импорт данных 281

Рис. 20.2. Диалоговое окно Export

В раскрывающемся списке Туре (Тип данных) следует указать, в какой тип


файлов будет осуществляться передача данных. В нашем случае мы выбрали
следующее — см. рис. 20.2.
В поле ввода То (Куда) необходимо указать местоположение и имя файла,
который будет "принимать" данные. Здесь можно как просто вписать имя
будущего файла, так и воспользоваться расположенной справа кнопкой,
которая открывает диалоговое окно Save As (Сохранить как) (рис. 20.3).

Р и с . 20.3. Диалоговое окно Save As позволяет задать имя файла

Далее, в поле ввода From (Откуда) необходимо указать имя таблицы, из ко­
торой будут переданы данные.
°се, да не все... По умолчанию в файл-приемник будут переданы все записи
и все поля указанной таблицы. Иногда такое "изобилие" просто ни к чему,
и для задания условий передачи мы воспользуемся кнопкой Options (Оп-
ции) (рис. 20.4).
282 Часть I. Процедурное программирование в Visual FoxPro

Рис. 20.4. Диалоговое окно Export Options

В данном диалоговом окне мы видим четыре кнопки, которые позволяют


задать условия для экспорта исходного файла. При нажатии кнопки Scope
(Диапазон) появляется еще одно диалоговое окно, которое позволяет вы­
брать диапазон передаваемых записей (табл. 20.1).

Таблица 20.1. Параметры окна Scope

Параметр Описание

АН (Все) Все записи таблицы


Next (Следующие) Следующие после текущей. Число указывается в поле ввода
Record (Запись) Запись номер...
Rest (Оставшиеся) Все записи после текущей

При нажатии кнопок For (Для) и While (Пока) появится уже хорошо знаков
мое нам окно Expression Builder (Построитель выражений), в котором мож-
но задать необходимые условия.
Кнопка Fields (Поля) позволяет выбрать те поля исходной таблицы, кото­
рые будут переданы (рис. 20.5).

Рис. 20.5. Диалоговое окно Field Picker


Урок 20. Экспорт и импорт данных 283

В окне Field Picker находится два списка. В левом отображены все поля ис­
ходной таблицы, в правом — те, которые будут передаваться в файл-
приемник. Для переноса полей в правый список используется кнопка Move
(Перенести). Наконец, когда все "формальности" улажены, можно нажать
кнопку ОК и посмотреть, что там у нас из всего этого получилось (рис. 20.6).

Рис. 20.6. Данные экспортированы в Excel

Да, все хорошо, но опять возникает проблема с нашим пользователем...


Ему-то, бедняге, как это все проделать? А для него мы создадим поле ввода
и кнопочку — пусть себе спокойно работает!
1. Создаем новую форму с источником данных names.dbf (рис. 20.7).
2. Пишем код для события click кнопки Экспорт (листинг 20.1).

Листинг20.1. Кнопка Экспорт

IF EMPTY(Thisform.Text1.Value)
=MESSAGEBOX("УКАЖИТЕ ИМЯ ФАЙЛА","СШИБКА")
ELSE
SELE Names
284 Часть I. Процедурное программирование в Visual FoxPro

My_File=ALLTR(Thisform.Textl.Value)
EXPORT TO &My_File TYPE XLS
ENDIF

Рис. 20.7. Экранная форма для экспорта данных

Вот и все. Чем хорош данный способ? В отличие от предыдущего, здесь по­
мимо таблиц можно использовать и представления данных. Да и вообще
удобнее для пользователя. Ты скажешь, а как же ограничить число переда­
ваемых полей и записей? Да элементарно — добавь в форму еще несколько
элементов управления (например, раскрывающийся список с наименова-
ниями полей, поле ввода для установки фильтра и т. д.), используй макро-
подстановки и все получится! Это, как говорится, дело техники...
Но при данном способе передачи мы просто получаем книгу Excel и все.
А если нам нужен "красивый" отчет? Например, такой — рис. 20.8.
Чтобы получить такую "красоту", нам необходимо воспользоваться для пе­
редачи данных механизмом OLE.
Код для кнопки Экспорт будет следующим — листинг 20.2.

Листинг 20.2. Кнопка Экспорт ("красивый" отчет)

Omyexcelreport=CREATEOBJECT("EXCEL.SHEET";
Qmyexcelreport.Application.Visible=.T.
Omyexcelreport=Omyexcelreport.Sheets[1]
SELE Names
WITH Omyexcelreport
WITH .Range("Al")
.Value="СПИСОК КЛИЕНТОВ"
Урок 20. Экспорт и импорт данных 285

WITH .Font
.Bold-.т.
.Size=14
ENDWITH
ENDWITH
ENDWITH
Nrow=5
SCAN
Nrow=Nrow+l
Qmyexcelreport.Cells(Nrow,1).Value=ALLTR(Names.Cfirstname)+;
" "+ALLTR(Names.Csecondname);
+" "+ALLTR(Clastname)
WITH Omyexcelreport
WITH .Cells(Nrow,1)
WITH .Font
IF Names.Csex="M"
.Bold-.T.
.Colorindex=4
ELSE
.Bold=.F.
.Colorindex=5
ENDIF
ENDWITH
ENDWITH
ENDWITH
ENDSCAN
Qmyexcelreport.Visible=.T.
RELEASE Omyexcelreport

Но есть и еще один способ. Для этого создадим "еще более красивый" отчет
и заполним его значениями из нашей таблицы. Отчет будем создавать
в Excel, после чего обязательно сохраним его под каким-либо именем
(рис. 20.9).
Изменим код кнопки Экспорт таким образом, чтобы данные "попадали" в
только что созданный нами новый файл (листинг 20.3).

Листинг 20.3. Кнопка Экспорт ("еще более красивый" отчет)

Oexcel=CREATEOBJECT("EXCEL.APPLICATION")
Oexcel.Workbooks.Open("C:\OLDFOX\MYREPORT")
WITH Oexcel
• C e l l s (2, ID .Value=DTOC(DATE() )
ENDWITH
286 Часть I. Процедурное программирование в Visual FoxPro

SELE Names
Nrow=ll
SCAN
Nrow=Nrow+l
Oexcel.Cells(Nrow,1).Value=ALLTR(Names.Cfirstname)+"
"+ALLTR (Names. Csecondname) ;
+" "+ALLTR(Names.Clastname)
Oexcel.Cells(Nrow,2).Value=Names.Idrooms
Oexcel.Cells(Nrow,3).Value=DTOC(Names.Darrdate)
Oexcel.Cells(Nrow,4).Value=DTOC(Names.Ddepdate)
ENDSCAN
Oexcel.Visible=.T.

Результат — на рис. 20.10.

Рис. 20.8. "Красивый" отчет

Таким образом, Visual FoxPro предоставляет нам широкий выбор возможно­


стей передачи данных из своих таблиц в электронные таблицы Excel. Более
того, мы можем решать и обратную задачу — принимать в таблицы Visual
FoxPro данные из других приложений. Рассмотрим это на примере Excel.
Урок 20. Экспорт и импорт данных 287

Рис. 20.9. Мы создали шаблон будущего отчета

Рис. 20.10. Мы поместили данные из таблицы в заранее созданный файл Excel


288 Часть I. Процедурное программирование в Visual FoxPro

Допустим, имеется электронная таблица, данные из которой необходимо


перенести в таблицу Лиса. (А у нас она есть, это таблица my_excei, которую
мы создали на предыдущем занятии.) Для решения данной задачи восполь­
зуемся пунктом Import (Импорт) системного меню File (Файл). После выбо­
ра данной команды мы увидим диалоговое окно Import (Импорт) (рис. 20.11).

Рис. 20.11. Диалоговое окно Import

В раскрывающемся списке Туре (Тип файла) указываем, из файла какого!


типа мы будем импортировать данные, а в поле ввода From (Откуда) задаем]
имя файла. Поле ввода То (Куда) доступно только для чтения и по умолча-j
нию там указан путь к каталогу Visual FoxPro. При работе с данным окном
удобнее воспользоваться услугами мастера (Import Wizard), что мы и сдела-|
ем (рис. 20.12).

Рис. 20.12. Первый шаг работы мастера


Урок 20. Экспорт и импорт данных 289

На данном этапе мастер просит указать тип импортируемых данных в спи­


ске File Type (Тип файла), источник данных Source File, а также файл,
в который будет произведен импорт данных (Destination File). Причем этот
самый Destination File можно как выбрать, включив опцию Existing table
(Существующая таблица), так и создать новый — опция New table (Новая
таблица). В данном случае будет открыто диалоговое окно Save As (Сохра­
нить как), в котором нужно задать имя создаваемого файла.
На следующем этапе (рис. 20.13) мастер просит указать, будет ли наша таб­
лица включена в состав базы данных (опция Add my table to the following
database), или это будет свободная таблица (Create my table as a stand-alone
free table).

Р и с . 20.13. Определение типа таблицы

На втором шаге (рис. 20.14) мы можем указать, с какой строки начать им­
порт данных (Begin import at row) и на какой строке расположить наимено­
вания полей (Field names in row). А зачем нам в таблице их наименования?
Ставим ноль. В списке Worksheet можно указать конкретный лист элек­
тронной таблицы, в нашем случае он один-единственный. Также можно
задать формат данных (опция Data Format).
На третьем шаге работы мастера (рис. 20.15) мы можем задать типы полей
нашей таблицы и определить заголовки, которые будут отображены при
Просмотре таблицы.

10 ч»..
290 Часть I. Процедурное программирование в Visual FoxPro ч

Рис. 20.14. Второй шаг работы мастера

Рис. 20.15. Третий шаг работы мастера

Далее можно определить дополнительные параметры (рис. 20.16):


• Code Page — это кодовая страница (Для Windows — 1251);
• Currency Symbol — "денежный" символ, будет отображаться с полями ти­
па Currency;
Урок 20. Экспорт и импорт данных 291

• 1000 Separator — разделитель тысяч;


• Decimal Separator — разделитель между целой и дробной частью чисел;
• Date Format — формат отображения дат.
И наконец, долгожданный финиш (рис. 20.17).

Рис. 20.16. Определение дополнительных параметров

Рис. 20.17. Последний этап работы мастера


292 Часть I. Процедурное программирование в Visual FoxPro

После нажатия кнопки Finish (Готово) произойдет импорт данных, в чем мы


можем легко убедиться, открыв для просмотра нашу таблицу (рис. 20.18).

Рис. 20.18. Эти данные получены из электронной таблицы Excel

А что это мы все про Excel? Кроме Excel существует множество других при-
ложений, с которыми Лис может обмениваться данными. Вот, например,
его младший братец FoxPro for DOS наотрез отказывается воспринимать
таблицы, созданные в Visual FoxPro! Ну, вроде все нормально, обычная таб-
лица, dbf, все как положено — ан нет! "Ругается", пишет что это "Not a
database file". Вот тут-то и приходят на помощь экспортно-импортные oпe-
рации. (Хотя в данном конкретном случае экспорт и не нужен — "визуаль­
ный" Лис вполне адекватно воспринимает таблицы, созданные "Досов­
ским" Лисом.) Более того, чтобы передать таблицу в формат DOS, доста­
точно такой команды:
COPY My_Table TO My_Dos_Table TYPE FOXPLUS AS 886
УРОК 21

Наборы форм

В Visual FoxPro можно объединить несколько форм в набор форм FormSet,


поведение которого можно контролировать как для единого объекта. При
этом у нас появляется возможность одновременного отображения на экране
всех входящих в набор форм, их перемещение, обновление и т. д.
Самое главное, весь этот "комплект" может работать с единой средой дан­
ных.
Создадим три экранных формы. В каждой из них расположим объект Grid и
назначим источники данных. Для первой — countries.dbf (рис. 21.1).

Рис. 21.1. Первая экранная форма будущего набора форм

Теперь выполним команду Create FormSet (Создать набор форм) из меню


Form (Форма). Наша форма стала не просто формой, а формой, входящей
в состав набора FormSet. Для того чтобы добавить в набор новые экран­
ные формы, необходимо выполнить команду Add New Form (Добавить но­
вую форму) из системного меню Form (Форма). Так и поступим, указав
294 Часть I. Процедурное программирование в Visual FoxPro

в качестве источника данных для новой формы таблицу городов cities.dbf


(рис. 21.2).

Рис. 21.2. Мы добавили еще одну форму

Таким же образом добавим еще одну форму, назначив ей в качестве источ­


ника данных таблицу depclients.dbf (рис. 21.3).

Рис. 21.3. Набор форм в окне конструктора

Обрати внимание на то, что у всего набора форм общий источник данных. .
Сохраним наш набор под любым именем и запустим на выполнение
(рис. 21.4).
Урок 21. Наборы форм 295

Рис. 21.4. Использование набора форм


УРОК 22

Создание меню приложения

Графический интерфейс — это то, что пользователь видит в первый момент


после запуска какого-нибудь приложения, и наша с тобой задача состоит в
том, чтобы сделать этот самый интерфейс как можно более функциональ-;
ным, красивым и удобным для пользователя. Встречают-то по одежке...
А т. к. современный пользователь работает с приложениями Windows, он
просто не может представить свою работу без системы меню.
Как и все другие компоненты приложения Visual FoxPro, меню можно соз­
дать как программно (написать код "вручную"), так и воспользоваться соот­
ветствующим набором инструментов. Но сначала давай определим, что не­
посредственно входит в понятие системы меню.
Система меню включает в себя линейку меню, состоящую из пунктов линей­
ки меню (другое их название — заголовки подменю), самих подменю или
всплывающих меню (popup-menu) и пунктов меню (рис. 22.1).
Для того чтобы понять, как вся эта конструкция будет работать, мы сейчас
попробуем написать программный код для генерации простейшего меню.
Сразу оговорюсь, что в среде Visual FoxPro обычно для создания меню ис­
пользуется соответствующий конструктор (Menu Designer), а код, написан­
ный "вручную", встречается довольно редко. Но, тем не менее, мы научимся
это делать.
Основных команд для создания меню не так уж и много: DEFINE PAD — ДЛЯ
создания линейки меню, DEFINE BAR — для определения заголовков подме­
ню и DEFINE POPUP — для создания самих подменю (листинг 22.1).

Листинг 22.1. Создание меню

* Определим главное меню


DEFINE MENU Mymenu BAR && ЗДЕСЬ Mymenu - ИМЯ НАШЕГО МЕНЮ
DEFINE PAD Padone OF Mymenu PROMPT "ФОРМА"&& определяем пункты линейки
DEFINE PAD Padtwo OF Mymenu PROMPT "ОТЧЕТ"
Урок 22. Создание меню приложения 297

ON PAD Padone OF Mymenu ACTIVATE POPUP Popone && определяем действия при
&& выборе пункта линейки
ON PAD Padtwo OF Mymenu ACTIVATE POPUP Poptwo
DEFINE POPUP Popone && определяем первое всплывающее меню
DEFINE BAR 1 OF Popone PROMPT "ЗАПУСК ЭКРАННОЙ ФОРМЫ" && определяем
&& заголовки пунктов всплывающего меню
DEFINE BAR 2 OF Popone PROMPT "ВЫХОД"
ON SELECTION BAR 1 OF Popone DO FORM Main && определяем действия
&& при выборе пункта всплывающего меню
ON SELECTION BAR 2 OF Popone QUIT
DEFINE POPUP Poptwo && определяем второе всплывающее меню, пункты подменю
&& и действия при их выборе
DEFINE BAR l OF Poptwo PROMPT "ПЕЧАТЬ ОТЧЕТА"
DEFINE BAR 2 OF Poptwo PROMPT "ПРОСМОТР ОТЧЕТА"
ON SELECTION BAR 1 OF Poptwo DO Procl
ON SELECTION BAR 2 OF Poptwo REPORT FORM Myreport PREVI
ACTIVATE MENU Mymenu && активируем линейку меню
PROCEDURE Procl && а это внешняя процедура
SELE Mytab
SET ORDER TO Myorder
REPORT FORM Myreport TO PRINTER

Рис. 22.1. Пример системы меню


298 Часть I. Процедурное программирование в Visual FoxPro

Как видишь, ничего сложного: сначала определяем линейку меню с по-:


мощью команды
DEFINE MENU <Имя_Меню> BAR

Затем определяем количество пунктов линейки и их заголовки:


DEFINE PAD <Имя_Пункта> OF <Имя_Меню> PROMPT " З а г о л о в о к _ п у н к т а "

Теперь следует определить действия, которые могут происходить при выбо­


ре П у н к т а М е н ю : ON PAD <Имя__Пункта> OF <Имя__Меню>
После этого следует какая-нибудь команда Visual FoxPro. Например, вызов
всплывающего подменю, как в нашем примере:
ON PAD PADONE OF MYMENU ACTIVATE POPUP POPONE

Если указан вызов подменю, то его (подменю), естественно, нужно создать:


DEFINE POPUP <Имя_Всплывакщего_Меню>

и определить его пункты:


DEFINE BAR l OF Poptwo PROMPT "ИМЯ_ПУНКТА1"
DEFINE BAR 2 OF Poptwo PROMPT "ИМЯ_ПУНКТА2"

После этого определяем действия для пунктов всплывающего меню:


ON SELECTION BAR 1 OF <Имя_Всплывающего_Меню> ... <КОМАНДА>

Можно как просто написать команду, так и подключить какую-нибудь|


внешнюю процедуру или функцию:
ON SELECTION BAR 1 OF Poptwo DO Procl
После этого необходимо активировать созданную систему меню, выполнив
команду
ACTIVATE MENU <Имя_Меню>
Получившееся меню представлено на рис. 22.2.
Если выполнение нашей программы для генерации меню происходит в
главном окне Visual FoxPro, то наше меню заменит системное меню. Чтобы
вернуться обратно в системное меню Visual FoxPro, необходимо деактиви-
ровать наше меню, выполнив команду:
DEACTIVATE MENU <Имя_Меню>
затем удалить его:
RELEASE MENUS <Имя_Меню> EXTENDED

и выполнить команду, которая восстановит прежнее системное меню:


SET SYSMENU TO DEFAULT
Урок 22. Создание меню приложения 299

Рис. 22.2. Мы только что создали свое меню

Использование конструктора меню


Конструктор меню запускается так же, как и все остальные конструкторы
Visual FoxPro, поэтому не будем повторяться. Каким бы способом его не
запустили, на экране появится диалоговое окно New Menu (Новое меню)
(рис. 22.3).

Рис. 22.3. Диалоговое окно New Menu


300 Часть I. Процедурное программирование в Visual FoxPro

Здесь нам предлагается два варианта меню: Menu — обычное меню в виде
строки и Shortcut — всплывающее контекстное меню. Начнем с обычного
(рис. 22.4).

Рис. 22.4. Конструктор меню

Конструктор меню включает в себя область, предназначенную для форми­


рования меню (это где написано Prompt (Наименование), Result (Результат)
и Options (Опции)), раскрывающийся список Menu level (Уровень меню) и
четыре командные кнопки.
В поле Prompt (Наименование) вводятся названия пунктов меню, раскры-
вающийся список Result (Результат) предназначен для определения дейст-
вий, происходящих при выборе пункта меню, а с помощью диалогового ок­
на Prompt Option (Опции наименования), которое открывается при нажатии
кнопки Option, можно задать дополнительные параметры для данного эле­
мента меню. Кнопки, расположенные в правой части конструктора, имеют
следующее назначение — табл. 22.1.

Таблица 22.1. Кнопки конструктора меню

Кнопка Описание

Insert (Вставить) Добавляет в меню новый пункт


Insert Bar (Вставить команду Позволяет разместить в пользовательском меню
системного меню) команды системного меню Visual FoxPro
Delete (Удалить) Удаляет указанный пункт меню
Preview Предварительный просмотр внешнего вида меню
(Предварительный просмотр)

Что ж, начнем потихоньку. Создаваемое нами меню не будет иметь отно-


шения к нашему проекту с отелем — это будет полностью абстрактная сис-
Урок 22. Создание меню приложения 301

тема, используемая только в качестве примера. Определяем пункты линейки


меню — рис. 22.5.

Рис. 22.5. Определение пунктов меню

Мы определили пункты линейки меню, а заодно и "горячие" клавиши. "Го­


рячая" клавиша используется для активизации соответствующего пункта
меню — нажимаем <AIt> и, удерживая ее, нажимаем "горячую" клавишу.
Легко и удобно. Назначение "горячих" клавиш — требование абсолютно не
обязательное, но желательное — в чем мы и убедимся в дальнейшем.
Теперь, когда пункты меню определены, требуется указать, какие действия
будут происходить при выборе того или иного пункта, за это отвечают
пункты раскрывающегося списка Result (Результат) (табл. 22.2).

Таблица 22.2. Кнопки списка Result

Кнопка Описание

Command (Команда) Выполняется определенная команда


Pad Name Никаких действий. Может использоваться в качестве
(Наименование строки меню) дополнительного пояснения

Submenu (Подменю) Раскрывается связанное с данным пунктом Рорир-


меню
Procedure (Процедура) Выполняется определенная процедура

Command (Команда)
При выборе данного пункта с правой стороны появится поле ввода для
записи команды (рис. 22.6).
302 Часть I. Процедурное программирование в Visual FoxPro

Рис. 22.6. Поле для ввода команд

Submenu (Подменю)
При выборе данного пункта справа появится кнопка Create (Создать), при
нажатии которой откроется диалоговое окно для создания соответствующе­
го подменю (рис. 22.7).

Рис. 22.7. Создание подменю

Для определения дополнительных параметров пункта меню используется


диалоговое окно Prompt Options (Опции наименования) (рис. 22.8) — см.
табл. 22.3.

Таблица 22.3. Параметры окна Prompt Options

Параметр Описание

Skip for (Пропустить) Блокировка пункта меню


Message (Сообщение) Сообщение, отображаемое в строке состояния
Pad Name (Имя пункта) Имя пункта меню
Comment (Комментарий) Комментарий для пункта меню

В области Shortcut можно задать клавиши быстрого вызова, а область


Negotiate содержит два раскрывающихся списка:
• Container (Контейнер) — определяет расположение меню при редактиро­
вании OLE-объекта;
Урок 22. Создание меню приложения 303

• Object (Объект) — определяет расположение меню при выполнении при­


ложений Active Document.

Рис. 22.8. Диалоговое окно Prompt Options

Определение клавиш быстрого доступа


Клавиши быстрого доступа похожи на "горячие" клавиши, но между ними
есть и отличия. Например, при назначении "горячих" клавиш используются
только символы, входящие в текст пункта меню, а при назначении клавиш
быстрого доступа можно использовать функциональные клавиши, клавиши
символов и комбинации клавиш. "Горячие" клавиши работают в сочетании
с клавишей <Alt>, а клавиши быстрого доступа "сами по себе". При нажа­
тии клавиши быстрого доступа активизируется связанный с ней пункт ме­
ню, но само меню при этом не отображается. Наиболее часто применяемая
практически во всех приложениях клавиша быстрого доступа — это клави­
ша <F1>, используемая для вызова справочной системы приложения. Как
это сделать (рис. 22.9)?
1. Устанавливаем курсор на пункт меню Помощь.
2. Щелкаем по кнопке Options.
3. Устанавливаем курсор в поле Key Label (Метка клавиши) и нажимаем
соответствующую клавишу или комбинацию клавиш, в нашем случае
<F1>. В поле Key Text можно ввести краткое пояснение.
304 , Часть I. Процедурное программирование в Visual FoxPro

Рис. 22.9. Определение клавиши быстрого доступа

Рис. 22.10. Вставка разделителей пунктов меню

Рис. 22.11. Меню с разделителями


Урок 22. Создание меню приложения 305

В поле ввода Pad Name (Имя пункта) можно ввести желаемое наименование
для данного поля ввода. Делается это для улучшения читаемости программ­
ного кода, сгенерированного конструктором отчетов.
Для блокировки пунктов меню используется поле ввода Skip For (Пропус­
тить для). При нажатии расположенной справа кнопки откроется диалого­
вое окно Expression Builder (Построитель выражений), в котором можно за­
дать условие для блокировки пункта меню. Для разделения пунктов меню
по определенным категориям можно использовать символы \-. Как это де­
лается, отображено на рис. 22.10, 22.11.

Определение параметров меню


После создания меню можно определить те процедуры, которые будут вы­
полняться перед запуском меню, после выхода из него, а также указать рас­
положение строки меню. Для этого нужно вызвать диалоговое окно General
Options (Основные параметры) из системного меню View (Вид) (рис. 22.12).

Рис. 22.12. Диалоговое окно General Options

В поле ввода Procedure (Процедура) можно ввести фрагмент программы,


который будет выполняться при запуске меню. Флажок Setup позволяет от­
крыть окно для редактирования той программы, которая будет выполняться
при запуске меню, а флажок Cleanup — для редактирования программы,
выполняемой при выходе из меню. При установленном флажке Top-Level
Form (Форма верхнего уровня) меню будет располагаться в форме верхнего
Уровня, в противном случае — в главном окне Visual FoxPro.
Группа переключателей Location (Расположение) позволяет выбрать вариан­
ты расположения строки меню (табл. 22.4).
306 Часть I. Процедурное программирование в Visual FoxPro

Таблица 22.4. Варианты расположения строки меню

Параметр Описание

Replace (Заместить) Меню замещает системное меню


Append (Добавить) Меню добавляется в системное меню
Before (Вставить перед) Меню вставляется перед пунктом системного меню
After (Вставить после) Меню вставляется после пункта системного меню

Генерация меню
Чтобы меню можно было использовать в приложении, сначала его нужно
сгенерировать. Для этого используется пункт системного меню Menu (Ме­
ню) и диалоговое окно Generate Menu (Генерация меню) (рис. 22.13).

Рис. 22.13. Диалоговое окно Generate Menu

После нажатия кнопки Generate (Генерация) произойдет процесс генерации


меню и... все, наше меню готово!

Запуск меню
Существует несколько способов запустить меню на выполнение:
• в окне проекта приложения установить курсор на наименования нашего
меню и нажать кнопку Run;
• в командном меню написать следующую команду:
DO <имя_меню>. mpr

Запускаем наше меню и... сталкиваемся с "сюрпризом" — рис. 22.14.


В чем дело? А все дело в назначении "горячих" клавиш. Лис почему-то не
желает работать с "горячими" клавишами, назначенными кириллицей, т. е.
русскими буквами. Ему, видите ли, латиницу подавай. Ну и подадим — дос­
таточно переопределить заново "горячие" клавиши. А еще более прос­
той способ — вообще закомментировать использование "горячих" клавиш
(рис. 22.15). И все в порядке (рис. 22.16).
Урок 22. Создание меню приложения 307

Рис. 22.14. При запуске меню происходит ошибка

Рис. 22.15. Мы "слегка" поправили код меню


308 Часть I. Процедурное программирование в Visual FoxPro

Рис. 22.16. Теперь наше меню вполне работоспособно

Запуск меню в экранной форме


В рассмотренном примере мы запускали наше меню в главном окне Visual
FoxPro, а теперь рассмотрим работу меню с экранной формой.
Создадим произвольную экранную форму и установим для нее свойство
showwindow равным 2 — As top level form (Как форма верхнего уровня).
В методе i n i t пропишем:
DO MENU1.MPR WITH T H I S , . T .

Меню также надо немного "подправить", а именно установить флажок Top-


Level Form (Форма верхнего уровня) в диалоговом окне General Options
(Основные опции) и снова запустить процесс генерации меню. После этих
манипуляций можно запустить нашу форму (рис. 22.17).
Урок 22. Создание меню приложения 309

Рис. 22.17. Меню выполняется в экранной форме

Создание Shortcut-меню
Shortcut-меню по сути очень похоже на контекстное меню, вызываемое на­
жатием правой кнопки мыши. Мы уже не раз с ними встречались в процес­
се разработки приложения, а теперь и сами научимся создавать нечто по­
хожее.
В диалоговом окне New Menu (Новое меню) нажмем кнопку Shortcut (см.
рис. 22.3). Запустится конструктор меню (рис. 22.18).

Рис. 22.18. Создание меню типа Shortcut

Как видно, процесс создания меню типа Shortcut практически ничем не


отличается от создания обычного меню. После определения всех пунктов
меню необходимо запустить процесс генерации (рис. 22.19).
310 Часть I. Процедурное программирование в Visual FoxPro

Рис. 22.19. Готовое Shortcut-меню

Для того чтобы меню такого типа выполнялось при нажатии правой кнопки
мыши, необходимо использовать событие Right Click Event (Щелчок пра­
вой кнопкой), для которого написать следующую команду:
DO <имя меню>.mpr
УРОК 23

Создание
справочной системы
Для создания справочной системы нашего приложения мы воспользуемся
программным продуктом HTML HELP Workshop, который поставляется
вместе с Visual FoxPro. С помощью данного приложения, разработанного
корпорацией Microsoft, практически любой программист, не прилагая осо­
бых усилий, сможет создать справочную систему для своего приложения.
Если по какой-либо причине у тебя нет данного приложения (хотя оно
должно быть на установочном диске Visual FoxPro) — не беда, его можно
скачать с сайта производителя: www.microsoft.com/workshop/autor/htnilhelp.
Для установки данной системы необходимо дважды щелкнуть мышью на
файле самораспаковывающегося архива HTMLHELP.EXE и следовать даль­
нейшим инструкциям.
Главное окно HTML HELP Workshop представлено на рис. 23.1.
Посмотрели — теперь закроем. Сейчас мы займемся созданием самих фай­
лов нашей будущей справки. Как видно из названия, данная система рабо­
тает с файлами формата HTML. Где их взять? Естественно, нужно создать
самостоятельно. Для этого можно использовать любой HTML-редактор
(простенький редактор имеется в самой системе HTML Help Workshop). Но
гораздо более удобный способ — использовать обычный Word, в котором
создать файлы тем справочной системы и сохранить их в формате HTML.
Так и поступим — рис. 23.2.
После создания всех файлов тем справки запускаем HTML Help Workshop и
в меню File (Файл) выбираем пункт New (Новый).
В диалоговом окне New (рис. 23.3) можно указать тип создаваемого компо­
нента справочной системы: Project (Проект), Text (Текст), HTML File
(Файл в формате HTML), Table of Contents (Таблица содержания), Index
(Индексы). Так как мы создаем новое приложение, нам необходимо вы­
брать пункт Project (Проект) — рис. 23.4.
312 Часть I. Процедурное программирование в Visual FoxPro

Рис. 23.1. Главное окно HTML HELP Workshop

Рис. 23.2. Мы создаем темы справки в редакторе Word


Урок 23. Создание справочной системы 313

Рис. 23.3. Диалоговое окно New

Р и с . 23.4. Диалоговое окно N e w P r o j e c t

Данный инструмент предназначен для преобразования существующего про­


екта справочной системы в формате Win Help в формат HTML Help
Workshop, а также для включения в проект ранее созданных файлов. Так
как у нас пока нет никакого проекта, а есть только отдельные файлы тем,
мы не будем отмечать флажок Convert WinHelp Project (Преобразовать про­
ект WinHelp), а просто нажмем кнопку Далее. На экране появляется сле­
дующее диалоговое окно (рис. 23.5).
На данном этапе необходимо указать имя создаваемого проекта и путь
к нему. Для этой цели удобно воспользоваться кнопкой Browse (Обзор).
Если у нас есть ранее созданные файлы таблицы содержания, индексов или
тем справочной системы, мы можем включить их в состав проекта. А у нас
на данный момент есть именно файлы тем (мы их создали в Word) — вот их
то и включим, отметив соответствующий флажок (рис. 23.6).
314 Часть I. Процедурное программирование в Visual FoxPro

Рис. 23.5. Диалоговое окно Destination

Рис. 23.6. Диалоговое окно Existing Files

"Укажите, где расположены Ваши файлы тем?" — вот что спрашивает мас­
тер на данном этапе создания проекта (рис. 23.7). Для добавления файлов в
проект используется кнопка Add (Добавить), а для удаления — соответст­
венно, Remove (Удалить).
В результате перед нами появится окно нашего проекта (рис. 23.8). Слева
расположены кнопки, назначение которых описано в табл. 23.1.
Урок 23. Создание справочной системы 315

Рис. 23.7. Диалоговое окно HTML Files

Рис. 23.8. Диалоговое окно нашего проекта


316 Часть /. Процедурное программирование в Visual FoxPro

Таблица 23.1. Кнопки вкладки Project

Кнопка Описание

Изменение опций проекта


Change project options

Добавление или удаление файлов разделов справки


Add / Remove topic files

Установка опций Windows


Windows definition

Информация API
API information

Просмотр текстов HTML


View HTML source

Сохранение файлов проекта


Save project files

Сохранение файлов проекта и их последующая


компиляция
Save project and file compile

Теперь нам необходимо создать таблицу содержания (Table of Contents). Что


это такое, понятно из самого определения — данный файл включает в себя
наименования тем справочной системы, т. е. содержание. Количество пунк-
тов в данной таблице может быть любым, сколько надо — столько и вклю-
чаем. Создать эту таблицу можно, воспользовавшись вкладкой Contents
(Содержание) — рис. 23.9.

Рис. 23.9. Диалоговое окно создания таблицы содержания


Урок 23. Создание справочной системы 317

Данное диалоговое окно содержит две опции: Create a new contents file
(Создать новую таблицу содержания) и Open an existing contents file (От­
крыть существующую таблицу). Так как никакой таблицы у нас пока нет,
выбираем первый пункт.
В открывшемся диалоговом окне Save As (Сохранить как) необходимо ука­
зать имя таблицы, например MY-TABLE.hhc. Имя может быть любым, а вот
расширение — только hhc. После этого откроется вкладка Contents (Содер­
жание) (рис. 23.10).

Рис. 23.10. Вкладка Contents

Слева расположены одиннадцать кнопок, назначение которых пояснено в


табл. 23.2.

Таблица 23.2. Кнопки вкладки Contents

Кнопка Описание

Свойства содержания
Contents properties
318 Часть I. Процедурное программирование в Visual FoxPr

Таблица 23.2 (окончание)

Кнопка Описание

Вставка заголовка
Insert a heading

Вставка страницы
Insert a page

Редактирование выделенного
Edit selection

Удаление выделенного
Delete selection

Перемещение выделенного вверх


Moving selection up

Перемещение выделенного вниз


Moving selection down

Перемещение выделенного вправо


Moving selection right

Перемещение выделенного влево


Moving selection left

Просмотр текста HTML


View HTML source

Сохранение файла
Save file

Вставка заголовка добавляет в таблицу строку с пиктограммой — рис. 23.11.


В поле ввода Entry title (Введите заголовок) вводим текст заголовка, а с по­
мощью кнопки Add (Добавить) подключаем соответствующий файл справки-
Вид пиктограммы можно задать, открыв вкладку Advanced (Дополнитель­
но) — рис. 23.12.
После создания заголовка можно включить и соответствующие данному
разделу справки страницы, воспользовавшись кнопкой Insert a page (Вста­
вить страницу) — рис. 23.13.
Урок 23. Создание справочной системы 319

Рис. 23.11. Диалоговое окно для вставки заголовка

Рис. 23.12. Вид пиктограммы заголовка можно задать на этой вкладке


320 Часть I. Процедурное программирование в Visual FoxPro

Рис. 23.13. Вставка страницы

Рис. 23.14. Диалоговое окно после компиляции файла


Урок 23. Создание справочной системы 321

Теперь мы уже можем скомпилировать наш файл и посмотреть, что из этого


получится. Для компиляции воспользуемся кнопкой Save project and file
compile, после чего выведется окно отчета о компиляции файла —
рис. 23.14.
Для просмотра компилированного файла можно воспользоваться пунктом
Compiled file (Компилированный файл) из меню View (Просмотр) —
рис. 23.15.

Рис. 23.15. Окно нашей справочной системы

Создание предметного указателя


Для включения в проект предметного указателя существует два способа:
• при создании нового проекта отметить пункт Index (Индекс) в диалого­
вом окне New (Новый);
• в открытом окне проекта перейти на вкладку Index, что мы и сделаем.
После определения имени индекса и его расположения откроется соответ­
ствующая вкладка, содержащая одиннадцать кнопок с пиктограммами
(табл. 23.3).

П " W 1ПП-)
322 Часть I. Процедурное программирование в Visual FoxPro

Таблица 23.3. Кнопки вкладки Index

Добавляем ключевое слово — рис. 23.16.


Ключевым словом может быть обычный текст, но его необходимо связать
с соответствующим файлом справки, воспользовавшись кнопкой Add (Доба­
вить), иначе при компиляции возникнет ошибка. Если ключевое слово
Урок 23. Создание справочной системы 323

Рис. 23.16. Добавление ключевого слова

Рис. 23.17. В справку добавлен предметный указатель


324 Часть I. Процедурное программирование в Visual FoxPro

связано с несколькими страницами — ничего страшного, связать его можно


с любым количеством тем справки (как в нашем случае). После компиля­
ции наша справочная система примет примерно такой вид — рис. 23.17.
Так как наше ключевое слово связано с двумя файлами, при нажатии кноп­
ки Показать появится вот такое диалоговое окно — рис. 23.18.

Рис. 23.18. Диалоговое окно выбора раздела справки

Создание
контекстно-зависимых разделов справки
Допустим, есть некая экранная форма (рис. 23.19).

Рис. 23.19. Пример формы

Для того чтобы при вызове справочной системы сразу открывалась страни­
ца, связанная только с этой формой, необходимо выполнить указанные да-
лее действия.
У экранной формы есть свойство HeipContextiD. Присвоим данному свойст-
ву уникальное числовое значение, например 50. В метод init экранной
формы вставим следующий код: This.SetAll ("HeipContextiD",50). В ме­
тоде обработки события click для кнопки Справка пропишем: Help ID
This.HeipContextiD.
Урок 23. Создание справочной системы . 325

Создадим еще одну HTML-страницу, содержащую раздел справки, связан­


ный с данной формой, пусть она будет сохранена как Helpform.htm. В лю­
бом текстовом редакторе, например в Блокноте, создадим новый файл,
который будет включать следующую строку: #define iDH_HeipButton 50.
iDH_HelpButton — это символьное обозначение для HeipContextid. Сохраним
этот файл под любым именем, но с обязательным расширением h, напри­
мер Formhelp.h
Открываем наш проект справочной системы и нажимаем кнопку
HTMLHelpAPI information (рис. 23.20).

Рис. 23.20. Диалоговое окно HtmlHelpAPI information

Рис. 23.21. Диалоговое окно Alias


326 Часть I. Процедурное программирование в Visual FoxPro

С помощью кнопки Header file (Файл заголовка) подключаем наш файл,


который мы создали в Блокноте. Теперь нужно указать системе, какой
именно раздел справки мы свяжем с нашим HeipContextid. Для этого пере­
ходим на вкладку Alias и щелкаем кнопку Add (Добавить). Открывается диа­
логовое окно, в котором мы и указываем путь к нашему файлу — рис. 23.21.
В первом поле ввода мы указываем символьное обозначение, во втором —
имя нашего файла с разделом справки. После чего заново компилируем
файл и "испытываем" нашу форму — рис. 23.22.
Такой же результат получится, если нажать клавишу <F1>.

Рис. 23.22. Пример контекстно-зависимой справки

Кнопка What's This?


При таком способе вызова справки на экранной форме должна располагать­
ся кнопка со знаком вопроса. При щелчке на этой кнопке мышиный указа­
тель превращается в знак вопроса, и если щелкнуть на каком-либо объекте
формы — в отдельном окне появится раздел справки, связанный с данным
объектом. Чтобы она там появилась, необходимо присвоить некоторым
свойствам экранной формы следующие значения: whatThisHeip=.T.,
WhatThisButton =.T., MaxButton =.F., MinButton = .F., WhatThisHelpId —
уникальное значение, например 7. (Это свойство нужно установить не для
формы, а для объекта, для которого мы будем создавать раздел справки.)
В данном примере будем "препарировать" кнопку Выход. Если ты ничего не
перепутал, то форма примет такой вид — рис. 23.23.
Теперь опять возвращаемся к проекту справки и связываем соответствую-
щий раздел справки с данной кнопкой. Для этого включаем в заголовочный
файл formhelp.h еще одну директиву (рис. 23.24).
Урок 23. Создание справочной системы 227

Рис. 23.23. Форма с кнопкой What's This?

Рис. 23.24. Директива в Блокноте

После этого, перейдя на вкладку Alias (Псевдоним) в окне проекта справки,


связываем всю эту систему с конкретным разделом справки. Теперь можно
заново выполнить компиляцию проекта справки и все будет работать!
УРОК 2 4

Создание ЕХЕ-приложения

В предыдущих главах мы уже кратко познакомились с окном диспетчера


проекта и даже попытались создать АРР-приложение. Теперь мы продол­
жим знакомство и создадим исполняемый файл с расширением ехе.

Параметры проекта
При создании проекта можно задать дополнительные параметры, такие как
фамилия разработчика, пиктограмма для исполняемого файла и т. д. Для
этого необходимо воспользоваться пунктом Project Info (Информация о
проекте) меню Project (Проект). Появится диалоговое окно, содержащее
дополнительную информацию о проекте — рис. 24.1.

Рис. 24.1. Диалоговое окно Project Information


Урок 24. Создание ЕХЕ-приложения 329

Окно имеет три вкладки: Project (Проект), Files (Файлы) и Servers (Сер­
веры).
В поля ввода вкладки Project заносится информация о разработчике; Author
(Ф.И.О. автора), Company (Наименование компании разработчика), Address
(Адрес), City (Город), Country (Страна), State (Штат, область), Postal code
(Почтовый индекс).
Ноте (Домашний каталог) позволяет указать месторасположение проекта,
флажок Attach icon (Определить значок) и кнопка Icon (Значок) создать
значок (иконку), при щелчке на котором будет запускаться наше приложе­
ние. Флажок Debug info (Информация об отладке) позволяет включить в
исполняемый код отладочную информацию, а флажок Encrypted (Шифро­
вание) включает механизм шифрования исполняемого кода проекта.
На вкладке Files (Файлы) (рис. 24.2) отображены все файлы, входящие в
наш проект. Файлы представлены в табличном виде, и чтобы упорядочить
их, например по имени, достаточно щелкнуть на заголовке Name (Имя).
Таким же образом файлы можно упорядочить по типу (Туре) или по дате
последнего редактирования (Last Modified). Файлы, включенные в проект
(Included), отмечены крестиком.

Рис. 24.2. Вкладка Fifes

Установка основной программы


В любом проекте обязательно должен быть файл, который будет запускать
приложение. Эта штука и называется основной программой, ею может быть
330 Часть I. Процедурное программирование в Visual FoxPro

все, что угодно — экранная форма, меню, программа и т. д. Для установки


файла в качестве основного нужно открыть диспетчер проекта, установить
мышь на нужный файл, нажать правую кнопку и в контекстном меню вы­
брать пункт Set Main (Установить основным) — рис. 24.3. Файл при этом
будет выделен жирным шрифтом.

Рис. 24.3. Выбор основной программы

Опция Exclude
Такие компоненты приложения, как экранные формы, меню, программы
называются выполняемыми и должны быть включены в состав проекта при
помощи команды контекстного меню Include (Включить), что, кстати, и
происходит по умолчанию. С другой стороны, такие объекты, как индексы
и таблицы, являются компонентами невыполняемыми, и если их включить
в приложение, то они будут доступны только для чтения. Поэтому для таб­
лиц необходимо использовать команду Exclude (Исключить) из того же кон­
текстного меню (см. рис. 24.3). В принципе, включить или исключить из
приложения можно любой компонент. После исключения рядом с таким
компонентом появится перечеркнутый кружок (посмотри на наши табли-
цы...). Но при исключении компонента он не удаляется, просто ставится
пометка о его удалении. Для того чтобы окончательно очистить проект от
"ненужных" файлов, необходимо выполнить команду Clean Up Project
(Упаковать проект) из системного меню Project (Проект).

Построение исполняемого файла


Для того чтобы сделать исполняемый файл с расширением ехе, необходимо
выбрать опцию Build Executable (Построить исполняемый файл) в диалого-
Урок 24. Создание ЕХЕ-приложения 331

вом окне Build Options (Опции построения) (рис. 24.4), которое вызывается
при нажатии кнопки Build (Построить) в окне диспетчера проекта.

PMC. 24.4. Диалоговое окно Build Options

В данном окне имеется две группы переключателей: Action (Действие) и


Options (Опции), их назначение описано далее.
Пункты группы Action (Действие):
• Rebuild Project (Перестроить проект) — проверяет наличие необходимых
файлов и собирает проект;
• Build Application (Построить приложение) — создает исполняемое прило­
жение с расширением арр. Работает в среде Visual FoxPro;
• Build Executable (Построить исполняемый файл) — создает исполняемое
приложение с расширением ехе. Работает как в среде Visual FoxPro, так и
вне ее (при наличии соответствующих библиотек);
• Build COM DLL (Построить COM DLL) — создает динамическую биб­
лиотеку с расширением dll.
Пункты группы Options (Опции):
• Recompile All Files (Обновлять все файлы) — по умолчанию обновляются
только те компоненты, которые были изменены после последнего по­
строения. А при установке данного флажка будут обновлены все файлы,
входящие в проект;
• Display Errors (Показывать ошибки) — если в процессе построения при­
ложения возникнут ошибки, то они будут отображены в отдельном окне;
• Run After Build (Запускать после построения) — если тебе не терпится
запустить свое приложение сразу после построения, смело отмечай дан­
ный флажок;
332 Часть I. Процедурное программирование в Visual FoxPro

• Regenerate Component IDs (Заново генерировать идентификаторы Auto­


mation-серверов) — применяется в случае, если необходимо установить и
регистрировать содержащиеся в проекте Automation-серверы.
Еще в данном диалоговом окне имеется кнопка Version (Версия), при нажа­
тии которой можно указать версию продукта, а также некоторые дополни­
тельные параметры (внутреннее имя и т. д.) — рис. 24.5.

Рис. 24.5. Диалоговое окно EXE Version

После настройки всех параметров можно приступить к "строительству", на­


жав кнопку ОК.
Но в случае с исполняемым файлом ЕХЕ, особенно если он будет выпол-j
няться вне главного окна Visual FoxPro, тебя может поджидать мелкая не­
приятность — твое приложение мелькнет на экране и исчезнет в "неизвест­
ном направлении". Знаешь, почему так происходит? Потому что мы не
включили в основную программу обработчик READ EVENTS. А надо бы... На­
пример, вот так:
*основная программа

DO FORM MAIN
READ EVENTS

Это, как ты догадался, текст основной программы. Более того, если при за­
вершении работы не отключить эту штуку, то возникнет еще более непри­
ятная вещь — при завершении работы Windows появится сообщение
"Cannot quit Visual FoxPro" (Невозможно завершить работу Visual FoxPro)-
Урок 24. Создание ЕХЕ-приложения 333

Что теперь делать? Есть два способа. Первый — использовать всеми "люби­
мое" сочетание клавиш <Ctrl>+<Alt>+<Del>. Второй, менее экзотиче­
ский — обязательно включить строку CLEAR EVENTS перед командой QUIT,
которая завершает работу Visual FoxPro:

CLEAR EVENTS
QUIT
УРОК 25

Создание
установочных дисков
Теперь, когда приложение практически полностью готово, осталась самая
малость — каким-то образом предоставить его конечному пользователю.
Проблема частично решается, если у пользователя имеется Visual FoxPro —
достаточно переписать все необходимые файлы на дискеты и с торжествен­
ным видом вручить их пользователю — работайте. А если Visual FoxPro не
установлен? В этом случае можно вместе с файлами приложения передать и
дискеты с файлами необходимых динамических библиотек Visual FoxPro, на
в этом случае придется долго растолковывать пользователю: как, куда и что
за чем ставить. Все это конечно, хорошо, но как говорится — "а ларчик
просто открывался..." Дело в том, что в состав Visual FoxPro входит замеча­
тельное средство для создания дистрибутива — Setup Wizard (Мастер уста-
новки). Запускается этот хитрый механизм из меню Tools | Wizards | Setup
Wizard (Инструменты | Мастера | Мастер установки).
На первом шаге (рис. 25.1) необходимо указать, в каком каталоге находятся
файлы, включаемые в комплект поставки. Для выбора каталога необходимо
воспользоваться кнопкой, расположенной справа от поля ввода — при этом
откроется уже знакомое нам диалоговое окно Select Directory (Выбор папки).
На этом этапе (рис. 25.2) нужно указать, какие компоненты приложения
будут включены в комплект поставки. Если на компьютере пользователя
отсутствует среда Visual FoxPro, необходимо отметить флажок Visual FoxPro
runtime — при этом в комплект поставки будут включены необходимые
библиотеки. Если твое приложение использует элементы управления
Microsoft Graph 8.0, отметь соответствующий флажок. Если в приложений
используются компоненты ActiveX, файлы HTML-справки или доступ к
данным осуществляется с использованием драйверов ODBC, необходимо
отметить и эти флажки. Причем при установке данных флажков будут вы­
ведены соответствующие диалоговые окна для выбора конкретных компо­
нентов. Например, в случае использования элементов ActiveX появится та­
кое окно — рис. 25.3.
Урок 25. Создание установочных дисков 335

Рис. 25.1. Первый шаг Setup Wizard

Рис. 25.2. Второй шаг Setup Wizard

На третьем шаге (рис. 25.4) мастер создаст каталоги установки и поместит


их в указанную в поле ввода папку. Далее предлагается выбрать один из
трех вариантов типа установки: на дискетах (1.44 MB 3.5-inch) (понадобит­
ся минимум четыре дискеты), через сеть Web (Websetup (compressed)) или
через локальную сеть (Netsetup (uncompressed)).
336 Часть I. Процедурное программирование в Visual FoxPro

Рис. 25.3. Диалоговое окно для добавления компонентов ActiveX

Рис. 25.4. Третий шаг Setup Wizard

На четвертом шаге (рис. 25.5) мастер предложит указать текст заголовка


диалогового окна установочной программы, информацию об авторских пра­
вах, а также имя исполняемого файла, который будет запущен сразу по
окончании процесса установки. Последнее, впрочем, указывать и не обяза­
тельно.
На пятом шаге (рис. 25.6) необходимо указать имя корневого каталога на
компьютере пользователя, которое по умолчанию будет предлагать npo-
грамма установки. Также указывается имя программной группы, в которую
будет добавлено наше приложение. Расположенные ниже переключатели
определяют, может ли пользователь менять эти установки.
Урок 25. Создание установочных дисков 337

Рис. 25.5. Четвертый шаг Setup Wizard

Рис. 25.6. Шаг пятый Setup Wizard

Задание каталогов для специальных файлов происходит на шестом шаге ра­


боты мастера установки (рис. 25.7).
Здесь можно изменить подкаталоги для размещения любого файла и отме­
тить файлы ActiveX для их регистрации на компьютере пользователя.
338 Часть I. Процедурное программирование в Visual FoxPro

Рис. 25.7. Шестой шаг Setup Wizard

И наконец, последний шаг — рис. 25.8.


Флажок Generate a web executable file позволяет создать исполняемый файл
Web, а флажок Create a dependency (.DEP) file — файл взаимных связей.
Все, ФИНИШ!

Рис. 25.8. Завершающий этап создания установочной программы


Урок 25. Создание установочных дисков 339

После нажатия этой заветной кнопки начинается процесс создания устано­


вочной программы, что мы и можем наблюдать на экране (рис. 25.9).

Рис. 25.9. Отображение процесса создания установочной программы

Но в некоторых случаях мы можем наблюдать и такое — рис. 25.10.

Рис. 25.10. Ошибка при создании установочной программы

Рассказать секрет? Ладно, все очень просто — нужно перед созданием про­
граммы и запуском мастера закрыть окно диспетчера проекта. После по­
вторного запуска все пройдет успешно и мы увидим окно статистики
(рис. 25.11).
В данном окне мы видим количество дискет, необходимых для распростра­
нения нашего приложения. Для получения более подробной информации
нажмем кнопку Preview Report (Просмотр отчета) и в результате получим
подробнейший отчет — какой файл на каком диске и т. д. (рис. 25.12).
Программа установки Setup находится в каталоге Diskl (рис. 25.13).
А чтобы окончательно убедиться, что эта штука способна работать, мы про­
сто запустим ее на выполнение (рис. 25.14—25.16).
340 Часть I. Процедурное программирование в Visual FoxPro

Рис. 25.11. Диалоговое окно статистики

Рис. 25.12. Фрагмент файла отчета


Урок 25. Создание установочных дисков 341

Рис. 25.13. Программа установки нашего приложения

Рис. 25.14. Фрагмент работы программы установки


342 Часть I. Процедурное программирование в Visual FoxPro

Рис. 25.15. Идет процесс установки

Рис. 25.16. Установка успешно завершена!


ЧАСТЬ II
Объектно-ориентированное
программирование
Вот мы и добрались до части II нашей книги, в которой я тебе расскажу о
принципиально новых понятиях технологии программирования. Дело в том,
что Visual FoxPro представляет собой гибридный язык программирования,
который позволяет создавать приложения как с использованием старой тех­
нологии модульного программирования, так и применяя современную тех­
нологию объектно-ориентированного программирования. В чем их отличие?
Модульное, или процедурное программирование — это то, чем мы с тобой
занимались, изучая первую часть нашей книги. Наше приложение состояло
из набора отдельных модулей (экранных форм, процедур, программ), кото­
рые в совокупности и решали поставленную задачу. Именно такая техноло­
гия использовалась в FoxPro for DOS, в FoxPro for Windows и других языках
программирования. Как мы уже видели, ее же можно успешно применять и
при создании приложений в Visual FoxPro. А зачем, спросишь ты, от нее
отказываться? Да никто и не заставляет от нее отказываться — огромное
количество программистов (особенно те, кто "перешел" в Visual со старых
версий FoxPro) до сих пор так и создают свои приложения. Но... Представь
такую ситуацию: мы разработали некое приложение, которое успешно рабо­
тает в какой-то компании. И оно настолько всем нравится, что к нам при­
ходит представитель другой компании и говорит: "О-кей, ребята, мы хотим
то же самое. Правда, требования у нас немного другие..." А мы что, мы не
против. Мы с тобой берем кучу дискет, компакт-дисков и двигаемся в эту
фирму. Там мы устанавливаем свое приложение, но, т. к. у них "требования
немного другие", мы корректируем программный код наших модулей, под­
гоняя его под условия данного заказчика. А потом к нам приходит еще один
клиент и... все повторяется. Естественно, на все эти манипуляции уходит
время, деньги и нервы.
Принципиально другой подход к обновлению и адаптации приложений н
различным условиям предлагает технология объектно-ориентированного
программирования. Применяя данную технологию, можно создавать при-
ложение не столько как набор отдельных профаммных модулей, сколько
как совокупность объектов. Допустим, нам нужно смоделировать, т. е. про-
фаммно разработать объект "Организация". А для этого нам необходимо
знать, что же такое организация? И не конкретная фирма, а организация
вообще. Что она "знает" о себе, что "умеет" делать? Очевидно, что любая ор-
ганизация "знает" свое наименование, юридический адрес и т. д. Любая ор­
ганизация имеет счет в банке, у любой организации есть руководитель
и т. д. Любая организация "умеет" сохранять сведения о самой себе, сооб­
щать сведения о самой себе и т. д. Исходя из этого, можно понять, что те­
перь вместо профаммного модуля для обработки, скажем, исходящей доку-
ментации мы можем включить в приложение такие объекты, как "Органи-
зация", "Документы" и т. д.
И теперь, если возникнет необходимость адаптировать наше приложение
к новым условиям, "подогнать" его под требования нового пользователя —
нам достаточно внести эти отличия в новые объекты, которые будут созда-
ны на основе уже имеющихся. Все те функциональные возможности, свой­
ства и методы, заложенные в "основной", уже имеющийся объект, будут ав­
томатически перенесены во вновь созданный и при необходимости могут
быть изменены в нем.
Теперь, я думаю, более или менее понятно, для чего разработана технология
объектно-ориентированного профаммирования. В двух словах: упрощение
сопровождения приложений и возможность повторного использования про­
фаммного кода, который кто-то (необязательно ты), когда-то (необязатель­
но сегодня) уже создал.
УРОК 26

Объекты

А теперь, дружок, я тебя буду пугать страшными словами, без знания кото­
рых у тебя ничего не получится, если ты вздумаешь заняться объектно-
ориентированным программированием. Слова следующие: объект или сущ­
ность (entities), наследование (inheritance), инкапсуляция (encapsulation), поли­
морфизм (polymorphism). Вот. Я думаю, ты уже привык к шуткам автора и
пугаться даже не собирался. И правильно сделал, потому что сейчас я тебе
постараюсь объяснить смысл этих "страшных" терминов и все станет ясно и
прозрачно. Начнем с понятия самого объекта.
Объект представляет собой всего-навсего совокупность данных и функций.
То есть он содержит как данные, так и функции — способы или методы
выполнения каких-то действий. Теперь отвлекись от монитора и посмотри
на обычный телевизор — чем не объект? Он имеет свойства (например,
уровень громкости, число принимаемых каналов, цвет корпуса, размер ки­
нескопа и т. д.), он имеет свой интерфейс для "общения" с внешним ми­
ром — это кнопки управления, а также он умеет выполнять некоторые дей­
ствия — переключать каналы, увеличивать или уменьшать уровень яркости
изображения и т. д. Примерно такие же качественные характеристики имеет
и программный объект. Но внутри телевизора есть много чего такого, о чем
нам с тобой и знать не нужно: например, зачем нам в повседневной жизни
знать, каким образом происходит переключение каналов или на какой угол
отклоняется пучок электронов из пушки кинескопа? Работает, и ладно. Для
нас имеет значение только его средства общения с нами — кнопки, пере­
ключатели, пульт дистанционного управления — в общем, все то, с по­
мощью чего мы можем "заставить" объект выполнить те или иные действия.
Вот так незаметно мы и поняли суть сразу двух "страшных" слов — объекта
и инкапсуляции. Про объект ясно, а инкапсуляция? А про инкапсуляцию
ты только что прочитал — объект инкапсулирует, т. е. включает в себя (или
содержит в себе) всю необходимую информацию и набор функций, которые
и определяют его поведение.
346 Часть II. Объектно-ориентированное программирование

Данные, инкапсулированные в объекте, называются свойствами. Например,


одно из свойств экранной формы — backcoior, определяет цвет фона фор­
мы. С точки зрения нашего Лиса, данное свойство представляет собой все­
го-навсего переменную памяти, которая может принимать определенные
значения и которая присоединена к объекту и имеет область видимости
только в пределах своего объекта.
В свою очередь, процедуры, присоединенные к объекту, называются мето­
дами. А что такое процедуры? Это программный код, с помощью которого
объект может выполнять какие-либо действия.
А вот действия, которые происходят во "внешнем" мире и на которые объ­
ект должен реагировать, называются событиями. Классическим примером
может служить такое событие, как щелчок мышью. Оно происходит по
инициативе пользователя. А еще событие может наступить по инициативе
самой программы, например:
IF BOF ()
=MESSAGEBOX("ПОСЛЕДНЯЯ ЗАПИСЬ", "КОНЕЦ ФАЙЛА")
ENDIF

Теперь, чтобы уяснить суть оставшихся "страшных" слов, мы введем новое


понятие, которое именуется как классы.

Классы
Прочитав предыдущий раздел, ты уяснил следующее: в Visual FoxPro можно
создавать объекты. А вот какой в этом практический смысл, наверное, пока
непонятно. Действительно, в чем преимущества нового метода — ведь если
для каждого приложения придется каждый раз создавать новые объекты —
где же тут обещанные комфорт, экономия времени и нервов? А вот именно
для этого и существуют такие штуки, как классы. Именно они и являются
той основой, при помощи которой создаются различные объекты.
Например, возьмем обычную тарелку. Ясно, что каждую тарелку никто не
делает индивидуально. На заводе существует какая-то пресс-форма или
шаблон, с помощью которой можно изготовить миллион одинаковых таре­
лок. Улавливаешь аналогию? Правильно, точно так же никто не собирается
писать программный код для однотипных программных объектов — доста­
точно создать класс (этакую пресс-форму), а затем "наштамповать" сколько
угодно объектов на основе данного класса. Причем все вновь созданные
объекты будут являться экземплярами этого класса. И эти вновь созданные
объекты унаследуют все методы, события и свойства, присущие классу-
родителю. Вот это и называется наследованием. Чтобы лучше понять, как это
происходит, рассмотрим наглядный пример.
Урок 26. Объекты 347

В Visual FoxPro для создания классов используются две команды: DEFINE


CLASS И ENDDEFINE. Синтаксис первой команды следующий:'
DEFINE CLASS Имя_Класса AS Имя_Класса_Родителя

Классом-родителем (superclass) называется тот базовый класс, на основе ко­


торого будет создан новый. Давай создадим класс на основе класса обычной
формы:
DEFINE CLASS Myform AS FORM
Autocenter = .T.
Caption = "MYFORM"
Backcolor = RGB(0,255,0)
Name - "MYFORM"
ENDDEFINE

Вот и все, создана обычная форма да еще и зеленого цвета. Теперь, чтобы
посмотреть, как происходит процесс наследования, создадим объект на ос­
нове вновь созданного класса:
Oform=CREATEOBJECT ("Myform")
Oform.SHOW(l)
DEFINE CLASS Myform AS FORM
Autocenter = .T.
Caption = "MYFORM"
Backcolor = RGB(0,255,0)
Name = "Myform"
ENDDEFINE

Для создания экземпляра класса используется функция CREATEOBJECT ():


Oform = CREATEOBJECT("Myform")

To есть создается некоторая переменная типа object на основе указанного


класса. Теперь представь, что мы создали очень много каких-то объектов на
основе какого-то класса и по какой-то причине приходится изменить у них
У всех какое-то свойство. Можно сделать "по-старинке", вручную установив
для каждого необходимое значение свойства. А объектов-то этих самых ты
уже сотворил 15 487 шт! Как быть? Применяя новую технологию объектно-
ориентированного программирования, мы делаем это проще простого —
меняем значение необходимого свойства у класса-родителя. Попробуй из­
мени значение цвета фона в классе нашей формы и ты увидишь, как изме­
нится цвет и нашего объекта. Вот это и есть наследование.
А вот полиморфизмом называется возможность объектов по-разному реаги­
ровать на одни и те же события.
Таким образом, мы уяснили, что в Visual FoxPro можно создавать новые
классы на основе уже имеющихся. А что такое "уже имеющиеся"? Это так
348 Часть II. Объектно-ориентированное программирование

называемые базовые классы или суперклассы, которые поставляются вместе


с данным программным продуктом. В табл. 26.1 перечислены базовые клас­
сы Visual FoxPro.
Таблица 26.1. Базовые классы Visual FoxPro

FormControls
Доступен из
Визуальный

подклассов
(видимый)

контейнер
создания
Имя класса Назначение

Класс-
Для
ActiveDoc Активный документ Нет Да Нет Нет
CheckBox Флажок Да Нет Нет Да
Column Столбец элемента управления G r i d Да Нет Да Да
ComboBox Раскрывающийся список Да Нет Нет Да
CommandButton Кнопка Да Нет Нет Да
CommandGroup Группа командных кнопок Да Нет Да Да
Container Контейнер Да Да Да Да
Control Базовый визуальный класс. "Похож" Да Да Да Нет
на Container, но извне можно обра­
щаться только к этому классу, а не
к содержащимся в нем объектам
Cursor Определение курсора в среде дан­ Нет Нет Нет Нет
ных
Custom Базовый невизуальный класс. Можно Нет Да Нет Нет
использовать в качестве суперкласса
для создания собственных
DataEnvironment Совокупность курсоров и отношений Нет Нет Да Нет
EditBox Поле редактирования Да Да Нет Да
Form Экранная форма Да Да Да Да
FormSet Набор экранных форм Нет Да Да Да
Grid Таблица Да Да Да Да
Header Заголовок столбцов таблицы Да Нет Нет Нет
HyperLynk Гиппересылка Да Да Нет Да
Object

Image Изображение Да Да Нет Да


Label Надпись (Этикетка) Да Да Нет Да
Урок 26. Объекты 349

Таблица 26.1 (окончание)

ForrnControls
Доступен из
Визуальный

подклассов
(видимый)

контейнер
создания
Имя класса Назначение

Класс-
Для
Line Линия Да Да Нет Да
ListBox Список Да Да Нет Да
decontrol Элемент управления Нет Да Да Да
OptionButton Переключатель Да Нет Нет Да
OptionButton Группа переключателей Да Да Да Да
Page Вкладка формы Да Нет Да Нет
PageFrame Набор вкладок Да Да Да Да
ProjectHook Проект Нет Нет Да Нет
Relation Отношение между курсорами Нет Нет Нет Нет
Separator Разделитель Да Нет Нет Да
Shape Контур Да Нет Нет Да
Spinner Счетчик Да Нет Нет Да
TextBox Поле ввода Да Нет Нет, Да
Timer Таймер Нет Нет Нет Да
ToolBar Панель инструментов Да Да Да Нет

Единственным недостатком указанных классов является то, что их нельзя


изменить. Но зато ничто не мешает создавать на их основе свои, пользова­
тельские классы, которые будут полностью в твоей "власти".

Композитные классы
Композитными называются такие классы, которые содержат в себе объекты,
созданные на основе других классов. Иначе их называют классы-
контейнеры. Наша зеленая экранная форма также является классом-
контейнером, и сейчас мы рассмотрим, каким образом можно добавить в
этот класс объект из другого класса. Один из способов — использование
команды ADD OBJECT, которая имеет следующий синтаксис:
ADD OBJECT имя_объекта AS имя__класса
WITH переменная=зиачение
350 Часть II. Объектно-ориентированное программирование

Применительно к нашему случаю:


Of orm=CREATEOBJECT ("Myf orra")
Oform.SHOW(l)
DEFINE CLASS Myform AS FORM
Autocenter = .T.
Caption = "Myform"
Backcolor - RGB(0,255,0)
Name = "Myform"
ADD OBJECT Mylabel AS LABEL;
WITH Caption="ripMMep композитного класса",;
Autosize=.T.,;
Top=40,;
Left=100
ENDDEFINE

И вот что получилось — рис. 26.1.

Рис. 26.1. Пример добавления в класс объекта из другого класса

Другой способ — использование метода ADDOBJECTO. Применяя данный ме-|


тод, мы получим аналогичный результат:
Oform=CREATEOBJECT ("Form")
Oform.Autocenter=.T.
Oform.Caption="Myform"
Oform.ADDOBJECT("Mylabel","LABEL")
Oform.Mylabel.Caption="Пример Композитного Класса"
Oform.Mylabel.Autosize=.T.
Oform.Mylabel.Top=40
Урок 26. Объекты 351

Oform.Mylabel. Lef t=100


Oform.Mylabel.Visible=.T.
Oform.SHOW(l)

Ясно видно различие между ADD OBJECT И ADDOBJECTO- При использовании


ADD OBJECT свойства объекта можно задать в одном операторе, а при исполь­
зовании ADDOBJECT( ) это придется делать отдельно. Применяя ADDOBJECT(),
нужно не забывать устанавливать свойство visible — .т. (для визуальных
объектов).
УРОК 27

Создание классов
в Class Designer
Для создания классов в Visual FoxPro можно использовать два способа: пи-
сать программный код (что мы делали ранее) или (что гораздо удобнее)
воспользоваться услугами специального конструктора — Class Designer.
Этот инструмент очень похож на уже знакомый нам Form Designer (Конст-
руктор форм), но он имеет некоторые отличия — в частности, в меню до­
бавлен пункт Class (Класс) — рис. 27.1.

Рис. 27.1. Окно Class Designer


Урок 27. Создание классов в Class Designer 353

Ну а теперь приступим к практическим занятиям и первое, что мы сдела­


ем — создадим командную кнопку, которая будет закрывать экранную форму.
1. В окне диспетчера проекта перейдем на вкладку Classes (Классы) и на­
жмем кнопку New (Новый).
2. В открывшемся диалоговом окне New Class (Новый класс) (рис. 27.2)
в поле ввода Class Name (Имя класса) необходимо ввести имя создавае­
мого класса, а используя раскрывающийся список Based On (Основан
на), указать тот базовый класс Visual FoxPro, на основе которого мы бу­
дем создавать наш новый класс. Далее необходимо указать имя библио­
теки классов, в которой он будет сохранен. Можно как выбрать уже
существующую библиотеку классов, так и создать новую, свою собст­
венную.

Рис. 27.2. Диалоговое окно New Class

3. После этого, в окне Class Designer производим настройку свойств, мето­


дов и событий для нашего класса — точно так же, как мы это делали ра­
нее при работе с обычными объектами (рис. 27.3). Меняем название
кнопки (caption = выход) и пишем код для события click:
THIsFORM.RELEASE (), после чего сохраняем результат наших действий.

Все, класс готов! Его код представлен в листинге 27.1.

Листинг 27.1. Класс E x i t B u t t o n

DEFINE CLASS EXITBUTTON AS COMMANDBUTTON


HEIGHT - 27
WIDTH = 8 4
CAPTION = "ВЫХОД"
NAME - "EXITBUTTON"
PROCEDURE CLICK
THISFORM.RELEASE()
ENDPROC
ENDDEFINE
354 Часть II. Объектно-ориентированное программирование

Рис. 27.3. Создание класса

Это самый простой пример, а чтобы окончательно убедить тебя в удобности


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

Пример 1 — калькулятор
Сейчас мы попробуем сделать простейший калькулятор. Итак, нам понадо­
бятся: экранная форма, поле ввода и два класса кнопок. После того, как мы
должным образом сгруппируем эти объекты, у нас получится симпатичный
и даже более или менее работающий калькулятор. На экранной форме мы
останавливаться не станем — можешь сделать ее какую хочешь, только раз­
мести на ней два поля ввода. А вот на кнопочках остановимся подробнее:
все-таки новые классы создаем...
Для начала создадим класс цифровых кнопок и назовем его DigitButto
(рис. 27.4).
Сам класс DigitButton довольно "примитивен" (листинг 27.2).
Урок 27. Создание классов в Class Designer 355

Рис. 27.4. Мы создаем новый класс

Листинг 27.2. Класс DigitButton

DEFINE CLASS DIGITBUTTON AS COMMANDBUTTON


HEIGHT = 27
WIDTH = 4 8
FONTBOLD = .T.
CAPTION = "1"
NAME = "DIGITBUTTON"
PROCEDURE CLICK
THISFORM. TEXT1 .VALUE==THISFORM.TEXTl .VALUE+THIS. CAPTION
THISFORM.TEXT2.VALUE=THISFORM.TEXT2.VALUE+THIS.CAPTION
ENDPROC
ENDDEFINE

Теперь вернемся к нашей экранной форме и создадим для нее новое свой­
ство орег. Как это делается, мы еще не "проходили", вот заодно и научимся.
Дело в том, что, помимо базовых свойств (это те, которые отображены в
диалоговом окне Properties (Свойства)), практически для любого объекта
можно задать новые свойства и методы. Для этого нужно выбрать пункт
356 Часть II. Объектно-ориентированное программирование

New Property (Новое свойство) меню Form (Форма) в окне Form Designer
(Конструктор форм). На экране появится окно New Property (Новое свойст­
во) — рис. 27.5.

Рис. 27.5. Диалоговое окно New Property

В данном окне необходимо указать имя нового свойства и при необходимо­


сти установить флажки Access Method и Assign Method. При установке
флажка Access Method для данного свойства будет автоматически установ­
лен метод Access (Доступ), а при установке флажка Assign Method для свой­
ства будет автоматически создан метод Assign (Назначение). Ну а в том, что
наша экранная форма действительно обрела новое свойство, можно легко
убедиться, посмотрев на окно свойств (Properties) — рис. 27.6.

Рис. 27.6. Мы видим новое свойство в окне свойств


Урок 27. Создание классов в Class Designer 357

Теперь создадим еше один класс кнопок, по нажатию которых будет произ­
водиться то или иное математическое действие, и назовем его OperButton.
Код такой кнопки представлен в листинге 27.3.

Листинг 27.3. Класс OperButton

DEFINE CLASS OPERBUTTON AS COMMANDBUTTON


TOP - 5 3
LEFT = 147
HEIGHT = 27
WIDTH = 3 6
FONTBOLD = . T .
CAPTION = " + "
NAME = " 0 P E R 1 "
PROCEDURE CLICK
THISFORM.OPER=THIS.CAPTION
LASTVALUE=THISFORM.TEXT1.VALUE
THISFORM.TEXTl.VALUE=""
THISFORM.TEXT2.VALUE=THISFORM.TEXT2.VALUE+THISFORM.OPER
ENDPROC
ENDDEFINE

Все, теперь остается разместить наши кнопки на экранной форме. Для это­
го нужно нажать кнопку View Classes (Просмотр классов) на панели инст­
рументов Form Controls (Элементы управления экранной формы) и в рас­
крывшемся меню выбрать пункт Add (Добавить). После чего в открывшемся
диалоговом окне указать нашу библиотеку классов — рис. 27.7.
Получится следующее — рис. 27.8.
Теперь дело за малым — расположить наши объекты на форме, да в методе
init формы прописать следующее: PUBLIC LASTVALUE — рис. 27.9.
А как же получить результат? Придется поработать над событием click для
соответствующей кнопки "=" (листинг 27.4).

Листинг 27.4. Событие c l i c k кнопки "="

IF THISFORM.OPER="+"
THISFORM.TEXTl.VALUE=STR(VAL(THISFORM.TEXTl.VALUE)+VAL(LASTVALUE),20,2)
THISFORM.TEXT2.VALUE=THISFORM.TEXT2.VALUE+"="+
ALLTR(THISFORM.TEXTl.VALUE)
ENDIF
IF THISFORM.OPER="-"
THISFORM.TEXTl.VALUE=STR(VAL(LASTVALUE)-VAL(THISFORM.TEXTl.VALUE),20,2)
358 Часть II. Объектно-ориентированное программирование

THISFORM.TEXT2.VALUE=THISFORM.TEXT2.VALUE+"="+
ALLTR(THISFORM.TEXT1.VALUE)
ENDIF
I F THISFORM.OPER="*"
THISFORM.TEXT1.VALUE=STR(VAL(LASTVALUE)*
VAL(THISFORM.TEXT1.VALUE),20,2) -
THISFORM.TEXT2.VALUE=THISFORM.TEXT2.VALUE+"="+
ALLTR(THISFORM.TEXT1.VALUE)
ENDIF
IF THISFORM.OPER='7"
THISFORM.TEXT1.VALUE=STR(VAL(LASTVALUE)/VAL(THISFORM.TEXT1.VALUE),20,2)
THISFORM.TEXT2.VALUE=THISFORM.TEXT2.VALUE+"="+
ALLTR(THISFORM.TEXT1.VALUE)
ENDIF

Все, запускаем наш "агрегат" — рис. 27.10.


А что нам с тобой калькулятор, хочешь, сделаем игру? Легко!

G J ^ H H H I ШЯШШШШШЯШ^ШШШШШШЧШ
Папка: | iQ calc д|. : Ф3 IS & Ш"

Рис. 27.7. Добавление собственной библиотеки классов

Рис. 27.8. Наши классы расположились на панели Form Controls


Урок 27. Создание классов в Class Designer 359

Рис. 27.9. Наш суперкалькулятор почти готов! Рис. 27.10. Ура! Получилось!

Пример 2 — Puzzle
Когда-то, давным-давно, в FoxPro for DOS имелась встроенная простенькая
игрушка Puzzle (Пазл), более известная в нашей стране как "Пятнашки".
Смысл был такой: щелкая мышью, расположить цифры в порядке возраста­
ния от 1 до 15. Не знаю, почему, но в Visual FoxPro такой игры нет. Зато
мы можем, опираясь на только что полученные знания, соорудить нечто
подобное самостоятельно. Например, игрушку вот с таким игровым по­
лем — рис. 27.11.
Или вот с таким — рис. 27.12.

Рис. 27.11. "Классический" Puzzle Рис. 27.12. А это уже наша самодельная игрушка
360 Часть II. Объектно-ориентированное программирование

Мне кажется, ты не станешь думать, что я обе эти экранные формы "сотво­
рил" в Form Designer (Конструктор форм), расставил кнопки (81 шт!), напи­
сал для каждой кнопки обработчик щелчка мыши и т. д.? Правильно, все
это делает одна-единственная программка, размером 4 Кбайта! Сейчас по­
смотрим ее код (листинг 27.5), а затем подробно разберем, как там все ра­
ботает.

Листинг 27.5. Puzzle

***************************** *pn2ZLE**************************
**********************ди>рр}Орч. DMITRY SHAPOREV*****************
STARTPUZZLE=CREATEOBJECT("STARTPUZZLE")
STARTPUZZLE.SHOW(1)

DEFINE CLASS STARTPUZZLE AS FORM


HEIGHT = 82
WIDTH = 175
DOCREATE - .T.
AUTOCENTER - ,T.
CAPTION = "НАЧАЛО ИГРЫ"
CLOSABLE = .F.
MAXBUTTON = .F.
MINBUTTON = .F.
NAME = "FORM1"

ADD OBJECT LABEL1 AS LABEL WITH;


AUTOSIZE = .Т., ;
CAPTION = "УРОВЕНЬ СЛОЖНОСТИ (ОТ 4 ДО 9)",;
HEIGHT = 17,;
LEFT = 1,;
TOP = 4,;
WIDTH - 172,;
NAME = "LABEL1"

ADD OBJECT TEXT1 AS TEXTBOX WITH;


HEIGHT = 23, ;
LEFT = 37,;
TOP = 24, ;
WIDTH = 100, ;
NAME = "TEXT1"

ADD OBJECT COMMAND1 AS COMMANDBUTTON WITH;


TOP - 51,;
LEFT = 12,;
Урок 27. Создание классов в Class Designer 361

HEIGHT = 27,;
WIDTH = 60, ;
CAPTION = "ВЫХОД",;
NAME = "COMMANDl"

ADD OBJECT C0MMAND2 AS COMMANDBUTTON WITH;


TOP = 51, ;
LEFT = 93,;
HEIGHT = 27,;
WIDTH = 60, ;
CAPTION - "ЗАПУСК",;
NAME - "C0MMAND2"
PROCEDURE TEXT1.ERRORMESSAGE
=MESSAGEBOX("БУДЬТЕ ВНИМАТЕЛЬНЕЙ!","ОШИБКА")
ENDPROC

PROCEDURE TEXT1.VALID
IF EMPTY(THIS.VALUE)
RETURN it.
END IF
IF VAL(THIS.VALUE)<4
RETURN .F.
ENDIF
IF VAL(THIS.VALUE)>9
RETURN .F.
ENDIF
ENDPROC
PROCEDURE C0MMAND2.CLICK
PUBLIC NLEVEL
NLEVEL=VAL(THISFORM.TEXT1.VALUE)
**********************
**********************
#DEFINE COUNT_OF_ITEMS NLEVEL*NLEVEL
LOCAL ARRAY LARAND[COUNT_OF_ITEMS]
LOCAL ARRAY LATEMP[COUNT_OF_ITEMS]
LOCAL I,J, N
RAND(-l)
N=COUNT_OF_ITEMS
FOR 1=1 TO COUNT_OF_ITEMS
LATEMP[I]=1-1
ENDFOR
FOR 1=1 TO COUNT_OF_ITEMS
J=INT(RAND()*N)+1
LARAND[I]=LATEMP[J]
=ADEL(LATEMP,J)
N=N-1
ENDFOR
FOR 1=1 TO COUNT_OF_ITEMS
ENDFOR
**********************
**********************

************************************************************************
PUZZLE=CREATEOBJECT("FORM")
PUZZLE.CAPTION="FOXPUZZLE"
DL=30
WT=30
FOR F = l TO NLEVEL
FOR D=l TO NLEVEL

PUZZLE.ADDOBJECT("PZ"+ALLTR(STR(D))+ALLTR(STR(F)), "PUZZLEBUTTON")
M1="PZ"+ALLTR(STR(D))+ALLTR(STR(F))+".VISIBLE"
M2="PZ"+ALLTR(STR(D))+ALLTR(STR(F))+".LEFT"
M3="PZ"+ALLTR(STR(D))+ALLTR(STR(F))+".WIDTH"
M4="PZ"+ALLTR(STR(D))+ALLTR(STR(F))+".TOP"
M5="PZ"+ALLTR(STR(D))+ALLTR(STR(F))+".CAPTION"

PUZZLE.&M4=(F)*WT
PUZZLE.&M2=DL*(D-1)
PUZZLE.&M1=.T.
PUZZLE.&M3=DL
PUZZLE.WIDTH=DL*D
PUZZLE.HEIGHT=WT*(F+2)
ENDFOR
ENDFOR
1=0
FOR R = l TO NLEVEL
FOR K=l TO NLEVEL

M5="PZ"+ALLTR(STR(R))+ALLTR(STR(K))+".CAPTION"
1=1+1
PUZZLE.&M5=ALLTR(STR(LARAND(I)))
ENDFOR
ENDFOR

PUZZLE.AUTOCENTER=.T.
PUZZLE.SHOW(1)
ENDPROC
Урок 27. Создание классов в Class Designer 363

PROCEDURE COMMANDl.CLICK
THISFORM.RELEASE()
ENDPROC
ENDDEFINE
*— ENDDEFINE: PUZZLE
***********************************************************************
DEFINE CLASS PUZZLEBUTTON AS COMMANDBUTTON
HEIGHT = 2 7
WIDTH = 84
CAPTION = ""
NAME = "PUZZLEBUTTON"

PROCEDURE CLICK
THISNAME=THIS.CAPTION
DIGIT_PART=INT(VAL(RIGHT(THIS.NAME,2)))
IF
TYPE("THISFORM."+"PZ"+ALLTR(STR(DIGIT_PART+1))+".NAME")="C"

NEXTNAME="THISFORM."+"PZ"+ALLTR(STR(DIGIT_PART+1))+".CAPTION"
IF &NEXTNAME="0"
THIS.CAPTION=&NEXTNAME
&NEXTNAME=THISNAME
ENDIF
ENDIF
************************************************************************
IF TYPE("THISFORM."+"PZ"+ALLTR(STR(DIGIT_PART-
1))+".NAME")="C"
NEXTNAME="THISFORM."+"PZ"+ALLTR(STR(DIGIT_PART-1))+".CAPTION"
IF &NEXTNAME="0"
THIS.CAPTION=&NEXTNAME
&NEXTNAME=THISNAME
ENDIF
ENDIF

********************
IF
TYPE("THISFORM."+"PZ"+ALLTR(STR(DIGIT_PART+10))+".NAME")="C"

NEXTNAME="THISF0RM."+"PZ"+ALLTR(STR(DIGIT_PART+10))+".CAPTION"
IF &NEXTNAME="0"
THIS.CAPTION=&NEXTNAME
&NEXTNAME=THISNAME
ENDIF
ENDIF
364 Часть II. Объектно-ориентированное программирование

********************
IF TYPE("THISFORM."+"PZ"+ALLTR(STR(DIGIT_PART-10))+".NAME")="C"
NEXTNAME="THISFORM."+"PZ"+ALLTR(STR(DIGIT_PART-10))+".CAPTION"
IF &NEXTNAME="0"
THIS.CAPTION=&NEXTNAME
&NEXTNAME=THISNAME
ENDIF
ENDIF
ENDPROC
ENDDEFINE

Вот и вся программка. Теперь давай разбираться, чего мы тут с тобой насо­
чиняли. Для этого разобьем текст программы на несколько блоков.
"Блок 1" — создаем объект на базе класса, производного от класса формы
(листинг 27.6).

Листинг 27.6. Блок 1

STARTPUZZLE=CREATEOBJECT("STARTPUZZLE")
STARTPUZZLE.SHOW(1)

DEFINE CLASS STARTPUZZLE AS FORM


HEIGHT = 82
WIDTH = 175
DOCREATE = .T.
AUTOCENTER = .T.
CAPTION = "НАЧАЛО ИГРЫ"
CLOSABLE - .P.
MAXBUTTON = ,F.
MINBUTTON = .F.
NAME = "FORM1"

ADD OBJECT LABEL1 AS LABEL WITH;


AUTOSIZE = .T.,;
CAPTION = "УРОВЕНЬ СЛОЖНОСТИ (ОТ 4 ДО 9 ) " , ;
HEIGHT = 17,;
LEFT = 1,;
TOP = 4, ;
WIDTH = 172,;
NAME = "LABEL1"

ADD OBJECT TEXT1 AS TEXTBOX WITH;


HEIGHT = 23,;
Урок 27. Создание классов в Class Designer 365

LEFT = 37,;
TOP - 24, f •
WIDTH = 100,;
NAME = "TEXT1"

ADD OBJECT COMMAND1 AS COMMANDBUTTON WITH;


TOP = 51,;
LEFT = 12,;
HEIGHT - 27, ;
WIDTH = 60, ;
CAPTION = "ВЫХОД",;
NAME = "COMMAND1"

ADD OBJECT COMMAND2 AS COMMANDBUTTON WITH;


TOP = 51, ;
LEFT = 93,;
HEIGHT = 27,;
WIDTH = 60,;
CAPTION = "ЗАПУСК",;
NAME - "COMMAND2"
PROCEDURE TEXT1.ERRORMESSAGE
=MESSAGEBOX("БУДЬТЕ ВНИМАТЕЛЬНЕЙ!","ОШИБКА")
ENDPROC

PROCEDURE TEXT1.VALID
IF EMPTY(THIS.VALUE)
RETURN .F.
ENDIF
IF VAL(THIS.VALUE)<4
RETURN .F.
ENDIF
IF VAL(THIS.VALUE)>9
RETURN .F.
ENDIF
ENDPROC
PROCEDURE COMMAND2.CLICK
PUBLIC NLEVEL && Это - уровень сложности, а если проще -
количество кнопок
NLEVEL=VAL(THIS FORM.ТЕХТ1.VALUE)

ENDDEFINE
366 Часть II. Объектно-ориентированное программирование

"Блок 2" — на данном этапе мы создаем массив со случайной и, более того,


неповторяющейся последовательностью чисел (листинг 27.7). Размер масси­
ва определяется значением переменной NLEVEL.

Листинг 27.7. Блок 2


; £

#DEFINE COUNT_OF_ITEMS NLEVEL*NLEVEL


LOCAL ARRAY LARAND[COUNT_OF_ITEMS]
LOCAL ARRAY LATEMP[COUNT_OF_ITEMS]
LOCAL I , J , N
RAND(-l)
N=COUNT_OF_ITEMS
FOR 1=1 TO COUNT_OF_ITEMS
LATEMP[I]=1-1
ENDFOR
FOR 1=1 TO COUNT_OF_ITEMS
J=INT(RAND()*N)+1
LARAND[I]=LATEMP[J]
=ADEL(LATEMP, J)
N=N-1
ENDFOR
FOR 1=1 TO COUNT_OF_ITEMS
ENDFOR

"Блок 3" — создаем непосредственно игровое поле, размещаем на нем необ­


ходимое количество кнопок и случайным образом размещаем надписи на
них (листинг 27.8).

Листинг 27.8. Блок 3

PUZZLE=CREATEOBJECT("FORM")
PUZZLE.CAPTION="FOXPUZZLE"
DL=30
WT=30
FOR F=l TO NLEVEL
FOR D=l TO NLEVEL

PUZZLE.ADDOBJECT("PZ"+ALLTR(STR(D))+ALLTR(STR(F)) , "PUZZLEBUTTON")
M2="PZ"+ALLTR(STR(D) ) +ALLTR(STR(F) J +".LEFT"

M1="PZ"+ALLTR(STR(D))+ALLTR(STR(F))+".VISIBLE"
M3="PZ"+ALLTR(STR(D))+ALLTR(STR(F))+".WIDTH"
M4="PZ"+ALLTR(STR(D))+ALLTR(STR(F))+".TOP"
M5="PZ"+ALLTR(STR(D) )+ALLTR(STR(F) )+".CAPTION"
Урок 27. Создание классов в Class Designer 367

PUZZLE.&M4=(F)*WT
PUZZLE.&M2=DL*(D-1)
PUZZLE.&M1=.T.
PUZZLE.&M3=DL
PUZZLE.WIDTH=DL*D
PUZZLE.HEIGHT=WT*(F+2)
ENDFOR
ENDFOR
1=0
FOR R * l TO NLEVEL
FOR K=l TO NLEVEL

M5=-"PZ"+ALLTR (STR(R))+ALLTR(STR(K))+".CAPTION"
1=1+1
PUZZLE.&M5=ALLTR(STR(LARAND(I)))
ENDFOR
ENDFOR

PUZZLE.AUTOCENTER=.T.
PUZZLE.SHOW(1)
ENDPROC

PROCEDURE COMMAND1.CLICK
THISFORM.RELEASE()
ENDPROC
ENDDEFINE

"Блок 4" — самое интересное — мы размещаем на игровом поле не просто


командные кнопки, а объекты, созданные на основе собственного класса.
Код этого класса представлен в листинге 27.9.

Листинг 27.9. Блок 4

DEFINE CLASS PUZZLEBUTTON AS COMMANDBUTTON


HEIGHT = 27
WIDTH = 84
CAPTION = ""
NAME = "PUZZLEBUTTON"

PROCEDURE CLICK
THISNAME=THIS.CAPTION
DIGIT_PART=INT(VAL(RIGHT(THIS.NAME,2)))
I F TYPE("THISFORM."+"PZ"+ALLTR(STR(DIGITJPART+1))+".NAME")="C"
NEXTNAME="THISFORM."+"PZ"+ALLTR(STR(DIGIT PART+1))+".CAPTION"
368 Часть II. Объектно-ориентированное программирование

IF &NEXTNAME="0"
THIS.CAPTION=&NEXTNAME
&NEXTNAME=THISNAME
ENDIF
ENDIF
*********************************************************************
,
IF TYPE("THISF0P^."V PZ"+ALLTR(STR(DIGITJ>ART-1))V\NAME")="C"
NEXTNAME="THISFORM."+"PZ"+ALLTR(STR(DIGIT_PART-1))+".CAPTION"
IF &NEXTNAME="0"
THIS.CAPTION=&NEXTNAME
&NEXTNAME=THISNAME
ENDIF
ENDIF

**************
IF TYPE("THISFORM."+"PZ"+ALLTR(STR(DIGIT_PART+10))+".NAME")="C"

NEXTNAME="THISFORM."+"PZ"+ALLTR(STR(DIGIT_PART+10))+".CAPTION"
IF &NEXTNAME="0"
THIS.CAPTION=&NEXTNAME
&NEXTNAME=THISNAME
ENDIF
ENDIF
***************
IF TYPE("THISFORM."+"PZ"+ALLTR(STR(DIGIT_PART-10))+".NAME")="C"
NEXTNAME="THISFORM."+"PZ"+ALLTR(STR(DIGIT_PART-10))+". CAPTION"
IF &NEXTNAME="0"
THIS.CAPTION=&NEXTNAME
&NEXTNAME=THISNAME
ENDIF
ENDIF
ENDPROC
ENDDEFINE

Наиболее важным для нас является событие click, наступающее при щелч­
ке мышью на объекте. Но и тут ничего сложного: просто с помощью функ­
ции TYPE о , возвращающей переменную, обозначающую тип объекта, мы
проверяем — а есть ли вообще "соседние" объекты у нашей кнопки? Если
есть, производим проверку надписи соседнего объекта. Если надпись "0", то
просто меняем надписи на этих двух кнопках между собой. Вот и все. Ко­
нечно, это не готовая игрушка, а просто учебный пример, показывающий
тебе удобство использования объектно-ориентированного программирова­
ния. Для полноценной игрушки неплохо бы добавить процедуру провер-
Урок 27. Создание классов в Class Designer 369

ки — а не расположены ли надписи на кнопках уже по порядку? Можно


придумать счетчик ходов, изменить оформление и т. д. Но это уже, как по­
нимаешь, дело наживное.

Другие полезные примеры


Теперь мы немного поработаем с Class Designer и создадим с помощью
данного инструмента еще несколько классов. Как я уже говорил, работа с
этим конструктором почти ничем не отличается от работы с конструктором
форм. И вот первое задание, на "засыпку": попробуй изменить цвет команд­
ной кнопки. Что, никак? И не получится (по крайней мере, в шестой версии
Visual FoxPro). Тем не менее мы можем создать свой класс с определенны­
ми свойствами.
1. В окне диспетчера проекта перейдем на вкладку Classes (Классы) и на­
жмем кнопку New (Новый).
2. В открывшемся диалоговом окне укажем имя нового класса, класс-роди­
тель и библиотеку, в которой будет сохранен новый класс (рис. 27.13).

Рис. 27.13. Мы создаем новый класс на основе базового класса C o n t a i n e r

3. После нажатия кнопки ОК открывается диалоговое окно Class Designer


(Конструктор классов), в котором непосредственно и будет происходить
дальнейший процесс создания нового класса. Воспользовавшись стан­
дартной панелью Form Controls (Элементы управления экранной фор­
мы), разместим в окне Class Designer (Конструктор классов) объект
container, а затем поместим в него объект shape (рис. 27.14).
4. Настроив такие свойства наших объектов, как цвет, размеры и т. д., об­
ратимся к событию init объекта container (который имеет имя
ColorButton):

THIS.SHAPE1.WIDTH=THIS.WIDTH-2
THIS.SHAPE1.HEIGHT=THIS.HEIGHT-2

Что произойдет? Да просто размеры объекта shape соответствующим об­


разом будут "подогнаны" под размер "своего" контейнера.
370 Часть II. Объектно-ориентированное программирование

Рис. 27.14. Объекты размещены в окне Class Designer

5. А теперь напишем обработку для события click объекта shape:


THIS.LEFT=THIS..LEFT+2
THIS.TOP=THIS..TOP+2
WAIT "" TIMEOUT 0 . 1
THIS.LEFT=THIS..LEFT-2
THIS.TOP=THIS..TOP+2

Здесь мы изменяем значения свойств Left и тор, устанавливая их равж


ми соответствующим свойствам контейнера, которому "принадлежит"
данный объект. Изменение данных свойств приводит к эффекту "нажа-
тия" на объект, после чего мы восстанавливаем исходные значения ука­
занных свойств.
А для чего нам нужна строка WAIT "" TIMEOUT O . I ? Дело в том, что изме­
нение и восстановление этих значений произойдет так быстро, что мы
ничего и не увидим! А команда WAIT прерывает выполнение программы
на время, указанное в параметре TIMEOUT. Время указывается в секундах.
Более того, после WAIT необходимо использовать пустые кавычки, чтобы
подавить вывод системного сообщения FoxPro "Press any key to conti-
Урок 27. Создание классов в Class Designer 371

nue..." (Для продолжения нажмите любую клавишу). Кстати, в этих же


кавычках можно ввести текст своего собственного сообщения.
Результат наших действий представлен на рис. 27.15.

Рис. 27.15. Форма с цветными кнопками

А какой в этом практический смысл? Да сам не знаю. Хотя, если подумать...


Можно, допустим, создать собственную панель инструментов и разместить
там такие кнопки разного цвета. При нажатии на кнопку можно менять
цвет активной экранной формы или цвет активного элемента управления.
Можно использовать в какой-нибудь игрушке... А можно и вообще нигде не
использовать — поучились и ладно.
Более полезный пример — создание группы кнопок для навигации по записям
таблицы.
1. Создаем Класс Navigator на основе базового класса CommandGroup
(рис. 27.16).
2. Теперь осталось запрограммировать действия, происходящие при нажа­
тии кнопок (листинг 27.10).

Листинг 27.10. Группа кнопок для навигации

"Первая"
GO TOP
__SCREEN.ACTIVEFORM.REFRESH()
"Следующая"
IF EOF()
=MESSAGEBOX("Последняя запись", "Конец файла")
ELSE
SKIP
_SCREEN.ACTIVEFORM.REFRESH()
ENDDIF
372 Часть II. Обьектно-ориентированное программирование

"Предыдущая"
IF BOFO
=MESSAGEBOX("Первая з а п и с ь " , "Начало файла")
ELSE
SKIP-1
_SCREEN.ACTIVEFORM.REFRESH()
ENDIF
"Последняя"
GO BOTTOM
SCREEN.ACTIVEFORM.REFRESH()

Рис. 27.16. Создание нового класса

А вот и код с а м о г о класса — л и с т и н г 27.11.

Листинг 27.11. Класс N a v i g a t o r

***************************** ********* *****************************


*— CLASS: NAVIGATOR (C:\CALC\MYLIB.VCX)
*— PARENTCLASS: COMMANDGROUP
*— BASECLASS: COMMANDGROUP
*
Урок 27. Создание классов в Class Designer 373

DEFINE CLASS NAVIGATOR AS COMMANDGROUP


BUTTONCOUNT = 4
VALUE = 1
HEIGHT =36
WIDTH = 289
NAME = "NAVIGATOR"
COMMAND1.AUTOSIZE = .T.
COMMANDl.TOP = 5
COMMAND1.LEFT = 5
COMMAND1.HEIGHT = 25
COMMANDl.WIDTH = 54
COMMANDl.FONTSIZE = 8
COMMANDl.CAPTION = "ПЕРВАЯ"
COMMAND1.NAME = "COMMANDl"
COMMAND2.AUTOSIZE = .T.
COMMAND2.TOP = 5
COMMAND2.LEFT = 58
COMMAND2.HEIGHT = 2 5
COMMAND2.WIDTH =75
COMMAND2.FONTSIZE = 8
COMMAND2.CAPTION = "СЛЕДУЩАЯ"
COMMAND2.NAME « "COMMAND2"
COMMAND3.AUTOSIZE = .Т.
COMMAND3.TOP = 5
COMMAND3.LEFT = 132
COMMAND3.HEIGHT = 25
COMMAND3.WIDTH =81
COMMAND3.FONTSIZE = 8
COMMAND3.CAPTION = "ПРЕДВДУЩАЯ"
COMMAND3.NAME = "COMMAND3"
COMMAND4.AUTOSIZE - .T.
COMMAND4.TOP = 5
COMMAND4.LEFT = 212
COMMAND4.HEIGHT = 25
COMMAND4.WIDTH =71
COMMAND4.FONTSIZE = 8
COMMAND4.CAPTION = "ПОСЛЕДНЯЯ"
COMMAND4.NAME = "COMMAND4"

PROCEDURE COMMANDl.CLICK
GO TOP
_SCREEN. ACTIVE FORM. REFRESH ()
ENDPROC
PROCEDURE COMMAND2.CLICK
374 Часть II. Объектно-ориентированное программирование

IF EOF() = .T.
=MESSAGEBOX("ПОСЛЕДНЯЯ ЗАПИСЬ", "КОНЕЦ ФАЙЛА")
ELSE
SKIP
_SCREEN.ACTIVEFORM.REFRESH()
ENDIF
ENDPROC
PROCEDURE COMMAND3.CLICK
IF BOF()
=MESSAGEBOX("ПЕРВАЯ ЗАПИСЬ", "НАЧАЛО ФАЙЛА")
ELSE
SKIP-1
_SCREEN.ACTIVEFORM.REFRESH()
ENDIF
ENDPROC
PROCEDURE COMMAND4.CLICK
GO BOTTOM
_SCREEN.ACTIVEFORM.REFRESH()
ENDPROC
ENDDEFINE
*
*— ENDDEFINE: NAVIGATOR

Данный класс можно включать в свои проекты и использовать для навига­


ции по записям таблицы.
Еще один пример: масштабируемое поле ввода с тенью.
1. Разместим в окне Class Designer (Конструктор классов) элемент управ­
ления Container С расположенным "внутри" него Объектом TextBox
(рис. 27.17).
2. В методе I n i t для данного контейнера пропишем:
THIS.TEXT1.WIDTH=THIS.WIDTH-3
THIS.TEXT1.HEIGHT=THIS.HEIGHT-3
THIS.TEXT1.FONTSIZE=THIS .TEXTl.HEIGHT/1.6

Все, класс готов, можно посмотреть его в действии — рис. 27.18.


Посмотрим его код — листинг 27.12.

Листинг 2 7 . 1 2 . К л а с с ShadowTextBox

*-- CLASS: SHADOWTEXTBOX (C:\CALC\MYLIB.VCX)


*-- PARENTCLASS: CONTAINER
* - - BASECLASS: CONTAINER
*
Урок 27. Создание классов в Class Designer 375

DEFINE CLASS SHADOWTEXTBOX AS CONTAINER


WIDTH = 438
HEIGHT =36
BACKCOLOR - RGB(128,128,228)
NAME = "SHADOWTEXTBOX"
ADD OBJECT TEXTl AS TEXTBOX WITH;
HEIGHT = 23,;
LEFT - 0, ;
TOP = 0, ;
WIDTH = 336, ;
NAME = "TEXTl"
PROCEDURE INIT
THIS.TEXTl.WIDTH=THIS.WIDTH-3
THIS.TEXTl.HEIGHT=THIS.HEIGHT-3
THIS.TEXTl.FONTSIZE=THIS.TEXTl.HEIGHT/1.6
ENDPROC
ENDDEFINE
*
*— ENDDEFINE: SHADOWTEXTBOX
*************************************************************

Рис. 27.17. Новый класс в конструкторе классов


376 Часть II. Объектно-ориентированное программирование

Рис. 27.18. Три объекта, созданные на основе нового класса

Еще пример: создание собственного индикатора ProgressBar. Дело в том, что


мы не можем изменить, допустим, цвет стандартного ProgressBar и т. д.
А что мешает сделать свой индикатор?
1. За основу также берем контейнер. Затем размещаем на нем еще один и
надпись (Label). Примерно вот так — рис. 27.19.

Рис. 27.19. Класс m y p r o g r e s s в конструкторе классов


Урок 27. Создание классов в Class Designer 377

2. Теперь осталось лишь настроить свойства данных объектов. В init на­


шего "главного" контейнера пишем следующее:
THIS.LABEL1.LEFT=THIS.WIDTH/2-THIS.LABEL1.WIDTH/2
THIS.LABEL1.TOP=THIS.HEIGHT/2-THIS.LABEL1.HEIGHT/2
THIS.CONTAINER1.WIDTH=0
THIS.CONTAINER1.HEIGHT=THIS.HEIGHT

3. Разместим наш вновь созданный объект в экранной форме. Пусть это


будет обычная форма, в качестве источника данных у которой будет ка­
кая-нибудь таблица (например, с одним полем, но с пятью тысячами
записей), и кнопка, при нажатии которой начинается процесс сканиро­
вания записей нашей таблицы. В событии click данной кнопки пишем:
SCAN
THISFORM.MYPR0GRESS1.CONTAINER1.WIDTH=(THISFORM.MYPROGRESS1.WIDTH/;
RECCOUNT (j ) *RECNO ()
THISFORM.MYPROGRESS1.LABELl.CAPTION=STR(RECNO()/RECCOUNT()*100)+"%"
WAIT WINDOW "ОБРАБАТЫВАЕТСЯ ЗАПИСЬ № "+ ALLTR(STR(RECNO())) NOWAIT
ENDSCAN

Результат наших действий представлен на рис. 27.20.

Рис. 27.20. Пример использования P r o g r e s s B a r


378 Часть II. Объектно-ориентированное программирование

И, как всегда, посмотрим код нашего класса — листинг 27.13.

Листинг 27.13. Класс MyProgress

********************************************************************
*-- CLASS: MYPROGRESS (C:\CALC\MYLIB.VCX)
*— PARENTCLASS: CONTAINER
*— BASECLASS: CONTAINER
*
DEFINE CLASS MYPROGRESS AS CONTAINER
WIDTH = 4 0 2
HEIGHT =40
BACKSTYLE m 0
BORDERWIDTH = 2
SPECIALEFFECT = 1
NAME = "MYPROGRESS"

ADD OBJECT CONTAINERl AS CONTAINER WITH;


TOP - 2,;
LEFT = 0,;
WIDTH - 61, ;
HEIGHT = 37,;
BORDERWIDTH = 2 , ;
SPECIALEFFECT = 0, ;
BACKCOLOR - RGB(0,255,255),;
NAME = "CONTAINERl"

ADD OBJECT LABEL1 AS LABEL WITH;


AUTOSIZE = .T.,;
FONTBOLD - .T.,;
BACKSTYLE = 0 , ;
CAPTION = "LABEL1",;
HEIGHT = 17,;
LEFT = 120, ;
TOP = 12, ;
WIDTH = 40, ;
NAME = "LABEL1"

PROCEDURE INIT
THIS.LABEL1.LEFT=THIS.WIDTH/2-THIS.LABELl.WIDTH/2
THIS.LABELl.TOP=THIS.HEIGHT/2-THIS.LABELl.HEIGHT/2
THIS.CONTAINERl.WIDTH=0
THIS.CONTAINERl.HEIGHT=THIS.HEIGHT
ENDPROC
Урок 27. Создание классов в Class Designer 379

PROCEDURE LABEL1.INIT
THIS.CAPTION="0%"
ENDPROC

ENDDEFINE

*— ENDDEFINE: MYPROGRESS
********************************************************************

Понятно, что, используя свой собственный индикатор, мы можем легко ме­


нять его самые различные свойства. Можно вместо второго контейнера по­
пробовать использовать какое-нибудь изображение, можно "заставить" наш
индикатор подавать звуковые сигналы и т. д.
УРОК 28

Использование таймера

До сих пор мы вели разговор об использовании визуальных классов. Но,


если ты помнишь, существуют еще и невизуальные классы и одним из них
является Timer. Объект класса Timer позволяет организовывать выполнение
команд через заданный период времени. Основным свойством такого o6ъ-
екта является свойство interval — именно в нем задается значение проме-
•жутка времени в миллисекундах. После истечения заданного времени про­
исходит событие Timer. Сейчас мы рассмотрим использование объектов
класса Timer на конкретных примерах. Допустим, мы решили сделать кра­
сивую заставку, которая будет появляться перед запуском приложения, а
затем исчезать с экрана. Создадим новый класс на основе базового класса
Form (рис. 28.1).

Рис. 28.1. Создание нового класса

В конструкторе классов откроется макет нового класса. По виду это обыч­


ная экранная форма. Поместим на нее элемент управления Timer и произ­
ведем его настройку: свойство interval установим равным 2000 (две секун­
ды), а в событии Timer укажем: THISFORM. RELEASE о (рис. 28.2).
Код созданного класса представлен в листинге 28.1.
Урок 28. Использование таймера 381

Рис. 28.2. Настройка свойств таймера

Листинг 28.1. Класс с использованием таймера

*-- CLASS: SPLASH (C:\0LDF0X\MYL1B.VCX)


*— PARENTCLASS: FORM
*~ BASECLASS: FORM

DEFINE CLASS SPLASH AS FORM


HEIGHT = 2 8 6
WIDTH =379
SHOVWINDOW - 2
DOCREATE = .T.
AUTOCENTER = .T.
PICTURE = "..\DOCUMENTS AND SETTINGS\FLOWERS,
CAPTION = "FORM2"
CONTROLBOX = .F.
TITLEBAR = 0
NAME = "SPLASH"
ADD OBJECT TIMER1 AS TIMER WITH;
TOP = 24.;
382 Часть II. Объектно-ориентированное программирован

LEFT = 252, ;
HEIGHT = 23,;
WIDTH = 23,;
INTERVAL = 2000,;
NAME = "TIMER1"
ADD OBJECT IMAGE1 AS IMAGE WITH;
PICTURE = "..\PROGRAM FILES\MICROSOFT VISUAL
^STUDIO\VFP98\FOX.BMP", ;
STRETCH = 1,;
HEIGHT - 48,;
LEFT = 300,;
TOP = 72,;
WIDTH - 84,;
NAME = "IMAGE1"
ADD OBJECT LABEL2 AS LABEL WITH;
AUTOSIZE = .T.,;
FONTBOLD = .T.,;
FONTSIZE = 22, ;
BACKSTYLE = 0, ;
CAPTION - "THE OLD FOX HOTEL",;
HEIGHT = 37, ;
LEFT = 65,;
TOP = 81,;
WIDTH = 251,;
FORECOLOR = RGB(255,255, 255) , ;
NAME = "LABEL2"
ADD OBJECT IMAGE2 AS IMAGE WITH;
PICTURE = "..\PROGRAM FILES\MICROSOFT VISUAL
4>STUDIO\VFP98\FOX.BMP",;
STRETCH = 1,;
HEIGHT = 48,;
LEFT = 0,;
TOP = 72,;
WIDTH = 84,;
NAME ш "IMAGE2"
PROCEDURE TIMER1.TIMER
THISFORM.RELEASE()
ENDPROC
ENDDEFINE
*
*— ENDDEFINE: SPLASH

Что же будет делать экранная форма, созданная на основе нашего нового


класса? Да ничего особенного — просто исчезнет с экрана через две секун-
Урок 28. Использование таймера 383

ды после своего запуска. Еще один пример — "бегущая" строка. Для создания
эффекта "бегущей" строки создадим класс на основе контейнера (рис. 28.3).

Рис. 28.3. "Бегущая" строка

На данном контейнере расположим два объекта: Label (свойство caption


данного объекта будет определять текст бегущей строки) и Timer, в событии
Timer которого пропишем следующие команды:
WITH THIS.PARENT
IF .LABELl.LEFT < .WIDTH
.LABEL1.LEFT = .LABELl.LEFT + 1
ELSE
.LABELl.LEFT = -.LABEL1.WIDTH
ENDIF
ENDWITH

Что-то новенькое, да? Я имею в виду PARENT. А на самом деле все просто:
PARENT — это ссылка на объект, в состав которого входит наш элемент
управления. В данном случае мы ссылаемся на наш контейнер. Теперь ос­
талось только установить желаемую скорость прокрутки (меняя значения
свойства interval) и можно применять данный класс в любой экранной
форме.
Код созданного класса представлен в листинге 28.2.

Листинг 28.2. "Бегущая" строка

*— PARENTCLASS: CONTAINER
*— BASECLASS: CONTAINER
DEFINE CLASS RUNNING_STRING AS CONTAINER
WIDTH = 647
HEIGHT = 2 1
NAME = "MYCLASS"
ADD OBJECT LABELl AS LABEL WITH;
CAPTION = "LABELl",;
HEIGHT = 17,;
LEFT = 120,;
TOP = 4, ;
WIDTH = 4 0, ;
NAME = "LABELl"
384 Часть II. Объектно-ориентированное программирование

ADD OBJECT TIMER1 AS TIMER WITH;


TOP = 4, ;
LEFT = 288, ;
HEIGHT = 23,;
WIDTH = 23, ;
NAME = "TIMER1"
PROCEDURE TIMER1.TIMER
WITH THIS.PARENT
IF .LABEL1.LEFT < .WIDTH
.LABEL1.LEFT = .LABEL1.LEFT + 1
ELSE
.LABEL1.LEFT = -.LABELl.WIDTH
END IF
ENDWITH
ENDPROC
ENDDEFINE
*— ENDDEFINE: RUNNING_STRING

И еще один пример — класс-секундомер (еще несколько страниц — и я


только стихами — петь начну...).
Мы не будем подробно останавливаться на процессе создания данно.
класса, дабы не повторяться — этот класс также создан на базе экранн
формы, вот так примерно он выглядит — рис. 28.4.

Рис. 28.4. Секундомер

А как и почему эта штука работает — посмотри код в листинге 28.3.

I Листинг 28.3. Секундомер


i
*-- CLASS: SWATCH (C:\OLDFOX\MYLIB.VCX)
*— PARENTCLASS: FORM
* — BASECLASS: FORM

DEFINE CLASS SWATCH AS FORM


TOP = 21
LEFT = 77
HEIGHT = 7 7
WIDTH = 258
Урок 28. Использование таймера 385

D0CREATE - .Т.
B0RDERSTYLE = О
CAPTION = "FORM1"
TITLEBAR = О
BACKCOLOR = RGB(0,0,0)
HOUR = О
MINUTES = О
SEC = О
NAME = "F0RM1"
ADD OBJECT TIMERl AS TIMER WITH;
TOP = 48,;
LEFT = 120,;
HEIGHT = 23, ;
WIDTH = 23,;
INTERVAL = 1000,;
NAME = "TIMERl"
ADD OBJECT LABEL1 AS LABEL WITH;
AUTOSIZE = .T.,;
FONTITALIC = .T.,;
FONTSIZE - 28,;
ALIGNMENT = 2,;
CAPTION = "",;
HEIGHT » 46,;
LEFT = 125, ;
TOP = 2, ;
WIDTH = 2,;
FORECOLOR = RGB(255,255, 255) , ;
BACKCOLOR = RGB(0,0,0),;
NAME = "LABELl"
ADD OBJECT CCMMANDl AS COMMANDBUTTON WITH;
TOP = 48,;
LEFT = 4,;
HEIGHT = 27,;
WIDTH = 60,;
CAPTION = "ПАУЗА",;
NAME = "COMMAND1"
ADD OBJECT COMMAND2 AS COMMANDBUTTON WITH;
TOP = 48,;
LEFT = 68,;
HEIGHT = 27,;
WIDTH = 57,;
CAPTION - "ЗАПУСК",;
NAME = "CCMMAND2"
386 Часть II. Объектно-ориентированное программирование

ADD OBJECT COMMAND3 AS CQMMANDBUTTON WITH;


TOP = 48,;
LEFT = 130, ;
HEIGHT = 27,;
WIDTH = 57, ;
CAPTION = "СБРОС",;
NAME = "COMMAND3"

ADD OBJECT COMMAND4 AS COMMANDBUTTON WITH;


TOP = 48, ;
LEFT = 192,;
HEIGHT = 27,;
WIDTH = 57,;
CAPTION = "ВЫХОД",;
NAME = "COMMAND4"
PROCEDURE INIT
PUBLIC MINUTES,HR,NSECONDS
MINUTES=0
HR=0
NSECONDS=0
ENDPROC
PROCEDURE TIMER1.TIMER
NSECONDS=NSECONDS+l
IF NSECONDS=60
NSECONDS=0
MINUTES=MINUTES+1
THISFORM.LABEL1.CAPTION=ALLTR(STR(HR))+":"+ALLTR(STR(MINUTES))+;
":"+ALLTR(STR(NSECONDS))
ENDIF
*********•*******+******•***

THISFORM.LABEL1.CAPTION=ALLTR(STR(HR))+":"+ALLTR(STR(MINUTES))+;
":"+ALLTR(STR(NSECONDS))
IF MINUTES=60
MINUTES=0
HR=HR+1
THISFORM.LABEL1.CAPTION=ALLTR(STR(HR))+":"+ALLTR(STR(MINUTES))+;
":"+ALLTR(STR(NSECONDS))
ENDIF
******************************
IF HR=24
HR=0
NSECONDS=0
MINUTES=0
Урок 28. Использование таймера 387

THISFORM. LABEL1.CAPTI0N==ALLTR(STR(HR))+":"+ALLTR(STR(MINUTES))+;
":"+ALLTR(STR(NSECONDS))
END IF
ENDPROC

PROCEDURE COMMAND1.CLICK
THISFORM.TIMER1.INTERVAL=0
ENDPROC
PROCEDURE COMMAND2.CLICK
THISFORM.TIMER1.INTERVAL=1000
ENDPROC
PROCEDURE COMMAND3.CLICK
THISFORM. TIMER1. INTERVALS
THISFORM.LABEL1.CAPTION="0:0:0"
MINUTES=0
HR=0
NSECONDS=0
ENDPROC
PROCEDURE COMMAND4.CLICK
THISFORM.RELEASE()
ENDPROC
ENDDEFINE
*
*— ENDDEFINE: SWATCH

И еще несколько слов о применении элемента управления Timer. Допустим,


мы работаем в сети с какой-то базой данных. Для просмотра данных ис­
пользуется Grid. С помощью таймера можно указать период времени, через
который будет происходить обновление данных в Grid. Достаточно указать
в событии Timer:
THISFORM.GRID.REFRESH
УРОК 29

Создание экранных форм


на основе пользовательских
классов
До сего момента мы создавали экранные формы на основе базового класса
Form, поставляемого вместе с Visual FoxPro. Но мы можем создать на базе
этого основного класса свой класс, а уже на основе созданного класса соз­
давать экранные формы. В качестве примера "соорудим" свой MessageBox.
Что это такое, ты уже видел. Итак, создаем новый класс — рис. 29.1.

Рис. 29.1. Создаем новый класс на основе класса Form

Вот так будет выглядеть наш новый класс — рис. 29.2.

Рис. 29.2. Готовый класс на основе класса Form

А код созданного класса представлен в листинге 29.1.

Листинг 29.1. Класс MyMessageBox


*-- CLASS: MYMESSAGEBOX (C:\OLDFOX\MYLIB.VCX)
*— PARENTCLASS: FORM
*— BASECLASS: FORM
Урок 29. Создание экранных форм на основе пользовательских классов 389

DEFINE CLASS MYMESSAGEBOX AS FORM


HEIGHT - 40
WIDTH - 155
DOCREATE - .T.
AUTOCENTER - .T.
CAPTION - "Завершить работу?"
CLOSABLE - .P.
MAXBUTTON - .F.
MINBUTTON - .F.
ICON = "..\PROGRAM FILES\MICROSOFT VISUAL
4>STUDIO\COMMON\GRAPHICS\ICONS\MISC\QUESTION.ICO"
WINDOWTYPE = 1
BACKCOLOR = RGB(255,255,255)
NAME = "MYMESSAGEBOX"
ADD OBJECT SHADOWBUTTON1 AS SHADOWBUTTON WITH;
TOP = 6, ;
LEFT - 3,;
WIDTH = 69, ;
HEIGHT = 30, ;
NAME = "SHADOWBUTTON1",;
COMMAND1.CAPTION = "ДА",;
COMMANDl.NAME = "COMMAND1"
ADD OBJECT SHADOWBUTTON2 AS SHADOWBUTTON WITH;
TOP = 6, ;
LEFT * 80,;
WIDTH - 69, ;
HEIGHT = 30, ;
NAME - "SHADOWBUTTON2",;
COMMAND1.CAPTION = "НЕТ",;
COMMAND1.NAME = "COMMANDl"
PROCEDURE SHADOWBUTTONl.COMMANDl.CLICK
CLOSE ALL
CLEAR EVENTS
QUIT
ENDPROC
PROCEDURE SHADOWBUTTON2.COMMANDl.CLICK
THISFORM.RELEASE()
ENDPROC
ENDDEFINE
*— ENDDEFINE: MYMESSAGEBOX

Все хорошо, но не смущает ли тебя тот факт, что кнопки нашего MessageBox
сделаны не на основе уже знакомого нам базового класса CommanddButton, a
390 Часть II. Объектно-ориентированное программирование

на основе какого-то таинственного класса shadowButton? И непонятно, от­


куда взялся этот класс — ведь в программном коде он не определен... А этот
класс создан заранее, и расположен он в той же библиотеке классов, что и
н а ш Класс MessageBox (ЛИСТИНГ 29.2).

Листинг 29.2. Класс ShadowButton

DEFINE CLASS SHADOWBUTTON AS CONTAINER


WIDTH = 86
HEIGHT = 30
BACKCOLOR = RGB(0,0,0)
NAME = "SHADOWBUTTON"
ADD OBJECT COMMANDl AS COMMANDBUTTON WITH;
TOP = 0,;
LEFT - 0,;
HEIGHT - 27,;
WIDTH = 84,;
CAPTION = "COMMANDl",;
NAME = "COMMAND1"
PROCEDURE INIT
THIS.COMMAND1.WIDTH=THIS.WIDTH-2
THIS.COMMAND1.HEIGHT=THIS.HEIGHT-2
THIS.COMMANDl.FONTSIZE=THIS.COMMANDl.HEIGHT/4.5
ENDPROC
ENDDEFINE

Более интересным примером может послужить пример формы, в которой


размеры всех входящих в нее элементов управления изменяются при изме­
нении размеров самой формы. Данный пример найден автором на просто­
рах сети Интернет и создателем сего кода является В. Поторочин.
Откроем конструктор форм для создания новой формы — рис. 29.3.
Теперь добавим в нашу форму новые свойства:
• Firstheight — первоначальная высота формы;
• Firstwidth — первоначальная ширина формы;
• Nkofh — коэффициент изменения высоты формы;
• Nkofw — коэффициент изменения ширины формы;
• Amas[i,i] — в этом массиве будут храниться первоначальные значения
размеров всех объектов формы;
• Nkolm — размерность массива;
Урок 29. Создание экранных форм на основе пользовательских классов 391

• Nb1,Nb2 — эти значения будут использованы при изменении свойства


Fontsize (Размер шрифта);
• Ndelta — текущее смещение значения Fontsize.

Рис. 29.3. Новая форма в конструкторе

Как поместить в свойства формы массив? Точно так же, как и обычные пе­
ременные — рис. 29.4.
Теперь нашу форму необходимо "оснастить" новым методом Recurs. Его код
представлен в листинге 29.3.

Рис. 29.4. В качестве нового свойства — массив


392 Часть II. Объектно-ориентированное программирование

Листинг 29.3. Метод Recurs

LPARAMETERS OOBJ, LP
LOCAL NTOTMEM,I,AMEMS[1],М1
Ml - 7
WITH OOBJ
IF THISFORM.NAME # .NAME OR THISFORM.BASECLASS # .BASECLASS
IF TYPE("OOBJ.TOP") - "N" OR TYPE("OOBJ.HEIGHT") - "N";
OR TYPE("OOBJ.LEFT") - "N" OR TYPE("OOBJ.WIDTH") = "N";
OR TYPE("OOBJ.FONTSIZE") - "N"
THISFORM.NKOLM = THISFORM.NKOLM + 1
IF !LP
DIMENSION THISFORM.AMAS[THISFORM.NKOLM,Ml]
IF TYPE("OOBJ.TOP") = "N"
THISFORM.AMAS[THISFORM.NKOLM,1] =COBJ.TOP
ENDIF
IF TYPE("OOBJ.HEIGHT") = "N"
THISFORM.AMAS[THISFORM.NKOLM,2] = OOBJ.HEIGHT
ENDIF
IF TYPE("OOBJ.LEFT") = "N"
THISFORM.AMAS[THISFORM.NKOLM,3] = OOBJ.LEFT
ENDIF
IF TYPE("OOBJ.WIDTH") = "N"
THISFORM.AMAS[THISFORM.NKOLM,4] = OOBJ.WIDTH
ENDIF
IF TYPE("OOBJ.HEADERHEIGHT") = "N"
THISFORM.AMAS[THISFORM.NKOLM,5] =OOBJ.HEADERHEIGHT
ENDIF
IF TYPE("OOBJ.ROWHEIGHT") = "N"
THISFORM.AMAS[THISFORM.NKOLM, 6] = OOBJ.ROWHEIGHT
ENDIF
IF TYPE("OOBJ.FONTSIZE") = "N"
THISFORM.AMAS[THISFORM.NKOLM,7] =OOBJ.FONTSIZE
ENDIF
ELSE
IF TYPE("OOBJ.TOP") = "N"
OOBJ.TOP = THISFORM.AMAS[THISFORM.NKOLM,1]*THISFORM.NKOFH
ENDIF
IF TYPE("OOBJ.HEIGHT") = "N"
OOBJ.HEIGHT = THISFORM.AMAS[THISFORM.NKOLM,2]*THISFORM.NKOFH
ENDIF
I F TYPE("OOBJ.LEFT") = " N "
OOBJ.LEFT = THISFORM.AMAS[THISFORM.NKOLM,3]*THISFORM.NKOFW
ENDIF
Урок 29. Создание экранных форм на основе пользовательских классов 393

IF TYPEC'OOBJ.FONTSIZE") = "N"
IF (THISF0RM.AMAS[THISF0RM.'NK0LM,7]*THISTORM.NK0FH)-THISF0RM.NDELTA > 4
OOBJ.FONTSIZE = (THISFORM.AMAS[THISFORM.NKOLM,7]*THISFORM.NKOFH)-
THISFORM.NDELTA
ELSE
OOBJ.FONTSIZE = 4
THISFORM.NDELTA = THISFORM.NDELTA - 1
ENDIF
ENDIF
IF TYPE("OOBJ.WIDTH") = "N"
IF (OOBJ.BASECLASS ="LABEL" AND !.WORDWRAP);
OR OOBJ.BASECLASS ="CHECKBOX"
IF (TXTWIDTH(OOBJ.CAPTION,OOBJ.FONTNAME,OOBJ.FONTSIZE))*;
FONTMETRIC(6,OOBJ.FONTNAME,OOBJ.FONTSIZE) > OOBJ.WIDTH
THISFORM.NB1 = 1
THISFORM.NB2 = 0
ENDIF
IF (TXTWIDTH(OOBJ.CAPTION,OOBJ.FONTNAME,OOBJ.FONTSIZE+1)) *;
FONTMETRIC(6,OOBJ.FONTNAME,OOBJ.FONTSIZE+1) > OOBJ.WIDTH
THISFORM.NB2 = 0
ENDIF
ENDIF
OOBJ.WIDTH = THISFORM.AMAS[THISFORM.NKOLM,4]*THISFORM.NKOFW
ENDIF
IF TYPEC'OOBJ.HEADERHEIGHT") = "N"
OOBJ.HEADERHEIGHT = THISFORM.AMAS[THISFORM.NKOLM,5]*THISFORM.NKOFH
ENDIF
IF TYPE("OOBJ.ROWHEIGHT") = "N"
OOBJ.ROWHEIGHT = THISFORM.AMAS[THISFORM.NKOLM,6]*THISFORM.NKOFH
ENDIF
ENDIF
ENDIF
ENDIF
NTOTMEM = AMEMBERS(AMEMS,OOBJ,2)
FOR I = 1 TO M.NTOTMEM
OOBJ = EVAL("."+AMEMS[M.I])
IF TYPE("."+AMEMS[M.I]) = "0"
THISFORM.RECURS(OOBJ, LP)
ENDIF
ENDFOR
ENDWITH

Для этого необходимо вызвать пункт New Method (Новый метод) из систем­
ного меню Form (Форма), в диалоговом окне указать имя метода и нажать
394 Часть (I. Объектно-ориентированное программирование

кнопку Add (Добавить). Название данного метода отобразится в окне


свойств экранной формы Properties. Теперь нужно дважды щелкнуть
мышью на надписи Default (справа от имени метода) и внести в открывшее­
ся окно редактирования процедур приведенный ранее текст программного
кода.
В метод init экранной формы поместить:
THISFORM.FIRSTHEIGHT=THISFORM.HEIGHT
THISFORM.FIRSTWIDTH=THISFORM.WIDTH
THISFORM.NKOLM = 0
THISFORM.NDELTA = 0
THISFORM.RECURS (THISFORM, .F.)

А В метод Resize:

THISFORM.NKOFH = THISFORM.HEIGHT/THISFORM.FIRSTHEIGHT
THISFORM.NKOFW = THISFORM.WIDTH/THISFORM.FIRSTWIDTH
THISFORM.NKOLM = 0
THISFORM.NB1 = 0
THISFORM.NB2 = 1
THISFORM.RECURS(THISFORM, .T.)
IF (THISFORM.NB2 > 0 AND THISFORM.NDELTA > 0);
OR (THISFORM.NB1 > 0)
THISFORM.NDELTA = THISFORM.NDELTA + THISFORM.NB1
THISFORM.NDELTA = THISFORM.NDELTA - THISFORM.NB2
ENDIF

Все готово! Но мы ведь создали обычную экранную форму, а как же обе­


щанный класс? Превратить форму в класс проще простого — вызываем
пункт Save As Class (Сохранить как класс) из системного меню File
(Файл) — рис. 29.5.

Рис. 29.5. Диалоговое окно Save As Class


Урок 29. Создание экранных форм на основе пользовательских классов 395

В диалоговом окне Save As Class (Сохранить как класс) необходимо указать


имя класса и библиотеку классов, которой он будет принадлежать. Чтобы
убедиться, что наша форма действительно работает, разместим на ней ос­
новные элементы управления и попробуем ее запустить — рис. 29.6, 29.7.

Рис. 29.6. Исходное состояние формы

Рис. 29.7. После изменения размеров формы

Как видим, все прекрасно работает. Ну а как же все-таки создавать формы


на основе своих классов? Для этого нужно обратиться к диалоговому окну
настроек Visual FoxPro. Вызывается это окно из пункта Options (Настройки)
системного меню Tools (Инструменты) — рис. 29.8.
396 Часть II. Объектно-ориентированное программирование

Рис. 29.8. Диалоговое окно Options

Теперь нужно перейти на вкладку Forms (Формы) и в группе переключате­


лей Template classes (Шаблоны) установить флажок Form (Форма), после
чего откроется диалоговое окно Form Template (Шаблон формы) (рис. 29.8).
Здесь необходимо указать нужную библиотеку классов, а в окне Class Name
(Имя класса) указать имя класса.
После проделанных манипуляций все новые экранные формы будут созда­
ваться на основе выбранного класса.

Рис. 29.9. Диалоговое окно Form Template


УРОК 30

Создание
панели инструментов
Класс TooiBar (Панель инструментов) представляет собой разновидность
экранной формы. Обычно он включает в себя такие элементы управления,
как командные кнопки, но в данный контейнер, как и в форму, можно
включить все, что угодно.
Создаем свою панель — рис. 30.1.

Рис. 30.1. Создание панели инструментов


398 Часть II. Объектно-ориентированное программирование

Посмотрим код? Листинг 30.1.

Листинг 30.1. Создание панели инструментов

DEFINE CLASS MY_NAVIGATOR AS TOOLBAR


CAPTION = ""
HEIGHT = 4 0
LEFT = 0
TOP = 0
WIDTH = 136
NAME = "MY_NAVIGATOR"
ADD OBJECT COMMANDl AS COMMANDBUTTON WITH;
TOP = 5,;
LEFT - 5,;
HEIGHT - 31,;
WIDTH = 34,;
PICTURE = "..\PROGRAM FILES\MICROSOFT VISUAL
->STUDIO\COMMON\GRAPHICS\ICONS\ARROWS\ARW06UP. ICO", ;
CAPTION = "",;
TOOLTIPTEXT = "ПЕРВАЯ ЗАПИСЬ",;
NAME - "COMMANDl"
ADD OBJECT COMMAND2 AS COMMANDBUTTON WITH;
TOP = 5,;
LEFT - 38,;
HEIGHT = 31,;
WIDTH - 32,;
PICTURE = "..\PROGRAM FILES\MICROSOFT VISUAL
^STUDIO\COMMON\GRAPHICS\ICONS\ARROWS\ARW06RT.ICO",;
CAPTION = "",;
TOOLTIPTEXT = "СЛЕДУЮЩАЯ ЗАПИСЬ",;
NAME = "COMMAND2"
ADD OBJECT COMMAND4 AS COMMANDBUTTON WITH;
TOP - 5,;
LEFT - 69,;
HEIGHT = 31,;
WIDTH = 34,;
PICTURE = "..\PROGRAM FILES\MICROSOFT VISUAL
4>STUDIO\C(M4ON\GRAPHICS\ICONS\ARROWS\ARW06DN. ICO", ;
CAPTION = "",;
TOOLTIPTEXT = "ПРЕДЫДУЩАЯ ЗАПИСЬ",;
NAME = "COMMAND4"
Урок 30. Создание панели инструментов 399

ADD OBJECT COMMAND3 AS COMMANDBUTTON WITH;


TOP - 5,;
LEFT = 102, ;
HEIGHT = 31,;
WIDTH = 29, ;
PICTURE = "..\PROGRAM FILES\MICROSOFT VISUAL
"bSTUDIO\COMMON\GRAPHICS\ICONS\ARROWS\ARW06LT.ICO", ;
CAPTION = "",;
TOOLTIPTEXT = "ПОСЛЕДНЯЯ ЗАПИСЬ",;
NAME - "COMMAND3"
PROCEDURE COMMAND1.CLICK
IF !BOF()
GO TOP
_SCREEN.ACTIVEFORM.REFRESH()
ENDIF
ENDPROC

PROCEDURE COMMAND2.CLICK
IF !EOF()
SKIP
_SCREEN.ACTIVEFORM.REFRESH()
ENDIF
ENDPROC
PROCEDURE COMMAND4.CLICK
IF !EOF()
GO BOTTOM
_SCREEN.ACTIVEFORM.REFRESH()
ENDIF
ENDPROC
PROCEDURE COMMAND3.CLICK
IF !BOF()
SKIP -1
_SCREEN.ACTIVEFORM.REFRESH()
ENDIF
ENDPROC
ENDDEFINE

Данную панель инструментов можно включить в экранную форму —


рис. 30.2.
Естественно, в панели инструментов можно использовать как элементы
управления, созданные на основе базовых классов Visual FoxPro, так и соз­
данные на основе пользовательских классов.
400 Часть II. Обьектно-ориентированное программирование

Рис. 30.2. Использование панели инструментов для просмотра записей


УРОК 3 1

Управление классами

На этом уроке мы познакомимся с инструментом, который позволяет на­


много упростить работу с классами.

Class Browser
В Visual FoxPro имеется удобное средство, с помощью которого можно ра­
ботать с классами: создавать новые, редактировать существующие, а также
просматривать библиотеки классов. Называется оно Class Browser (Браузер
классов). Открыть его можно двумя способами: в системном меню Tools
(Инструменты) выбрать команду Class Browser (Браузер классов) или на­
брать в командном окне: DO (BROWSER) . Каким бы способом мы его не вы­
зывали, результат будет один — рис. 31.1.

Рис. 31.1. Окно Class Browser


402 Часть II. Объектно-ориентированное программирование

Данное окно содержит панель инструментов с кнопками, назначение кото­


рых описано в табл. 31.1.

Таблица 31.1. Кнопки панели окна Class Browser

При щелчке правой кнопкой мыши на окне Class Browser (Браузер классов)
открывается контекстное меню — рис. 31.2.
Описание команд контекстного меню приведено в табл. 31.2.
Урок 31. Управление классами 403

Рис. 31.2. Контекстное меню

Таблица 31.2. Команды контекстного меню Class Browser

Команда Описание

Descriptions (Описание) Включает или выключает панели описания биб­


лиотеки и класса в нижней части окна Class
Browser
Always on Top Если стоит отметка, то окно Class Browser на­
(Всегда на переднем плане) ходится всегда на переднем плане
Auto Expand Если стоит отметка, список автоматически раз­
(Автоматическое расширение) ворачивается
Parent Class Toolbar Если стоит отметка, в системное меню доба­
(Просмотр родительского класса) вится кнопка для редактирования методов ро­
дительских классов
Restore Defaults (Восстановить Восстанавливает настройки Class Browser
настройки)
Hierarchical (Иерархия) Если стоит отметка, то список классов отобра­
жается в виде иерархического дерева
Protected (Защищенные) Если стоит отметка, то будут отображаться и
защищенные члены класса
Hidden (Скрытые) Если стоит отметка, то будут отображаться и
скрытые члены класса
Empty (Пустые) Если стоит отметка, то будут отображаться и
пустые члены класса
404 Часть II. Объектно-ориентированное программирование

Таблица 31.2 (окончание)

Команда Описание

Modify (Изменение) Происходит изменение (модификация) выбран­


ного класса
Rename (Переименовать) . Переименование выбранного объекта
Redefine (Переопределить) Изменение родительского класса для выбран­
ного класса
Remove (Удалить) Удаляет указанный класс из библиотеки клас­
сов
View (Просмотр) Просмотр текущего значения для выбранного
свойства
Container Icon (Иконка) Пиктограмма для выбранного класса
Select Parent Class (Выбор) Выбор базового класса для указанного объекта
New Window (Новое окно) Новое окно Class Browser
New Component Gallery Новое окно галереи компонентов
(Новая галерея компонентов)
Refresh (Обновить) Обновление окна
Help (Справка) Справка о Class Browser

При создании приложений очень удобно использовать окно просмотра кода


класса — достаточно скопировать текст и затем можно его использовать
в качестве программ или подпрограмм.

Информация о классе
и пиктограмма класса
Для просмотра информации о классе используется диалоговое окно Class
Info (Информация о классе) (рис. 31.3). Оно вызывается с помощью одно­
именной команды из меню Class.
Данное окно содержит две вкладки: Class (Класс) и Members (Члены). На
вкладке Class (Класс) мы можем указать значок (пиктограмму) для каждого
класса. Вернее, значка там можно указать два: один в поле ввода Toolbar
icon (Значок на панели инструментов) — данный значок будет отображаться
на панели инструментов Form Controls, а другой — в поле Container icon
(Значок контейнера) — он будет отображаться в окне Class Browser. He
знаю, как насчет второго, а вот первый рекомендую указывать — ты ведь
уже заметил, что все однотипные объекты твоей библиотеки отображаются
на панели инструментов одинаковыми значками и определить, "кто есть
Урок 31. Управление классами 405

кто" можно только по всплывающей подсказке. Представь себе 187 одина­


ковых значков и ты поймёшь, о чем это я...
Перейдем к рассмотрению вкладки Members (Члены) — рис. 31.4.

Рис. 31.3. Диалоговое окно Class Info, вкладка Class

Рис. 31.4. Диалоговое окно CJass Info, вкладка Members


406 Часть II. Объектно-ориентированное программирование

На данной вкладке отображен список объектов класса, а также перечень


методов и свойств. Столбец Name (Имя) содержит имя класса, столбец
Visibility (Видимость) может принимать три значения: Public (Глобальный),
Protected (Защищенный) и Hidden (Скрытый). В столбце No Init можно за­
претить выполнение метода init при создании объекта. По нажатию кноп­
ки Modify (Модификация) открывается диалоговое окно Edit Property/Method
(Редактирование свойств и методов) (рис. 31.5), в котором можно как изме­
нить значения выбранных свойств, так и добавить новое свойство или ме­
тод (кнопки New Property и New Method). Используя кнопку Remove (Уда­
лить), можно удалить указанный компонент.

Рис. 31.5. Диалоговое окно Edit Property/Method

В столбце Name (Имя) отображается наименование объекта, свойства ил


метода, в столбце Туре (Тип) — тип объекта (О — объект, М — метод, Р -
свойство). Столбцы Access и Assign указывают, были ли созданы соответст-­
вующие методы. Столбец Visibility определяет тип свойства или метода.
УРОК 32

Фундаментальные классы
Visual FoxPro
Конечно, хорошо самому писать различные классы — есть чем и народ уди­
вить, и себя показать... Но! Зачем "изобретать велосипед"? Ведь наивно бы­
ло бы думать, что, допустим, класс командной кнопки, которая осуществля­
ет единственное действие — закрытие экранной формы — придумали вчера.
Нет, конечно. Все эти базовые или фундаментальные классы изобретены
давным-давно. Нам же остается их где-то взять и уметь применять в своих
приложениях. А где их взять? Подсказываю три возможных варианта.
• Купить.
• Украсть (карается законом!).
• Использовать библиотеки фундаментальных классов, входящих в ком­
плект поставки Visual FoxPro.
Вот третий вариант и обсудим. В Visual FoxPro есть набор библиотек клас­
сов, которые могут быть использованы в наших приложениях для решения
большинства основных задач.
Хранится все это "добро" в обычных файлах с расширением vex, а каталог,
где все это "лежит", так и называется Foundation Classes (Фундаментальные
классы). Какие же такие "хитрые" классы и библиотеки приготовили для
нас отцы-основатели нашего Лиса? Ответ на этот вопрос — в табл. 32.1.

Таблица 32.1. Фундаментальные классы из комплекта Visual FoxPro

Название
Название класса Описание класса
библиотеки
About Dialog _dialogs.vcx Включает в приложение стандартное
диалоговое окно About
ActiveX Calendar _datetime.vcx Позволяет включить в форму календарь
Application Registry.vcx Операции, связанные с реестром Win­
Registry dows
408 Часть //. Объектно-ориентированное программирование

Таблица 32.1 (продолжение)

Название
Название класса Описание класса
библиотеки
Array Handler jjtility.vcx Операции с массивами, недоступные
при использовании стандартных средств
Cancel Button _miscbtns.vcx Кнопка Cancel (Отмена), закрывающая
экранную форму
Clock _datetime.vcx Выводит в экранную форму текущее
время
C o n f l i c t Catcher _dataqwery.vcx Диалоговое окно, в котором показаны
конфликтные значения при редактиро­
вании данных
Cookies Class Jntenet.vcx Используется в качестве FoxISAPI
Cross Tab _utility.vcx Используется для создания перекрест­
ных таблиц
Data E d i t Button Wizbtns.vcx Панель навигации по записям таблицы.
Кнопки Top, Previous, Next, Bottom,
Find, Print, Add, Delete, Edit, Save (Пер­
вая, Предыдущая, Следующая, Послед­
няя, Найти, Печать, Добавить, Удалить,
Редактировать, Сохранить)
Data Navigation _datanav.vcx Группа кнопок (Top, Previous, Next,
Buttons Bottom) (Первая, Предыдущая, Сле­
дующая, Последняя)
Data Session _app.vcx Обслуживает обновление данных в эк­
Manager ранных формах при работе с данными
Data V a l i d a t i o n _datanav.vcx Отслеживает конфликты между данными
Data Navigation Jable.vcx Данный класс обязательно используется
Object в сочетании с элементами управления
для перемещения (навигации) по запи­
сям таблиц
_dbf3html Jnternet.vcx Курсор для HTML
D i s t i n c t Values _dataqwery.vcx Заполняет поле со списком (ComboBox)
Combo уникальными значениями
Error Object _app.vcx Стандартный обработчик ошибок
F i e l d Mover _app.vcx Диалоговое окно, с помощью которого
можно переносить поля из одного спи­
ска в другой. (Мы видели такую штуку
при использовании построителя для
Grid)
F i l e Version _utility.vcx Считывает ресурс версии файла
Урок 32. Фундаментальные классы Visual FoxPro 409

Таблица 32.1 (продолжение)

Название
Название класса Описание класса
библиотеки

F i l t e r Dialog Box Jable.vcx Кнопка, которая используется в диало­


Button говом окне Filter (Фильтр)
F i l t e r Dialog Box Jable.vcx Диалоговое окно Filter (Фильтр)
Find Button Jable.vcx Кнопка, используемая в диалоговом
окне поиска записи
Find Dialog Box Jable.vcx Диалоговое окно, с помощью которого
можно отыскать указанный текст
Find Object Jable.vcx Данный объект отыскивает указанную
запись по заданному условию
Find (Find Next) _utility.vcx Кнопки Find (Найти) и Find Next (Найти
Buttons следующую)
Font Combobox Jormat.vcx Раскрывающийся список с перечнем
доступных шрифтов
Font Size Combobox Jormat.vcx Раскрывающийся список с перечнем
доступных размеров шрифтов
Format Toolbar Jormat.vcx Панель инструментов для форматирова­
ния текста

FRX-HTML Jnternet.vcx Преобразует отчет VFP (с расширением


frx) в формат HTML

G e t f i l e and _controls.vcx Диалоговое окно для выбора папок и


Directory файлов
Goto Dialog Box Jable2.vcx Кнопка, применяемая в диалоговом окне
Button Goto
Goto Dialog Box Jable.vcx Диалоговое окно для перемещения по
записям
Graph by Record _utility.vcx Используется для построения графиков
Graph Object _autgraph.vcx Используется с Graph Wizard (Мастер
диаграмм (графиков))
Help Button jniscbth.vcx Кнопка, отображающая раздел справки,
заданный свойством HelpContextld
Hyperlink Button Jiyperlink.vcx Кнопка, запускающая Web-браузер
Hyperlink Image Jiyperlink.vcx Изображение, запускающее Web-
браузер
Hyperlink Label Jiyperlink.vcx Надпись, запускающая Web-браузер
410 Часть II. Обьектно-ориентированное программирование

Таблица 32.1 (продолжение)

Название
Название класса Описание класса
библиотеки
Item Locator _dialogs.vcx Диалоговое окно для поиска файла
I N I Access Registry.vcx Осуществляет доступ к системному рее­
стру Windows для получения информа­
ции из INI-файла
Keywords Dialog Box _dialogs.vcx Диалоговое окно со списком ключевых
слов
Launch Button jnsicbtn.vcx Кнопка для запуска приложения. Ис­
пользуется командой RUN
Locate Button Jable2.vcx Кнопка для вызова диалогового окна,
выполняющего функции, аналогичные
команде Locate
Lookup Combobox _dataquery.vcx ComboBox, список значений которого
заполняется данными из полей
M a i l Merge Object Mailmerge.vcx Класс, который использует Mail Merge
Wizard (Мастер слияния данных) для
формирования документа Word
Messagebox Handler _dialogs.vcx Оболочка функции MESSAGEBOX ()
Mover _movers.vcx Элемент управления списком для орга­
низации перемещения данных
MouseOver E f f e c t s _ui.vcx Обеспечивает выполнение функций вы­
деления элемента управления при пе­
ремещении над ним указателя мыши
Navigator Shortcut _table2.vcx Контекстное меню, содержащее коман­
Menu ды навигации
Navigation Toolbar _table2.vcx Панель инструментов для перемещения
по записям таблицы
Object State _app.vcx Элемент управления, определяющий
состояние объекта
ODBC R e g i s t r y Registry.vcx Извлекает связанную с ODBC информа­
цию из системного реестра Windows
O f f l i n e Switch _dataquery.vcx Набор кнопок, позволяющий переклю­
чаться между Online- и Offline-данными
при работе с удаленными представле­
ниями
OK Button _miscbtn,vcx Кнопка, которая закрывает экранную
форму и фиксирует все изменения дан­
ных
Урок 32. Фундаментальные классы Visual FoxPro 411

Таблица 32.1 (продолжение)

Название
Название класса Описание класса
библиотеки
Output Object _reports.vcx Этот класс организует взаимодействие
с источником данных для отчетов
Output Controls _reports.vcx Формирует запросы для ввода опций
при выводе отчета
Output Dialog Box _reports.vcx Диалоговое окно для ввода опций при
выводе отчета
Password Dialog Box _dialogs.vcx Диалоговое окно для ввода пароля
Pivot Table _pivtable.vcx Используется в Pivot Table Wizard для
формирования таблицы Excel
Preview Report _miscbtn.vcx Набор кнопок, используемый при пред­
варительном просмотре отчета
QBF _dataquery.vcx Набор кнопок для выполнения запроса
R e g i s t r y Access Registry, vex Используется для получения информа­
ции из системного реестра Windows
Resize Object _controls.vcx Данный класс организует изменение
размеров объекта при изменении раз­
меров экранной формы
RTF Controls _format.vcx Используется для форматирования тек­
ста в формате RTF
Run Form Button _miscbtn.vcx Кнопка для запуска экранной формы
SCX-HTML _innternet.vcx Преобразует файл формата FRX в файл
формата HTML
Sendmail Button _miscbtn.vcx Используется для отправки почтового
сообщения из экранной формы
S h e l l Execute _environ.vcx Кнопка для запуска некоторого прило­
жения из текущего приложения
Shortcut Menu Class _menu.vcx Используется при создании контекстных
меню
Simple E d i t Buttons Wizbtns.vcx Набор кнопок Add, Delete, Edit,
Dublicate, Save, Cancel (Добавить, Уда­
лить, Редактировать, Копировать, Со­
хранить, Отмена) для редактирования
таблиц и видов
Simple Picture _table.vcx Пиктографические кнопки Next (Сле­
Navigation Buttons дующая) и Previous (Предыдущая) для
перемещения по записям таблицы или
представления данных
412 Часть II. Объектно-ориентированное программирование

Таблица 32.1 (продолжение)

Название
Название класса Описание класса
библиотеки

Simple Navigation .table, vex- Обычные кнопки Next (Следующая) и


Buttons Previous (Предыдущая) для перемеще­
ния по записям таблицы или представ­
ления данных
Sort Dialog Box Jable2.vcx Данная кнопка используется в диалого­
Buttons вом окне сортировки
Sort Object Jable2.vcx Используется для сортировки данных
Sort Selector _table2.vcx Набор кнопок для сортировки данных по
возрастанию или убыванию
Sort Mover _movers.vcx Используется для автоматической сор­
тировки данных
Sound Player jnutimedia.vcx Используется для загрузки и проигрыва­
ния звуковых файлов
Splash Screen _dialogs.vcx Используется для создания заставки для
приложений
SQL Pass Through _dataquery.vcx Используется для выполнения операций
SQL Path Through
Stop Watch _datetime.vcx Секундомер
String Library _utility.vcx Удаляет символы возврата каретки и
перевода строки из данных строкового
типа
Super Mover _movers.vcx Элемент управления списком. Имеет
кнопки Move, Remove, MoveAII, Re-
moveAII (Переместить, Удалить, Пере­
местить все, Удалить все) для переме­
щения данных

System Toolbar _app.vcx Используется в приложениях для


установки или удаления системной
панели управления
Table Mover _movers.vcx Список, который автоматически загру­
жает таблицы и поля из текущего источ­
ника данных
Text Preview Текстовый редактор для диалоговых
окон
Thermometer _controls.vcx Элемент управления в виде термометра
Trace Aware Timer _app.vcx Управляет окном трассировки
Урок 32. Фундаментальные классы Visual FoxPro 413

Таблица 32.1 (окончание)

Название
Название класса Описание класса
библиотеки
Type Library _utility.vcx Извлекает информацию о типе из биб­
лиотеки типов и формирует текстовый
файл
URL Combo _intemet.vcx Поле со списком для ввода адреса ин­
тернет-страницы
URL O p e r a t i o n _internet.vcx Диалоговое окно для хранения адресов
D i a l o g Box ресурсов Интернет
VCR B u t t o n s _table.vcx Группа кнопок для перемещения по
записям
VCR P i c t u r e s _table.vcx Группа пиктографических кнопок для
Navigation Buttons перемещения по записям
Video Player _multimedia.vcx Загрузка и проигрывание видеофайлов
Web Browser C o n t r o l _webview.vcx Позволяет включать в экранную форму
браузер Internet Explorer
Window Handler _ui.vcx Используется для управления окнами

Просмотрев эту таблицу, ты наверняка с недоумением пожмешь плечами и


скажешь: "Ну и что? А я то здесь причем?" А притом, что все эти уже гото­
вые классы ты можешь использовать при разработке своих приложений.
Другой вопрос, как и с помощью чего это сделать? Именно для этого случая
разработчики приготовили для нас еще один сюрприз, о котором мы пого­
ворим на следующем уроке.
УРОК зз

Галерея компонентов
(Component Gallery)
С помощью галереи компонентов можно группировать такие компоненты,
как проекты, классы, формы, отчеты и т. д. Также она предоставляет сред­
ства для создания новых проектов, форм и т. д. А еще, как я уже говорил,
с помощью этой хитрой штуки можно включать в свои приложения фунда­
ментальные (и не только) классы.
Для запуска придется выполнить одно из следующих действий: выбрать
команду Component Gallery (Галерея компонентов) из меню Tools
(Инструменты) или набрать команду DO (GALLERY) В командном окне. В
любом случае галерея появится на экране — рис. 33.1.

Рис. 33.1. Диалоговое окно Component Gallery


Урок 33. Галерея компонентов (Component Gallery) 415

Как видишь, диалоговое окно разбито на две части. Левая, в которой нахо­
дятся каталоги, называется панель каталогов, а правая, на которой располо­
жены объекты, — панель объектов.
По умолчанию каталоги в галерее компонентов организованы следующим
образом — табл. 33.1.

Таблица 33.1. Каталоги в галерее компонентов

Каталог Описание

Catalogs Корневой каталог

VFP Main Содержит компоненты, используемые другими


каталогами

Favorites В этот каталог мы можем поместить те компонен­


ты, которые чаще всего используем при работе

Visual FoxPro Содержит все базовые классы Visual FoxPro, шаб­


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

Data Содержит средства для работы с данными

Foundation Classes Библиотеки фундаментальных классов

Help Файлы с разделами справки

Templates Шаблоны различных мастеров (Wizard)

Tools Содержит инструменты для разработки приложе­


ний

My Base Classes Подклассы основных классов Visual FoxPro

ActiveX Содержит перечень всех зарегистрированных на


компьютере элементов управления ActiveX

World Wide Web Список адресов Web-страниц, посвященных Visual


FoxPro

Multimedia Файлы мультимедиа (звуковые, видео, изображе­


ния), которые можно включать в приложения

Samples Программы учебных приложений


416 Часть II. Объектно-ориентированное программирование

Панель инструментов Component Gallery


Панель инструментов содержит следующие к н о п к и — табл. 33.2.

Таблица 33.2. Кнопки панели инструментов

Рис. 33.2. Диалоговое окно Open


Урок 33. Галерея компонентов (Component Gallery) 417

Рис. 33.3. Диалоговое окно Component Gallery Options, вкладка Standard

Вкладка Standard (Стандартные) позволяет настроить общие параметры ок­


на галереи компонентов (рис. 33.3). Опции вкладки Standard (Стандартные)
перечислены в табл. 33.3.

Таблица 33.3. Опции вкладки Standard

Опция Описание

Группа Global defaults (Общие установки)

Enable item renaming Если установлен данный флажок, раз­


(Разрешить переименовывать объект) решается переименовывать каталоги и
объекты

FFC Builder Lock (Запуск построителя) При установке данного флажка при
перетаскивании объекта на экранную
форму будет автоматически запущен
соответствующий построитель

Drag and drop to desktop (Перенести При установке данного флажка объект
и оставить на рабочем столе) можно перетащить на рабочий стол.
(Правда, работать он там не будет)

Advanced editing enabled При установке этого флажка в окно


(Возможность дополнительного свойств объекта будут добавлены до­
редактирования) полнительные вкладки (Type, Scripts,
Views, Comments) (Тип, Скрипты,
Представления, Комментарии)
418 Часть II. Объектно-ориентированное программирование

Таблица 33.3 (окончание)

Опция Описание

Группа Catalog default behavior (Действия каталога по умолчанию)

Open file as new view (Открыть файл) Если установлен этот переключатель,
то объект, который может быть либо
открыт, либо добавлен при двойном
щелчке мыши, будет именно открыт

Add file to current view (Добавить файл) Если установлен этот переключатель,
то объект, который может быть либо
открыт, либо добавлен при двойном
щелчке мыши, будет именно добавлен

Группа Item default behavior (Действия объекта по умолчанию)

Modify item file (Модифицировать файл) При установке этого переключателя


объект будет модифицирован при
двойном щелчке

Run item file (Запуск файла) При установке этого переключателя


объект будет запущен на выполнение
при двойном щелчке

Рис. 33.4. Диалоговое окно Component Gallery Options, вкладка Catalogs

На вкладке Catalogs (Каталоги) расположен список входящих в состав гале­


реи компонентов каталогов (рис. 33.4). При желании можно добавить но­
вый каталог, воспользовавшись кнопкой New (Новый).
Урок 33. Галерея компонентов (Component Gallery) 419

Рис. 33.5. Раскрывающийся список View Type

На панели инструментов галереи компонентов имеется раскрывающийся


список View Type (Тип представления) — рис. 33.5
Здесь имеется список значений, управляющих видом отображения данных в
окне галереи компонентов. Изменить (см. рис. 33.7), удалить или добавить
дополнительные значения можно с помощью вкладки Dynamic Views (Ди­
намические представления) — рис. 33.6.

Рис. 33.6. Диалоговое окно Component Gallery Options, вкладка Dynamic Views
420 Часть II. Объектно-ориентированное программирование

Рис. 33.7. Диалоговое окно Edit View

Работа с галереей компонентов


Сейчас попробуем на практике применить все ранее описанное. В конст­
рукторе форм создадим обычную форму. Затем, не закрывая окна конструк­
тора форм, вызовем окно галереи компонентов, в котором откроем каталог
Foundation Classes (Фундаментальные классы), а в нем — каталог Buttons
(Кнопки). В правом окне галереи компонентов выберем объект OK Button и
перетащим его мышью в нашу форму. Теперь откроем подкаталог DateTime
(Дата/Время), в правом окне выберем объект Clock (Часы) и нажмем пра­
вую кнопку мыши. В появившемся контекстном меню выберем команду
Add to form (Добавить в форму). Запустим форму на выполнение —
рис. 33.8.

Рис. 33.8. Использование компонента из галереи

Видишь, за десять секунд мы сделали форму, которая отображает текущие


дату и время, да еще и закрывается при щелчке по кнопке. Удобно, правда?
Еще мы узнали, что добавлять объекты можно как используя контекстное
меню, так и просто перетаскивая их — галерея компонентов полностью
поддерживает метод Drag and Drop (Перенести и оставить).
Более того, на основе фундаментальных классов с помощью галереи компо­
нентов можно создавать новые компоненты для своих приложений. Пом­
нишь, при изучении таймера мы делали форму-заставку? Так вот, в галерее
компонентов уже есть готовый класс экрана-заставки.
Урок 33. Галерея компонентов (Component Gallery) 421

1. Открой подкаталог Dialogs (Диалоги или диалоговые окна) и щелкни


правой мышью по объекту Splash Screen. В контекстном меню выбери
команду Create Form (Создать форму).
2. После этого откроется диалоговое окно, в котором нужно указать имя
новой формы, а затем автоматически запустится конструктор форм с уже
готовым шаблоном — рис. 33.9.

Рис. 33.9. Создание новой формы

Использование галереи компонентов


для создания приложения
С помощью галереи компонентов можно создавать не только компоненты
приложений, но и сами приложения.
1. В окне галереи компонентов открой корневой каталог (Catalogs) и дваж­
ды щелкни по объекту New Application (Новое приложение).
2. Откроется диалоговое окно Enter Project Name (Введите имя проекта)
(рис. 33.10). Всего то и остается, что указать имя проекта, и через не­
сколько секунд запустится построитель проекта (Application Builder).
422 Часть II. Объектно-ориентированное программирование

Рис. 33.10. Диалоговое окно Enter Project Name

Но это еще не все! Галерея компонентов содержит несколько готовых при­


ложений, на базе которых можно построить свое собственное. Хранятся они
в папке Applications (Приложения) каталога Templates (Шаблоны) (рис. 33.11).

Рис. 33.11. Шаблоны приложений


Заключение

Ну вот, подходит к концу наша книга, пора подводить итоги. Пройдя все
уроки, ты научился (а мне хотелось бы верить, что это так) создавать сво­
бодные таблицы и таблицы базы данных, экранные формы, отчеты, слож­
ные (и не очень) запросы и представления данных, перекрестные таблицы,
графики и т. д. В общем, можно сказать, что ты полностью усвоил основ­
ные навыки работы с Visual FoxPro. Почему основные? Да потому, что эта
книга лишь приоткрыла для тебя дверь в мир СУБД, и я думаю, что это бы­
ла интересная экскурсия...
О Visual FoxPro написано немало книг, справочников, учебных пособий, и
если ты решишь серьезно заняться программированием, тебе не составит
труда найти их. А я напоследок "подарю" тебе список ресурсов Интернет,
посвященных FoxPro.
• Официальные:
http://www.microsoft.com/rus/ — Microsoft в России.
http://msdn.microsoft.com/vfoxpro/default.asp — Microsoft Visual FoxPro.
• Пресса:
www.newsletter.narod.ru/foxtaIk/FoxTalk.htm — "FoxTalk".
• Коллективные:
www.firststeps.ru — "Первые шаги" — Клементьев В. А., Сергей Платонов,
Каев Артем.
www.infocity.kiev.ua — "Виртуальный город компьютерной документа­
ции" — Пинкус Михаил.
www.universalthread.com — Michel Fournier, Nick Neklioudov, Evan Delay,
Gerald Santerre, Claudio Lassala, MartHn SalHas.
• Частные:
www.dbrad32.narod.ru — Баянов Дмитрий Александрович.
www.wet.narod.ru — Ветчинов Владимир.
424 Заключение

www.Foxpopuli.narod.ru — Горяинов Евгений.


www.clickexpIorer.narod.ru — Грицюк Сергей.
www.vfpdev.narod.ru — Дроздов Михаил.
www.nsvisual.com/fox2 — Жирнов Сергей.
www.foxuser.by (nm) (boom).ru — Закиров Орион.
www.skc.narod.ru — Коваль Александр.
www.urfin.boom.ru — Радченко Виктор Вадимович.
www.foxtools.newmail.ru — Сидоров Леонид.
www.dushes.hotbox.ru — Смирнов Андрей Валерьевич.
www.sumarokov.nm.ru — Сумароков Сергей.
www.vfp.narod.ru — Тананаев Дмитрий Александрович.
• Форумы:
http://talk.mail.ru/forum/fido7.ru.foxpro — Эха по FPD.
http://talk.mail.ru/forum/fido7.ru.visual.foxpro — Эха по VFP.
http://ljuda_m.chat.ru/foxolb_07_02.rar — Обзор русскоязычных ресурсов
FoxPro — Alex Kise.

А теперь хочется сказать слова благодарности всем, кто помогал мне при
создании этой книги. Огромное СПАСИБО:
• моей супруге Елене — за понимание и поддержку в этом нелегком начи­
нании;
• семье Ушаковых, Владимиру и Татьяне — за оказанную техническую по­
мощь;
• Жанне Манойленко — за полуночное редактирование.
И, конечно же, огромное спасибо тебе, уважаемый читатель — ведь это
не я, это МЫ вместе с тобой написали эту книгу. Успехов тебе и
СЧАСТЛИВОГО ПРОГРАММИРОВАНИЯ!
Дмитрий Шапорев
foxbook@list.ru
ПРИЛОЖЕНИЯ
ПРИЛОЖЕНИЕ 1

Настройка параметров
конфигурации Visual FoxPro
Для настройки параметров, определяющих работу Visual FoxPro, необходимо
вызвать диалоговое окно Options (Параметры) посредством команды Options
(Параметры/Опции) системного меню Tools (Инструменты) (рис. П1.1).

Рис. П1.1. Вызов окна Options

После выполнения этой команды окно настроек не заставит себя ждать


рис. П1.2.
428 Приложение 1

Рис. П1.2. Диалоговое окно Options

Все параметры разделены на соответствующие группы, расположенные на


двенадцати вкладках, описание которых приведено в табл. П1.1.
Таблица П1.1. Вкладки окна Options

Вкладка Описание

Controls (Элементы управления) Настройка визуальных классов и объектов OLE


Data (Данные) Настройка параметров для управления данными
Debug (Отладка) Настройка параметров трассировки и отладки
программ
Field Mapping (Поля) Определяет тип объекта, который будет создан
в форме при переносе на нее полей таблиц из
окна Data Environment (Среда окружения),
Database Designer (Конструктор базы данных)
или проекта
File Locations Отображает расположение файлов и каталогов
(Расположение файлов)
Forms (Формы) Настройка конструктора экранных форм
General (Основные параметры) Настройки звука и ввода данных
Projects (Проекты) Настройка окна проекта
Настройка параметров конфигурации Visual FoxPro 429

Таблица П1.1 (окончание)

Вкладка Описание

Regional Настройка формата отображения дат, чисел,


(Региональные параметры) денежных единиц и времени
Remote Data (Удаленные данные) Настройка удаленного доступа к данным
Syntax Coloring (Цвет Настройка цвета шрифта
синтаксиса)
View (Вид) Настройка отображения на экране строки со­
стояния, системного времени, системных со­
общений

Начнем по порядку описание каждой вкладки.


С помощью вкладки Controls (Элементы управления) (рис. П1.3) можно до­
бавлять как библиотеки классов, так и элементы управления ActiveX (мы
уже делали это). Для добавления элемента или библиотеки служит кнопка
Add (Добавить), для удаления — Remove (Удалить).

Рис. П1.3. Диалоговое окно Options, вкладка Controls

Вкладка Data (Данные) (рис. Ш.4) позволяет настроить определенные па­


раметры, описание которых приведено в табл. П1.2.
430 Приложение 1

Рис. П1.4. Диалоговое окно Options, вкладка Data

Таблица П1.2. Параметры вкладки Data

Параметр Описание
Open exclusive Это и есть тот самый эксклюзивный доступ, о
(Открывать монопольно) котором мы говорили ранее. При выборе этой
опции таблица будет открыта в монопольном
режиме, и никто другой не сможет открыть эту
таблицу (имеется в виду работа нескольких
пользователей в сети)
Show field names При выполнении таких команд, как SUM,
(Отображать имена полей) DISPLAY, AVERAGE, L I S T , НЭД с т о л б ц а м и б у д у т
отображаться названия соответствующих полей.
Эта опция соответствует команде SET HEADING
Prompt for code page Определяет, предлагать ли пользователю вы­
(Предлагать выбор кодовой брать кодовую страницу. Например, при попыт­
страницы) ке просмотра таблицы FoxPro for DOS будет
предъявлено диалоговое окно Code Page. Со­
ответствует команде SET CPDIALOG
Ignore deleted records Определяет, каким образом будут обрабаты­
(Игнорировать удаленные записи) ваться "удаленные" записи. Дело в том, что
команда DELETE не удаляет записи физически,
а лишь помечает их определенным образом.
Если этот флажок не установлен, то такие
записи будут обрабатываться как и все осталь­
ные. Соответствует команде SET DELETED
Настройка параметров конфигурации Visual FoxPro 431

Таблица П1.2 (продолжение)

Параметр Описание
Rushmore optimization Определяет, включен ли метод ускоренного
(Оптимизация Rushmore) поиска информации, называемый Rushmore.
Рекомендуется отключать лишь в особых слу­
чаях. Соответствует команде SET O P T I M I Z E
Unique records in indexes Соответствует команде SET UNIQUE. При уста­
(Уникальные записи в индексах) новке данного флажка индексы будут поддер­
живать только неповторяющиеся значения
ключей, несмотря даже на то, что могут быть
записи и с одинаковыми значениями
Collation sequence С помощью раскрывающегося списка можно
(Порядок сортировки) выбрать желаемый порядок сортировки симво­
лов. Соответствует команде SET COLLATE
Record counter interval Определяет частоту выдачи сообщений в стро­
(Интервал отсчета записей) ку состояния о количестве обработанных запи­
сей при выполнении таких команд, как PACK И
RE INDEX. Соответствует команде SET ODOMETR.
Значения могут быть в интервале от 1 до
32 787, но при установке слишком малого ко­
личества записей может замедлить работу
приложения, т. к. потребует более частого об­
новления экрана

Memo block size Соответствует команде SET BLOCKS IZE и опре­


(Размер мемо-блоков) деляет длину Memo-блока в байтах
Browse refresh interval Определяет, через какой интервал времени
(Интервал обновления при (в секундах) данные в окне Browse будут об­
просмотре) новлены в соответствии с физическими данны­
ми в таблице. Команда SET REFRESH
Table refresh interval Определяет, через какой интервал времени
(Интервал обновления таблицы) (в секундах) данные в любом окне (не только
Browse) будут обновлены в соответствии с фи­
зическими данными в таблице
SET NEAR on Влияет на действия Лиса при неудачном поис­
(Установить вблизи) ке записи. Если флажок снят, то при неудач­
ном поиске указатель остановится в конце
файла. При установленном же флажке указа­
тель остановится на следующей по алфавиту
записи относительно той позиции, в которой
ожидалось найти искомое значение. Соответ­
ствует команде SET NEAR
SET EXACT on Управляет поиском символьных строк. При
(Установить точно) установленном флажке искомое значение
должно точно совпадать с критерием поиска,
т. е. как по длине строки, так и посимвольно.
Соответствует команде SET EXACT
432 Приложение 1

Таблица П1.2 (окончание)

Параметр Описание

SET ANSI on При сравнении двух строк разной длины более


(Установить ANSI) короткая дополняется пробелами, чтобы длины
сравниваемых строк стали одинаковыми. Если
флажок не установлен, строки сравниваются
посимвольно до длины более короткой. Коман­
да SET ANSI

Опции для работы в сети (многопользовательский режим)

Automatic file locking Соответствует команде SET LOCK и устанавли­


(Автоматическая блокировка вает режим автоматической блокировки фай­
файлов) лов при совместном доступе

Multiple record locks Соответствует команде SET MULTILOCKS и ис­


(Блокировка нескольких записей) пользуется для блокировки и совместной обра­
ботки сразу нескольких записей

С помощью параметров вкладки Debug (Отладка) (рис. П1.5) настраивается


работа отладчика (табл. П1.3).

Рис. П1.5. Диалоговое окно Options, вкладка Debug


Настройка параметров конфигурации Visual FoxPro 433

Таблица П1.3. Параметры вкладки Debug

Параметр Описание
Environment (Среда) Определяет среду для отладчика. При выборе
Debug Frame (Оболочка отладчика) все окна
отладчика располагаются внутри окна Visual
FoxPro Debugger (Отладчик Visual FoxPro).
При выборе FoxPro Frame отдельные окна от­
ладчика можно отображать в главном окне Visual
FoxPro
Display Timer Events При отмеченном флажке в процессе отладки
(Отображать события таймера) будут отображены события таймера
Specify Window Здесь перечислены окна отладчика, для которых
(Определить для окна) можно задать такие параметры, как размер и
цвет шрифта и т. д. Все эти параметры перечис­
лены в нижней части вкладки

Рис. П1.6. Диалоговое окно Options, вкладка Field Mapping

С помощи вкладки Field Mapping (Поля) (рис. П1.6) можно назначить дей­
ствующие по умолчанию элементы управления в зависимости от типа поля.
Для чего это нужно? А вот смотри: раньше тип объекта, связанный с типом
поля, был строго фиксирован и представлял собой в большинстве случаев
434 Приложение 1

текстовое поле. Но, допустим, для поля типа Logical удобнее использовать
такой элемент управления, как флажок. Теперь мы легко это можем опре­
делить. Замечу, что началось такое "удобство" с пятой версии Visual FoxPro.

Опишем параметры базы данных (Database options) — табл. П1.4.

Таблица П1.4. Группа Database options


Параметр Описание

Drag and drop field caption При установке этого флажка заголовок поля
("Перетащить и оставить" будет сформирован на основе свойства
заголовки полей) Caption структуры таблицы и включен при
добавлении поля на экранную форму

Copy field comment Копируется комментарий к данному полю


(Копировать комментарии полей)
Copy field input mask Копируется маска ввода для данного поля
(Копировать маску ввода)
Copy field format Копируется формат данного поля
(Копировать формат поля)

Для изменения элемента управления, связанного с каким-либо типом поля,


необходимо нажать кнопку Modify (Модификация) и указать в диалоговом
окне Modify Field Mapping (Модификация полей) объект базового или поль­
зовательского класса (рис. П1.7).

Рис. П1.7. Диалоговое окно Modify Field Mapping

Во время своей работы наш трудяга Лис использует огромное количество


различных файлов. А как управляться со всем этим хозяйством, где что ис­
кать? А вот на вкладке File Locations (Размещение файлов) (рис. П1.8) име-
Настройка параметров конфигурации Visual FoxPro 435

ется таблица, которая и используется для определения расположения фай­


лов и папок (табл. П1.5).

Рис. П1.8. Диалоговое окно Options, вкладка File Locations

Таблица П1.5. Файлы для работы Visual FoxPro

Имя
Тип файла Назначение файла (по умолчанию)

ActiveDoc Launcher Определяет имя и расположение при­ Runactd.prg


ложения, вызываемого командой Run
Active Doc (Запустить активный доку­
мент) из меню Tools (Инструменты)
Builders Определяет имя и расположение при­ Builder.app
ложения построителя (Builder)
Class Browser Определяет имя и расположение при­ Browser.app
ложения Class Browser
Component Gallery Определяет имя и расположение при­ Galery.app
ложения Component Gallery
Converter Определяет имя и расположение при­ Converter.app
ложения, осуществляющего конверта­
цию форм и отчетов, разработанных в
ранних версиях FoxPro в формат данной
версии
436 Приложение 1

Таблица П1.5 (продолжение)

Имя
Тип файла Назначение файла
(по умолчанию)

Coverage Profiler Определяет имя и расположение при­ Coverage.арр


ложения для статистической обработки
созданных приложений
Default Directory Имя каталога по умолчанию, в котором
Visual FoxPro будет размещать про­
граммные файлы и таблицы

Default Include File Определяет имя и расположение фай­


ла, в котором будут заданы различные
константы
Documenting Wizard Определяет имя и расположение при­ Beautify.app
ложения для документирования прило­
жений и программ

Expression Wizard Определяет имя и расположение по­


строителя приложений

HTML Generator Определяет имя и расположение при­ GetbtmJ.app


ложения, которое используется для со­
хранения созданного приложения в
формате HTML

Help File Определяет имя и расположение справ­


ки
Menu Builder Определяет имя и расположение по­
строителя меню
Resource File Определяет имя файла ресурсов.
Ресурсный файл FOXUSER.DBF- обыч­
ная таблица, в которой хранится ин­
формация об установках редактора,
режимах работы, размерах окон и т. д.

Samples Directory Определяет имя и расположение ката­


лога с учебными примерами Visual FoxPro

Search Path Задает каталог, в котором будет про­


должен поиск файлов, не найденных в
текущем каталоге

Spelling Checker Определяет имя и расположение при­


ложения для проверки орфографии
Startup Program Определяет имя и расположение при­ Vfp6strt.app
ложения, которое начинает работать при
запуске Visual FoxPro
Настройка параметров конфигурации Visual FoxPro 437

Таблица П1.5 (окончание)

Тип файла Назначение файла Имя


(по умолчанию)
Temporary Files Каталог для создания временных фай­
лов
Wizards Определяет имя и расположение масте­
ров

Вкладка Forms (Формы) (рис. ГЛ.9) используется для настройки конструк­


тора форм. Ее параметры описаны в табл. Ш.6.

Рис. П1.9. Диалоговое окно Options, вкладка Forms

Таблица П1.6. Параметры вкладки Forms

Параметр Описание

Grid lines (Линии сетки) Отображение линий сетки


Horizontal spacing Определяет расстояние между горизонталь­
(Интервал по горизонтали) ными линиями сетки (в пикселах)
Vertical spacing Определяет расстояние между вертикальны­
(Интервал по вертикали) ми линиями сетки (в пикселах)
438 Приложение 1

Таблица П1.6 (окончание)

Параметр Описание

Snap to grid (Привязка к сетке) При перемещении объекта в макете формы


он автоматически устанавливается в ближай­
шую точку пересечений линий сетки
Show position (Показать позицию) При установленном флажке в строке состоя­
ния будут отображаться размер и позиция
верхнего левого угла объекта
Tab ordering (Порядок табуляции) Определяет, в каком порядке элементы I
управления будут получать фокус при работе
формы. Имеется два значения: Interactive
(Интерактивно) и By list (По списку). При ус­
тановленном значении Interactive (рис. П1.10)
для определения порядка получения объек­
тами фокуса необходимо нажать клавишу
<Sr»ft> и поочередно щелкать мышью на эле­
ментах управления. При установке значения
By list (рис. Л 1.11) порядок табуляции будет
отображен в виде списка
Scale units (Единица измерения) Выбор единицы измерения для определения
размеров объектов. Используются две едини­
цы: пиксел и фоксел
Maximum design area Задается максимальная разрешающая спо­
(Максимальная рабочая область) собность экрана
Template classes С помощью данного шаблона можно опреде­
(Классы шаблонов) лить два класса, которые будут использованы
как шаблоны для форм и наборов форм
Builder lock Автоматический запуск построителя при
(Привязка построителя) встраивании обьекта в форму
Prompt to save changes before Если этот флажок снять, то все изменения
running form (Предлагать сохранять после редактирования формы будут автома­
изменения при запуске формы) тически сохранены перед ее запуском

На вкладке Genera] (Общие уста*говки) (рис. П1.12) устанавливаются пара-


метры общего назначения, такие <ак звук, цветовая палитра и т. д.
Т и п звукового сигнала, которыег будет звучать п р и вводе недопустимых
данных, задается в области WJirning sound (Предупреждающий сигнал)
(табл. П1.7).
Совместимость с ранними версиями определяется установкой флажка dBase
compatibility (Совместимость с dBase). Если флажок сброшен, то Visual
FoxPro выполняет программы и приложения, написанные в ранних версиях
FoxPro (например, FoxPro for DOS). Если же флажок установлен, то коман­
ды, перечисленные в табл. П1.8, будут выполняться по-другому.
Настройка параметров конфигурации Visual FoxPro 439

Рис. П1.10. Интерактивное определение порядка табуляции

Рис. П1.11. Определение порядка табуляции по списку


440 Приложение 1

Рис. П1.12. Диалоговое окно Options, вкладка General

Таблица П1.7. Параметры группы Warning sound

Параметр Описание

Off (Выключен) Звуковой сигнал отсутствует


Default (По умолчанию) Частота (512 Гц) и продолжительность (2 с) звукового
сигнала установлены по умолчанию
Play (Проиграть) Проигрывается выбранный файл

Таблица П1.8. Выполнение команд

Команда ON OFF

@ GET RANGE Всегда проверяет диапазон Проверяет диапазон только


при изменении данных

@ SAY При выводе информации на Вывод информации прекра­


экран происходит прокрутка щается при достижении пра­
экрана вого нижнего угла
@ SAY Функция CHR О вызывает Функция CHR () не вызывает
звуковой сигнал звуковой сигнал
Настройка параметров конфигурации Visual FoxPro 441

Таблица П1.8 (продолжение)

Команда ON OFF

@ SAY В предложении PICTURE В предложении PICTURE


крайняя правая цифра крайняя правая цифра отсе­
округляется кается

ACTIVATE SCREEN При активизации экрана При активизации экрана по­


курсор занимает пози­ зиция курсора не меняется
цию 0,0

ACTIVATE WINDOW При активизации окна кур­ При активизации окна пози­
сор занимает позицию 0,0 ция курсора не меняется

APPEND MEMO Расширение по умолчанию Расширение отсутствует


txt

DECLARE Создает массив Рекомендуется применять


аналогичную команду
DIMENSION

FSIZE Возвращает размер файла Возвращает размер поля

GO/GOTO (совместно Выводит сообщение с номе­ Такое сообщение не выво­


С SET TALK ON) ром рабочей области дится
и записи

INKEY() При нажатии клавиш <Shift> При нажатии клавиш <Shift>


и <Shift>+<Home> возвра­ и <Shift>+<Home> возвра­
щается код 26, а при нажа­ щается код 1, а при нажатии
тии клавиш <Ctrl>+<Left> клавиш <Ctrl>+<Left>
возвращается код 1 возвращается код 26

LASTKEY() Возвращает код последней Рекомендуется использовать


нажатой клавиши INKEY()

LIKEO Пробелы в строках удаляют­ Пробелы не удаляются


ся перед сравнением

MENU И POPUP Меню размещается в теку­ Меню размещается в собст­


щем окне, курсор распола­ венном окне, курсор распо­
гается на одной из опций лагается в активном окне
списка

Вложенные При возвращении на более При возвращении на более


операторы высокий уровень выполняет­ высокий уровень текущие
ся команда CLEAR GETS установки GETS остаются

Передаваемые Параметры, передаваемые Параметры, передаваемые


параметры по ссылке, доступны в вызы­ по ссылке, недоступны
ваемой процедуре в вызываемой процедуре
442 Приложение 1

Таблица П1.8 (продолжение)

Команда ON OFF

PLAY MACRO Добавляется неявная ком­ Ничего не добавляется


бинация клавиш <Alt>+<F10>
перед макросами, начи­
нающимися с букв A—Z,
а перед макросами F1— F9
неявно добавляется <Alt>
READ При нажатии клавиши <F_sc> Проверка не выполняется
проверяется значение
оператором V A L I D

RUN Перед началом вывода кур­ Вывод происходит с текущей


сор передвигается на пер­ позиции курсора. После вы­
вую позицию 24 строки. По­ полнения экран сдвигается
сле завершения экран сдви­ на 2 строки вверх
гается на 3 строки вверх
SELECT () Возвращает наибольший Возвращает номер выбран­
номер неиспользованной ной рабочей области
рабочей области
SET COLOR TO Устанавливает цвета окон и Рекомендуется использовать
меню, определенных поль­ команду COLOR OF SCHEME
зователем
SET BORDER Устанавливает границы
окон, меню и полей
SET FIELDS Определяет список полей,
к которым возможен доступ
SET MEMOWIDTH Определяет ширину
символьных выражений
и Мемо-полей
SET MESSAGE Отображает символьное Выражение отображается
выражение в последней только при установке SET
строке экрана STATUS ON
SET PRINTER TO Выходной файл имеет Не имеет расширения
расширение prt
STORE Не может присвоить значе­ Может присвоить значения
ния сразу всем элементам сразу всем элементам мас­
массива сива
SUM Количество десятичных Количество десятичных зна­
знаков при выполнении этой ков при выполнении этой
команды определяется команды определяется фор­
КОМаНДОЙ SET DECIMALS TO матом суммируемого поля
Настройка параметров конфигурации Visual FoxPro 443

Таблица П1.8 (окончание)

Команда ON OFF

SYS(2001,"COLOR") Возвращает значение, уста­ Возвращает значение цвето­


новленное командой SET вой пары для оператора SET
COLOR COLOR TO
TRANSFORM Возвращает строку симво­
лов из символьного или чи­
слового выражения
USE Если указан путь VFP и в Если указан путь VFP
команде указано устройст­ и в команде указано устрой­
во, то поиск файла произ­ ство, то поиск файла произ­
водится только на указан­ водится сначала на указан­
ном устройстве ном устройстве, а потом —
по указанному пути

Если установлен флажок Use Visual FoxPro color palette (Использовать па­
литру Visual FoxPro), то Лис будет использовать собственную цветовую па­
литру при просмотре растровых изображений. В противном случае будет
задействована палитра, используемая при создании изображения. Данный
параметр соответствует команде SET PALETTE.
Опция Confirm file replacement (Подтверждать замену файла) определяет,
будет ли отображаться сообщение перед записью существующего файла.
Команда SET SAFETY.
Флажок Browse IME Control (Просмотр с помощью IME) устанавливается
только при использовании двухбайтовой символьной системы. IME — это
Input Method Editor (Редактор метода ввода).
А еще на вкладке General (Общие установки) имеются три опции, связан­
ные с программированием:
• Cancel programs on escape (Прекращать работу программ при нажатии
клавиши <Esc>). Соответствует команде SET ESCAPE;
• Log compilations errors (Отслеживать ошибки при компиляции) — при
компиляции файлов информация о возникших ошибках выводится на
экран. В то же время вся информация об ошибках сохраняется и в спе­
циальном файле с расширением err;
• При установке флажка SET DEVELOPMENT (Режим разработки) перед
запуском откомпилированного файла происходит проверка, не вносились
ли в него изменения. Если изменения обнаружены, файл будет переком­
пилирован.
Раскрывающийся список Navigation keys (Клавиши навигации) содержит
два элемента: Windows Compatible и MS-DOS Compatible (соответственно,
444 Приложение 1

совместимые с Windows и совместимые с DOS). Выбор значения этого спи­


ска соответствует команде SET KEYCOMP.
С помощью опции Fill new records with current values (Заполнять новые за­
писи текущими значениями) можно переносить содержимое текущей запи­
си в новую запись таблицы. Соответствует команде SET CARRY.
Если установлен флажок Enter or tab to exit fields (Нажать <Enter> или
<Tab> для выхода из поля), то пользователь может перейти на следующее
поле, лишь используя клавиши <Enter> или <ТаЬ>.

Рис. П1.13. Диалоговое окно Options, вкладка Projects

Параметры вкладки Projects (Проекты) (рис. П1.12) связаны с использова­


нием диспетчера проектов. В области Project double-click action (Действие,
выполняемое проектом при двойном щелчке) находятся следующие опции:
• Run selected file (Запустить выбранный файл) — при двойном щелчке на
имени файла в окне диспетчера проекта указанный файл запускается на
выполнение;
• Modify selected file (Модифицировать выбранный файл) — при двойном
щелчке на имени файла в окне диспетчера проекта указанный файл от­
крывается для модификации. Например, при щелчке на файле экранной
формы эта форма откроется в конструкторе.
Настройка параметров конфигурации Visual FoxPro 445

При установленном флажке Prompt for Wizards (Предлагать мастеров) Лис


"поинтересуется", будем ли мы создавать файл вручную или же воспользу­
емся соответствующим мастером.
Установка флажка Display user-defined container icons (Отображать значки,
определенные пользователем) позволяет отображать эти самые значки в ок­
не диспетчера проекта.
Далее расположена группа опций Source control options (Параметры управ­
ления ресурсами) (табл. П1.9). Если установлен пакет Microsoft Visual
SourceSafe (VSS), то его название должно быть указано в раскрывающемся
списке Active source control provider (Активный провайдер управления ре­
сурсами).

Таблица П1.9. Параметры группы Source control options

Параметр Описание

Automatically add new projects to source Понятно из названия


control (Автоматически добавлять новые
проекты в систему управления исходными
данными)
Check out files upon modify (Отметить При попытке модифицировать файл
файлы при модификации) автоматически будет вызван Microsoft
Visual SourceSafe
Add files to source control upon add Происходит автоматическое добавле­
(Добавлять файлы в систему управления ние новых файлов проекта в Microsoft
исходными данными при добавлении Visual SourceSafe
в проект)
Remove files from source control upon То же самое, что и предыдущий пара­
removal from project (Удалять файлы из метр, только наоборот. При удалении
системы управления ресурсами при уда­ файла из проекта удаляются ссылки на
лении из проекта) него в Microsoft Visual SourceSafe
Display dialog box for shortcut menu При установке этого флажка можно
commands (Открывать диалоговое окно выполнять команды Microsoft Visual
из всплывающего меню команд) SourceSafe из контекстного меню про­
екта для нескольких файлов

В поле ввода Text generation (Генерация текста) можно задать имя файла,
который осуществляет сохранение целостности информации между
Microsoft Visual SourceSafe и VFP.
В поле ввода Project class (Класс проекта) можно ввести имя класса, кото­
рый будет использован при создании новых проектов.
На вкладке Regional (Региональные) (рис. П1.14) можно задать параметры,
отвечающие за форматы дат, времени, валюты и числовых данных. Самым
"главным" здесь является флажок Use System Settings (Использовать сие-
446 Приложение 1

темные установки). А знаешь почему? Да потому что при его установке все
остальные опции станут недоступными и в работу вступят системные уста­
новки. Другое дело, когда данный флажок не установлен — табл. ШЛО.

Рис. П1.14. Диалоговое окно Options, вкладка Regional

Таблица П1.10. Параметры вкладки Regional

Параметр Описание

Date Format (Формат даты) Из данного раскрывающегося списка можно


выбрать название наиболее подходящего
формата для отображения дат
Date Separator (Разделитель даты) Изменение символа разделения даты
Century (Столетие) Влияет на отображение в дате года— либо
четырьмя символами, либо двумя
12-Hour, 24-Hour 12- либо 24-часовой формат отображения
(12 часов, 24 часа) времени
Seconds (Секунды) При установке данного флажка отображаются
секунды
Currency Format С помощью этого списка можно определить,
(Формат денежной единицы) где будет отображаться символ денежной
единицы: перед числом или за ним
Настройка параметров конфигурации Visual FoxPro 447

Таблица П1.10 (окончание)

Параметр Описание
Currency Symbol Позволяет определить символ денежной еди­
(Символ денежной единицы) ницы. Команда SET CURRENCY TO
1000 Separator Здесь задается символ, который отображает­
(Разделитель тысяч) ся после каждой третьей цифры слева от де­
сятичного знака — разделяет тысячи
Decimal Separator Символ для разделения целой и дробной час­
(Десятичный разделитель) тей числа
Decimal Digits Определяет минимальное количество деся­
(Десятичные цифры) тичных знаков.
Диапазон значений от 0 до 18.
Команда SET DECIMALS TO
Week Starts on Здесь можно указать, с какого дня начинается
(Неделя начинается с) неделя. Что? Это у нас с понедельника, а
у "них" немного по-другому...
First Week of Year Тут возможны три значения: Contains Jan 1
(Первая неделя года) (Включая 1 января), First 4-Day Week (Первая
неделя — 4-дневная) и First Full Week (Первая
неделя — полная)

На вкладке Remote Data (Удаленные данные) (рис. П1.15) определяется,


каким образом Лис работает с удаленными данными и с представлениями
удаленных данных (табл. П1.11). Что такое представление удаленных дан­
ных? Это любой файл данных, который не является базой данных или таб­
лицей FoxPro.

Таблица П1.11. Параметры вкладки Remote Data

Параметр Описание
Share connection При установке флажка данной опции можно
(Общее соединение) открыть несколько удаленных представлений
данных
Fetch memo Выборка мемо-полей при удаленном соединении
(Выбрать мемо-поля) происходит только в том случае, когда пользо­
ватель активизировал Мемо-поле. Данный фла­
жок рекомендуется устанавливать для снижения
нагрузки сети
Criteria (Критерий) Используется для управления обновлением SQL.
Возможны четыре значения: Key Fields Only
(Только ключи), Key and update Fields (Ключи и
обновляемые поля), Keys and Modified Fields
(Ключи и модифицированные поля), Key and
TimeStamp (Ключи и поля меток времени)
448 Приложение 1

Таблица П1.11 (продолжение)

Параметр Описание

Method (Метод обновления) При выборе первого варианта SQL Update (Об­
новление) обновление данных происходит с по­
мощью SQL-функции update, а при выборе вто­
рого (SQL Delete + SQL Insert— удаление и
вставка) сначала удаляются старые записи, а
затем вставляются другие с новыми значениями
Records to fetch at a time Данная опция предназначена для ограничения
(Одновременно выбрать записи) нагрузки на сеть и определяет количество запи­
сей, возвращаемых от запроса за один раз
Maximum records to fetch Позволяет определить максимальное число
(Максимальное число записей, возвращаемых запросом за один раз
считываемых записей)
Use memo for fields >= Некоторые удаленные таблицы могут поддержи­
(Использовать тип memo вать длинные символьные поля. Данная опция
для полей) позволяет автоматически преобразовывать та­
кие поля в поля типа Memo
Records to batch update Здесь определяется число записей, отправляе­
(Число записей для группового мых серверу в одной инструкции SQL
обновления)
Asynchronous execution При установке асинхронного выполнения твое
(Асинхронное выполнение) приложение может не дожидаться, пока пол­
ностью закончится обработка инструкции SQL, a
выполнять в это время другие действия
Display warnings Определяет, нужно ли выводить на экран сооб­
(Отображать предупреждения) щения об ошибках, возникающих при обработке
инструкции SQL
Batch processing Данная опция определяет, каким образом будут
(Пакетная обработка) считываться несколько результирующих набо­
ров
Automatic transactions Определяет, будет ли транзакция SQL обраба­
(Автоматическая обработка тываться средствами Visual FoxPro (автоматиче­
транзакций) ски)
Show login В некоторых случаях при доступе к удаленным
(Показывать окно регистрации) данным может потребоваться регистрация. Вот в
этом раскрывающемся списке и можно настро­
ить отображение окна регистрации: Always
(Всегда), Never (Никогда), Only When Neces­
sary (При необходимости)
Connection timeout Указывается интервал времени (в секундах), в
(Время ожидания соединения) течение которого средства соединения будут
ожидать распознавание сервером
Настройка параметров конфигурации Visual FoxPro 449

Таблица П1.11 (окончание)

Параметр Описание

Idle timeout Определяется время (в минутах), в течение ко­


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

Query timeout Указывается, сколько секунд приложение будет


(Время ожидания завершения ждать завершения отправленного запроса. Если
запроса) за указанное время ответ не пришел, будет вы­
дано сообщение об ошибке

Wait time (Время ожидания) Время в миллисекундах, через которое Лис


проверяет, завершилось или нет выполнение
инструкции SQL

Рис. П1.15. Диалоговое окно Options, вкладка Remote Data

С помощью параметров вкладки Syntax Coloring (Раскраска синтаксических


структур (рис. П1.16) можно выделять цветом различные типы текста про­
грамм.

15 3ак. 1002
450 Приложение 1

Рис. П1.16. Диалоговое окно Options, вкладка Syntax Coloring

Те типы текста, которые "поддаются" раскраске, перечислены в раскры­


вающемся списке Area (Область):
• Comments — комментарии;
• Keywords — ключевые слова;
• Literals — литералы;
• Normal — стандартно;
• Operators — операторы;
• Strings — строки;
• Variables — переменные.
Для любого типа текста можно выбрать любой стиль шрифта из раскры­
вающегося списка Font style (Стиль шрифта):
• Automatic — автоматически;
• Normal — обычный;
• Bold — полужирный;
• Italic — курсив;
• Bold italic — полужирный курсив.
Раскрывающиеся списки Foreground (Цвет шрифта) и Background (Цвет фо­
на) содержат перечень возможных цветов для любого типа текста.
Настройка параметров конфигурации Visual FoxPro 451

Рис. П1.7. Диалоговое окно Options, вкладка View

С помощью вкладки View (Вид) (рис. П1.16) можно указать, что и как будет
отображаться в строке состояния (табл. П1.12).

Таблица П1.12. Параметры вкладки View

Параметр Описание
Status bar (Строка состояния) С помощью этой опции можно указать, отобра­
жать или не отображать в нижней части экрана
строку состояния. Если строка состояния отсут­
ствует, то все системные сообщения будут ото­
бражаться в служебном окне в правом верхнем
углу экрана
Clock (Часы) При установке этого флажка в строке состояния
будет отображаться системное время
Command results При установке этого флажка в строке состояния
(Результаты команд) будут отображаться результаты выполнения
команд
System messages При установке этого флажка можно разрешить
(Системные сообщения) или запретить вывод системных сообщений
Recently used project list При установке этого флажка в меню File (Файл)
(Запомнить список последних будет отображен список последних четырех про­
проектов) ектов
452 Приложение 1

Таблица П1.12 (окончание)

Параметр Описание

Open last project on startup При запуске Visual FoxPro будет автоматически
(Открывать последний проект открыт последний проект
при запуске)

Что еще сказать про настройку нашего Лиса? Наверное, лишь то, что если
после установки всех необходимых параметров ты нажмешь кнопку ОК, все
твои установки сохранятся только на время текущего сеанса работы. А вот
если щелкнуть на кнопке Set As Default (Установить по умолчанию), уста­
новленные тобой параметры будут действовать вечно, т. е. до последующего
их изменения.
ПРИЛОЖЕНИЕ 2

Возможные значения
различных параметров
Здесь я расскажу о значениях некоторых параметров, которые ты можешь
использовать в своей работе с Visual FoxPro и которые значительно облегчат
тебе жизнь.
А начну я с клавиш ускоренного доступа к командам системного меню —
табл. П2.1.
Таблица П2.1. "Горячие" клавиши

Меню Команда меню "Горячие" клавиши


File New (Создать) <Ctrl>+<N>
(Файл)
Open (Открыть) <Ctrl>+<0>
Save (Сохранить) <Ctrl>+<S>
Print (Печать) <Ctrl>+<P>
Edit Undo (Отменить) <Ctrl>+<Z>
(Редактирование)
Redo (Повторить) <Ctrl>+<R>
Cut (Вырезать) <Ctrl>+<X>
Сору (Копировать) <Ctrl>+<C>
Paste (Вставить) <Ctrl>+<V>
Select All (Выделить все) <Ctrl>+<A>
Find (Найти) <Ctrl>+<F>
Find Again (Найти еще) <Ctrl>+<G>
Replace (Заменить) <Ctrl>+<L>
Program Do (Выполнить) <Ctrl>+<D>
(Программа) Resume (Продолжить) <Ctrl>+<M>
Do текущая программа <Ctrl>+<E>
(Выполнить текущую программу)
454 Приложение 2

Таблица П2.1 (окончание)

Меню Команда меню "Горячие" клавиши


Window (Окно) Cycle (Цикл) <Ctrl>+<F1>
Command Window (Окно команд) <Ctrl>+<F2>

Возможные значения свойства Format (Формат) для элементов управления


EditBox, TextBox, Spinner представлены в табл. П2.2.

Таблица П2.2. Значения свойства Format

Символ Описание
1 Преобразование прописных букв в строчные
А Разрешается ввод только алфавитных символов без знаков пунктуации и
пробелов
D Используется текущий формат SET DATE
Е Редактирование данных типа Date в формате BRITISH
К При переходе на элемент управления TextBox выделяется все его со­
держимое
L В полях ввода вместо пробелов будут отображаться лидирующие нули
(для числовых данных)
М Позволяет задать список значений для элемента управления TextBox
R Позволяет создавать маску ввода для элемента управления

Возможные значения свойства input Mask (Маска ввода) для элементов


управления EditBox, TextBox, Spinner представлены в табл. П2.3.

Таблица П2.3. Значения свойства input Mask

Символ Описание
9 Цифры и знаки
# Цифры, пробелы и знаки
X Любой символ
$ Отображение текущего денежного символа
(определяется командой SET CURRENCY)
* Отображения символа "звездочка" слева от значения
Десятичная точка отображается символом "точка"
1 Для отделения порядков в числе используется запятая
Возможные значения различных параметров 455

Форматы дат, устанавливаемые командой SET DATE, описаны в табл. П2.4.

Таблица П2.4. Отображение дат по команде SET DATE

SET DATE TO . . . Формат отображения


AMERICAN мм/дд/гг
ANSI гг.мм.дд
BRITISH дд/мм/гг
ITALIAN дд-мм-гг
FRENCH дд/мм/гг
GERMAN дд.мм.гг
JAPAN гг/мм/дд
TAIWAN гг/мм/дд
USA мм-дд-гг
MDY мм/дд/гг
DMY дд/мм/гг
YMD гг/мм/дд

Типы экспортируемых форматов описаны в табл. П2.5.


Таблица П2.5. Экспортируемые форматы

Тип Обозначение Назначение

Visual FoxPro 3.0 (DBF) Копирование таблиц


FoxPro for Windows 2.x (DBF) FOX2X Экспорт в формат FoxPro for
Windows 2.x
FoxBase+ (DBF) FOXPLUS Экспорт в формат FoxBase+
dBase IV (DBF) • Экспорт в формат dBase IV
Delimited Text Экспорт в текстовый файл с
разделителями
Microsoft Excel 5.0 (XLS) XL5 Экспорт в формат Microsoft
Excel 5.0
Microsoft Excel 2.0, 3.0, 4.0 XLS Экспорт в формат Microsoft
(XLS) Excel 2.0, 3.0, 4.0
Lotus 1-2-3 2.x (WK1) WK1 Экспорт в формат Lotus 1 -2-3 2.x
Lotus 1-2-3 1 -A (WKS) WKS Экспорт в формат Lotus 1 -2-3 1 -А
456 Приложение 2

Таблица П2.5 (окончание)

Тип Обозначение Назначение

Symphony 1.10 (WR1) WR1 Экспорт в формат Symphony 1.10


Symphony 1.01 (WRK) WRK Экспорт в формат Symphony 1.01
MultiPlan 4.01 (MOD) MOD Экспорт в формат Multiplan 4.01
Data Interchange Format (DIF) DIF Экспорт в текстовый файл,
используемый приложением
VisCalc
System Data Format (SDF) SDF Экспорт данных в стандартный
текстовый файл
Symbolic Link Format SYLK Экспорт в текстовый файл,
используемый таблицей Multiplan

Использование диалоговых окон


типа MessageBox
Мы с тобой уже знаем, что такое MessageBox, и неоднократно его использо­
вали. Но, оказывается, в MessageBox можно задать несколько дополнитель­
ных параметров, после чего его вид существенно преобразится. В общем,
синтаксис тут такой:
MessageBox {Текст сообщения, тип диалогового окна, заголовок)

Раньше мы с тобой успешно обходились без указания типа диалогового ок­


на, его, кстати, можно вообще не указывать, как и заголовок. Но если ты
решишь использовать данный аргумент, то необходимо знать, что это всего-
навсего число, которое определяется как сумма трех параметров: типа кно­
пок, типа значков и номера кнопки, выбранной по умолчанию. Вот значе­
ния этих параметров — табл. П2.6—П2.9.

Таблица П2.6. Тип кнопок, отображаемых в диалоговом окне

Значение Кнопка
0 ОК
1 ОК и Cancel (Отмена)
2 Abort, Retry, Ignore (Прекратить, Повторить, Пропустить)
3 Yes, No, Cancel (Да, Нет, Отмена)
4 Yes, No (Да, Нет)
5 Retry, Cancel (Повторить, Отменить)
Возможные значения различных параметров 457

Таблица П2.7. Типы значков, отображаемых в диалоговом окне

Значение Значок
16 Значок Stop
32 Вопросительный знак
48 Восклицательный знак
64 Значок (1)

Таблица П2.8. Кнопка, выбираемая по умолчанию

Значение Кнопка
0 Первая кнопка
256 Вторая кнопка
512 Третья кнопка

Таблица П2.8. Значения, возвращаемые функцией MESSAGEBOX

Значение Кнопка

1 ОК
2 Cancel (Отмена)
3 Abort (Прекратить)
4 Retry (Повторить)
5 ignore (Пропустить)
б Yes (Да)
7 No (Нет)

Рис. П2.1. Пример диалогового окна MessageBox


458 Приложение 2

А теперь самое время для практического примера:


IF MESSAGEBOX("ЗАКОНЧИТЬ РАБОТУ С ПРИЛОЖЕНИЕМ?",; 1+32+256,
"ЗАВЕРШЕНИЕ РАБОТЫ")=1
QUIT
ENDIF

Результат представлен на рис. П2.1.


ПРИЛОЖЕНИЕ 3

Полезные советы

Здесь я дам тебе несколько полезных советов, касающихся как отдельных


элементов управления, так и программирования в целом.

Экранные формы
Лис хранит формы, классы, проекты, отчеты в обычных DBF-таблицах, ко­
торые можно открыть простой командой USE И просмотреть содержимое
(рис. ПЗЛ). Например:
USE main.sex
BROWSE

Для чего это нужно? А не попадалось ли тебе такое сообщение об ошибке:


"Error loading file — record number 5 main <or one of its membersX Methods
c:\oldfox\mine.scx is not an object file".
Вот как раз в этом случае и нужно открыть форму как таблицу:
USE main.sex EXCL

найти запись с номером, указанным в сообщении об ошибке (record


number 5) и очистить в ней Memo-поле objeode.
Чтобы запретить запуск одной формы несколько раз, нужно в событии mit
формы поместить следующий код:
LOCAL I,WINDOWNAME,RETVAL
RETVAL=.Т.
1=0
WINDOWNAME=WCHILD("", 0)
DO WHILE NOT EMPTY(WINDOWNAME)
IF WINDOWNAME=UPPER(THIS.NAME)
I=I+1
460 Приложение 3

IF I>1
RETVAL=.F.
EXIT
ENDIF
END I F
WINDOWNAME=WCHILD("",1)
ENDDO
RETURN RETVAL

Рис. П3.1. Экранная форма — обычная таблица

Как создать массив свойств формы?


Выбери Form | Edit Property/Method (Форма | Редактировать свойство/ме­
тод). В появившемся окне щелкни на кнопке New Property (Новое свойст­
во). В диалоговом окне New Property введи имя массива, например
amassivfio], и нажми клавишу <Enter>. Обращение к элементам массива
можно видеть на следующем примере:
FOR 1 = 1 ТО 10
THISFORM.AMASSIV[l] = I
ENDFOR
Полезные советы 461

Для закрытия всех открытых форм приложения достаточно выполнить сле­


дующий код:
FOR EACH OFORM IN _VFP.FORMS
OFORM.RELEASE
ENDFOR

Объект Grid
Подсветку активной строки в шестой лисьей версии приходится делать
вручную.
1. В событии i n i t объекта Grid пишем:
SELECT XXXXXXXXXX
THISFORM.NRECNO = 1
IF RECNO()#0
THIS.SETALLC'DYNAMICBACKCOLOR", "IIF(RECNO() = THISFORM.NRECNO,
^RGB (255, 255,0), RGB (255, 255, 255) ) ", "COLUMN")
ENDIF
В событии AfterRowColChange
THISFORM.NRECNO = RECNOO
THIS.REFRESH

2. А у формы должно быть новое свойство nrecno = l.


Еще один вариант:
1. В событии i n i t объекта Grid запиши:
THIS.TAG = STR(RECNOO)
THIS.SETALL("DYNAMICBACKCOLOR",;
" I I F ( S T R (RECNOO ) ==THIS.TAG, RGB ( 1 9 2 , 1 9 2 , 1 9 2 ) , ; i
RGB(255,255,255))","COLUMN")

2. В с о б ы т и и AfterRowColChange о б ъ е к т а G r i d д о б а в ь :

LPARAMETERS NCOLINDEX
THIS.TAG = STR(RECNOO)
THIS.REFRESH ()

Добавление и удаление колонок


в объекте Grid без использования Grid Builder
Не используй Grid Builder (Построитель таблицы) для того, чтобы добавить
или удалить в существующем объекте Grid колонки. Чтобы добавить колон­
ку, перейди в окно свойств, выберите из списка объект Grid и в свойстве
462 Приложение 3

coiumncount добавь необходимое количество колонок. Чтобы удалить колон­


ку, выдели объект Grid в Form Designer (Конструктор форм), вызови правой
кнопкой мыши контекстное меню и выбери пункт Edit (Редактировать). За­
тем щелкни мышью на первой строке удаляемой колонки и нажми клавишу
<Delete>. Или здесь же, в режиме Edit, перетащи удаляемые колонки за
заголовки в конец направо, а затем уменьши свойство Grid coiumncount на
удаляемое количество колонок.

"Полосатый" Grid
В метод init нужно вставить:
THISF0RM.GRID1.SETALL("DYNAMICBACKCOLOR", "IIF(MOD(RECNO;
(), 2)=0, RGB(255,255,255), RGB(234,234,234))", "COLUMN")
THISFORM.GRID1.SETALL("DYNAMICFORECOLOR", "IIF(MOD(RECNO;
(), 2)=0, RGB(0,0,0), RGB(255,0,0))", "COLUMN")

Элемент управления TextBox


Изменение цвета объекта при изменении фокуса:
* событие getfocus
THIS.FORECOLOR - RGB(0,0,0)
THIS.BACKCOLOR = RGB(255,255,128)
* событие lostfocus
THIS.FORECOLOR = RGB( 0, 0, 0)
THIS.BACKCOLOR = RGB(255,255,255)

А лучше всего создать свой класс...

Элементы управления ListBox и ComboBox


Для обновления списка элемента управления ListBox после добавления,
удаления или правки пунктов, лучше пользоваться методом Requery, а не
Refresh.

Как скрыть специфичные колонки


в ComboBox или ListBox
Чтобы скрыть колонки в ListBox и ComboBox, надо установить их ширину
равной нулю в свойстве coiumnwidth. Например, в ComboBox, содержащем три
колонки, скроем первые две, а в третьей установим ширину 50:
THISFORM.COMBOBOX1.COLUMNWIDTHS - "0,0,50"
Полезные советы 463

Программное раскрытие списка ComboBox


Чтобы программно раскрыть список ComboBox, можно использовать описан­
ную далее функцию (COMBOBOXDOWNCLICK), у которой имеются следующие па­
раметры:
• icForm — имя формы, где расположен объект ComboBox;
• loCombo — ссылка на объект ComboBox.
Примерный вызов функции из метода формы:
ComboBoxDownClick(Thisform.name, Thisform.combo1)

FUNCTION COMBOBOXDOWNCLICK
LPARAMETERS LCFORM, LOCOMBO
LOCAL XCOOR, YCOOR, LCNAME
XCOOR = MCOL(LCFORM)
YCOOR = MROW(LCFORM)
MOUSE CLICK AT OBJTOCLIENT(LOCOMBO,1) + 2 , ;
OBJTOCLIENT(LOCOMBO,2)+OBJTOCLIENT(LOCOMBO,3) - 2 ;
WINDOW (LCFORM);
PIXELS
MOUSE AT YCOOR, XCOOR WINDOW (LCFORM)
RETURN

Подсказки в ListBox
Чтобы включить подсказку для каждой строки объекта ListBox (если шири­
на текста превышает ширину объекта или ширину колонки), установи сле­
дующие свойства:
LISTBOX.ITEMTIPS = .Т.
FORM.SHOWTIPS = .Т.

В объекте с несколькими колонками подсказка устанавливается только для


первой колонки.

Сохранение в списке ComboBox DropDown


новых строк, введенных пользователем
Чтобы comboBox в стиле DropDown мог сохранять введенные пользователем
новые элементы списка, запиши в метод valid этого объекта следующий
код:
IF !(THIS.DISPLAYVALUE = THIS.VALUE)
THIS.ADDITEM(THIS.DISPLAYVALUE)
464 Приложение 3

THIS.VALUE -|
THIS.LISTITEM(THIS.NEWITEMID,THIS.BOUNDCOLUMN)
ENDIF

К а к ДОбаВИТЬ HOBbie СТрОКИ В МНОГОКОЛОНЧатые ComboBox И ListBox?


Например, если у тебя есть трехколончатый ListBox или ComboBox, то добав­
ление новой строки и значений для каждой колонки строки будут выглядеть
следующим образом:
THIS.ADDITEMO
THIS.ADDLISTITEM(, THIS.NEWITEMID,2)
THIS.ADDLISTITEM(, THIS.NEWITEMID,3)

или
THIS.ADDITEMO
THIS.LISTITEM(THIS.NEWITEMID,2) =
THIS.LISTITEM(THIS.NEWITEMID, 3) =

У с т а н о в и в СВОЙСТВО I n c r e m e n t a l S e a r c h = . T . В э л е м е н т а х у п р а в л е н и я ListBox И
ComboBox, получим возможность поиска нужного пункта последовательным
уточнением в соответствии с введенными с клавиатуры символами. Период
времени, в течение которого продолжается поиск, определен в системной
переменной _DBLCLICK. По истечении этого периода начинается новый
поиск.

Запуск других приложений из Visual FoxPro


Не секрет, что из среды Visual FoxPro можно запустить любое Windows-
приложение:
RUN /N C:\WINDOWS\SYSTEM\CALC.EXE

Данный пример запустит стандартный калькулятор Windows. Кстати, о каль­


куляторе: у Лиса тоже свой имеется, запускается так:
ACTIVATE WINDOW CALCULATOR

Меню
Создать подменю? Легко!
Всем известна комбинация символов, применяемая в меню (\<) для выде­
ления горячей клавиши или (\-) для сепаратора. Но попробуй в меню вме­
сто сепаратора поставить (\|), увидишь, что получится (рис. П3.2).
И вот что получилось — рис. ПЗ.З.
Полезные советы 465

Рис. П3.2. Мы решили немного "пошалить"

Рис. ПЗ.З. Пример подменю

Расширь свое системное меню


Тебе не хватает функциональных возможностей системного меню в интег­
рированной оболочке FoxPro? Тогда построй собственное меню, в котором
сможешь, например, менять текущий каталог для того, чтобы перейти
466 Приложение 3

к своему другому проекту, вызвать калькулятор или ежедневник. При по­


строении меню выбери в системном меню View (Вид) пункт General options
(Основные опции) и поставь в положение Append (Добавить) переключатель
Location (Расположение) После генерации файла меню mymenu.mpr запиши
в конфигурационный файл config.fpw строку вызова программы при старте
FoxPro:
COMMAND = DO m y m e n u . m p r

После перезапуска системное меню FoxPro дополнится пунктами твоего


меню.

Панели инструментов
Скрытие системных панелей инструментов (Toolbar).
Стандартные панели инструментов скрываются/отображаются с помощью
HIDE WINDOW /SHOW WINDOW, где имя окна панели инструментов определяется в
блоке #DEFINE . . . :
#DEFINE TB_FORMDESIGNER_LOC "Form Designer"
#DEFINE TB_STANDARD_LOC "Standard"
#DEFINE TB_LAYOUT_LOC "Layout"
#DEFINE TB_QUERY_LOC "Query Designer"
#DEFINE TB_VIEWDESIGNER_LOC "View Designer"
#DEFINE TB_COLORPALETTE_LOC "Color Palette"
#DEFINE TB_FORMCONTROLS_LOC "Form Controls"
#DEFINE TB_DATADESIGNER_LOC "Database Designer"
#DEFINE TB_REPODESIGNER_LOC "Report Designer"
#DEFINE TB_REPOCONTROLS_LOC "Report Controls"
#DEFINE TB_PRINTPREVIEW_LOC "Print Preview"
#DEFINE WIN_COMMAND_LOC "Command"

Шифрование пароля
Простой способ шифрования имени пользователя и пароля — это использо­
вание функции
SYS(2007,"моя строка")

которая возвращает контрольную сумму строки:


lcheck = SYS(2007,ALLTRIM(mylogin)+ALLTRIM(mypassword))

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


ражение: имя любимой девушки, кличку твоего кота или другое слово... Это
уж от твоей фантазии зависит.

Вам также может понравиться