powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Программирование [игнор отключен] [закрыт для гостей] / MS SQL, VIEW в VFP и функции SETFLDSTATE( ), GETFLDSTATE( )
3 сообщений из 3, страница 1 из 1
MS SQL, VIEW в VFP и функции SETFLDSTATE( ), GETFLDSTATE( )
    #32086903
Alexey Savelyev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кто VFP совместно с MS SQL не использует, может дальше не читать. Но если все-таки кто-то заинтересуется данной проблемой, буду благодарен!

Ну ладно, ближе к телу!
Нашел кое-какие функции в VFP, только никак не могу разобраться как они работают. Вернее или я их применяю не для того, для чего они нужны или они не работают с MS SQL серваком.
Функции следующие:

SETFLDSTATE( ) - Assigns a field or deletion state value to a field or record in a table or cursor. Т.е. назначает полю записи состояние, что оно редактируется или удалено

GETFLDSTATE( ) - Returns a numeric value indicating if a field in a table or cursor has been edited or had a record appended, or if the deleted status of the current record has been changed.
Т.е. возвращает состояние поля, что было ли оно - я так понимаю – раз поле, то и текущая запись отредактирована, добавлена, удалена.

GETFLDSTATE( ) – возвращает 1 – если запись не редактировалась и не удалялась
2 – если запись изменялась или ее удалили

Подробное описание этих функций есть в хелпе VFP7.0

Используя эти две функции, очень было бы удобно управлять совместным доступом к данным в сети (на SQL серваке в частности).

Как я использую функцию GETFLDSTATE( ):
У меня создан view к таблице (таблица на SQL-сервере).
Таблица примерно следующая:
num decimal – primary key
naim char – наименование чего-то

Перед тем как редактировать запись, я вызываю
nState=GETFLDSTATE("num")
IF nState=2 &&-проверка изменена ли запись
WAIT 'Данная запись изменена другим пользователем' wind
ELSE
Do form (pathform+'Edit_form') &&- если нет, то редактирую ее
ENDIF

Но почему то GETFLDSTATE( ) не всегда правильно отрабатывает. Т.е. возвращает 1 когда текущая запись редактируется другим пользователем. Хотя как я понимаю должна возвращать 2.

Может кто-то кроме меня уже работал с данными функциями. Или прочитав этот вопрос попробует их и быстрей меня «въедет с чем их едят».
...
Рейтинг: 0 / 0
MS SQL, VIEW в VFP и функции SETFLDSTATE( ), GETFLDSTATE( )
    #32087033
Фотография Вася
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот кусок из фоксового форума может поможет:


Hi, ALL!
Есть курсор с буферизацией по умолчанию (3) и связанный с ним Grid. Все поля выбраны для обновления, Send SQL Updates включен. В Grid.BeforeRowColChange отслеживаю изменения текущей записи с помощью GETFLDSTATE().
Если изменить какое-либо поле и сместиться в другое, оставаясь в текущей строке, а затем перейти в другую строку, то GETFLDSTATE() срабатывает.
Если же после изменения сразу перейти в другую строку, то GETFLDSTATE() не срабатывает. Аналогично CURVAL() = OLDVAL() = старое значение.
В чем может быть причина? Заранее спасибо тем, кто откликнется.

RE: Cursor+Grid+GETFLDSTATE
JS , 05/23/02 09:36:01 AM

Привет!
Было такое, но до конца разбираться, что к чему, не было времени,
поэтому проверку делал в LostFocus() соответствующей колонки.
Все работало. А с этим надо разобраться.
Удачи!

RE: Cursor+Grid+GETFLDSTATE
Sergey Titow , 05/23/02 11:36:16 AM

Вроде как проблема в этом - изменения в поле сбрасываются на сразу, а при выходе из текущего объекта. BeforeRowColChange выполняется ДО смены объекта - значит изменения еще не попали в источник. При переходе сначала по строке происходит смена объекта и соответственно обновление данных. Выходы:
1. Использовать BeforeRowColChange
2. В InteractiveChange объекта записывать его value в источник

RE: Cursor+Grid+GETFLDSTATE
Sergey Titow , 05/23/02 02:53:50 PM

Извиняюсь - использовать, естественно, не BeforeRowColChange, а AfterRowColChange

RE: Cursor+Grid+GETFLDSTATE
bell , 05/23/02 05:02:21 PM

Сергей, попробовал AfterRowColChange - не помогает.
JS, у колонки нет события LostFocus. Ты имел в виду объект колонки?

RE: Cursor+Grid+GETFLDSTATE
JS , 05/24/02 12:34:56 AM

Доброй ночи!
Только, что вернулся поэтому задержка с ответом.
Разумеется объекта колонки

RE: Cursor+Grid+GETFLDSTATE
Влад Гринчишин , 05/24/02 12:41:17 PM

