Введение

Разработка приложений в Microsoft FoxPro 2.5 (2.0)

Лес Пинтер
Это руководство сначала было написано для FoxPro 2.0. В январе 1993 года Microsoft выпустила версию 2.5. При всем моем уважении к версии для DOS следует сказать, что новая версия не имела особых новшеств. Действительно большим шагом был выпуск FoxPro for Windows.  

Книга является продолжением  издания "FoxPro Programming 2nd Edition". Я предлагаю вам книгу о том, как разрабатывать приложения в среде FoxPro 2.0. 

При обсуждении проблемы разработки приложений для версии 2.0 высказываются самые различные мнения, и я начну прямо с этой темы. Если вы проанализируете примеры, поставляемые вместе с пакетом, то обнаружите, что они все написаны с использованием того, что Fox называет Foundation Reads. Версия 2.0 поддерживает предложение VALID команды READ, что позволяет выполнить команду READ без наличия активных GET. Предложение VALID команды READ служит для получения ответа на вопрос: "Мы завершаем работу с READ?" До тех пор пока структура VALID не вернет значение ИСТИННО, READ просто сидит и ждет. Однако, так как структура может быть активизирована событием, предполагающим завершение READ, - нажатие клавиши ESC, выбор элемента управления, имеющего атрибут "завершить выполнение READ" (например, переменная GET с атрибутом типа *RT), закрытие окна - вам необходимо проверить, действительно ли событие, активизировавшее структуру VALID, имело целью завершить READ или нет. В последнем случае ожидание продолжается.

 Глава 1 Стратегия проектирования приложений

Система FoxPro 2.0 предлагает совершенно новый стиль программирования. Он также обеспечивает поддержку методов разработки экранов и меню, использованных в тысячах продуктов поддержки баз данных. 


Конструктор экранов (Screen Builder) побуждает программистов разрабатывать экраны определенного вида и функциональности. Хотя мне и нравится этот стандарт, я не хочу, чтобы у вас создалось впечатление, будто это единственный тип экрана, который возможно создать в FoxPro. Поэтому я начну с концепций, а средства разработчика оставлю на потом. Если вы будете рассматривать конструктор экранов скорее как инструмент, нежели как набор альтернатив, то будете чувствовать себя более комфортно и сможете сделать то, что вам нужно.

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

Простые модели

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

Плоский файл с простым меню

Код ввода данных в простую базу данных, состоящую из одного плоского файла и простое меню представлены в листинге 1-1. Такой подход типичен для небольших плоских файлов. Я включил несколько трюков, позволяющих выделить цветом объекты на экране, пользователям это нравится.

Глава 2 Стратегия разработки приложений

Файлы, связанные отношением один-ко-многим Большинство начинающих и среднего уровня FoxPro-программистов способны создавать экраны для работы с плоскими файлами.

Однако, реальные приложения не ограничиваются работой с плоскими файлами. Если вы посмотрите на экран программы ввода данных по счетам, вы увидите в верхней части экрана информацию о, скажем, заказчике, и итоговые цифры внизу. В середине вы найдете строки с данными по позициям, включенным в счет. Эти данные мы получаем из другого файла, который иногда называют файлом детальной информации или дочерним файлом. Различные способы организации связи между двумя группами записей - составляющих заголовок наверху экрана и данными в средней части - одна из наиболее интересных тем программирования на FoxPro.

Экраны на базе BROWSE для работы с файлами,
связанными отношением один-ко-многим

Fox Software рекомендует использовать BROWSE для организации вывода записей из связанных файлов. Команда BROWSE NOWAIT оставляет окно BROWSE активным, так что при перемещении указателя записи в родительском файле, указатель в дочернем файле также перемещается. В Листинге 2-1 показан пример программы.

Глава 3:BROWSE (часть1)

Можно сказать, что BROWSE - наиболее мощная и гибкая команда FoxPro. Значительные куски вашего приложения вы можете построить, не используя ничего кроме функций, вызываемых из предложений команды.

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

Перемещение в окне BROWSE

Стрелки управления курсором перемещают курсор в окне на одну запись, клавиши PgUp, PgDn - перемещают курсор на группу записей. Перемещение между полями выполняется клавишей табуляции Tab или Shift-Tab.


Выход из режима BROWSE

Для выхода с сохранением изменений нажмите Ctrl-W, Ctrl-End или приведите курсор мыши на элемент управления в верхнем левом углу окна и нажмите левую кнопку. Если вы нажмете Ctrl-Q или Escape, вы потеряете изменения, внесенные в текущее поле. Программно выйти из режима с сохранением данных можно использовав команду:

ON KEY LABEL F10 KEYBOARD[{Ctrl+W}]

в установочной части программы и добавив сообщение "F10 для выхода" в текст на верхней или нижней части рамки окна.

Глава 3:BROWSE (часть2)

Простой пример Самая простая демонстрация требует только одной команды BROWSE. Получающееся окно занимает примерно две трети экрана. Если вы хотите, чтобы окно заняло весь экран выполните следующие команды:

DEFINE WINDOW big FROM 0,0 TO 24,79 NONE
BROWSE WINDOW big

Как сделать BROWSE умнее

Первое, что мне хотелось получить от BROWSE, - это возможность автоматического перехода на новую строку после окончания текущей. Такое свойство полезно, когда вы вводите данные и не хотите нажимать клавишу "стрелка вниз" для перехода на новую строку. Для этого потребовалось немного больше усилий чем можно было ожидать (Листинг 3-2 (Реализация автоматического перехода на следующую запись в BROWSE))

Сложный пример

Программа, приведенная в Листинге 3-3 (Экран ввода данных на базе BROWSE), представляет большую часть приложения, разработанного для магазина, торгующего одеждой, с использованием BROWSE как основы для ввода данных. Я не привожу блок программы, отвечающий за ввод платежа (позволяющий вводить различные виды платежей), так как он слишком велик и не относится к теме нашего обсуждения.

Структура программы

В примере мы используем файл заказчиков, файл заголовков счетов и файл с данными по счетам, кроме того у нас есть несколько файлов с данными, используемыми при анализе ввода. Так как единственной задачей программы является добавление записей в файлы заголовков и данных по счетам, я создаю копию этих двух файлов и заполняю их пустыми записями перед началом каждой операции. Это позволяет избежать довольно сложной проблемы добавления записей в режиме BROWSE при активном предложении KEY. Все описания файлов даны в конце программы.

Глава 4:Сетевое программирование (часть1)

 Когда я впервые прочел о разработке сетевых приложений, я был так напуган, что решил, будто это мне не по зубам. В итоге, когда один из заказчиков предложил написать программу для работы в сети, я не рискнул принять предложение. Увидев же парня, которого наняли для выполнения этой работы, я понял, что на самом деле мне бы это также удалось. Следовало бы послать ему благодарность за избавление от комплекса.

Однажды мне довелось прочесть, что за создание сетевого приложения разработчик должен требовать двойную или тройную плату. Должен сказать, на самом деле включение сетевых возможностей добавляет около 2% к стоимости проекта, кроме особо сложных случаев. Причина в том, что большая часть из того, что, как вам кажется, должно быть сделано, вовсе не нужна.

Команды и функции для сетевого программирования

Команды, которые используются при разработке сетевых приложений, приведены в таблице 4-1.

Наибольшее влияние на поведение FoxPro при попытке заблокировать файл или запись оказывает команда SET REPROCESS:

SET REPROCESS TO 0 возвращает системное сообщение [Попытка установить блокировку - нажмите ESCAPE для отмены], если первая попытка блокировки не удалась. Если система имеет процедуру обработки ошибок, то она имеет приоритет в обработке возвращаемого кода ошибки.

SET REPROCESS TO -1 бесконечный цикл попыток блокировки без выдачи сообщения, генерации ошибки или возможности отмены клавишей Esc.

SET REPROCESS TO -2 (или SET REPROCESS TO AUTOMATIC) повторяет попытки до успешной блокировки или отмены клавишей Esc.

SET REPROCESS TO expN (или SET REPROCESS TO <expN> SECONDS) команда в таком виде ограничивает число попыток блокировки значением expN или временным интервалом expN секунд.

Глава 4:Сетевое программирование (часть2)

Установка окружения Я могу дать вам одну рекомендацию, пригодную независимо от того, какую технологию вы выберете. В большинстве сетей, с которыми мне приходилось иметь дело, рабочие станции имеют собственный жесткий диск или несколько мегабайт дополнительной памяти. Вы повысите производительность, если направите все временные файлы FoxPro на локальный диск или на виртуальный диск вместо того, чтобы качать их по сети. Вставьте следующие команды в файл Config.Fp:


TMPFILES=C:\WORK
OVERLAY=C:\WORK
где C:\WORK - каталог на диске рабочей станции


