Анимация
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

REPLACE account WITH 203 ?OLDVAL("account")

*** Будет возвращено значение 103 =TABLEUPDATE(.t.)

?OLDVAL("account")

*** Будет возвращено значение 203

Функция CURVAL() имеет следующий синтаксис: CURVAL(cExpress/on [, cTableAlias nWorkArea])

Функция CURVAL() возвращает значение поля прямо с диска для таблицы или внешнего источника данных.

Значения полей, возвращаемые функциями CURVAL() и OLDVAL(), можно сравнивать, для того чтобы выяснить, изменял ли другой пользователь в сети значения поля, пока проводилось редактирование данного поля. Естественно, что CURVAL() и OLDVAL() возвращают разные значения только при использовании оптимистической буферизации записи или таблицы.

Функция CURVAL() возвращает значение для текущего поля, и тип возвращаемого значения определяется типом выражения cExpress/on.

В качестве примера слегка увеличим количество объектов в форме JUSTMADEFORMFORBUFFERINGVALIDATE. Добавьте два объекта TextBox, не связанных ни с каким полем, и две командные кнопки. Для события AfterRowColChange объекта Grid1 напишите следующий код:

LPARAMETERS nColIndex

THisForm.Text1.Value =;

OLDVAL(ThisForm.Grid1.Columns(nColIndex).ControlSource) THisForm.Text2.Value =;

CURVAL(ThisForm.Grid1.Columns(nColIndex).ControlSource)

Для первой командной кнопки (она будет, к примеру, кнопкой сохранения) напишите всего две строчки: =TABLEUPDATE(.F.) ThisForm.Grid1.SetFocus

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

=TABLEREVERT(.F.) ThisForm.Grid1.SetFocus

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

На рис. 7.19 представлена ситуация, когда первоначальное значение поля RRR для третьей записи Greece в одном экземпляре формы было изменено на Israel, а в другом на Cyprus.



Inl vtl


Рис. 7.19.

Так как значение Israel было записано на диск раньше, то теперь в самой правой форме мы имеем разные значения, возвращаемые функциями OLDVAL() и CURVAL().

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

GETFLDSTATE(cF/eldWame nFieldNumber [, cTableAlias nWorkArea])

Следует отметить, что GETFLDSTATE() только определяет, изменялся ли статус удаления для записи. Например, если вы пометите запись для удаления, а затем выполните команду RECALL, то функция GETFLDSTATE() укажет, что статус деления изменился, даже если вы вернули его в перовоначальное положение. Поэтому мы рекомендуем использовать функцию DELETED() для определения статуса удаления.

Функция GETFLDSTATE() может употребляться и при отсутствии буферизации. Значения, которые возвращает эта функция, приведены в табл. 7.7.

Таблица 7.7. Возвращаемые значения и соответствующий статус Значение Статус

1 Поле не изменялось, и статус удаления не изменялся

2 Поле было отредактировано или статус удаления был изменен

3 Поле в добавленной записи не редактировалось, и его статус удаления не изменилось

4 Поле в добавленной записи изменялось, и его статус удаления изменялся

Функция GETNEXTMODIFIED() возвращает номер следующей измененной записи в буферизованой таблице или курсоре:

GETNEXTMODIFIED(nRecordNumber [, cTableAlias nWorkArea])

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

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



Транзакциями в Visual FoxPro называется набор операций, которые:

• изменяют данные, но могут рассматриваться как одна единица;

• могут управлять конкурирующими изменениями данных;

• могут использоваться для более легкого управления в целях перехвата ошибок.

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

Visual FoxPro предоставляет три команды, которые обеспечивают контроль за транзакциями:

• BEGIN TRANSACTION - предназначена для инициализации транзакции.

• ROLLBACK - выполняет откат всех изменений, сделанных после последней команды BEGIN TRANSACTION.

изменен статус удаления.

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

В качестве примера внесем еще несколько изменений в форму JUSTMADEFORMFORBUFFERVALIDATING. Добавьте кнопку, к примеру, с заголовком "Все-таки изменить" и сделайте ее изначально недоступной. Код для события Click кнопки "Сохранить" перепишите следующим образом:

GO GETNEXTMODIFIED(0)

k=TABLEUPDATE(.F.)

IF k = .F.

This.Parent.Command3.Enabled=.T. ENDIF

ThisForm.Grid1.SetFocus

Для кода события Click кнопки "Все-таки изменить" напишите следующий код:

=TABLEUPDATE(.F.,.T.)

This.Enabled=.F.

ThisForm.Grid1.SetFocus

Для события Click кнопки "Отменить" внесите следующие несущественные изменения:

=TABLEREVERT(.F.)

ThisForm.Command3.Enabled=.F.

ThisForm.Grid1.SetFocus

В итоге у вас получится форма, которая будет работать следующим образом. Когда вы внесете изменения в одни и те же записи и в первом и во втором образце формы, то после нажатия кнопки "Сохранить" вы попадете на первую измененную запись. Если никаких проблем не возникнет, то есть значение CURVAL() и OLDVAL() совпадет, то значение будет сброшено из буфера на диск. В случае возникновения проблем, если переменная k примет значение .F., то станет доступна кнопка "Все-таки изменить" и при этом в текстовых полях Text1 и Text2 вы увидите и значения, возвращаемые функциями OLDVAL() и CURVAL(). То есть у вас есть вся информация для принятия решения. При особом желании вы можете модифицировать вашу форму так, что будет возможность при конфликтных ситуациях восстанавливать значение, которое имело поле до начала буферизации, то есть то значение, которое возвратит функция

OLDVAL().



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