bell, ЛЮБАЯ перерисовка грида вызовет автоматическое обновление данных на сервере (автоматический tableupdate()). Это потому что для рисования записей грид сканирует записи или перемещает указатель записи, что, как известно, приводит к автоматическому обновлению при 3-ей буферизации.
Оно и неудивиоельно что что-то не так <g>
Рекоммендуется с гридами использовать только 5-ю буферизацию /-:

RE: Cursor+Grid+GETFLDSTATE
bell , 05/24/02 08:20:54 PM

Влад, попробовал 5-ю буферизацию. Поведение изменилось, но все равно не то, что хотелось.
При переходе на другую строку сразу после изменения GETFLDSTATE() по-прежнему не реагирует.
А если потом вернуться на строку, где были изменения, и вновь ее покинуть, то GETFLDSTATE() срабатывает.
Это, наверное, потому, что в Grid.AfterRowColChange есть Grid.Refresh.
Пробовал вставить Grid.Refresh в Grid.BeforeRowColChange до GETFLDSTATE() - не помогает.
JS, действительно GETFLDSTATE() в LostFocus срабатывает при первом переходе на другую строку.
Но она срабатывает также и при переходе в другую колонку, даже если строка не изменяется.
А нужно выдать подтверждение на сохранение изменений только при смене строки.
Не могу сообразить, как отследить смену строки без BeforeRowColChange.
Кроме того, неудобно, что это подтверждение прийдется вставлять в LostFocus объектов каждой колонки.

RE: Cursor+Grid+GETFLDSTATE
Влад Гринчишин , 05/27/02 01:28:02 PM

bell, GETFLDSTATE() работает только для текущей записи. Скорее всего запись уже новая когда Вы пробуете использовать эту функцию.
Попробуйте такую методику определения изменилась ли строка, которая заодно моможет и корректно вызвать GETFLDSTATE():
Заведите свойство формы (или грида - добавьте при помощи AddProperty() в Init), например, nRecNo. В свойстве будет хранится текущая запись в алиасе грида. В событии AfterRowColChange проверяйте изменилось ди RecNo() по сравнению с nRecNo. Если нет - это просто получение фокуса гридом или переход по колонкам грида. Если изменилось, имеет место переход на другую строку в гриде. Во втором случае запоминаем RecNo() во временной переменной, возвращаемся назад при момощи комманды GO и проверяем GETFLDSTATE(). Выдаем все что надо, если надо остаться там - остаемся и т.п., но если остаемся, надо обязательно вызвать Grid.Refresh. Если переход ok, делаем Go на запись, номер которой запомнили (запись на которую перезодим), обновляем содержимое nRecNo, и все...
Кстати, nRecNo и методика его обновления используется также для подсветки строки в гриде при помощи DynamicBackColor.

RE: Cursor+Grid+GETFLDSTATE
bell , 05/27/02 06:43:37 PM

Влад, большое спасибо за советы.
Все получилось.

RE: Cursor+Grid+GETFLDSTATE
bell , 05/28/02 08:45:28 PM

