Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 [ 81 ] 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

! Properties - form buffer.sc3t

Object:

Forml

Data Methods LaiJOut

Other

Boy.

[Default]

BufferMode

i - Pessimistic

Caption

Forml

Circle

jDef

Class

ClassLibrary

Click Event

iDefauit]

ClipControls

.fr-fruelDefauitj

Closable

Tfr-TruePefauit)

реШ

Comment

ControlBox

J--W{DbfOit-j

ControlCount

Controls

CurreniX

CurrentY

izzzizzizizriiiiiizi

DataSession

2 - Private Data Session

Occurs when a FormSet, Form, or Page object becomes active or when a ToolBar object is shown.

Рис. 7.17.

После сохранения формы запустите ее из командной строки вначале с помощью следующей команды:

DO FORM justmadeformforbufferingvalidate NAME f1

А затем запустите эту же форму, но уже с другим именем DO FORM justmadeformforbufferingvalidate NAME f2

Если вы хотите установить пессимистическую блокировку нескольких записей, то используйте функцию CURSORSETPROP() следующим образом:

= CURSORSETPROP("Buffering",4)

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

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

Первым делом создайте форму, поместите в нее объект Grid. Теперь для формы установите значение свойства BufferMode равным 1 (pessimistic), а значение свойства DataSession равным 2 (private data session), как это показано на рис. 7.17.



\f, Work Area Properties

Data Buffering Options-

Enable Data Buffering

"Lock Records When Edited

С When Written

ГВ uf f er-

С Current Record

< All Edited Records

Cancel

ModifiJ..

Data Filter

Index Order I <no order>

rAllow Access to-

(* AJI Fields in the work area

С Onlv fields specified by Field Filter

Field Filter..

c: \proiect book\larisa. dbf

Рис. 7.18.

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

Для установки оптимистической блокировки нескольких записей используйте следующее выражение:

= CURSORSETPROP("Buffering",5)

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

1. Пытается блокировать каждую отредактированную запись.

2. После успешной блокировки сравнивает текущее значение на диске со значением до начала буферизации.

3. Записывает данные на диск, если сравнение прошло успешно.

4. Генерирует ошибку, если данные различаются.

Для доступа к данным в буфере можно использовать функцию RECNO(). Номер записи из таблицы используется для обращения к ее аналогу в буфере. Если записи добавляются, то при установленной буферизации они вначале попадают в буфер, и номер вновь добавленной записи отрицательный. Отрицательные числа последовательно нарастают по абсолютному значению по мере добавления записей. В табл. 7.6 представлена ситуация, которая может сложиться при добавлении двух записей.

Таблица 7.6. Порядок нумерации записей в буфере Номер записи Операция

4 Редактируется

9 Редактируется

В диалоговом окне View Window с помощью списка CurrentSession можете проверить, что у вас на данный момент загружено несколько сессий данных, а точнее, одна плюс количество экземпляров нашей формы. Если вы таким же способом загрузите еще одну форму, то количество сессий данных, как вы уже догадались, увеличится на единицу. В окне View Window, переключившись в одну из сессий данных, связанных с одним из экземпляров нашей формы, перейдите в рабочую область, в которой открыта таблица, данные из которой отображаются с помощью объекта Grid. Нажав на кнопку Properties, вы можете увидеть, что буферизация для данной таблицы действительно пессимистическая и множественная (рис. 7.18).



12 Редактируется

45 Редактируется

-1 Добавляется

-2 Добавляется

Для того чтобы удалить запись, которая была добавлена, но не записана на диск, вам следует использовать функцию TABLEREVERT(), при этом помните, что ее использование с аргументом .T. очистит буфер полностью, а с аргументом .F. - только от текущей записи. Если вы не выполните функцию TABLEREVERT() раньше, чем функцию TABLEUPDATE(), то все записи, даже помеченные на удаление, запишутся на диск и при этом будут помечены на удаление.

Мы уже не раз упоминали и использовали в примерах функции TABLEUPDATE() и TABLEREVERT(). Эти функции можно использовать при установлении буферизации. В противном случае появится системное сообщение о том, что без буферизации их использовать нельзя. Посмотрим более подробно на синтаксис этих функций:

TABLEUPDATE([ \ Rows] [,lForce]] [, cTableAlias nWorkArea])

Первый аргумент lAllRows принимает значения .T. или .F.. Если значение аргумента равно .T. и установлена табличная буферизация, то на диск запишутся изменения во всех отредактированных записях, в противном случае запишутся только изменения из текущей записи.

Второй аргумент lForce, также принимающий логическое значение, определяет, как относиться к изменениям других пользователей. Если вы вызываете функцию TABLEUPDATE() с аргументом lForce, равным .F., Visual FoxPro сгенерирует ошибку, как только найдет запись, в которой были сделаны изменения другим пользователем. Вам остается только решить, каким образом поступить с этой записью. В случае, если вы используете функцию TABLEUPDATE() со вторым аргументом, равным .T., то все изменения, сделанные другим пользователем или пользователями, будут переписаны.

Если вы работаете с таблицей в текущей рабочей области, то третий аргумент cTableAlias или nWorkArea можете не указывать. В противном случае надо указать либо псевдоним, либо номер рабочей области таблицы, которую вы редактируете.

Функция TABLEREVERT() выполняет обратное по отношению к TABLEUPDATE() действие -она очищает буфер без записи изменений на диск.

TABLEREVERT([lAllRows] [, cTableAlias nWorkArea])

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

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

Это функции OLDVAL(), CURVAL(), GETNEXTMODIFIED(), GETFLDSTATE(). Функция OLDVAL() имеет следующий синтаксис:

OLDVAL(cExpression [, cTableAlias nWorkArea])

Функция OLDVAL() возвращает первоначальное значение поля таблицы для текущей записи при установленной буферизации. При этом надо упомянуть, что если таблица в базе данных или курсор имеют правила проверки ввода, то устанавливать буферизацию не обязательно.

Если указатель записи переместится на другую запись, когда установлена буферизация записи, или будет выполнена функция TABLEUPDATE() для записи изменений на диск, или будут произведены какие-либо другие действия, которые ведут к модификации данных, первоначальное значение больше доступно не будет.

Тип значения, которое вернет функция OLDVAL(), соответствует типу значения аргумента cExpression. Например:

OPEN DATABASE auto store

USE account

=CURSORSETPROP("Buffering",5) GO 3



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 [ 81 ] 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146