:: Visual Foxpro, Foxpro for DOS
Лишний SKIP после EOF()
vylv

Сообщений: 30
Дата регистрации: 26.09.2012
На форме несколько TextBox для отображения данных из полей одной таблицы. И пара CommandButton, для перемещения вверх или вниз по строкам таблицы. В методе Click кнопки cmdUp, управляющей движением вверх по строкам таблице, делаю проверку BOF() и в случае .F. выполняю SKIP-1. Все работает нормально, данные отображаются в соответствующих «боксах», а доходя до первой строки , в случае BOF()=.T. перемещение по строкам прекращается, в боксах отображается первая строка таблицы. Можно кликать сколько угодно, перемещения нет.
А вот с кнопкой cmdDn, управляющей движением вниз по строкам таблицы, так не получается. Делается проверка на EOF() , в случае .F. делаю SKIP. Данные корректно отображаются в своих боксах». Но в случае .Т. программа, тем не менее, делает еще раз шаг вниз, идет на SKIP , на следующую за ним логику и отображает пустое поле в «боксе», чего не хотелось бы.. При отладке, в этой ситуации, в окне Data Session, видно, что курсор стоит на последней строке отображаемой таблицы, но EOF(), тем не менее, дает .F.


SELECT f007
LOCATE FOR data=ld1
IF EOF()

ELSE
SKIP
Thisform.txtData.Value=DTOC(data)
ENDIF

Может быть кто-нибудь объяснить, почему так происходит и как с этим справиться?
Ratings: 0 negative/0 positive
Re: Лишний SKIP после EOF()
Taran

Сообщений: 13624
Откуда: Красноярск
Дата регистрации: 16.01.2008
BOF([nWorkArea | cTableAlias])
Определяет, установлен ли указатель записи в начале таблицы.

EOF([nWorkArea | cTableAlias])
Определяет, находится ли указатель записи после последней записи в текущей или в указанной таблице.

Т.е. BOF() проверяет была ли попытка выйти за начало таблицы. При этом ты физически все-равно стоишь на первой записи. Т.е. можно ли еще раз делать SKIP -1.

EOF() проверяет, а не находишься ли ты после последней записи.

Т.е. примерно надо
if !eof()
skip
if eof()
skip -1
endif
endif
Ratings: 0 negative/1 positive
Re: Лишний SKIP после EOF()
vylv

Сообщений: 30
Дата регистрации: 26.09.2012
Благодарю!
Ratings: 0 negative/0 positive
Re: Лишний SKIP после EOF()
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Taran
BOF([nWorkArea | cTableAlias])
Определяет, установлен ли указатель записи в начале таблицы.
Хелп не совсем корректен в этой части. Чуть позже написано более точно:
Цитата:
BOF( ) returns true (.T.) if you have tried to move the record pointer to a position before the first record in the table.
Само по себе нахождение на первой записи не даёт BOF()=.T. Вот после попытки SKIP -1 с этой самой первой записи таки BOF()=.T. При том RECNO() по прежнему = 1 - если нет фильтров/активных индексов (как будто никуда и не перемещались), НО попытка сделать ещё раз SKIP -1 приведёт к ошибке Beginning of file encountered (Error 38) - тут ты не прав.
С EOF немного веселее - там реально идёт перемещение на "запись которой нет". Скажем если в таблице 2 записи, то SKIP 1 стоя на последней, приведёт к RECNO()=3. И да, СЛЕДУЮЩАЯ попытка как раз и даст ошибку End of file encountered (Error 4).
Есть нюансы и с "пустой" таблицей - где нет записей, и указатель всегда находится на записи #1 "фиктивной", при том и EOF и BOF говорят .T.
Для "перемещения к началу" тоже имеет смысл аналогичный код использовать - только и там и там вместо SKIP во внутреннем IF стоит применять более безопасные LOCATE или GO TOP (переход на 1 запись, если таковая есть - LOCATE оптимизирован если есть какие "фильтры/индексы", GO TOP нет, а так они аналогичны) и GO BOTTOM (переход на последнюю запись, если она есть).
Автору темы нужно понять ключевой момент - ни EOF, ни BOF не говорят о том что мы НАХОДИМСЯ на последней или первой реально существующей записи. Они лишь говорят о том, что последняя команда SKIP пыталась "выйти за границы". При том SKIP 1 это по сути удаётся, а SKIP -1 хоть и оставляет RECNO "как будто внутри таблицы", тем не менее запоминает что "попытка была", и следующий SKIP -1 уже приведёт к ошибке. Ну и пустая таблица как "особый случай".
Это особенно чётко станет видно, когда захочется написать код блокирующий соответствующие кнопки навигации (ну чтобы не была доступна кнопка "назад", если мы и так уже на первой записи находимся). "В лоб" использовать EOF/BOF не получится - потребуется делать "попытку перемещения", после которой уже будет видно можно или нельзя реально перемещаться