Влад, одна проблема все-таки осталась. :-((
Если исправить какое-либо поле и тут же закрыть форму с Grid, то Grid.AfterRowColChange не имеет места.
Где тогда можно проверить, были изменения или нет?

RE: Cursor+Grid+GETFLDSTATE
Влад Гринчишин , 05/29/02 11:26:12 AM

На выходе ыормы, естественно. Рекоммендую оформить код проверки как метод формы и вызывать его в соответствующих местах.
Есть только одно "но".
Если форма закрывается извне, по ON KEY LABEL или еще как-нибудь так, что не успевается вызваться событие Valid для контрола на форме (и соответственно, значение контрола еще не записанно в таблицу - в том-то и проблема), надо писать дополнительный код для насильного запиывания значения. Если надо, пришлю пример такого кода.

RE: Cursor+Grid+GETFLDSTATE
bell , 05/29/02 04:57:55 PM

Влад, пример кода не помешает, пришли, пожалуйста.
В каких "соответствующих" местах его вызывать?
Что значит закрытие формы "извне"?

RE: Cursor+Grid+GETFLDSTATE
Влад Гринчишин , 05/29/02 05:16:18 PM

>В каких "соответствующих" местах его вызывать?
Ну, AfterRowColChange грида я уже указал. Другое место - при закрытии формы когда грид активен.
>Влад, пример кода не помешает, пришли, пожалуйста.
>Что значит закрытие формы "извне"?
Извне значит по событиях извне формы: ON KEY LABEL, с меню, с toolbar и т.п., т.е. форма уничтожается тогда когда значение набранное в контроле еще не записанно в поле в ControlSource.
Сорри, пример кода временно недоступен мне, но написать его просто. Вот он, но не проверил - набрал по памяти:
&& берем активный контрол
oObj = thisform.ActiveControl
if vartype(m.oObj) == "O" AND PEMSTATUS(m.oObj,"value",5)

&& проверяем грид ли он, если да, ищем текущий активный контрол
if upper(m.oObj.BaseClass) == "GRID"
nIndex = m.oObj.ActiveColumn
for i=1 to m.oObj.ColumnCount
if m.oObj.Columns(i).COlumnOrder = nIndex
nIndex = i
exit
endif
endfor
oObj = m.oObj.Columns(nIndex)
oObj = evaluate("m.oObj." + m.oObj.CurrentControl)
endif

&& проверяем менялся ли контрол по сравнению со значением ControlSource
if !(m.oObj.value==evaluate(m.oObj.ControlSource))
m.oObj.SetFocus && этого достаточно чтобы записать изменения в ControlSource
end if
end if

RE: Cursor+Grid+GETFLDSTATE
bell , 05/29/02 06:52:20 PM

Влад, большое спасибо за пример. При закрытии формы - это Destroy или Unload?
Еще мне бы хотелось вставить такую проверку при потере фокуса гридом. Но у него нет свойства LostFocus.
Неужели прийдется вставлять проверку в LostFocus каждого контрола грида?

RE: Cursor+Grid+GETFLDSTATE
Влад Гринчишин , 05/30/02 02:14:01 PM

При закрытии формы это QueryUnload и Release. В Destroy или Unload уже все контролы формы уничтоженны. Чтобы вернуться с Release без закрытия формы, используй nodefault. А еще лучше, чтобы все бфло в одном месте в форме, в Release формы поставь следйющее:
if NOT this.QueryUnload()

nodefault
return .F.
endif
Т.о. в QueryUnload возвращай .F. если фрма не должна быть закрыта. Это будет работать как при закрытии форма программным образом (обычно это вызов thisform.Release по кнопке на форме), так и при закрытии формы нажатием "X" в правом-верхнем углу формы или дабл-клик на левом верхнем углу формы (закрывание через интерфейс Windows).

RE: Cursor+Grid+GETFLDSTATE
bell , 05/30/02 04:30:40 PM

Влад, с закрытием формы все понятно.
У меня еще был вопрос с проверкой по GETFLDSTATE() в момент потери фокуса гридом. Где ее делать?
В LostFocus каждого контрола грида или в GetFocus других контролов формы (кроме грида есть еще кнопки типа "Добавить", "Удалить" и др.)?
А нельзя ли это сделать где-то в одном месте? Пробовал Valid грида, но там видно курсор еще не обновился.

RE: Cursor+Grid+GETFLDSTATE
Влад Гринчишин , 05/30/02 04:49:41 PM

Упс, сорри, пропустил этот вопрос.
Грид можно положить внутрь контэйнера и ловить LostFocus контэйнера.

RE: Cursor+Grid+GETFLDSTATE
bell , 05/30/02 08:06:55 PM

Спасибо всем, принявшим участие в обсуждении, особенно Владу Гринчишину.
...
Рейтинг: 0 / 0
MS SQL, VIEW в VFP и функции SETFLDSTATE( ), GETFLDSTATE( )
    #32089046
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прежде всего следует уяснить, что такое вообще технология клиент-сервер.

В самых общих чертах суть сводится к следующему:

Клиент посылает инструкцию на сервер. Сервер выполняет эту инструкцию и возвращает результат клиенту.

Итого, когда ты сделал запрос SQLExec() или Remote View то в результате ты получил некоторую выборку (не саму таблицу), физически расположенную у клиента .

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

Любое View в FoxPro открывается в режиме оптимистической буферизации строк (3) и может быть перключено только в режим оптимистической буферизации таблиц (5) и никак иначе. Результат выполнения SQLExec() в этом смысле обладает всеми свойствами Remote View.

Итого, после выполнения SQLExec() или Remote View у клиента появляется:

1. Временная таблица, содержащая результат выборки
2. Буфер этой временной таблицы

Все команды FoxPro типа GetFldState(), SetFldState(), OldVal(), CurVal(), GetNextModify() и т.п. работают только с файловыми таблицами. Т.е. применительно к Remote View сравнение идет между выборкой у клиента и буфером этой выборки у того же клиента.

Эти команды просто ничего не могут сказать о том, что произошло на самом сервере. Для этого требуется сделать еще один запрос на сервер.

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

Как это сделать?

Обрати внимание на группу "SQL WHERE clause includes" на закладке "Update Criteria" в Remote View, а также внимательно прочитай описание использования второго параметра в команде TableUpdate().
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Программирование [игнор отключен] [закрыт для гостей] / MS SQL, VIEW в VFP и функции SETFLDSTATE( ), GETFLDSTATE( )
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]