Форум » [x]Harbour » Хочется странного - DBEDIT() » Ответить

Хочется странного - DBEDIT()

Sergy: Добрый день. Неожиданно, понял, что меня раздражает в "стандартном" DBEDIT(), который с минимальными добавками (в основном, под мышь) использую из стандартного Harbour 3.4. Пример: есть НЕБОЛЬШОЙ справочник, наподобие такого: [pre2] ┌─ Выберите способ доставки ─────┐ │008 Газель 1.5т 8 куб.м │ │003 Зил-Бычок 3.0т 17 куб.м │ │002 Зил-Бычок 3.0т 25 куб.м │ │001 МАЗ-Зубренок 5.0т 35 куб.м │ │004 MAN тент 5.0т 36 куб.м │ │005 Foton 5.0т 26 куб.м │ │006 Truck 7.0т 36 куб.м │ │007 Доставка ТК (опл.за кг) │ └────────────────────────────────┘ [/pre2] Юзер выбирает некоторый элемент из него, программа в STATIC запоминает - чтобы юзеру было удобно. Например, он выбрал Foton. Через некоторое время юзер вновь открывает этот справочник, по STATIC переменной подставляется "прежнее" значение, оно становится "текущим" в этом справочнике, а DBEDIT() выглядит примерно таким образом: [pre2] ┌─ Выберите способ доставки ─────┐ │005 Foton 5.0т 26 куб.м │ │006 Truck 7.0т 36 куб.м │ │007 Доставка ТК (опл.за кг) │ │ │ │ │ │ │ │ │ │ │ └────────────────────────────────┘ [/pre2] Ну некузяво-же... Хотелось-бы видеть таблицу без пустого пространства снизу, но при этом текущая запись д.б. той, которую юзер использовал в предыдущий раз. Как с этим можно побороться? Загнать справочник строками в ACHOICE, который не имеет таких проблем - тоже способ, но какой-то уж очень "европейский". Спасибо.

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

Dima: а если после установки на нужную запись сделать примерно следующее... [pre2] FUNCTION FreshRecno( b ,als) LOCAL nrec hb_default(@als,alias()) nrec := (als)->(Recno()) b:rowPos:= 1 - Eval( b:skipBlock, 1 - b:RowPos ) (als)->(dbgoto(nrec)) b:RefreshAll() b:forceStable() RETURN NIL [/pre2]

Sergy: Сорри, не очень понял, куда поставить FreshRecno() Обычно у меня бывает так: [pre2] USE ... NEW SET FILT TO ... IF nLastRec > 0 // static GO nLastRecno ELSE GO TOP ENDIF DBEDIT(...) IF LASTKEY() # K_ESC nLastRec := RECNO() // сохраняем в static ENDIF CLOSE ...[/pre2] Или вместо GO nLastRecno идет SEEK на какой-нить xLastId, но суть от этого не меняется - DBEDIT может стартовать как с начала таблицы, так и с какой-то записи, возможно в ее конце.

SergKis: Использовать xUserFunc, в ней при выборе запоминаем выбранную запись и oBrowse:rowPos, и по Диме, делаем skip назад до oBrowse:rowPos == 1 и запоминаем recno этой записи, на нее будем делать потом goto и hb_pushkey(VK_F21), на эту клавишу в xUserFunc делаем перемещение на запомненный rowPos-1, Eval(oBrowse:skipBlock, rowPos-1), возврат из xUserFunc - refresh


Dima: Sergy Я подумал было что ты давно уже пересел на свой бровс http://clipper.borda.ru/?1-4-0-00001164-000-0-0-1480187096 а ты все еще Dbedit мучаешь

Sergy: Dima пишет: Я подумал было что ты давно уже пересел на свой бровс http://clipper.borda.ru/?1-4-0-00001164-000-0-0-1480187096 а ты все еще Dbedit мучаешь Добавил в текст DBEDIT() 7 строк и доп.параметр : [pre2] // // поддержка цвета // IF HB_ISARRAY( aColorBlocks ) // задан массив ? IF nPos <= LEN(aColorBlocks) // в пределах ? oColumn:colorBlock := aColorBlocks[nPos] ENDIF // ELSEIF HB_ISBLOCK( aColorBlocks ) // задан один блок ? oColumn:colorBlock := aColorBlocks // присваиваем всем столбцам ENDIF [/pre2] Все заработало. Пока не очень понимаю, зачем менять полностью DBEDIT(). Да, бесит пустое место в данном случае. Перфекционизм? Но твой пример в 10 строк - попробую и думаю,что получится добавить. Или я просмотрел в oBrowse что-то кардинально изменяющее представление о работе с открытой таблицей (связкой таблиц) ?

