Форум » [x]Harbour » Непонятки при отборе из базы ? » Ответить

Непонятки при отборе из базы ?

Andrey: Что то при отборе из базы двояться записи .... База проиндексирована по полю INET. Делаю так: [pre2]nInet := 0 aRec := {} ..... SELECT ZMAIN DbSetOrder(3) GOTO TOP dbSeek(nInet, .T. ) // Set softseek on DO WHILE !EOF() IF ZMAIN->INET < 5 .AND. ZMAIN->DATE2 >= CtoD("01.01.17") AADD( aRec, { ZMAIN->ID, ZMAIN->NNZ, RECNO() } ) ENDIF dbSkip(1) ENDDO MsgDebug("массив = ", aRec) [/pre2] Правлю базу, т.е. для ТРЕХ записей делаю ZMAIN->INET := 0 Вызываю эту функцию и она возвращает массив из 6 элементов !!! Почему ? 1 {56614, "622/03", 56614} 2 {56615, "623/03", 56615} 3 {56616, "624/03", 56616} 4 {56614, "622/03", 56614} 5 {56615, "623/03", 56615} 6 {56616, "624/03", 56616} Что не так делаю ?

Ответов - 37, стр: 1 2 All

Dima: Andrey пишет: AADD( aRec, { ZMAIN->ID, ; ZMAIN->NNZ, RECNO() } ) Для начала [pre2] AADD( aRec, { ZMAIN->ID, ; ZMAIN->NNZ, ZMAIN->(RECNO()) } ) [/pre2]

Dima: Ходишь по базе ZAIVKA2MAIN в цикле а массив заполняешь с одной и той же записи ZMAIN , так как не видать ни каких телодвижений с ней. С будуна код писал ?

Andrey: Dima пишет: Ходишь по базе ZAIVKA2MAIN в цикле а массив заполняешь с одной и той же записи ZMAIN , Да нет, ошибся при переносе в форум.


SergKis: Andery пишет Да нет, ошибся при переносе в форум. Что даст в файл комада COPY all FOR ZMAIN->INET < 5 .AND. ZMAIN->DATE2 >= CtoD("01.01.17")

SergKis: PS. COPY all TO _a_ FOR ZMAIN->INET < 5 .AND. ZMAIN->DATE2 >= CtoD("01.01.17")

Andrey: SergKis пишет: Что даст в файл комада COPY all TO _a_ FOR ZMAIN->INET < 5 .AND. ZMAIN->DATE2 >= CtoD("01.01.17") Получается база из 3-х записей.... Всё правильно ! А в моём алгоритме 6 элементов. Так как база проиндексирована по полю INET, сделал доп.условие - получается тоже 3 элемента: [pre2]DbSetOrder(3) GOTO TOP dbSeek(nInet, .T. ) // Set softseek on DO WHILE !EOF() IF ZMAIN->INET < 5 .AND. ZMAIN->DATE2 >= CtoD("01.01.17") AADD( aRec, { ZMAIN->ID, ZMAIN->NNZ, RECNO() } ) ENDIF dbSkip(1) IF ZMAIN->INET == 5 EXIT ENDIF ENDDO [/pre2]

SergKis: Andrey пишет Получается база из 3-х записей.... Надеюсь ты делал тут COPY ... ? DbSetOrder(3) COPY all ... GOTO TOP dbSeek(nInet, .T. ) // Set softseek on ...

Andrey: SergKis пишет: Надеюсь ты делал тут COPY ... ? Нет конечно... Сделал где посоветовал, образуется база с 3-мя записями. Всё верно ! А в моём алгоритме 6 элементов... Непонятка какая-то...

SergKis: Andrey где copy поставь _logfile(.T., hb_valtoexp(aRec)) и после enddo

Haz: Andrey пишет: ZMAIN->INET == 5 Точно больше ошибок при переносе в форум не добавилось? Что у тебя в полях по которым идёт отбор никому не показал, а ответ просишь., . Пиши подробнее. Да и незачем было делать while! Eof если по ключу отбираешь, достаточно While ZMAIN->INET <5 Aadd Skip End По коду который в форуме дублироваться записи в массиве не должны, Выкладывай код из программы без изменений. Мож там что есть. Всю функцию целиком!

Andrey: SergKis пишет: где copy поставь _logfile(.T., hb_valtoexp(aRec)) и после enddo Дибилизм ! Сегодня попробовал, ВСЁ работает, костыль убрал и теперь выбирается 3 элемента. Может индекс был сбойным, а сегодня сделал индексацию и всё заработало ... Haz пишет: Да и незачем было делать while! Eof если по ключу отбираешь, достаточно While ZMAIN->INET <5 А если конец базы ? С таким уже сталкивался. Ну как не задашь вопрос на форуме - ВСЁ начинает сразу работать !!! Всё таки не зря говорят: задай вопрос и сам поймешь на него ответ... Спасибо всем за поддержку ! Алгоритм был правильным !

Dima: Andrey пишет: While ZMAIN->INET <5 Andrey пишет: А если конец базы ? While ZMAIN->INET <5 .and. !ZMAIN->(eof())

Pasha: У меня после первого зацикливания лет дцать назад выработался безусловный рефлекс: любой while со skip делать обязятельно с eof(), т.е: go top / seek while ! eof() .and. ... ... skip enddo ставлю так не думая, на автомате.

Andrey: Dima пишет: While ZMAIN->INET <5 .and. !eof() Так раньше делал и перестал. На таком варианте, программа подвешивается... Не знаю, может из-за сбойного индекса.

Dima: Andrey пишет: На таком варианте, программа подвешивается... Маловероятно. У меня не вешается и у Паши не вешается. Повесить её можно только если Dbskip() не в том месте сделать.

Haz: Там какая то мутная история с индексом)) Дублирование в массиве могло косвенно указывать что что по ключу 5 сбит в индексе адрес записи И скип опять бросало на три позиции вверх, но тогда почему не циклило и всего один повтор. Андрей, в следующий раз весь секретный код своей секретной функции выкладывай, а то народ на фантизии изойдет искать тараканов там где их нет

Петр: Haz пишет: Там какая то мутная история с индексом)) К примеру аддитивный индекс. Haz пишет: Андрей, в следующий раз весь секретный код своей секретной функции выкладывай А вот провоцировать не надо

Andrey: Haz пишет: Андрей, в следующий раз весь секретный код своей секретной функции выкладывай Хорошо ! Только я всю функцию выложил почти целиком. Там у меня один IF был, но я думаю что его и не нужно было выкладывать.

Pasha: Andrey пишет: SELECT ZMAIN DbSetOrder(3) GOTO TOP dbSeek(nInet, .T. ) // Set softseek on DO WHILE !EOF() IF ZMAIN->INET < 5 .AND. ZMAIN->DATE2 >= CtoD("01.01.17") AADD( aRec, { ZMAIN->ID, ZMAIN->NNZ, RECNO() } ) ENDIF dbSkip(1) ENDDO Не забываем про оптимизацию. Оператор go top лишний - его можно выбросить. Поскольку индекс по полю INET - грех его не использовать в условии цикла, чтобы не обрабатывать всю таблицу. В итоге получаем: SELECT ZMAIN DbSetOrder(3) dbSeek(nInet, .T. ) DO WHILE !EOF() .and. ZMAIN->INET < 5 IF ZMAIN->DATE2 >= CtoD("01.01.17") AADD( aRec, { ZMAIN->ID, ZMAIN->NNZ, RECNO() } ) ENDIF dbSkip(1) ENDDO

Andrey: Спасибо Pasha !



полная версия страницы