Если у вас достаточно памяти для организации виртуального диска, способного вместить как рабочие файлы, так и FOXPROL.OVL, тем лучше. Именно так я поступаю при работе на своем компьютере. Прирост скорости весьма заметен. FOXPROL.OVL имеет размер примерно 1,5 Мб, и к нему обращаются каждый раз, когда необходимо выполнить одну из многочисленных команд, отсутствующих в корневом сегменте FOXPROL.EXE.

Чем больше у вас имеется памяти, тем лучше. Стандартная память исключительно важна для FoxPro, также как и большой объем расширенной (expanded) памяти - 4 МБ хорошо, но 6 или 8 МБ еще лучше. Похоже, что парни, работающие в Quarterdeck, получили знамение свыше о том, как нужно писать программы управления памятью. Вы немедленно ощутите разницу.

В многопользовательской среде вам, может быть, придется загружать команду DOS Share. Novell Netware 386, похоже, больше не требует этого при работе с FoxPro, но LANtastic и Invisible она нужна до сих пор, также как это может потребоваться для других сред. Если происходит блокировка сети, используйте Share, если нет, не нужно. Кстати, LANtastic задохнется, если вы не установите Share c указанием примерно 1000 файлов и 5000 блокировок. Не спрашивайте почему. Для четырех пользователей попробуйте F=5000 и L=12000.

Глава 5:Концепции построения интерфейса

 Я постепенно прихожу к заключению, что написание собственно кода - самая легкая часть в разработке программного обеспечения. Эта часть работы обычно отнимает большую часть времени, но не является самой трудной. Труднее всего решить, что писать.

Однажды я имел разговор с потенциальным клиентом, который спросил меня, сколько времени потребуется, чтобы написать программу обработки счетов. Я ответил, что это обойдется примерно между 100 и 1 000 000 долл., в зависимости от того, что ему нужно. На это мне было сказано, раз я не знаю, что из себя представляет подобная система, вряд ли у меня достаточно опыта для такой работы.

Проблема в том, что они видели одну систему в общем, тогда как мне приходилось иметь дело с тридцатью и в мельчайших деталях. На свете существует по меньшей мере тысячи такого рода систем и ни одна из них не похожа на другую. Различия в функциональности, внешний вид и принципы взаимодействия с пользователем, структуры файлов и т. д. бесконечны. Каждый разработчик считает, что именно его дизайн - единственно правильный.

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

Глава 6:Пример разработки: агентство по найму

 Одна из многих интересных программ, пришедших мне на ум, когда я увидел пример Laser, поставляемый с FoxPro, была разработка для агентства по найму. Способность быстро перемещаться по базе данных очень заманчива. Использование memo-полей FoxPro для хранения текста резюме кажется совершенно естественным. Применение маленького трюка, заключающегося в создании индекса на индекс, позволяет выполнять сверхбыстрый поиск по ключевым словам.

Файлы и индексы

Большинство полагают, что для поиска всех подходящих резюме нужно провести поиск во всех memo-полях на предмет вхождения в текст нужной подстроки. Это может и неплохо, но после ввода в базу данных 5000 резюме такой метод работает довольно медленно. Попробуем что-нибудь побыстрее.

Я построил файл с данными о соискателях, со структурой, представленной в Табл.6-1.KEYWORDS- - текстовое поле, куда вы вводите слова, действительно важные для быстрого поиска. Это похоже на квадратики, которые нужно зачеркивать на бумажных формах, заполняемых во многих агентствах по найму. В Табл. 6-2 приведены структуры индексных файлов.

Технология поиска

Почему бы просто не определить несколько полей, представляемых на экране как независимые переключатели? Тому есть две причины. Во- первых, число таких переключателей, необходимых для представления даже самого общего списка требующихся специальностей в области, скажем, обработки данных, перевалит за сотню. Только перечисление наиболее часто встречающегося оборудования и программ займет несколько страниц. Кроме того выход того или иного пакета из обращения заставит вас каждый год звать программиста для перестройки экрана и базы данных. Это неплохо с точки зрения постоянной работы, но неразумно дорого. Давайте попробуем составить конкуренцию японцам и создадим что-нибудь быстрое и дешевое, а?