Sergy: SergKis пишет: Использовать xUserFunc, в ней при выборе запоминаем выбранную запись и oBrowse:rowPos, и по Диме, делаем skip назад до oBrowse:rowPos == 1 и запоминаем recno этой записи, на нее будем делать потом goto и hb_pushkey(VK_F21), на эту клавишу в xUserFunc делаем перемещение на запомненный rowPos-1, Eval(oBrowse:skipBlock, rowPos-1), возврат из xUserFunc - refresh Вариант с xUserFunc "не очень" . У меня вызвов DBEDIT() больше сотни, у каждого свой xUserFunc(), соотв. дописывать десятки функций, думаю, неразумно. Хотелось-бы допилить единственный DBEDIT(). Ну или освоить получше TBrowse.

Dima: Sergy пишет: Ну или освоить получше TBrowse. Именно !

SergKis: Sergy пишет Хотелось-бы допилить единственный DBEDIT() DbEdit собрана на TBrowse, так что пробнуть можно так:[pre2] FUNCTION dbEdit( nTop, nLeft, nBottom, nRight, ; ... nOldCUrsor := SetCursor( SC_NONE ) FreshRecno(oBrowse) // предложение от Димы /* --------------------------- */ /* Go into the processing loop */ /* --------------------------- */ lAppend := .F. lFlag := .T. lDoIdleCall := .T. lContinue := .T. DO WHILE lContinue ... [/pre2] вставка портить не должна, при выполнении всегда или добавить доп. параметр и по нему выполнять вставку

Sergy: Dima пишет: FUNCTION FreshRecno( b ,als) LOCAL nrec hb_default(@als,alias()) nrec := (als)->(Recno()) b:rowPos:= 1 - Eval( b:skipBlock, 1 - b:RowPos ) (als)->(dbgoto(nrec)) b:RefreshAll() b:forceStable() RETURN NIL Потихоньку разбираюсь с Tbrowse. Не очень понятна логика предложенного решения, а именно: b:rowPos:= 1 - Eval( b:skipBlock, 1 - b:RowPos ) Насколько понимаю, :RowPos показывает текущую позицию курсора Tbrowse. При старте оно равно 1, что приводит к тому, что если от текущей записи до EOF() строк меньше, чем до конца BOX, выделенного для TBrowse, появится пустое место. Приведенный код должен запустить метод skipBlock столько раз, насколько b:RowPos меньше единицы. Т.е. НОЛЬ.

SergKis: Sergy Попилил DBEDIT, получился вариант:[pre2] твой код с добавкой USE ... NEW SET FILT TO ... PRIV dbEditGoto IF nLastRec > 0 // static GO nLastRecno dbEditGoto := nLastRecno ELSE GO TOP ENDIF DBEDIT(...) IF LASTKEY() # K_ESC nLastRec := RECNO() // сохраняем в static ENDIF CLOSE ... модификация DBEDIT ... oBrowse := TBrowseDb( nTop, nLeft, nBottom, nRight ) oBrowse := __objAddMethod( oBrowse, "RowLast", @getRowLast() ) // добавляем метод oBrowse:headSep := iif( ISCHARACTER( xHeadingSeparators ), xHeadingSeparators, Chr( 205 ) + Chr( 209 ) + Chr( 205 ) ) oBrowse:colSep := iif( ISCHARACTER( xColumnSeparators ), xColumnSeparators, " " + Chr( 179 ) + " " ) oBrowse:footSep := iif( ISCHARACTER( xFootingSeparators ), xFootingSeparators, "" ) oBrowse:skipBlock := {| nRecs | Skipped( nRecs, lAppend ) } oBrowse:autoLite := .F. /* Set to .F. just like in CA-Cl*pper. [vszakats] */ ... STATIC FUNCTION getRowLast( oBrw ) // метод для считывания protected переменной nLastRow Return oBrw:nLastRow модифицируем функцию CallUser STATIC FUNCTION CallUser( oBrowse, xUserFunc, nKey, lAppend, lFlag ) ... nPrevRecNo := RecNo() * NOTE: CA-Cl*pper won't check the type of the return value here, * and will crash if it's a non-NIL, non-numeric type. We're * replicating this behavior. CallTest( oBrowse, nMode, nKey, xUserFunc ) nAction := iif( ISBLOCK( xUserFunc ), ; ... STATIC FUNCTION CallTest( oBrw, nMode, nKey, xUserFunc ) Local nRowPos := oBrw:rowPos Local nRowCnt := oBrw:rowCount() Local nLastRow := oBrw:RowLast(oBrowse) Local nSkip // Local nColPos := oBrowse:colPos // Local nColCnt := oBrowse:colCount() If nLastRow < nRowCnt .and. nMode == 0 .and. nKey == 0 If __mvExist("dbEditGoTo") .and. hb_IsNumeric(__mvGet("dbEditGoTo")) nGoto := __mvGet("dbEditGoTo") nSkip := nLastRow - nRowCnt EVal(oBrw:skipBlock, nSkip) oBrw:rowPos := 1 + nSkip * (-1) oBrw:RefreshAll() oBrw:forceStable() __mvPut("dbEditGoTo", Nil) EndIf EndIf RETURN Nil переменную dbEditGoto можно перенести в DBEDIT и значение для нее передавать параметром [/pre2] Сделаешь почище вариант, выложи

SergKis: PS строку подправить надо Local nLastRow := oBrw:RowLast(oBrowse) на Local nLastRow := oBrw:RowLast(oBrw)

Петр: SergKis пишет: PS строку подправить надо Local nLastRow := oBrw:RowLast(oBrowse) на Local nLastRow := oBrw:RowLast(oBrw) Тогда может лучше так STATIC FUNCTION getRowLast() local self := QSelf() Return ::nLastRow и, соответственно, nLastRow := oBrw:RowLast()

SergKis: Петр

Dima: SergKis пишет: nGoto := __mvGet("dbEditGoTo") Для чего переменная nGoto если она не используется в дальнейшем ?

SergKis: Dima пишет Для чего переменная nGoto если она не используется в дальнейшем ? Для проверки [pre2] If nGoto == RecNo() nSkip := nLastRow - nRowCnt EVal(oBrw:skipBlock, nSkip) oBrw:rowPos := 1 + nSkip * (-1) oBrw:RefreshAll() oBrw:forceStable() EndIf [/pre2] Я хотел, но забыл добавить. Еще надо учесть, что бы CallTest выполнилась только один раз. В DBEDIT код для стабилизации 1-го входа, по идее, должен быть по умолчанию, с учетом строк в просмотре меньше размера oBrw (учесть при скип назад и вычислении rowPos новой). Но мне это вроде совсем не надо, vwt не использую, потому не стал делать в примере.

Dima: SergKis Понял. SergKis пишет: Но мне это вроде совсем не надо, vwt не использую Кто его знает , вдруг понадобится.

SergKis: Dima пишет Кто его знает , вдруг понадобится. Линукс в перспективе не маячит (практически умер), на Гуи в тсб проще все такое делать. Местные в своей "истории успеха", так налоги поднимают, что работать бессмысленно становится. Возможно этот год посуетимся еще и ... песец, завязывать надо.

Dima: SergKis пишет: Возможно этот год посуетимся еще и ... песец, завязывать надо. С чем завязать решил , кодить в смысле ?

SergKis: Dima с работой, а кодить в пустоту ... но это уже др. тема.

SergKis: Dima пишет Кто его знает , вдруг понадобится. У меня такой вышел вариант [pre2] FUNCTION DBEDIT( nTop, nLeft, nBottom, nRight, ; ... oBrowse := TBrowseDb( nTop, nLeft, nBottom, nRight ) oBrowse := __objAddData( oBrowse, "lFirstStable" ) oBrowse := __objAddMethod( oBrowse, "RowLast", @getRowLast() ) oBrowse:lFirstStable := .T. oBrowse:headSep := iif( ISCHARACTER( xHeadingSeparators ), xHeadingSeparators, Chr( 205 ) + Chr( 209 ) + Chr( 205 ) ) ... STATIC FUNCTION getRowLast() RETURN QSelf():nLastRow STATIC FUNCTION CallUser( oBrowse, xUserFunc, nKey, lAppend, lFlag ) LOCAL nPrevRecNo LOCAL nAction LOCAL nMode := iif( nKey != 0, DE_EXCEPT, ; iif( !lAppend .AND. IsDbEmpty(), DE_EMPTY, ; iif( oBrowse:hitBottom, DE_HITBOTTOM, ; iif( oBrowse:hitTop, DE_HITTOP, DE_IDLE ) ) ) ) LOCAL nRowPos oBrowse:forceStable() If oBrowse:lFirstStable If oBrowse:rowLast() < oBrowse:rowCount() For nRowPos := 1 To ( oBrowse:rowCount() - oBrowse:rowLast() ) nPrevRecNo := RecNo() EVal(oBrowse:skipBlock, -1) If nPrevRecNo == RecNo() EXIT EndIf Next oBrowse:rowPos := nRowPos oBrowse:RefreshAll() oBrowse:forceStable() EndIf oBrowse:lFirstStable := .F. EndIf nPrevRecNo := RecNo() ... [/pre2]



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