|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
Всем здравствуйте прошу подсказки, как правильно обновить данные на форме, сходу не нашел ответов. Работа построена следующим образом - прога многопользовательская, в ней, в том числе, форма - что-то вроде счета или ттн, т.е. имеет заголовок и детали, и связана прямо с таблицей (заголовок документа) и view (детали, строки документа). Через терминал несколько пользователей (2...4) юзают эту форму, чаще всего она открыта постоянно - смотрят в нее и на основании увиденного что-то сообщают заказчикам, редактируют, печатают и т.д. Если с деталями, т.е. view, никаких проблем не возникает, т.е. при переходе на документ строки на форме обновляются, то с заголовками документа возникают некоторые проблемы - если один внес изменения или создал документ, то у второго они видны только после перезагрузки этой формы. Подскажите, как правильно организовать обновление - таймер какой-то пробовать ставить, или подставить view вместо таблицы, или все вместе - в общем, куда правильно думать ? p.s. Прошу при ответе учитывать низкий уровень подготовки по теме ) ... |
|||
:
Нравится:
Не нравится:
|
|||
04.03.2017, 12:11 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
Если данные на форме могут редактировать, то автоматическое обновление (например, по таймеру) - категорически запрещено! Поставьте себя на место пользователя, Вы вводите/изменяете значение какого-то поля и оно "вдруг" изменяется. Прямо в процессе ввода! Вот как далеко и надолго Вы пошлете того программиста, который ТАК сделал интерфейс? Это значит, во-первых, что использование напрямую записей таблиц в формах - крайне неудачное решение. Дело в том, что данные в таблицах обновляются автоматически! Интервал обновления задается при помощи настройки SET REFRESH В данном случае, интересует второй параметр, который определяет периодичность считывания данных из сети. Т.е. изменения, сделанные другими пользователями. По умолчанию, это 5 секунд. Если Вы не меняли эту настройку, то у Вас каждые 5 секунд и так происходит обновление данных в таблице. Просто Вы их не видите, поскольку не обновили "картинку" на форме. Обновить "картинку" можно примерно так Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
Но! Повторюсь, сама идея прямого чтения/изменения данных в таблице - крайне неудачное решение. Будет много проблем с пользователями. Как минимум, нужно сделать буферизацию текущей записи. Хотя бы строковую, чтобы можно было физически "развести" процесс ввода изменений и процесс сохранения этих изменений. Возвращаясь к обновлению. Поскольку автоматически данные на форме обновляться не должны, то это значит, что обновление данных, должно быть только по прямому требованию пользователя. Это может быть либо кнопка "Обновить" на форме, либо пункт меню и (или) горячая клавиша. Хотя делать горячую клавишу без создания пункта меню тоже не есть хорошо. Как о ней пользователь узнает-то? А если забудет? При использовании пункта меню или горячих клавиш, потребуется некоторая реорганизация базового класса формы. Т.е. каждая форма должна будет иметь некий метод, к которому и будет обращаться пункт меню или горячая клавиша. Для унификации, чтобы имя этого метода у всех форм было одно и то же, и надо создавать этот метод в базовом классе форм проекта. Ну, а далее, в пункте меню происходит вызов метода активной формы. Примерно так _SCREEN.ActiveForm.MyMethodRefresh() Где MyMethodRefresh - это и есть имя вашего метода обновления формы. Хотя, это конечно, только "схема". Тут надо бы добавить проверку на факт существования активной формы и метода с указанным именем. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 11:07 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
ВладимирМ, Огромное спасибо за пояснение. Команда SET REFRESH не применяется. Настройки Fox-а вкладка DATA следующие: Browse refresh interval (sec) : 0 Table refresh interval (sec) : 5.000 Если не ошибаюсь, это аналогично SET REFRESH TO 0, 5 т.е. не обновляются просматриваемые записи. Буфферизация таблицы, конечно, применяется. Заголовок документа на форме выводится в контролы, и кроме того, часть таблицы выведена в грид, обновление предусмотрено в AfterRowCalChange: LPARAMETERS nColIndex thisform.requery thisform.Refresh метод requery формы обеспечивает обновление второго грида с источником view - те самые детали документа, то же самое, как для ТТН или счета строки с товаром. Т.е., при переходе от одного документа к другому, на гриде или тулбаре навигации, меняется документ. Так вот строки с деталями обновляются без вопросов. Если форма открыта, второй пользователь внес изменения, затем первый совершил переход по заголовкам туда обратно, то изменения в строках (деталях) - все без вопросов, изменения в заголовке, в частности в контроле ComboBox и некоторых других – увы, нет. Но если перегрузить форму - все, конечно, корректно и на месте. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 13:14 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
ВладимирМ... Это значит, во-первых, что использование напрямую записей таблиц в формах - крайне неудачное решение.... Ну как напрямую, я имел ввиду, что без прокладки view, т.е. обычное редактирование таблицы через контролы на форме. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 13:35 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
DmitryKnНу как напрямую, я имел ввиду, что без прокладки view, т.е. обычное редактирование таблицы через контролы на форме. Я так и понял. Поскольку SET REFRESH не трогали, то данные у Вас обновляются. Просто Вы их не видите. Как я и описал, Вам требуется "передернуть" указатель записи (go Recno()) и обновить картинку (thisForm.Refresh()) Если запись буферизирована, то, естественно, перед этим надо откатить буфер. Ну, или попытаться его сохранить через TableUpdate(.f.,.f.). В данном случае важен второй параметр .f., который отклонит сохранение, если запись изменена другим пользователем Но, повторюсь, лучше пусть это будет сознательное действие пользователя, а не какой-либо вариант автообновления Хотя, конечно, организация работы неудачная, если форму постоянно "перекашивает". В смысле, содержимое строк перестает соответствовать шапке. С этим надо что-то делать. Т.е. менять организацию работы, чтобы такого не было ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 15:51 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
ВладимирМ, буфферизация: =CURSORSETPROP("Buffering", 5, "tablename") сохранение: =TABLEUPDATE(.T.,.T.,'tablename') UNLOCK in tablename SELECT tablename IF THISform.IsNew=.T. GO bott ELSE GO lnrecno && Перед началом процедуры сохранения изменений есть lnrecno = RECNO('tablename') ENDIF т.е. все сохраняется нормально. И это ВладимирМ... Вам требуется "передернуть" указатель записи (go Recno()) и обновить картинку (thisForm.Refresh()) ... вроде как выполняется. Но не обновляется, если были потом изменения, только перегрузкой формы. Собственно, в этом: ВладимирМ... Хотя, конечно, организация работы неудачная, если форму постоянно "перекашивает". В смысле, содержимое строк перестает соответствовать шапке. С этим надо что-то делать. Т.е. менять организацию работы, чтобы такого не было и заключается вопрос. Как и куда мне это поменять, первая мысль была - это подложить view вместо таблицы, но, может еще какой совет получить думал. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 16:20 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
DmitryKn, ВладимирМ... Хотя, конечно, организация работы неудачная, если форму постоянно "перекашивает". В смысле, содержимое строк перестает соответствовать шапке. С этим надо что-то делать. Т.е. менять организацию работы, чтобы такого не было Кстати, содержимое шапке соответствует, не обновляются на форме изменения в шапке без перегрузки формы у одного пользователя, после внесения изменений другим. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 16:24 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
=TABLEUPDATE(.T.,.T.,'tablename') Это записать текущие изменения поверх изменений, сделанных другим пользователем. Второй параметр это делает. Поэтому, естественно, чужих изменений Вы не видите. Вы их просто затираете. Что-то там читать с диска после этого смысла нет. Там будет то же самое, что у Вас сейчас на экране. Если есть конфликт обновлений, то нужен анализ на предмет этих самых конфликтов Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 16:48 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
ВладимирМ, Я очень прошу извинить меня за мое косноязычие, мой вопрос некорректно, наверное, задан, и в любом случае, неправильно понят. Нет проблем с обновлением (сохранением) данных в таблице несколькими пользователями. Есть проблема с отображением этих изменений на форме. У двух юзеров загружена одна и та же форма, один из них редактирует шапку и строки, успешно сохраняет и все видит хорошо. Второй при этом видит то, что и было, ничего не делая, затем выполняет thisform.refresh и видит в строках изменение, а в шапке все равно видит то же самое. Но если он выгрузит форму и снова встанет на эту запись - все отобразится корректно. Где можно было накосячить, если шапка - контролы, завязанные на поля таблицы? Может из-за терминального режима, где таблица открывается у каждого в своей сессии, как-то требуется переоткрыть таблицу, что ли.. p.s. Одновременное редактирование пользователями вроде как предусмотрено: в методе toedit ("открываем" форму на редактирование) if rlock() выполняется код else =messagebox('Данные заблокированы другим пользователем'...) endif ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 17:09 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
Я же уже несколько раз повторил. thisform.refresh недостаточно. Нужно "передернуть" указатель записи через go recno(). Если и это не поможет, то попробуйте отключать/включать буферизацию ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 19:21 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
ВладимирМЯ же уже несколько раз повторил. thisform.refresh недостаточно. Нужно "передернуть" указатель записи через go recno(). Если и это не поможет, то попробуйте отключать/включать буферизацию При перемещении указателя на соседнюю запись и обратно, при этом refresh и срабатывает, вручную - не помогает. А отключать/включать буферизацию - это, например, в кнопке "обновить" отменить буферизацию и снова назначить, потом рефрешить? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 20:04 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
DmitryKn У вас, случаем, фильтр не стоит на этой таблице? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 21:08 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
sg12, Возможность сортировок и поисков конечно есть, их много. Но и без применения фильтров не обновляет. Т.е. фильтры изначально не включены вроде.. Что характерно - новую созданную показывает без перегрузки окна. Затем, если один изменил запись в шапке, второй изменений не видит, но если "откроет" форму на редактирование, произойдет rlock(), затем "отменит", там произойдет : =TABLEREVERT(.T.,'tablename') UNLOCK IN tablename SELECT tablename IF THIS.IsNew=.T. GO gnOldRecOpt ELSE GO RECNO() ENDIF ... thisform.refresh Так вот тогда все отображает отлично. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 21:30 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
DmitryKn Попробуйте такое передергивание: SKIP -1 SKIP ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 21:42 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
sg12, Сделал кнопку, в ней: Код: sql 1. 2. 3. 4. 5. 6. 7.
не помогло. Возможно с буферами что-то, только не подниму я сходу эту тему ( Что вообще мы видим, каждый в своем сеансе гоняет каждый свой указатель каждый - по чему? это ведь уже не таблица выходит, что ли. и SKIP и GO RECNO() отправляют указатель в рамках сеанса, а потому и не обновляют. Когда происходит при отмене (я выше пример писал) TABLREVERT(), вот видимо тогда как-то истинная таблица с диска и перегружается. Как мне эту хрень перегружать каждый раз, когда по гриду указатель идет в своем сеансе? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 21:59 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
Да, еще проверьте, что показывает SET('Exlusive') и разблокировывается ли таблица. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 21:59 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
DmitryKnsg12, Сделал кнопку, в ней: Код: sql 1. 2.
* - случайная, простите, нет ее в коде ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 22:00 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
DmitryKn Не понял про сеансы - у вас, что, у каждого своя DataSession? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 22:06 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
Таблица не заблокировано и Exlusive off sg12DmitryKn Не понял про сеансы - у вас, что, у каждого своя DataSession? Не, default data session Имел ввиду - терминальный режим пользователя на сервере, по сути выходит одновременный запуск нескольких сессий FoxPro, так вроде. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 22:16 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
DmitryKn, Подскажите, как отключить/включить правильно буферизацию ? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 22:25 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
DmitryKn С этим терминальным режимом туман. Убедитесь точно с сессиями, что происходит. Но если с View у вас нормально, надо переходить на них или курсоры. Даже если сейчас у вас прояснится, с одновременной работой с таблицей опять может что-то выскочить. Если решитесь, могу дать совет - не надейтесь на чьи-то советы, лучше самому во всем разобраться. Про буферизацию почитайте в хелпе - buffering data, и далее по ссылкам, смысла ее отключать нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 22:40 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
sg12, Отключить/включить буфер - чтобы понять, чего происходит, ведь на tablerevert() обновляется же. А делать два view - не очень комфортно все-таки, ведь как работает - перемещаюсь по гриду таблицы - одновременно обновляется грид с view. А если заменить таблицу на view и перемещаться по гриду (это, интересно, таблица или уже нет?) - как view будет requery сам на себя запрашивать? Привязаться к чему-то надо, и это, id например, все равно в таблице лежит (( Попробую такой ход - раз с гридом не идет, так может перемещаться через BROWSE, а грид выкинуть.. но уже завтра, видимо. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 22:58 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
DmitryKn, Посмотрите функцию CURSORSETPROP() Переход на BROWSE это глупость, грид и есть модернизированный BROWSE, отображение таблицы. Изменять систему вам все равно придется - в лучшем случае вы наложите заплатку, а не решение. С перемещениями у вас какая-то путаница, похоже что-то неладно со связанными таблицами, с RELATION. Попробуйте связать в форме, в DATAENVIRONMENT. View или курсор это в принципе те же таблицы, только со своими нюансами. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.03.2017, 23:34 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
DmitryKn Похоже, действительно буфер держит таблицу. REQUERY() освобождает только VIEW. Попробуйте после TABLEUPDATE() дать CURSORSETPROP("Buffering",1,table) или TABLEREVERT(.T.) И, возможно, Thisform.Grid.Refresh(). ... |
|||
:
Нравится:
Не нравится:
|
|||
07.03.2017, 02:44 |
|
Как правильно обновить данные на форме
|
|||
---|---|---|---|
#18+
sg12, Доброго дня вам и всем шаманам форума. Browse никак не спас, что было ожидаемо, а теперь подтверждено. Вопрос точно в буферах. В гриде, завязанном на таблицу, в методе AfterRowCalChange поместил код: Код: sql 1. 2. 3.
В методе формы refreshform() поместил код: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
Теперь при движении по гриду таблицы все обновляет. И показывает постоянно отмену каких-то данных - то 1 строку, то 2, то как-то было 3...Что оно там отменяет, какие изменения? А если поставить =CURSORSETPROP("Buffering", 1, "tablename") То ругается, что есть незафиксированные изменения таблицы. Как мне эту хрень в человеческий облик облечь? Ну ведь не запускать же tablerevert() при каждом движении указателя ( ... |
|||
:
Нравится:
Не нравится:
|
|||
07.03.2017, 10:59 |
|
|
start [/forum/topic.php?fid=41&fpage=15&tid=1581982]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
26ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
112ms |
get tp. blocked users: |
2ms |
others: | 350ms |
total: | 530ms |
0 / 0 |