
_2.x. Программирование в VFP-работа сБД.ppt
- Количество слайдов: 21
Программирование в VFP: работа с БД Тема Х. Лекция 7 1
Поиск и фильтрация записей LOCATE FOR <Exp. L> [Scope] – поиск записи, соответствующей заданному выражению SEEK (Expr [, Idx]) – поиск в индексной таблице подходящего значения ключа FOUND. ( ) =. T. Continue – повторить поиск SET NEAR ON|OFF (настройка): On – остается на записи, после которой поиск не имеет смысла; Off – выявляет все записи, начинающиеся на заданный символ. SET FILTER TO [Exp. L] – установка /отмена фильтра EOF ([<Exp. L>]) – указываем на то место в файле, где нет записи 2
Поиск и фильтрация записей LOCATE FOR <Exp. L> [Scope] – поиск записи, соответствующей заданному выражению SEEK (Expr [, Idx]) – поиск в индексной таблице подходящего значения ключа FOUND. ( ) =. T. Continue – повторить поиск SET NEAR ON|OFF (настройка): On – остается на записи, после которой поиск не имеет смысла; Off – выявляет все записи, начинающиеся на заданный символ. SET FILTER TO [Exp. L] – установка /отмена фильтра EOF ([<Exp. L>]) – указываем на то место в файле, где нет записи 3
Вычисления на записях. Анализ и обработка данных COUNT TO <Var Name> (количество отобранных записей) SUM {список полей} to {<Var Name>} CALCULATE……. (ср. квадратичное, максимум, минимум, …) Большинство команд и функций, возвращающие переменную или массив, при их отсутствии создают их. SCAN [<Scope>] [FOR, WHILE]…[EXIT]…[LOOP]…ENDSCAN – оператор цикла для перемещения по записям таблицы. SCATTER [//FIELDS Field. Name. List | FIELDS [LIKE Skeleton ] [EXCEPT Skeleton] | FIELDS EXCEPT Skeleton//] [MEMO] [BLANK] //TO Array. Name | MEMVAR | NAME Object. Name [ADDITIVE]// - переносит данные из записи в переменные. [BLANK] - создает пустые переменные; [ADDITIVE] – обновляет существующие свойства; [MEMO] – позволяет копировать мемо-поля. Поля типа General в свойства созданного объекта не копируются 4
нить ице ния iew Буферизация таблиц: виды буферизации Рабочая область – некоторое абстрактное число, идентифицирующее открытую таблицу. Любая таблица (просмотр) может быть открыта в одной или нескольких рабочих областях. При открытии каждой таблице задается псевдоним, который по умолчанию совпадает с именем файлов таблицы (двух одинаковых псевдонимов быть не должно). Окружение данных – это набор конкретных таблиц, заданных на них порядков и временных связей, необходимых для работы конкретной компоненты Fox. Pro (форма, отчет, этикет) Сессия данных (Data session) – копия рабочих областей. Как правило, сессия данных используется для работы с буферизированными таблицами. Для каждой сессии требуется задавать ряд настроек Fox. Pro, определяющих режим работы с таблицами. Существует 5 видов режима буферизации: 1. Выключено 2. Пессимизация записи 3. Оптимизация записи 4. Пессимизация таблицы 5. Оптимизация таблицы 5
Буферизация таблиц в конструкторе форм Буферизация настраивается в формах и их наборах и окружении Data. Environment. Всего существует следующие варианты настройки, или режимы, буферизации 1. Отключенная буферизация 2. Пессимистическая буферизация записи. Запись блокируется сразу по началу ее редактирования. Обновление записи – при переходе на новую запись 3. Оптимистическая буферизация записи. Запись блокируется только при перемещении указателя на новую запись. 4. Пессимистическая буферизация таблицы - аналогична буферизации записи. 5. Оптимистическая буферизация таблицы - аналогична буферизации записи. Для просмотров View (локальных и удаленных) возможны только 3 и 5 режимы буферизации. 6
нить ице ния iew Буферизация таблиц: фиксация изменений OLDVAL() Исходное значение поля до редактирования. Для новой записи Old. Val()=. Null. Значение функции сохраняется прежним и не зависит от того, сколько раз меняется значение поля в процессе редактирования записи. CURVAL() Текущее значение поля (учитывает возможность его модификации другим пользователем). Если OLDVAL<> CURVAL, это значит, что запись в таблице-оригинале была изменена другим пользователем. GETFLDSTATE(N|f. Name [, Table]) Контроль наличия модификации поля или изменения статуса удаления для текущей ил добавленной записи GETNEXTMODIFIED(n. Re c. Num[, Table]) Возвращает значение указателя следующей (для n=0 – 1 -й) модифицированной записи (0, если такой нет) 7
нить ице ния iew Буферизация таблиц: функции транзакций BEGIN TRANSACTION До 5 вложений. Конец по END T. / ROLLBACK TXNLEVEL() Уровень вложений. 0=нет ROLLBACK Отмена текущей транзакции END TRANSACTION Завершение транзакции SQLSETPROP() Задать начало транзакции просмотра SQLROLLBACK() Отменить транзакцию просмотра SQLCOMMIT() Завершить транзакцию просмотра REFRESH() REQUERY([View]) Обновить просмотр текущим значением (кроме блокированных записей). Записи просмотра должны иметь уникальное значение первичного ключа. Записи без такового отмечаются на удаление Для ускорения выполнения свойство Prepared нужно установить в. T. LOCK(), FLOCK(), UNLOCK(), SET REPROCESS TO 8
нить ице ния iew Буферизация таблиц: функции транзакций Фиксация изменений буферизированной TABLEUPDAT таблицы или курсора. E([n. Rows=0 – только [, текущей строки, 1 l. Force=f]] всей таблицы (если [, позволяет режим c. Table. Alias буферизации), 2=1, но | не генерируется n. Work. Area] ошибка. Сведения о [, ней помещаются в c. Error. Array, если его ]) указать. LForceпринудительная перзапись данных. TABLEREVER T([l. All. Rec =f [, c. Alias|n Wrk. Ar]]) Отмена внесенных изменений в буферизированную таблицу или курсор. 1 -й параметр – отмена изменений во всех или только одной записи. 9
Буферизация таблиц: функции транзакций Фиксация изменений буферизированной TABLEUPDAT таблицы или курсора. E([n. Rows=0 – только [, текущей строки, 1 l. Force=f]] всей таблицы (если [, позволяет режим c. Table. Alias буферизации), 2=1, но | не генерируется n. Work. Area] ошибка. Сведения о [, ней помещаются в c. Error. Array, если его ]) указать. LForceпринудительная перзапись данных. TABLEREVER T([l. All. Rec =f [, c. Alias|n Wrk. Ar]]) Отмена внесенных изменений в буферизированную таблицу или курсор. 1 -й параметр – отмена изменений во всех или только одной записи. 10
Буферизация таблиц: комментарии При реверте (откате) поля таблицы или курсора принимают значения, которые они имели до начала внесения изменений. Для таблиц все просто: при реверте в них устанавливаются значения из исходных таблиц (все буферизованные таблицы – это копии соответствующих исходных таблиц). Для курсоров же при откате восстанавливается только текущая запись и только то ее состояние, в котором она находилась до передачи внесенных в запись изменений в порождающие ее таблицы и другие курсоры. Иными словами, в курсоре отмнить измененные значения полей можно только до тех пор, пока указатель записи не переместится на другую строку. При перезаписи (команда TABLEUPDATE) внесенные в буферизованную таблицу изменения переносятся в исходную таблицу. В зависимости от команды и режима буферизации обновляются данные только из текущей записи или всех записей таблицы, включая удаленые и добавленные записи. Для просмотров необходимость в подаче данной команды почти не возникает, так как обновление имеет место всякий раз после внесения изменений в поле, помеченное в конструкторе просмотров на соответствующей закладке как ключевое. Поэтому в просмотре TABLEUPDATE подается только при программном изменении значения поля, если не предполагается переодить указатель записи в другое место. Ее необходимо такжеподавать тогда, кокгда изменения вносится только в мемо-поля, так как его их нельзя сделать ключевыми в конструкторе просмотров (и иным образом) для выполнения автоматической перезаписи. Другая важная особенность выполнения перезаписи для просмотров (выполнеямой как командой TABLEUPDATE, так и автоматически при мереходе на другую запись) заключается в том, что перезапись данных производится только в порождающих просмотр таблицах и других просмотрах, открытых в текущей сессии. Поэтому, чтобы сохранить внесеные изменения в самой БД (т. е. в исходных таблицах), необходимо дополнительно подать команду TABLEUPDATE для всех входящих в просмотр таблиц, в которые требуется внести сделанные в просмотре изменения. 11
Особенности работы с просмотрами данных При перезаписи данных из просмотров (по команде TABLEUPDATE или автоматически) не исключена возможность возникновения конфликта перезаписи. Такой конфликт возникает в случае, если данные в порождающих просмотр таблицах изменены не за счет перезаписи из данного просмотра, а каким – либо иным образом (например, программно, другими средствами интерфейса, через другой просмотр, который может входить в данный просмотр, или другим пользователем). Подача в этом случае TABLEUPDATE с принудительной перезаписью приводит к отмечанию соответствующей строки просмотра на удаление, но перезаписи данных в конечном итоге не происходит. К ошибкам при перезаписи может приводить и случай, когда в просмотре создается новая строка, которой в порождающих просмотр таблицах соответствуют пустые записи, т. е. записи, в которой значения всех полей пусты. Другая причина возникновения конфликта – когда в просмотр вносятся данные, для которых отсутствует соответствующая запись в порождаюшей просмотр таблице. А для этого, в свою очередь, просмотр должен быть создан с использованием внешних соединений xx OUTER JOIN. 12
Особенности работы с просмотрами данных При перезаписи данных из просмотров (по команде TABLEUPDATE или автоматически) не исключена возможность возникновения конфликта перезаписи. Такой конфликт возникает в случае, если данные в порождающих просмотр таблицах изменены не за счет перезаписи из данного просмотра, а каким – либо иным образом (например, программно, другими средствами интерфейса, через другой просмотр, который может входить в данный просмотр, или другим пользователем). Подача в этом случае TABLEUPDATE с принудительной перезаписью приводит к отмечанию соответствующей строки просмотра на удаление, но перезаписи данных в конечном итоге не происходит. К ошибкам при перезаписи может приводить и случай, когда в просмотре создается новая строка, которой в порождающих просмотр таблицах соответствуют пустые записи, т. е. записи, в которой значения всех полей пусты. Другая причина возникновения конфликта – когда в просмотр вносятся данные, для которых отсутствует соответствующая запись в порождаюшей просмотр таблице. А для этого, в свою очередь, просмотр должен быть создан с использованием внешних соединений xx OUTER JOIN. 13
Особенности работы с просмотрами данных В формах и их наборах может быть задано 3 различных метода буферизации, задаваемых свойством Object. Buffermode. 0. Выключенная буферизация. Блокировка начинается при начале редактирования поля. Поля записываются при перемещении указателя записи. 1. Пессимистическая буферизация. То же, что и режим 0, но по Tablerevert() можно отменить изменения, внесенные в текущую запись. 2. Оптимистическая буферизация. Запись блокируется только при записи на диск по Table. Update(). В окружении буферизация задается свойством Data. Enveronment. Cursor. Buffer. Mode. Override индивидуально для каждого курсора. При этом может быть реализовано 6 различных методов буферизации. 0. Буферизация отключена. 1. Буферизация, режим которой определяется формой (ПУ). 2. Пессимистическая буферизация записи 3. Оптимистическая буферизация записи. 4. Пессимистическая буферизация таблицы. 5. Оптимистическая буферизация таблицы. Для просмотров View (локальных и удаленных) возможны только 3 и 5 режимы буферизации. 14
Особенности работы с просмотрами данных Команда восстановления REQUERY восстанавливает данные в запросах. При этом важно отметить, что для потсроения таблиц используются не данные буферизованных таблиц, на которых строится запрос, а данные непосредственно из исходных таблиц БД. Исключение – значения полей таблиц, входящих в запрос как параметры. Кроме того, если запрос построен на основе других запросов, то при восстановлении он использует данные из них. Поэтому в таких случаях команда REQUERY должна подаваться последовательно для всех просмотров, входящих в даннный, в соответствии с их иерархией. Если хранимые в запросе и его компонентах (порождающих запрос таблицах и других запросах) данные не согласованы, при восттановлении может также произойти ошибка обновления, вызванная конликтом данных. Поэтому перед подачей команды REQUERY необходимо сначала завершить все внесенные в запрос и его компоненты изменения, и лишь затем подавать саму команду. Важно помнить, что без данной команды никакие сделанные в его компонентах изменения в запросе не отразятся! К сожалению, точно и до конца все нюансы процесса выполнения команды восстановления REQUERY выяснить не удалось. В частности, вроде бы было установлено, что вычисляемые поля в просмотрах после восстановления не меняются, но это может оказаться не совсем так. 15
Работа с триггерами Default Field Validati on Rule Record Validati on Rule Unique Key Insert + + + + Переход на следующую запись при наличии в текущей записи измененных полей + + + Переход на следующую запись при отсутствии в текущей записи измененных полей + + + Событие Создание записи Изменение значения поля и переход на следующее поля той же записи + DD elet e + Переход на следующую запись после внесения изменений в поле текущей записи Update Удаление Отмена удаления записи + + + В таблице знаком плюс отмечены методы, вызываемые при совершении того или иного события. Последовательность вызова данных методов определяется последовательностью столбцов данной таблицы. 16
Пример приложения: определения Добавить примеры: задание фильтров, подсчет записей через новый метод и свойство 17
Пример приложения: определения Пример программного модуля для задания рабочего каталога приложения *Main Program "Book. Ceaper". Version V 00. 001124 (базовый номер и дата модификации) *инициализация работы программы: нахождение ее места на диске и задание нужных путей: *c. Path. R: device: . . . c. Root. Dir - к базовому каталогу (из корневого) *c. Path. B: device: . . . c. Root. Dirc. Base. Dir - к рабочему каталогу и компонентам приложения из базового каталога *c. Path. W: device: . . . c. Root. Dirc. Base. DirDATc. Path. W - к вариабельным данным *где *c. Root. Dir - "корневой" или главный каталог, где лежат общие для всех приложений VFP каталоги: библиотек, процедур, графики и т. п. * в текущем соглашении это каталоги: @ Grf (графика), @Lib (библиотеки), @Prg (программы, универсальные процедуры и функции) * в конечном продукте *. EXE - не нужен, так как все нужные компоненты из этого каталога уже д. б. включены в приложение * при работе с *. (APP&FXP&PRG) в процессе разработки нужен, т. к. в нем м. б. нужные для проекта компоненты *c. Base. Dir - "базовый" каталог приложения, где лежит: сначала только программа Setup, а затем - основной *. exe/app/prg - файл * и прочие каталоги конкретного приложения. В частности, для BC это каталоги: * DAT (данные), FRM (формы), PRG (программы), Grf (графика), Lib(библиотеки), Rp. L (Reports &Labels), Oth (Other Files: *. h, *. txt etc) - прочие файлы *c. Work. Dir - "рабочий" каталог, находящийся внутри каталога DAT базового каталога с вариабельными данными пококретному набору или группе * для BC группа или набор - это данные, относящиеся к конкретно выбранному в процессе работы приложения предприятию * в программе значение c. Work. Dir хранится в Var. Name "c. Wrk. Dir" If Type("o. Bc")="O" &&объект o. Bc уже есть и значит программа - уже запущена! Message. Box("This File Already Running! Программа уже запущена") Return End. If If Type("gn. Used")="U" &&This module not running before (IF 000) #INCLUDE Mess. Box. H &&в принципе, не нужно Clear All - не может быть применена, т. к. класс - не уничтожается!!! Close All Clear Program *Release All Clear ON KEY 18
Пример приложения: задание путей Public c. Path. R, c. Path. B, c. Path. W, c. Wrk. Dir &&путь в каталоги: "корневой", базовый, рабочий и его название c. Wrk. Dir="New 1" &&Name of Special Data Directory: название рабочего каталога с конкретными данными Local x, y, c. Sepatator 1, c. Sepatator 2 *FIND CURRENT PATH ========================================== c. Path. B=sys(16, 1) &&название исполняемой программы с полным путем к ней на уровне вложеннности программ=1. If Empty(c. Path. B) &&если нет перезапуска BC, вложений нет и c. Path. B=''. c. Path. B=sys(16, 0) &&название исполняемой программы на уровне вложеннности программ=0 (первый пуск) End. If x=Rat("", c. Path. B) &&первое вхождение в текст пути с конца разделителя каталога If x=0 &&разделителя каталогов не найдено x=Rat(": ", c. Path. B) &&найти разделитель устройства c. Sepatator 1=": " MESSAGEBOX("Приложение не должно лежать в корневом каталоге!") RETURN Else c. Sepatator 1="" End. If c. Path. B=Left(c. Path. B, x-1) &&путь к базовому каталогу, не включая конечного разделителя ": " или "" x=Rat("", c. Path. B) &&следующее вхождение в текст пути разделителя каталогов If x=0 &&разделителя каталогов не найдено c. Sepatator 2=": " x=Rat(": ", c. Path. B) &&найти разделитель устройства Else c. Sepatator 2="" End. If c. Path. R=Left(c. Path. B, x-1) &&каталог верхнего уровня без конечного разделителя ": " или "" Wait Window "Executable Base directory path= "+ c. Path. B+", Root Dir/ path="+c. Path. R+", Main program ="+sys(16, 0) *Set path to вышележащий, текущий католог, а также каталоги в вышележащем каталоге ( нач. с @) *в которых хранятся данные и модули общего назначения x=c. Path. R &&путь к "базе" без конечного разделителя y=c. Path. B &&путь к "крыше" без конечного разделителя c. Path. R=c. Path. R+c. Sepatator 2 &&путь к "базе" c конечным разделителем c. Path. B=c. Path. B+c. Sepatator 1 &&путь к "крыше" с конечным разделителем c. Path. W=c. Path. B+"DAT « *УСТАНОВКА БАЗОВЫХ ПУТЕЙ ========================================== *в дистрибутиве - должно быть много меньше, только пути к данным set path to &x, &y, ; &c. Path. B. dat, &c. Path. B. frm, &c. Path. B. Grf, &c. Path. B. Lib, &c. Path. B. Oth, &c. Path. B. prg, &c. Path. B. Rp. L ; , &c. Path. R. @Grf, &c. Path. R. @Lib, &c. Path. R. @Prg clear 19
Пример приложения: завершение старта clear *ПОДКЛЮЧЕНИЕ НУЖНЫХ БИБЛИОТЕК И ПРОЦЕДУР ========================================== Set Procedure to Proc. Uni &&универсальные процедуры общего назначения Set Class. Lib to BCLib Set Class. Lib to Base. Class Additive *#Define c. Prog. Name "BC" &&название головного модуля программы "BC" - пока не используется *СОЗДАНИЕ УПРАВЛЯЮЩЕГО ОБЪЕКТА & ИНИЦИАЛИЗАЦИЯ ПРИЛОЖЕНИЯ =========================================== *APP_MNG, APP_TLB &&Main , Base Special Procedures, Base Toolbar *#Define APP_MNG "o. BC" &&название управляющего приложением объекта - для ссылки на него из классов *#Define APP_TLB "otlb. Base" &&название управляющего приложением объекта - для ссылки на него из классов Public gn. Used, o. Access &&текущее количество окон, режим доступа к данным Do Access. prg gn. Used=0 &&количество открытых окон on key label ALT+R do bc End. If &&***IF 000 Public o. Bp, otlb o. Tlb=Create. Object("tlb. Table") o. Tlb. show() o. Tlb. Dock(0) &&Tool. Bar. Dock(n. Location [, X, Y]): -1=Undock, 0. . 3=top, left, right, bottom o. Tlb. Control. Box=. f. &&No Handle Close!!! o. Bp=Create. Object("cst. BC") &&Base Procedures: Universal&Special Base Methods&Properties of The Application=Procedures, Functions and Public Variables *Sintax: Object. Name=Create. Object("c. Class. Name"[, {e. Parameter_i_For_Init, }]) gn. Used=0 &&количество открытых окон 20
Требования к расчетному заданию 1. 2. 3. 4. 5. 6. Создать приложение, запускаемое из окна VFP, включающее меню и обеспечивающее реализацию главной функции приложения, включая возможность ввода, удаления и редактирования соответствующих основному объекту приложения записей, их отбор и просмотр отчета Создать для приложения главную форму, с помощью которой можно бы было просматривать списки, содержащие основные объекты или операции в соответствующей предметной области. Предусмотреть возможность отбирать в списках записи, удовлетворяющие некоторому набору условий, свойств или требований, количество которых должно быть не менее двух. Выбор необходимых для отбора условий (одно или несколько из имеющихся) определяется пользователем. На форме должна присутствовать информация об общем (отобранном) числе содержащихся в списке записей. Приложение должно иметь панель инструментов, хотя бы одна кнопка которой синхронизирована с пунктом основного меню и кнопкой главной формы Остальное содержание задания (необходимость включения дополнительных функций и форм) определяется исполнителем самостоятельно 21
_2.x. Программирование в VFP-работа сБД.ppt