![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Роковое число 255! [D6, dBase, FoxPro]
buka © (2004-08-23 06:42:00)Уважаемые мастера! Без вашей помощи никак не разобраться в том, что надо сделать.
Суть в следующем. Имеется таблица .mdb (Access). В ней 240 записей (всего -то!)
Имеется DBGrid (точнее abcDBFixedGrid, но это насколько я понимаю не столь важно).
Для просмотра записей имеется DBNav с соответствующими кнопками First, Last и пр.
После запуска программы курсор устанавливается на последнюю запись:
procedure Tfm_main.FormActivate(Sender: TObject);
begin
….
ADOTable1.Last;
end;
Щелчками по кнопкам “First” и “Last” без всяких проблем курсор устанавливается на первую и соответственно – последнюю запись. И это отражается, соответственно в DBGrid.
Таблицу я защитил паролем и реализовал это так:
procedure TPasswordDlg.OKBtnClick(Sender: TObject);
label lb1,lb2,lb3;
begin
i:= i+1;
if Password.Text='sezam' then goto lb1;
if i<2 then MessageDlg ('Ага! Фигушки!Пароль введен неправильно!', mtError,[mbOK],0);
if i>=2 then MessageDlg (‘Программа будет закрыта', mtError,[mbOK],0);
if i>=2 then fm_main.Close;
Password.Text:= '';
Password.SetFocus;
goto lb2;
lb1:
fm_main.abcPicBtn2.Visible:= false;
fm_main.abcPicBtn5.Visible:= true;
if Password.Text='sezam'then PasswordDlg.Close;
fm_main.ADOTable1.Close;
fm_main.abcPicBtn11.Visible:= true;
fm_main.ADOTable1.ReadOnly:= false;
fm_main.abcHDBGrid1.ReadOnly:= false;
fm_main.abcnpAppend1.Visible:= true;
fm_main.abcnpDelete1.Visible:= true;
fm_main.abcnpPost1.Visible:= true;
fm_main.ADOTable1.Open;
fm_main.Edit9.Text:= IntToStr (fm_main.ADOTable1.RecordCount);
LoadKeyboardLayout( StrCopy(Layout,'00000419'),KLF_ACTIVATE);
lb2:
end;
После этого курсор устанавливается на первую запись в таблице и соответственно – в DBGrid.
И дальше-при попытке «нырнуть» в конец таблицы (вне зависимости от того используешь ли Append или Last возникает исключение EInvalidGridOperation с сообщением ‘Grid index out of range’.
Скорее всего для Мастеров сразу очевидно в чем дело, но мне пришлось потратить достаточно времени для того чтобы понять, что несмотря на то, что в таблице –240 записей, тем не менее с учетом удаленных ранее реальный index 234 записи имеет № 255! (это я увидел через Access и копию таблицы с дополнительным полем «счетчик»).
Вот туда и устанавливается курсор после того как закроешь вышеуказанное сообщение.
Если используешь Next и до конца таблицы, то исключение не возникает. Записи под №242, 243 вписываются и отображаются нормально (в конце DBGrid, после № 241), но только до тех пор пока не закроешь редактирование таблицы.
Закрываю следующим образом:
procedure Tfm_main.abcPicBtn5Click(Sender: TObject);
begin
fm_main.abcPicBtn2.Visible:= true;
fm_main.abcPicBtn5.Visible:= false;
fm_main.ADOTable1.Close;
fm_main.ADOTable1.ReadOnly:= true;
fm_main.abcHDBGrid1.ReadOnly:= true;
fm_main.abcnpAppend1.Visible:= false;
fm_main.abcnpDelete1.Visible:= false;
fm_main.abcnpPost1.Visible:= false;
fm_main.abcPicBtn11.Visible:= false;
fm_main.ADOTable1.Open;
end;
Курсор после этого устанавливается на первую запись, но … 242 и 243 записи оказываются сразу после 238, т.е. последовательность записей такова …237, 238, 242,243,239,240.
Вот я и спрашиваю: как этот чертов range раздвинуть? Можно ли это сделать принципиально? Или идти по какому другому пути? Пробовал также перехватить исключение, так работа кнопки Last программно не отображается и исключение возникает ранее события
buka (2004-09-09 11:43:00) [1]Спасибо что ответили. Я некоторое время не прсматривал форум (был занят).никаких "приколов" с моей стороны не было.
Sniiknik, если правильно понял вот это:"насчет автоинкремента, абсолютно правильное поведение... " и т.д., фактически подтвердил закономерность поведения записи.
DBGrid - менял на простой - ничего не меняется. такое впечатление, что хотя "отражение" вот такого поведения вставляемых записей идет в DBGride, но сам "кавардак" - происходит в таблице. Хотя при наблюдении этой же таблицы через Access - все "чики-чики".
Defunct! счетчик (если Вы имеете ввиду автоинкремент) мною использовался лишь для наблюдения и выявления той закономерности о которой Вы, как следует из вашего замечания знаете.
GOTO - непосредственно в программке используется только лишь один раз - при рассмотрении пароля для ввода в програмку. Остальные lb, мною просто не удалены, а использовались на этапе отладки программы.
(Я знаю отношение программистов к GOTO, но в тоже время некоторые серьезные авторы книг по программированию, считают, что зря отказываться от GOTO если програмка будет выглядеть проще).Но в любом случае спасибо за доброжелание и уделенное внимание.Больше я пока беспокоить Вас не буду. А сейчас наблюдается следующая картинка: все вновь добавляемые записи идут по порядку, так как я их и нумерую, но как вот начали писаться после, например, 237 - так и пишутся, а после них идут 238, и т.д. до 241, т.е те по которым я изначально увидел проблемку. И... сообщение как выскакивало, так и выскакивает. Ну да ладно буду сам разбираться.
Спасибо всем.
Defunct (2004-09-06 21:01:00) [2]Что-то мне кажется, что автор вопроса просто прикалывается...
Поменяйте тип счетчика с Byte на Integer (Байт на Целое).
Посмотрите, может у этого abcDBGrid есть параметры типа DefaultRowCount или MaxRowCount или нечто подобное, установленное в 255 (хотя такого быть не должно).
Настоятельно рекомендую, использовать пока обычный DBGrid, ищите обновления к ABC компонентам.
GOTO и EXIT вносят элемент запутывания, так что со временем вы сами с трудом разберетесь как работает ваша программа. На будущее, постарайтесь забыть о существовании GOTO/EXIT.
sniknik (2004-09-05 23:11:00) [3]> для чистоты "эксперимента" желательно из набора ABC6и панельку навигации
вот в этом наверное и проблема (если она есть, так и не понял в чем выражается, но по коственным данным...)
замени свои abcHDBGrid на стандартные DBGrid-ы и попробуй повторить свои эксперементы.
вполне допускаю что компанент написан с использованием внутренних счетчиков, скорее всего порядкового номера записи, тогда становится понятным глюк (ну нельзя на порядковый номер закладыватся в клиент серверных базах...) и странная ошибка " Gridindex out of range." идет от грида а не от базы/рекордсета как ожидается) (ну мало ли что там создатель выдает).
насчет автоинкремента, абсолютно правильное поведение, счетчик только увеличивается и увеличивается в момент добавления записи, что с ней будет дальше неважно останентся или удалится, счетчик останется уже увеличенным.
никаких эксперементов не проводил ввиду отсутствия всяких левых компонент, а в стандартных уверен, уже столько всего работает, что если бы было то наверняка ктонибуди в это 255 уткнулся бы...
Arm79 (2004-09-05 21:19:00) [4]Вопрос - а разве поле "счетчик" не должно вести себя именно так? это же автоинкрементное увеличение. Этому полю по барабану, удалили ли предыдущую запись или нет. Оно обеспечивает уникальность записи, собственно и все. Очевидно, где то в программе есть привязка именно к номеру строки.
Что то я в приведенном куске кода не узрел Post... Хотя вроде и редактирование есть и добавление
Может, стоит подумать о SQL-реализации работы с БД?
buka (2004-09-04 10:48:00) [5]Ну кто-нибудь пробовал эксперимент?
buka (2004-08-25 06:39:00) [6]Скажу позже. По памяти- 4.0 (если опять с чем-то не перепутал)
KSergey (2004-08-24 16:08:00) [7]Мдя, случай странный...
Какая версия MDAC и MS Jet установлена?
buka (2004-08-24 15:23:00) [8]Точно что-то переклинило, действительно mdb.Сам удивляюсь (имел ввиду одно, а сообщил другое.Простите Христа ради. ).Я сейчас посмотрел Access 2000. Тип данных так и называется "счетчик".
Простите Христа ради.
buka (2004-08-24 15:20:00) [9]Ошибочно.Я сейчас посмотрел Access 2000. Тип данных так и называется "счетчик".
KSergey (2004-08-24 14:55:00) [10]> [16] buka (24.08.04 14:42)
> БД (с табличкой) сформирована Access-2000; файл имеет расширение
> .dbf
Вранье чистейшей воды. Базы MS Acces имеют расширение mdb.
> Ни о каком Fox речи не было.
Тоже вранье. Есть, в заголовке.
buka (2004-08-24 14:42:00) [11]Тип этого поля устанавливается автоматически при формировании таблицы, кажется там так и указано "счетчик".Если это очень важно вечером посмотрю и скажу точно.Но зачем? Если у Вас есть Acceess-2000 запустите - откройте соответствующую (справа) графку и увидете "счетчик". (говорю по памяти, вечером, если это еще важно-посмотрю)
БД (с табличкой) сформирована Access-2000; файл имеет расширение .dbf
Ни о каком Fox речи не было.Такой файл БД сформирован именно Access (ом).
==========
Я предлагаю всем желающим повторить экспримент.
KSergey (2004-08-24 13:33:00) [12]Да, и что-то там про индексы бало. Откуда они???
А вообще что-то у меня сильное подозрение, что либо с типом автосчетчика косяк, либо косяк драйвера доступа к dbf (если все же о них речь) в части построение индексов (если они, к стати, есть; это тоже не понятно из описания)
KSergey (2004-08-24 13:31:00) [13]> 1. Сделайте BD в Access с одной табличкой.
Табличка - какого типа? Аксесовская? В вопросе вроде про dbf было...
Если DBF - то какая версия ODBC стоит для DBF? (ну или какой версии фокс)
> 2. У этой таблички сделайте 1-е поле -автосчетчиком
Конкретно ТИП этого поля когда-нибудь напишем в конце концов???
buka (2004-08-24 13:10:00) [14]Отвечаю KSergey, поскольку как мне кажется он все-таки стремится помочь (roottima и прочих "уставших" прошу не беспокоить ).
KSergey: прошу понять- выше я написал все то, что наблюдал.
1. БД создал в Access.
2.Компоненты доступа (связи с НД?)ADOTable и др. компоненты ADO.
3. Компоненты визуализации: abcHDBGrid (кажется так называется)и второй дублирующий abcDBFixedGrid.Использую также и другие -для вспомогательных работ, как-то просмотр отдельных записей. Почему использовал DBGrid из комплекта компонентов ABC6? Так он же вертикальный и удобно наблюдать. Но та проблема с которой я столкнулся наблюдаема в обоих Grid(ах).
4.Навигация по НД - панель со стандартными кнопками (First,Last, Delete, и пр.) также из комплекта компонентов ABC
Ну что опять описывать то, что уже описал выше? Не вижу смысла.
Но отвечаю на ваш вопрос о номерах.
Моя нумерация записывается без проблем, но после того, как в таблице (я знаю разницу между таблицей и компонентом визуализации DBGrid) набралось 240 записей (с моей нумерацией!)видимых в DBGride, при попытке сделать Append (или Last)выскакивает исключение с сообщением о котором я указал.
Долго пытался разобраться. Число 240 (присвоенный мною номер очередной записи- той записи достигнув которой я увидел вышеописанные фокусы) не имеет какого-либо значения. Оно может быть и меньше и зависит от того СКОЛЬКО Я ЗАПИСЕЙ УДАЛЯЛ, КАК ОШИБОЧНО ВНЕСЕННЫХ!!!
Ну что опять описывать то, что уже описал выше? Чтобы получить упрек о бредятине и рекомендации "умников" типа 13-го Sergeyя.
Grid сообщает: Index Out of range.
Я понимаю его так: "не могу поставить курсор на последнюю запись под твоей нумерацией, т.к. ее индекс находится за пределами максимально допустимого значения верхней границы диапазона, который я могу отобразить".И... курсор становится где-то на 234 запись (в моей нумерации).Далее ... я уже описывал выше, установив, что Delphi ведет свой собственный счет и у таблицы, которую я просмотрел через Access помимо моей нумерации записей ведется и своя.
===========
Там еще много чего любопытного наблюдается, но если Вам тяжело меня понять или никогда не сталкивались с подобным, Бог с ним попробую-таки сам разобраться и сообщу о результатах.
==============
Любой желающий может повторить мой опыт по следующей схеме (и это не займет много времени).
1. Сделайте BD в Access с одной табличкой.
2. У этой таблички сделайте 1-е поле -автосчетчиком (чтобы увидеть ту бредятину, которую кто не может, а кто - не пытается понять)
3. Сделайте 2-е поле -текстовым, а остальные 1-2- на свой вкус.
4. Простую форму, на нее положите DBGrid (для чистоты "эксперимента" желательно из набора ABC6 и панельку навигации. увяжите то и другое с НД.
5. внесите во 2-е поле "1" (единичку).(остальные можете заполнить, а если лень, то и не заполняйте). главное чтобы у вас светился в DBGride счетчик и поле с нумерацией.
6.Сделайте еще какое не лень количество записей. сохраняя каждую запись (Append,Post,)
7. Затем удалите 1-2 записи (для чистоты эксперимента - последние внесенные)
8.продолжайте еще вносить записи.
9. Внеся их несколько штук-ПОСМОТРИТЕ на автонумерацию в 1-м поле! Что вы увидете?
10. продолжайте далее вносить записи, по прежнему нумеруя их чере 1-е поле, также используя Append.
11. По ходу удаляйте несколько раз.
12. Смотрите на автосчетчик!!!
13.Достигнув по автосчетчику 255 записи (уж какой там будет № записи по вашей нумерации- Бог его знает) может быть и Вы при очередном Append или Last увидите то, что наблюдаю я.
==========
Ей-богу это много времени не займет
KSergey (2004-08-24 10:02:00) [15]> [9] buka (24.08.04 06:54)
> времени.тип поля в которое я вношу свою нумерацию обычный
> текстовый.
Зашибись... "мы не ищем легких путей!"
К стати, конкрентно тип поля можно привести? Ну блин, ну че все клещами надо тянуть?? Кому это надо-то?
> Так вот оказалось, что Delphi где-то учитывает удаленные
> записи и очередная запись у него (мне не видно где)идет
> уже под следующим номером.
В конце концов, вы можете толком написать о каком таком номере здесь идет речь?? Как вы его получаете??? Это тот же, который и вы задаете, или как??
Кроме того, мы когда-нибудь услышим ответ об используемых компонентах доступа??
Ну неужели трудно ответить на встречные вопросы вместо того, чтобы в пятый раз описывать какую-то мистику?
roottim (2004-08-24 09:22:00) [16]я даже читать нестал
по причине вот этого
label lb1,lb2,lb3;
тут непонимание не толко в СУБД но и в Delphi в придачу
Sergey13 (2004-08-24 09:18:00) [17]>Что скажете мастера?
Я хоть и не мастер, но скажу. 8-) Тебе надо книжек почитать по теории и практике БД. Понять что грид и таблица (набор данных) - это две большие разницы. Понять, что сами собой только кошки родятся. И еще много чего понять. Это не издевательство и не прикол над тобой. Просто что бы получать нормальные ответы надо задавать нормальные вопросы.
buka (2004-08-24 06:54:00) [18]Я уже писал ответ, да что-то не вижу его. КSergey. Я попробую, конечно,обычный Grid но это будет где-то позже. Сейчас нет времени.тип поля в которое я вношу свою нумерацию обычный текстовый. (я туда пишу: 1,2,3 и.т.д.сейчас запись идет под № 240).Еще раз попробую попроще объяснить что происходит.
По ходу заполнения записей (кроме текстового поля в которое я пишу № записи там есть естественно и другие поля)возникает необходимость удалять записи (заполнил- сохранил- заметил ошибку -удалил - и опять заполнил-сохранил в уже правильном варианте). Так вот оказалось, что Delphi где-то учитывает удаленные записи и очередная запись у него (мне не видно где)идет уже под следующим номером.И как только вот этот внетренний счет превышает 255 -при попытке сразу прыгнуть в конец Grida (таблицы) и возникает указанное исключение.Как я это вычислил я описал выше.Причем при последовательном переборе до конца (NEXT) исключения не возникает, но запись вставляется (визуально по Grid) туда где закончилась 255. И наблюдаю в Gride 237,238, 242,239,240. И это при всем при том что при внесении и дальнейшем сохранении 242 запись стояла на своем месте.Спрашивали причем Append и Last? Да при том, что и в том и в другом случаях визуально курсор с первой записи в DBGrid должен перейти в конец таблицы.А поскольку Grid считает, что конец где-то на 238 или другой записи, то он туда и прыгает и пишает, что индекс искомой записи находится за пределами диапазона DBGrid (я надеюсь мой "вольный" перевод записи 'Grid index out of range’- правильный). Мой вопрос состоял в том: как увеличить диапазон визуализации табличных данных DBGrid?
Что скажете мастера?
Sergey13 (2004-08-23 13:58:00) [19]2buka
Ну ты даешь! Так длинно и так непонятно!
>Понятно или опять смутно?
Второе. 8-)
Нарисуй структуру таблиц с типами и задачу? И не надо мистики типа "В Delphi есть какая-то штука, которая невидимо нумерует". 8-)
Рамиль (2004-08-23 13:55:00) [20]Э... мало ли что ты концом считаешь? И вообще, "конец" в таблице БД бессмысленное понятие, забей на него.