------------------
WBR, Igor




Исправлено 1 раз(а). Последнее : Igor Korolyov, 28.02.18 15:26
Ratings: 0 negative/0 positive
Re: Лишний SKIP после EOF()
Taran

Сообщений: 13624
Откуда: Красноярск
Дата регистрации: 16.01.2008
Igor Korolyov
Само по себе нахождение на первой записи не даёт BOF()=.T. Вот после попытки SKIP -1 с этой самой первой записи таки BOF()=.T. При том RECNO() по прежнему = 1 - если нет фильтров/активных индексов (как будто никуда и не перемещались), НО попытка сделать ещё раз SKIP -1 приведёт к ошибке Beginning of file encountered (Error 38) - тут ты не прав.

Да я в курсе, что только после SKIP -1 это работает. Просто я излишне сократил цитату хелпа.

Про все остальное можно говорить бесконечно.
Надо ли это автору вопроса? Он шестой год на форуме.
Может банальный сиюминутный затык и потом опять забыть про все.
Ratings: 0 negative/0 positive
Re: Лишний SKIP после EOF()
akvvohinc
Автор

Сообщений: 4219
Откуда: Москва
Дата регистрации: 11.11.2008
Автор неверно описывает то, что у него происходит.
Например, оба этих предложения неверны:
vylv
Но в случае .Т. программа, тем не менее, делает еще раз шаг вниз, идет на SKIP , на следующую за ним логику и отображает пустое поле в «боксе», чего не хотелось бы.. При отладке, в этой ситуации, в окне Data Session, видно, что курсор стоит на последней строке отображаемой таблицы, но EOF(), тем не менее, дает .F.

1) если EOF()=.T. приведенный кусок кода не пойдет на SKIP;
2) по окну Data Session не видно, где стоит курсор, а если речь об окне Browse, то курсор в нем и не может стоять ни перед первой, ни за последней записью, так что использовать его для подобной проверки бессмысленно. Как только активным станет окно Browse, то признак EOF() станет равен .F. в любом случае (если имеется хотя бы одна запись).
К тому же нет ничего удивительного, что при нахождении курсора на последней записи, EOF() = .F.

Если вы при отладке после LOCATE смотрите, где вы находитесь в окне BROWSE, то вы тем самым "испортили" значение, возвращаемое функцией EOF()!
Ratings: 0 negative/0 positive
Re: Лишний SKIP после EOF()
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Вроде как понятно, что автор имел в виду... При нахождении НА последней записи его условие IF !EOF() не работает (он то полагал что при этом будет EOF()=.T. но это не так), и позволяет сделать SKIP - после чего уже в текстбоксах "пустота" из "фиктивной" записи
P.S. Ну и то что BROWSE не только не "покажет правду", но ещё и всё испортит - сбросит и EOF/BOF да и указатель записи переместит (например с "фиктивной" записи "за концом таблицы" на реально последнюю) - это тоже надо понимать...


------------------
WBR, Igor




Исправлено 1 раз(а). Последнее : Igor Korolyov, 28.02.18 23:13
Ratings: 0 negative/0 positive
Re: Лишний SKIP после EOF()
akvvohinc
Автор

Сообщений: 4219
Откуда: Москва
Дата регистрации: 11.11.2008
Igor Korolyov
При нахождении НА последней записи его условие IF !EOF() не работает (он то полагал что при этом будет EOF()=.T. но это не так)
По приведенному коду и написанному тексту я не вижу, чтобы он такое полагал.

А то, что написано в его тексте, происходить не может:
vylv
А вот с кнопкой cmdDn, управляющей движением вниз по строкам таблицы, так не получается. Делается проверка на EOF() , в случае .F. делаю SKIP. Данные корректно отображаются в своих боксах». Но в случае .Т. программа, тем не менее, делает еще раз шаг вниз, идет на SKIP

Программа не может идти на SKIP по одной ветке и при EOF()=.F., и в противном случае - это же очевидно.
В случае .T. программа ни на какой SKIP не идет, указатель уже находится за последней записью, и поэтому текстбоксы отображают "пустоту".

Поэтому, если автор что-то и полагал, то его логика была прямо противоположной, а именно, что несмотря на EOF()=.T. указатель находится на последней записи (то есть, он ожидал от EOF() поведения, аналогичного BOF()).



Исправлено 4 раз(а). Последнее : akvvohinc, 01.03.18 02:03
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 30 (Гостей: 30)

© 2000-2024 Fox Club 
Яндекс.Метрика