Глава 7:Утилиты программиста

 Выражение "сапожник без сапог" относится к профессионалу, не использующему собственные инструменты для облегчения своей работы. Программисты тоже люди. Им нужно извлечь пользу из используемой технологии и создать собственный инструментарий. Эта глава включает три инструмента, способные облегчить вам жизнь: построитель словаря данных, программу, изменяющую структуру файла данных по данным словаря без использования оболочки FoxPro, и программу исправления поврежденного файла, написанную с помощью замечательного специалиста в области восстановления данных Ли Хилларда из Себастополя, Калифорния.

Построение словаря данных

Вы разрабатываете продукт, способный осчастливить мир: еще один бухгалтерский пакет. Внезапно вы понимаете, что пропустили поле, которое должен иметь файл клиентов. Вы меняете структуру файла, делаете копию пустого файла и рассылаете заказчикам вместе с инструкцией на целую страницу. 97% из них позвонят вам в течение ближайших трех дней и вы потратите все свое время на объяснения. Десяток действительно скопирует файл в рабочий каталог и удалит основной файл не сделав страховочной копии. Что будете делать?

Не стреляйте в них, это противозаконно. Используйте программу DATADICT (Листинги 7-1...7-4) для построения словаря данных и поставляйте его вместе с вашей разработкой. Если вам понадобится изменить структуру файла, пошлите им новый словарь данных и скажите, чтобы они запустили программу DATAFIX, включенную в эту главу, для обновления файлов данных из своего приложения. Включите вызов программы в меню "Утилиты". Можете включить в обработчик ошибок режим, выводящий сообщение о необходимости запуска этой программы при получении сообщения об ошибке: "variable not found".

Глава 8:Сводим все воедино - программа ведения деловых контактов 

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

Файлы и индексы

В этой маленькой системе всего два файла. Файл, где хранится список дел, является дочерним файлом файла PEOPLE и связан с ним по полю COMPANY (табл. 8-1).

Для вывода списка запланированных дел используется индекс по полю DATE.

Элементы управления

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

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

Глава 9:Система электронных заказов

 Некоторое время назад я занимался программированием на КОБОЛе для большой машины (mainframe), переболел этим и почти забыл вид этих здоровых железок, как вдруг неожиданный контракт на крупную сумму заставил меня вспомнить прошлые дела.

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

В главе я привожу пример приложения, в котором использованы обобщенные методики. Можно разработать универсальный инструментарий для решения некоторых из такого рода задач, так как на каждом этапе разработки используются списки полей, длины полей, протоколы преобразований и стандартные форматы. Однако, мне кажется, что при чрезмерном обобщении есть опасность потерять основную идею. Если вам потребуется писать по приложению в неделю, тогда есть смысл придумать нечто универсальное.

Я выбрал в качестве примера электронную систему заказов, так как она вполне может оказаться той первой задачей, с которой вам придется иметь дело. Обычный сценарий работы подразумевает посылку на большой компьютер файла с данными из .DBF-файла и ожидание ответа. Большие машины обычно выполняют запись и чтение в формате стандартного КОБОЛа, и обмен данными является ключевым участком всего приложения.

Глава 10:FoxPro и электронные таблицы

 Я начинал карьеру консультанта как специалист по Lotus 1-2-3. Мой шаблон для Lotus (справочник по недвижимости) был первой такого рода разработкой, продававшейся как отдельный продукт. Долгое время я считал, что вы можете сделать все в 1-2-3.

Действительно это так, но во многих случаях это будет не лучшим выбором. Текстовые процессоры обрабатывают текст быстрее программ, не предназначенных для такого типа работы. Именно разочарование в "2" (Lotus получил свое название от совмещения в одном продукте трех возможностей 1 - электронные таблицы, 2 - базы данных, 3 - графика) привело меня к новой тогда программе dBASE II.

Я до сих пор уважаю электронные таблицы. Когда вам нужно обработать несколько столбцов данных табличной формы - они как раз то, что нужно. Однако, если ваши цифры размещены в базе данных, имеет смысл использовать другие средства.

Предлагаемая в этой главе программа реализует электронную таблицу с 20 строками и 6 столбцами данных, суммы по строкам и столбцам пересчитываются, когда вы нажимаете клавишу, вызывающую функцию Recalc. (FoxPro работает быстро в определенных случаях, но немедленный пересчет массива в 120 элементов не входит в этот список).

Таблицы. В самом простом случае в каждой клетке содержится число определенного формата. Единственной процедурой анализа данных является модуль пересчета сумм; большинство электронных таблиц позволяют отключать глобальный пересчет для ускорения работы программы. Такой набор требований прекрасно подходит для программы на базе цикла обработки событий.