Форум » GUI » TsBrowse в Минигуи (продолжение) » Ответить

TsBrowse в Минигуи (продолжение)

Vlad04: TsBrows определяется в виде строки ПАРМЕТРОВ объекта и их значений К примеру [quote] DEFINE TBROWSE oBrw2 ; AT 60,450 ; ALIAS cAlias ; OF Form1 ; WIDTH 330 ; HEIGHT 340 ; FONT "Verdana" ; SIZE 9 ; ON DBLCLICK CopyRec(); ON GOTFOCUS fModelo_Hab(2) ; AUTOFILTER ; CELLED EDIT; VALUE nRec; GRID [/quote] Здесь я собрал параметры из разных tBrows Можно или нет и какие парметры заменить выражением ( и каким) ? oBrw2:.... oBrw2:....

Ответов - 148, стр: 1 2 3 4 5 6 7 8 All

Andrey: Dima пишет: А Григорий что говорит по этому поводу ? Не знает. Сказал обращаться к Haz .... Цвета задаю после объявления TBROWSE: END TBROWSE // 1 , "Цвет текста в ячейках таблицы" oBrwLic:SetColor( { 1 }, { { || CLR_WHITE }}) // 2 , "Цвет фона в ячейках таблицы" oBrwLic:SetColor( { 2 }, { { || CLR_HBLUE }}) // 3 , "Цвет текста шапки таблицы" oBrwLic:SetColor( { 3 }, { { || CLR_YELLOW }}) // 4 , "Цвет фона шапка таблицы" oBrwLic:SetColor( { 4 }, { { || { RGB( 43, 149, 168 ), RGB( 0, 54, 94 )}}}) // 5 , "Цвет текста курсора, текст в ячейках с фокусом" oBrwLic:SetColor( { 5 }, { { || CLR_BLACK }}) // 6 , "Цвет фона курсора" oBrwLic:SetColor( { 6 }, { { || { 4915199,255} } } ) // 7 , "Цвет текста редактируемого поля" oBrwLic:SetColor( { 7 }, { { || CLR_RED }}) // 8 , "Цвет фона редактируемого поля" oBrwLic:SetColor( { 8 }, { { || CLR_YELLOW }}) // 9 , "Цвет текста подвала таблицы" oBrwLic:SetColor( { 9 }, { { || CLR_YELLOW }}) // 10 , "Цвет фона подвала таблицы" oBrwLic:SetColor( { 10 }, { { || { RGB( 43, 149, 168 ), RGB( 0, 54, 94 )}}}) // 11 , "Цвет текста неактивного курсора (selected cell no focused)" oBrwLic:SetColor( { 11 }, { { || CLR_GRAY }}) // 12 , "Цвет фона неактивного курсора (selected cell no focused)" oBrwLic:SetColor( { 12 }, { { || { RGB( 255, 255, 74 ), RGB( 240, 240, 0 )}}}) // 13 , "Цвет текста шапки выбранного индекса" // 14 , "Цвет фона шапки выбранного индекса" // 15 , "Цвет линий между ячейками таблицы"

SergKis: Andrey цвет окну не пробовал устанавливать или label сцветной по tsb ?

Andrey: SergKis пишет: цвет окну не пробовал устанавливать или label сцветной по tsb ? Не догадался. Сделаю, отпишусь.


Andrey: Блин, а ларчик открывался просто... DEFINE TBROWSE oBrwLic ; ........ BACKCOLOR BLUE ; ......... END TBROWSE Спасибо за подсказку !

Andrey: Мучаюсь с цветами в TBROWSE. Как то по хитрому устроено с цветами, не ко всем есть доступ. Вот еще не знаю как закрасить ДВА квадратика 1) и 2). Подскажите кто знает ? Хотя один нашел: // Левый верхний уголок - specialаselector header background color oBrw:nClrSelectorHdBack := CLR_HMAGENTA Цвета нужны для примера MiniGUI\SAMPLES\Advanced\Tsb_config

Dima: переменных по цветам там не так много [pre2] DATA nClrHeadBack, nClrHeadFore // headers colors DATA nClrFocuBack, nClrFocuFore // focused cell colors DATA nClrEditBack, nClrEditFore // editing cell colors DATA nClrFootBack, nClrFootFore // footers colors DATA nClrSeleBack, nClrSeleFore // selected cell no focused DATA nClrOrdeBack, nClrOrdeFore // order control column colors DATA nClrSpcHdBack,nClrSpcHdFore,nClrSpcHdActive // special headers colors DATA nClrSelectorHdBack // specialаselector header background color [/pre2] Поиграйся методом научного тыка ;) У Define TBROWSE тож есть цвета [pre2] .......... [ BACKCOLOR <backcolor> ] ; [ FONTCOLOR <fontcolor> ] ; [ <color: COLOR, COLORS> <aColors,...> ] ; [/pre2]

Andrey: Dima пишет: Поиграйся методом научного тыка ;) Поигрался. Не нашёл. Из-за этого и написал.

Andrey: Как можно получить высоту таблицы уже нарисованной на экране ? Нужно рядом с таблицей, с такой же высотой нарисовать прямоугольник.

Haz: Andrey пишет: Как можно получить высоту таблицы уже нарисованной на экране ? local aPos := {0,0,0,0} GetWindowRect(oBrw:oWnd:hWnd, aPos) Height := aPos [4] - aPos [2]

Dima: CLASS TSBrowse FROM TControl вероятно сработает oBrw:nBottom - oBrw:nTop не ?

Haz: Dima пишет: вероятно сработает oBrw:nBottom - oBrw:nTop не ? точно, но простые пути нам не интересны

Dima: Haz

Dima: Andrey что касается цветов вот еще 2 из TCONTROL nClrText ,nClrPane

Andrey: Нашел еще лучше - oBrw:nHeightHead !

Andrey: Dima пишет: что касается цветов вот еще 2 из TCONTROL nClrText ,nClrPane Нет это не то ! Не перекрашивают то что нужно.

Dima: Andrey пишет: oBrw:nHeightHead так это высота заголовка , не ?

Andrey: Точно, высота заголовка. Я что-то не то увидел...

Andrey: Переношу цвета с одного бровса в другой. Если цвет - число, то переноситься, а если блок кода, то не переноситься. Как сделать перенос цвета (блока кода) ? nCol := 2 // или 3 колонка с цветом oCol := oBrw9:aColumns[ nCol ] // считаем цвет с oBrw9 oCol:SaveColor() aColor := oCol:aColorsBack FOR nI := 1 TO 15 IF VALTYPE(aColor[nI]) == "B" // Здесь как сделать ? ELSE oBrw8:Setcolor( { nI }, { aColor[nI] }, 1 ) // 1-я колонка oBrw8:Setcolor( { nI }, { aColor[nI] }, 2 ) // 2-я колонка ENDIF NEXT

Andrey: Andrey пишет: Блин, а ларчик открывался просто... DEFINE TBROWSE oBrwLic ; ........ BACKCOLOR BLUE ; ......... END TBROWSE Цвет окна (где НЕТ записей) в таблице установил, а по ходу в задаче НЕ МОГУ исправить цвет: // ------ Установить фон окна таблицы ---------- Form_0.oBrw.BackColor := n2RGB(M->nTbrwColorPane) Что не так делаю ?

Andrey: Всем привет. Вот новая проблема. У меня в TBROWSE есть поиск, т.е. при нажатии анг. или русских букв включается фильтр и отбираются записи. Так вот после отбора, НАЧИНАЕТСЯ СРАЗУ редактирование первой записи попавшей по условию !!! Мне это не нужно. Нужно убрать это редактирование и поставить редактирование ТОЛЬКО после нажатия клавиши ENTER или по двойному клику мышки. Как это сделать ? У себя в коде делаю так: // обработка нажатий клавиш, включая ENTER &cBrw:bKeyDown := { | nKey , nFalgs| MyKeyAction(nKey,nFalgs) } // Двойной клик мышки на МАРКЕРЕ &cBrw:bLDblClick:= { || MyKey_Edit() } // ---------- назначить обработку клавиши F9 на первую колонку ----------- &cBrw:nFireKey := VK_F9 &cBrw:bUserKeys := { |a,b,c| MyKey_F9(a,b,c) } ................ Функция MyKeyAction(): ////////////////////////////////////////////////////////////////////////////// STATIC FUNCTION MyKeyAction(nKey,nFlags) LOCAL ret :=.t. IF !Alltrim(cStSearchValue) == Form_Spr.Text_1.Value cStSearchValue := Form_Spr.Text_1.Value ENDIF DO CASE CASE nKey == VK_ESCAPE CASE nKey == VK_F2 MsgInfo("VK_F2 !") CASE nKey == VK_F3 MsgInfo("VK_F3 !") CASE nKey == VK_INSERT //"[Ins] Добавить запись" RecnoInsertSpr("oBrw_1") CASE nKey == VK_DELETE //"[Del] Удалить запись" RecnoDeleteSpr("oBrw_1") CASE nKey == VK_BACK // Backspace IF LEN(Form_Spr.Text_1.Value) > 0 // удалить символ слева cStSearchValue := LEFT(cStSearchValue,LEN(cStSearchValue)-1) Form_Spr.Text_1.Value := cStSearchValue RefreshBrowse() ENDIF CASE nKey > 31 .AND. nKey < 254 // добавить символ в поиск cStSearchValue := cStSearchValue + KeyToChar(nKey) Form_Spr.Text_1.Value := cStSearchValue RefreshBrowse() CASE nKey == VK_RETURN MyKey_Edit(nKey) OTHERWISE // MsgInfo("Нажата клавиша: "+STR(nKey)+" !") ENDCASE Return NIL

Dima: Andrey пишет: Так вот после отбора, НАЧИНАЕТСЯ СРАЗУ редактирование первой записи попавшей по условию Очищай буфер после нажатия

gfilatov2002: Andrey пишет: Как это сделать ? Попробуй перенести обработку нажатий клавиш для поиска из функции MyKeyAction() в обработчик bUserKeys Примерно это будет выглядеть так: STATIC FUNCTION MyKey_F9((nKey,nFlags) IF !Alltrim(cStSearchValue) == Form_Spr.Text_1.Value cStSearchValue := Form_Spr.Text_1.Value ENDIF DO CASE CASE nKey == VK_F9 MsgInfo("VK_F9 !") CASE nKey > 31 .AND. nKey < 254 // добавить символ в поиск cStSearchValue := cStSearchValue + KeyToChar(nKey) Form_Spr.Text_1.Value := cStSearchValue RefreshBrowse() Return .F. // <----------- важно вернуть здесь FALSE ENDCASE Return .T.

Andrey: gfilatov2002 пишет: Попробуй перенести обработку нажатий клавиш для поиска из функции MyKeyAction() в обработчик bUserKeys А от MyKeyAction() тогда отказаться вообще ?

Andrey: gfilatov2002 пишет: Попробуй перенести обработку нажатий клавиш для поиска из функции MyKeyAction() в обработчик bUserKeys Перенес. От MyKeyAction() отказался вообще, т.е. &cBrw:bKeyDown := { | nKey , nFalgs| MyKeyAction(nKey,nFalgs) } убрал. Перестали работать клавиши управления маркером - стрелки (вверх, вниз и т.д.) Как быть ?

Haz: Andrey пишет: Перестали работать клавиши управления маркером сам их наверное и отключил вернув .F. из bUserkey Andrey пишет: Как быть ? смотреть как обрабатывается bUserKey в h_browse.prg строка 6197 If ::bUserKeys != Nil uReturn := Eval( ::bUserKeys, nKey, nFlags, Self ) If uReturn != Nil .and. ValType( uReturn ) == "N" .and. uReturn < 200 // interpreted as a virtual key code to nKey := uReturn //V90 // change the original key pressed ElseIf uReturn != Nil .and. ValType( uReturn ) == "L" .and. ! uReturn ::nUserKey := 255 // want to inhibit the KeyDown and KeyChar Methods for key pressed Return 0 EndIf EndIf

Andrey: Haz пишет: сам их наверное и отключил вернув .F. из bUserkey Да вроде не отключал. Модифицировал пример из \MiniGUI\SAMPLES\Advanced\Tsb_config т.е. поставил функцию обработки MyKeyEdit() и MyFieldEdit() и добавил фильтр по текстовому полю. Клавиши управления стрелок не работают. Помогите пожалуйста разобраться ? Пример Tsb_config-1.1.7z тут - https://cloud.mail.ru/public/5d315f972a72/MiniGui-Error

Haz: Andrey пишет: Да вроде не отключал. Ну-ну CASE nKey > 31 .AND. nKey < 254 cStaticSearch := cStaticSearch + KeyToChar(nKey) Form_0.Text_Seek.Value := cStaticSearch RefreshBrowse() xRet := .F. вот коды кнопок со стрелками #define VK_NEXT 34 #define VK_END 35 #define VK_HOME 36 #define VK_LEFT 37 #define VK_UP 38 #define VK_RIGHT 39 #define VK_DOWN 40 #define VK_SELECT 41 #define VK_EXECUTE 43 #define VK_SNAPSHOT 44 #define VK_INSERT 45 #define VK_DELETE 46 #define VK_HELP 47

Andrey: Haz пишет: вот коды кнопок со стрелками Спасибо БОЛЬШОЕ ! Я сделал как в терминалке. Ошибся. Как правильно сделать ? Достаточно ли сделать: CASE nKey > 47 .AND. nKey < 254 или еще что-то нужно сделать Так уже сделал - работает !

Andrey: Всем привет. Как при показе таблицы обойтись без дополнительных баз с SET RELATION. Есть массив aDim := {"---","город","село"} Создаю колонку: ADD COLUMN TO oBrw9 HEADER "Группа" + CRLF + "местности" ; DATA FieldWBlock( "KGROUP", Select() ) ; SIZE 150 ; ALIGN DT_CENTER,DT_CENTER,DT_RIGHT ; EDITABLE oBrw9:aColumns[6]:bPrevEdit := { || MyDimGroup(), FALSE } Как вместо кодов в базе выводить значения из массива ? Т.е. если в базе 0 - выводить aDim[1] := "---"? 1 - aDim[2] := "город" и т.д. Или ткните в пример, если он есть ?

Dima: Andrey пишет: Как вместо кодов в базе выводить значения из массива ? Этот вопрос ты уже задавал и тебе ответили , поройся в своей старой теме.

Andrey: Dima пишет: Этот вопрос ты уже задавал и тебе ответили , поройся в своей старой теме. Не помню, покажи пожалуйста. Я тогда не сделал, а сейчас нужно сделать.

Dima: Andrey Да мне тоже лень вместо тебя рыться в твоей старой теме см. MiniGUI\SAMPLES\Advanced\Tsb_array\

Haz: Andrey пишет: Как вместо кодов в базе выводить значения из массива ? Т.е. если в базе 0 - выводить aDim[1] := "---"? 1 - aDim[2] := "город" и т.д. Или ткните в пример, если он есть ? См. в примерах TsBrowse как использовать :bData или :SetData :bData - определяет кодовый блок выборки/записи в колонке TsBrowse :SetData - чуть сложнее и работает с двумя массивами aData и aValue , работает так - если значение в колонке будет найдено в aData то в ячейке отобразится соответствующее из aValue ( тут же в примерах использование ComboWBlock в :SetData - редактирование кода через выбор его соответствия из комбика )

Andrey: Haz Спасибо БОЛЬШОЕ ! Буду рыться... Dima Где ты взял такого классного пирата ?

Dima: Andrey пишет: Dima Где ты взял такого классного пирата ? В форме ответа слева есть смайлы а под ними цифирки Не пробовал на них нажимать ?

Andrey: Dima пишет: В форме ответа слева есть смайлы а под ними цифирки Не пробовал на них нажимать ? Я пирата раньше не видел ....

Andrey: Всем доброй ночи.... Вот что-то не идет у меня контекстное меню для TBROWSE... Объявил окно DEFINE WINDOW Form_5 ; .......................... ОN INIT MyTbr2() END WINDOW /////// Function MyTbr2() ............... DEFINE TBROWSE oBrw_1 ; ................. END TBROWSE DEFINE CONTEXT MENU CONTROL oBrw_1 MENUITEM "Включить показ удаленных записей" ... ............................ END MENU // строка 794 Выдает ошибку: Error BASE/1132 Переполнение массива: Неверное количество аргументов Called from _ENDMENU(517) Called from SPRCREATEBROWSE(794) Подскажите пожалуйста, что не так делаю ?

Haz: Andrey пишет: что не так DEFINE CONTEXT MENU CONTROL oBrw_1 OF Form_5

Andrey: Haz пишет: OF Form_5 Спасибо ! Заработало !

Andrey: Поймал глюк... Очередной... Если в моём справочнике несколько записей то в TBROWSE если раз 10 - колёсиком мышки покрутить, то база отсоединяется от TBROWSE ... пропадает соединение и всё.... После этого на экране можно листать базу вверх-вниз, но если попробовать редактировать, то вылет по ошибке: Error DBCMD/2001 Файл не открыт: Вот так выглядит это на экране: Как с этим бороться ?

Haz: Andrey пишет: если раз 10 - колёсиком мышки покрутить, минут 10 крутил колесиком , палец уже устал а база никак не хочет отсоединяться и все работает как положено Andrey пишет: Как с этим бороться ? смотреть чего понаписал в исходнике

Andrey: Haz пишет: смотреть чего понаписал в исходнике Отдельно программа работает КАК ЧАСЫ (ни как не убивается....) ! Занимает 2,5 Мб - на диске и в памяти. Включаю эту же программу в свою систему (5.5Мб на диске и 4.8 Мб в памяти) и на этой же базе получаю вылет. Колесиком вверх-вниз секунд 20 и вылет. Я понимаю, что не каждый юзер так будет делать, но у меня и быстрей иногда сваливается с такой же ошибкой: Error DBCMD/2001 Файл не открыт: При создании TBROWSE открываю всю базу. Потом по кнопке делаю условную индексацию (этой базы) по городу и уменьшаю список показа записей. Может в этом дело ? При большом ехе-нике перестает работать ?

Haz: Andrey пишет: Включаю эту же программу в свою систему (5.5Мб) и на этой же базе получаю вылет 1 Возможно в большой системе другие установки или есть конфликт имен .. от размера исполняемого модуля это точно не зависит 2 Смотреть что висит на ON CHANGE и ON DRAW твоего справочника Andrey пишет: При создании TBROWSE открываю всю базу. Потом по кнопке делаю условную индексацию (этой базы) по городу и уменьшаю список показа записей. Может в этом дело ? Может и в этом , нужно как минимум oBrw:Reset() после того как была изменена рабочая область PS/ а если не делать условную индексацию - эффект отключения наблюдяется ?

Andrey: Haz пишет: 1 Возможно в большой системе другие установки или есть конфликт имен .. А какие другие установки ? Конфликта имен точно нет. Переменные все переискал в других исходниках - таких нет. Были, уже удалил. Haz пишет: 2 Смотреть что висит на ON CHANGE и ON DRAW твоего справочника ON GOTFOCUS ( MyChangeBrowse(cAlias), Form_Spr.oBrw_1.Setfocus) ; ON CHANGE (CorrectionFirstLast("oBrw_1"),MyChangeBrowse(cAlias), Form_Spr.oBrw_1.Setfocus) Функция MyChangeBrowse(cAlias) //////////////////////////////////////////////////////////// STATIC FUNCTION MyChangeBrowse(cAlias) LOCAL nI, cVal nI := INDEXORD() IF nI == 0 cVal := NTOC(Recno()) + '/' + NTOC(RecCount()) ELSE cVal := NTOC(OrdKeyNo()) + '/' + NTOC(OrdKeyCount()) ENDIF Form_Spr.Label_StatusBar2.Value := " Запись: " + cVal Form_Spr.oBrw_1.Setfocus RETURN Nil Функция CorrectionFirstLast("oBrw_1") не моя, брал и примеров: *--------------------------------------------------------------------------------* Static procedure CorrectionFirstLast(oBrw) *--------------------------------------------------------------------------------* IF &oBrw:nRowCount() == &oBrw:nRowPos() &oBrw:Refresh( .F. ) ENDIF IF &oBrw:nLogicPos() > 0 .and. &oBrw:nRowPos() == 1 &oBrw:Refresh( .F. ) ENDIF RETURN Haz пишет: Может и в этом , нужно как минимум oBrw:Reset() после того как была изменена рабочая область Да я рабочую область и не меняю. Алиас тот же самый. cBaseMain := "STREET" nSel := SELECT(cBaseMain) IF nSel > 0 DBCLEARINDEX() // Удаление временного индексного файла myDelTmpIndex(cFileIndexTemp) MyIndexOpenRestore(aStaticMemIndexOpen) // Восстановить открытые индексы nOrder := INDEXORD() // Результат: NUMBA BuildIndex( cBaseMain, "STREET00",,, cFileIndexTemp , ; "KCITY=="+HB_NtoS(nCity)+".AND.!DELETED()", ; "UPPER(STREET)" ) // { "Идет индексация БД-справочника",,, "15/2", "2/15" } ) DBSetOrder( nOrder + 1 ) // переключится на новый индекс RefreshBrowse() goto TOP oBrw_1:Reset() oBrw_1:Refresh(.T.) ELSE MsgDebug("Нет открытой базы:", cBaseMain, "Тек.база:", ALIAS(), SELECT() ) ENDIF ENDIF Form_Spr.oBrw_1.Setfocus RETURN NIL

Haz: ОТКЛЮЧИ ON CHANGE и попробуй без него Andrey пишет: RefreshBrowse() Это что делает ?

Andrey: Haz пишет: Это что делает ? Поиск по введенным буквам: //////////////////////////////////////////////////////////// STATIC FUNCTION RefreshBrowse() LOCAL cSeek := Alltrim( Form_Spr.Text_1.Value ) LOCAL cStrSeek := '('+Alias()+')->'+cStPole_DbSetFilter LOCAL cExp := "'" + UPPER(cSeek) + "' $ UPPER(MASTER->MASTER)" cExp := "'" + UPPER(cSeek) + "' $ UPPER("+cStPole_DbRelation+")" //MsgDebug(cExp, cStrSeek) IF !Empty(cSeek) ( Alias() )->( DbSetFilter( &("{||" + cExp + "}"), cExp ) ) ELSE ( Alias() )->( DbClearFilter() ) END oBrw_1:Reset() Form_Spr.oBrw_1.Setfocus RETURN Nil

Andrey: Haz пишет: ОТКЛЮЧИ ON CHANGE и попробуй без него Так же вылетает после 20-30 секундного мышка-колёсико.... Error DBCMD/2001 Файл не открыт:

Haz: Andrey пишет: Так же вылетает после 20-30 секундного мышка-колёсико.. после каждого "мышка-колёсико" вызывается ON CHANGE, можно предположить что проблема в нем. Отключи и проверь Явно база нигде не закрывается , может уперся в максимальное число открытых баз/индексов ?

Andrey: Haz пишет: может уперся в максимальное число открытых баз/индексов ? Да там только эти справочники и открываются. Еще только оболочку сделал и менюшку справочники. И десяти баз открытых не будет.... Haz пишет: после каждого "мышка-колёсико" вызывается ON CHANGE, можно предположить что проблема в нем. Отключи и проверь Проверил, только что еще раз. Убрал вообще ON CHANGE и ON GOTFOCUS Так же вылетает после 20-30 секундного мышка-колёсико.... Error DBCMD/2001 Файл не открыт: Может неправильно написал, хотя из примеров брал: // создать объект TBROWSE SprCreateBrowse( cSection, "oBrw_1", 'Form_Spr', nBrwTop+2, nBrwLeft, nBrwWdth, nBwrHght-2-nHB, ALIAS() ) ниже в программе: PUBLIC &cBrw DEFINE TBROWSE &cBrw ; AT nRow, nCol ; ALIAS cAlias ; OF &cParent ; WIDTH nWidth ; HEIGHT nHeight ; COLORS { CLR_BLACK, CLR_BLUE } ; BACKCOLOR aBackColor ; FONT 'Tahoma' SIZE ModeSizeFont() //ON GOTFOCUS ( MyChangeBrowse(cAlias), Form_Spr.oBrw_1.Setfocus) //ON CHANGE (CorrectionFirstLast("oBrw_1"),MyChangeBrowse(cAlias), Form_Spr.oBrw_1.Setfocus) END TBROWSE Есть какая нибудь функция показывающая открытые базы ? Или самому писать надо ? У меня такая в терминалке была...

Haz: Andrey пишет: Или самому писать надо имеется ввиду список Алиасов ? готовой нет или бровс по алиасу - такая есть внутри h_tbrowse.prg Function SBrowse( uAlias, cTitle, bSetUp, aCols, nWidth, nHeight, lSql ) можно вызвать с одним параметром uAlias // создать объект TBROWSE SprCreateBrowse( cSection, "oBrw_1", 'Form_Spr', nBrwTop+2, nBrwLeft, nBrwWdth, nBwrHght-2-nHB, ALIAS() ) PS попробуй Alias() явно задать ввиде символьного значения. такое впечатление что бровс его забывает PPS проверь чему равно значение &cBrw:cAlias

Dima: Haz пишет: имеется ввиду список Алиасов ? Pasha пишет: Оказывается, в харборе есть функция hb_waEval( bBlock ) Блок кода bBlock вызывается для каждой открытой рабочей области. Т.е. массив алиасов или номеров р/о можно получить так: aAlias := {} hb_waEval( {|| AADD(aAlias, Alias())} ) или aSelect := {} hb_waEval( {|| AADD(aSelect, Select())} )

SergKis: Andrey может так надо: DEFINE TBROWSE &cBrw ; AT nRow, nCol ; ALIAS &cAlias ; OF &cParent ; Или самому писать надо ? a := {}; AEval(array(50), {|x,e| iif( (e)->( used() ), aAdd(a, (e)->( alias() ), nil) }) msgDebug(a)

Andrey: SergKis пишет: может так надо: DEFINE TBROWSE &cBrw ; AT nRow, nCol ; ALIAS &cAlias ; Делал и так тоже. у Григория пример брал из \MiniGUI\SAMPLES\Advanced\Tsb_filter\demo.prg

Andrey: SergKis пишет: AEval(array(50), {|x,e| iif( (e)->( used() ), aAdd(a, (e)->( alias() ), nil) }) Error E0030 Syntax error "syntax error at '}'"

Andrey: Haz пишет: PS попробуй Alias() явно задать ввиде символьного значения. такое впечатление что бровс его забывает PPS проверь чему равно значение &cBrw:cAlias Для проверки сделал отдельное меню: MENUITEM "Алиас этой БД" ACTION { || MyGetUse("oBrw_1") } SEPARATOR MENUITEM "Список открытых БД" ACTION { || MyGetAllUse() } После потери связи с базой выдает что база открыта: "STREET" А если опросить все базы то показывает что 3 базы открыты !!! Получается TBROWSE сам теряет связь с базой.... Что делать ?

Haz: Andrey пишет: Получается TBROWSE сам теряет связь с базой.... Что делать ? Скорре всего слетат ( а точнее становится невыполнимым ) условие в блоке выборки/записи по колонке( или колонкам ) и уверен слетает не само а какой то кусок кода ему помогает. нужно проверить до слета и сразу после 1. oBrw:cAlias - должно быть "STREET" 2. oBrw:aColumns[x]:cData должно быть что то типа "STREET->имя поля или FieldGet(). " 3. Eval( oBrw:aColumns[x]:bData) должно вернуть значение из текущей записи для колонки х ЗЫ в функции RefreshBrowse() есть вызов Alias() ? Андрей ты уверен в том что при выполнении RefreshBrowse() ВСЕГДА Alias() == "STREET" ? и что там с тассировкой ошибки - на какую строку из h_browse.prg ругается ?

Andrey: Слетает всегда в одном месте, когда редактировать начинаешь. После того как колёсиком поездишь, кол-во записей становится 0/0 и начинаешь редактировать. Я назначил свою функцию обработки и в зависимости условий, разрешаю/запрещаю редактировать ячейки или вызываю справочник (отдельный): For nI := 1 to Len(aPoleField) ADD COLUMN TO TBROWSE &cBrw // добавить новую колонку в TBROWSE ..... IF cTypeField # "+" // кроме - автоинкремент поля &cBrw:aColumns[nI]:lEdit := .T. oBrw_1:aColumns[nI]:bPrevEdit := {|| MyFieldEdit( oBrw_1:aColumns[oBrw_1:nCell]:Cargo ) } ENDIF Next Вылет всегда в: Error DBCMD/2001 Файл не открыт: RLOCK Called from RLOCK(0) Called from RECLOCK(31) // это моя функция Called from MYFIELDEDIT(1471) // это моя функция Called from (b)SPRCREATEBROWSE(964) Called from TSBROWSE:KEYDOWN(6329) Called from TSBROWSE:HANDLEEVENT(7084) Called from EVENTS(76) RECLOCK(31) // это моя функция из терминалки FUNCTION RecLock( nRetry ) // nRetry == 3 - кол-во попыток захватить запись LOCAL lForever LOCAL lRet := .T. nRetry := IF(nRetry == NIL, MAX_NOF_ATTEMPTS, nRetry) lForever := (nRetry == 0) WHILE !RLOCK() .AND. ((nRetry > 0 .OR. lForever)) // строка - 31 IF Msg( MSG_TRY_LOCK_REC ) == K_ESC EXIT ENDIF nRetry-- END IF !RLOCK() Msg( MSG_LOCK_NO_SUCCESS ) lRet := !lRet ENDIF RETURN (lRet)

Haz: Andrey пишет: Called from TSBROWSE:KEYDOWN(6329) похоже что то с блоком выборки не алё вот тут спотыкается при редактировании TSBROWSE:KEYDOWN(6329 проверив что есть bPrevEdit и бровс не по массиву пытается выполнить блок и вылетает с ошибкой If ::aColumns[ nCol ]:bPrevEdit != Nil If ::lIsArr .and. ( ::lAppendMode .or. ::nAt > Len( ::aArray ) ) // append mode for arrays Else // GF 16-05-2008 uVal := Eval( ::aColumns[ nCol ]:bData ) uVal := Eval( ::aColumns[ nCol ]:bPrevEdit, uVal ) If ValType( uVal ) == "L" .and. ! uVal Return 0 EndIf EndIf EndIf ЗЫ MYFIELDEDIT в студию ЗЫЫ И все же мне кажется что где то меняется рабочая область ! в bPrevEdit тыкни MsgDebug( Alias() )

Andrey: Сделал новый тест в функции MyFieldEdit() до начала редактирования при слёте базы: MsgDebug(oBrw_1:nLen, ALIAS(), oBrw_1:cAlias ) MsgDebug( "RLock()=", (oBrw_1:cAlias)->(RLock()) ) Т.е. колёсиком подергал вверх-вниз на 5 записях, функция MyChangeBrowse(cAlias) показывает 0/0 начинаю редактировать: 1. MsgDebug показывает 5, "", "STREET" 2. MsgDebug показывает "RLock()=" .T. Т.е. АЛИАС по всей задачи ALIAS() = "" - убит !!! Кем ? На экране таблица есть (в объекте) а все связи разорваны ! Еще раз пишу, отдельная задача работает как часы, а в сборке с другими (там только еще один TBROWSE есть) начинает вылетать.

Dima: Haz пишет: MYFIELDEDIT в студию +1

SergKis: Andrey AEval(array(50), {|x,e| iif( (e)->( used() ), aAdd(a, (e)->( alias() )), nil) })

Haz: пишет: Т.е. АЛИАС по всей задачи ALIAS() = "" - убит !!! Кем ? не убит, где-то сработал Select(0) вот и стал текущим пустой алиас. На 99% уверен что если твой RecLock() вызывать из алиасного выражения STREET->(RecLock()) то ошибка уйдет. Но это костыль, а не исправление ошибки. По уму надо найти "виновника"

Andrey: Haz пишет: MYFIELDEDIT в студию Да вот она, с терминалки перетащил, еще не вычищал... STATIC FUNCTION MyFieldEdit(aCargo) // aCargo не используется, везде Static переменные LOCAL cTemp, cPoleTemp, cTemp2, aRet LOCAL cRunFun, tmp, cScr25, cFuncName, cT, cRetval, cTitle LOCAL nRet, nSRet, nPoleEdit, cPoleEdit LOCAL nCol := oBrw_1:nCell // колонка на которой стоит маркер LOCAL cPoleField := aPoleField[nCol] // поле БД на котором стоит маркер LOCAL cPolePict := aPolePict[nCol] // формат поля БД на котором стоит маркер LOCAL lEditField := .F. , nKey := oBrw_1:nFireKey LOCAL cTitleSpr := " " + aPoleName[nCol] // Справочник MsgDebug(oBrw_1:nLen, ALIAS(), oBrw_1:cAlias ) MsgDebug( "RLock()=", (oBrw_1:cAlias)->(RLock()) ) IF oBrw_1:nLen == 0 // для отладки, чтобы искать ошибки MyMESSAGE( 'Нет записей для редактирования ! ;;Переоткройте справочник ЗАНОВО !' ) RETURN .F. ENDIF // aFields[1] - первое поле справочника (Код) для сверки с == 0 IF FieldGet( FIELDNUM( aPoleField[1] ) ) == 0 // нет прав доступа к записи MyMESSAGE( 'Нельзя редактировать запись с КОДОМ = 0 !', 2 ) RETURN .F. ENDIF // aPoleDost, aPoleWrite - STATIC IF M->aOperator[ M->nSP_ENTER ] == "0" // нет прав доступа к записи MyMESSAGE( 'Нет прав доступа редактирования записи !', 2 ) ELSE IF aPoleDost[ nCol ] == "SF" IF Len( aPoleWrite[ nCol, 4 ] ) == 0 aPoleWrite[ nCol, 4 ] := aPoleWrite[ nCol, 3 ] + "2" ENDIF cTemp := AllTrim( aFiltPole[ nCol ] ) IF Len( cTemp ) > 0 nSRet := Sel_Dim( , , aPoleWrite[ nCol, 1 ], aPoleWrite[ nCol, 2 ], ; aPoleWrite[ nCol, 3 ], aPoleWrite[ nCol, 4 ], cTemp, "OPEN", cTitleSpr,.F. ) ELSE nSRet := Sel_Dim( , , aPoleWrite[ nCol, 1 ], aPoleWrite[ nCol, 2 ], ; aPoleWrite[ nCol, 3 ], aPoleWrite[ nCol, 4 ], "", ,cTitleSpr, .F. ) ENDIF IF nSRet > -1 //0 cTemp2 := aPoleWrite[ nCol, 2 ] // сетевой захват записи IF ( RecLock( LOCK_RETRY ) ) FIELDPUT(FIELDNUM(cTemp2), nSRet ) IF FIELDNUM( "KOPERAT" ) > 0 FIELDPUT(FIELDNUM("KOPERAT"), M->nOperat ) // кто изменил справочник ENDIF //DBCOMMIT() DBUnlock() ENDIF ENDIF ELSEIF aPoleDost[ nCol ] == "AS" IF Len( aPoleWrite[ nCol, 4 ] ) == 0 aPoleWrite[ nCol, 4 ] := aPoleWrite[ nCol, 3 ] + "2" ENDIF nSRet := Sel_Dim( , , aPoleWrite[ nCol, 1 ], aPoleWrite[ nCol, 2 ], ; aPoleWrite[ nCol, 3 ], aPoleWrite[ nCol, 4 ], "", ,cTitleSpr, .F. ) IF nSRet > -1 //0 cTemp2 := aPoleWrite[ nCol, 2 ] // сетевой захват записи IF ( RecLock( LOCK_RETRY ) ) FIELDPUT(FIELDNUM(cTemp2), nSRet ) IF FIELDNUM( "KOPERAT" ) > 0 FIELDPUT(FIELDNUM("KOPERAT"), M->nOperat ) // кто изменил справочник ENDIF //DBCOMMIT() DBUnlock() ENDIF ENDIF ELSEIF aPoleDost[ nCol ] == "S" IF Len( aPoleWrite[ nCol, 4 ] ) == 0 aPoleWrite[ nCol, 4 ] := aPoleWrite[ nCol, 3 ] + "2" ENDIF IF aFiltBase[ 1 ] == .T. IF aFiltBase[ 4 ] == "N" cTemp := aFiltBase[ 2 ] + " ==" + AllTrim( Str( aFiltBase[ 3 ] ) ) ELSE cTemp := aFiltBase[ 2 ] + " ==" + aFiltBase[ 3 ] ENDIF nSRet := Sel_Dim( , , aPoleWrite[ nCol, 1 ], aPoleWrite[ nCol, 2 ], ; aPoleWrite[ nCol, 3 ], aPoleWrite[ nCol, 4 ], cTemp, "OPEN",cTitleSpr,.F. ) ELSE nSRet := Sel_Dim( , , aPoleWrite[ nCol, 1 ], aPoleWrite[ nCol, 2 ], ; aPoleWrite[ nCol, 3 ], aPoleWrite[ nCol, 4 ], "", ,cTitleSpr,.F., ) ENDIF IF nSRet > -1 //0 cTemp2 := aPoleWrite[ nCol, 2 ] // сетевой захват записи IF ( RecLock( LOCK_RETRY ) ) FIELDPUT(FIELDNUM(cTemp2), nSRet ) IF FIELDNUM( "KOPERAT" ) > 0 FIELDPUT(FIELDNUM("KOPERAT"), M->nOperat ) // кто изменил справочник ENDIF //DBCOMMIT() DBUnlock() ENDIF ENDIF lEditField := .F. ELSEIF aPoleDost[ nCol ] == "T" IF Len( aPoleWrite[ nCol, 4 ] ) == 0 aPoleWrite[ nCol, 4 ] := aPoleWrite[ nCol, 3 ] + "2" ENDIF cPoleTemp := aFiltPole[ nCol ] IF FIELDNUM( cPoleTemp ) > 0 nSRet := FieldGet( FIELDNUM( cPoleTemp ) ) IF nSRet == 0 Message( 'полe "' + cPoleTemp + '" == 0', 5 ) ELSE cTemp := aFiltPole[ nCol ] + " == " + AllTrim( Str( tmp ) ) nSRet := SEL_DIM( , , aPoleWrite[ nCol, 1 ], aPoleWrite[ nCol, 2 ], ; aPoleWrite[ nCol, 3 ], aPoleWrite[ nCol, 4 ], cTemp, "OPEN", cTitleSpr,.F. ) IF nSRet > -1 //0 cTemp2 := aPoleWrite[ nCol, 2 ] // сетевой захват записи IF ( RecLock( LOCK_RETRY ) ) FIELDPUT(FIELDNUM(cTemp2), nSRet ) IF FIELDNUM( "KOPERAT" ) > 0 FIELDPUT(FIELDNUM("KOPERAT"), M->nOperat ) // кто изменил справочник ENDIF //DBCOMMIT() DBUnlock() ENDIF ENDIF ENDIF ELSE Message( 'Нет поля "' + cPoleTemp + '" в БД' + Alias(), 5 ) ENDIF lEditField := .F. ELSEIF aPoleDost[ nCol ] == "R" Message( "Нельзя редактировать поле", 2 ) lEditField := .F. ELSEIF aPoleDost[ nCol ] == "J" cRunFun := aPoleWrite[ nCol, 1 ] IF ( RecLock( LOCK_RETRY ) ) aRet := &cRunFun cTemp2 := aRet[ 1 ] nSRet := aRet[ 2 ] // сетевой захват записи FIELDPUT(FIELDNUM(cTemp2), nSRet ) IF FIELDNUM( "KOPERAT" ) > 0 FIELDPUT(FIELDNUM("KOPERAT"), M->nOperat ) // кто изменил справочник ENDIF //DBCommit() DBUnlock() ENDIF lEditField := .F. ELSE IF nCol == 1 // первое поле КОД // &cBrw:aColumns[1]:lEdit := .F. // Редактирование поля 1 всегда ЗАПРЕЩЕНО // нужно делать отдельный доступ для оператора 101 // т.к. в справочниках 1-е поле это КОД НАИМЕНОВАНИЯ IF oBrw_1:nFireKey == VK_F9 .AND. M->nOperat == 101 lEditField := .T. // Можно редактировать эту ячейку ! ELSE MyMessage( "Нельзя редактировать это поле !", 2 ) ENDIF ELSE cPoleEdit := FieldGet( FIELDNUM( cPoleField ) ) // обработка на ТИП ПОЛЯ // MsgDebug(nCol," > ", "обработка на ТИП ПОЛЯ", cPoleField) IF FIELDTYPE(FIELDNUM( cPoleField )) == "M" cTitle := aPoleWrite[ nCol, 1 ] cFuncName := aPoleWrite[ nCol, 2 ] cT := Type( cFuncName ) IF .NOT.( cT == 'UI' .OR. cT == 'UE' ) MyMessage( 'Функции '+cFuncName+' нет в EXE-файле !; Обратитесь к разработчику программы !', 1 ) cRetval := "" ELSE cRetval := &cFuncName ENDIF // сетевой захват записи IF ( RecLock( LOCK_RETRY ) ) IF VALTYPE(aPoleWrite[nCol,3]) # "A" MyMessage( 'Нет массива координат !; Обратитесь к разработчику программы !', 1 ) Edit_Memo(cTitle+cRetval ,'' , cPoleField, .T., ) ELSE Edit_Memo(cTitle+cRetval ,'' , cPoleField, .T., aPoleWrite[nCol,4] ,aPoleWrite[nCol,3] ) ENDIF cPoleEdit := FieldGet( FIELDNUM( cPoleField ) ) //DBCommit() DBUnlock() ENDIF ELSE //MsgDebug("Line23ed()", "Set CURSOR ON","@ y, x GET cPoleEdit PICTURE cPolePict","READ") lEditField := .T. // Можно редактировать эту ячейку ! ENDIF IF lEditField // сетевой захват записи IF ( RecLock( LOCK_RETRY ) ) FieldPut( FIELDNUM( cPoleField ), cPoleEdit ) IF FIELDNUM( "KOPERAT" ) > 0 FIELD->KOPERAT := M->nOperat ENDIF //DBCommit() DBUnlock() ENDIF ENDIF ENDIF // nCol == 1 // первое поле КОД ENDIF // aPoleDost[ nCol ] == "SF", "S" ..... ENDIF IF lEditField == .F. oBrw_1:Refresh() ENDIF DoMethod( 'Form_Spr',"oBrw_1", "SetFocus" ) RETURN lEditField Только до редактирования же НЕ ДОХОДИТ !!! Я колёсиком вверх-вниз и алиас уже слетает !!! Т.е. стоя на 5-7 записях в справочнике уже видно что база отвалилась !!! Andrey пишет: Сделал новый тест в функции MyFieldEdit() до начала редактирования при слёте базы: MsgDebug(oBrw_1:nLen, ALIAS(), oBrw_1:cAlias ) MsgDebug( "RLock()=", (oBrw_1:cAlias)->(RLock()) ) Т.е. колёсиком подергал вверх-вниз на 5 записях, функция MyChangeBrowse(cAlias) показывает 0/0 начинаю редактировать: 1. MsgDebug показывает 5, "", "STREET" 2. MsgDebug показывает "RLock()=" .T. Т.е. АЛИАС по всей задачи ALIAS() = "" - убит !!! Кем ? На экране таблица есть (в объекте) а все связи разорваны ! А вот еще облом, если записей много колёсиком-мышки нужно подергать вверх-вниз (просто на экране, не на всю длину) и то же вылетает .... 0/0 записей....

Andrey: Haz пишет: в bPrevEdit тыкни MsgDebug( Alias() ) Где поставить проверку ?

Haz: Andrey пишет: Где поставить проверку ? так уже поставил , выяснил что текущий алиас меняется . поставь первой строкой в MyFieldEdit dbSelectArea("STREET")

Andrey: Haz пишет: поставь первой строкой в MyFieldEdit dbSelectArea("STREET") Понял, СПАСИБО БОЛЬШОЕ ! Только я через статик переменную это поставил в MyChangeBrowse() и в MyFieldEdit() IF LEN(ALIAS()) == 0 dbSelectArea( cStaticAliasMain ) ENDIF Спасибо БОЛЬШОЕ всем кто помогал !!!

Haz: Andrey пишет: Только я через статик переменную а лучше так dbSelectArea( oBrw:cAlias ) ты ж бровс редактируешь а в нем алиас и так есть

Andrey: Опять Как создать колонку для показа/редактирования записей из массива ? Т.е. в базе содержится поле KGROUP и взамен его значения нужно показывать значение из массива MyDimGroup() ADD COLUMN TO oBrw9 HEADER CRLF + "Группа" SIZE 150 ; ALIGN DT_CENTER,DT_CENTER,DT_RIGHT ; DATA FieldWBlock( "KGROUP", Select() ) ; // как здесь определить ? EDITABLE oBrw9:aColumns[6]:bPrevEdit := { || MyDimGroup(), FALSE } // как здесь сделать вызов ? Если делаю напрямую, без oBrw9:aColumns[6]:bPrevEdit := .... ...... EDITABLE MyDimGroup() то справочник вызывается....

Haz: Andrey пишет: Как создать колонку для показа/редактирования записей из массива Вот стандартный из TSCOLUMN для понимания как работает Function ArrayWBlock( oBrw, nEle ) Return {|x| If(PCount() > 0, oBrw:aArray[ oBrw:nAt, nEle ] := x, oBrw:aArray[ oBrw:nAt, nEle ] ) } Вообще любой блок выборки записи упрощенно работает так 1. Если ему передают параметр - присваивает значение этого параметра ( запись) 2. Если не передают - читает ( выборка ) т.е. выборка должна быть типа aArray[ Ascan( aArray, (Alias())->KGROUP )] , при этом учитывать что если не найдет - будет вылет по ошибке aArray[0] ЗЫ. Пример условный т.к. не ясно что за массив ЗЫЫ Или опять тот же совет - смотреть как используется ::SetData() в исходниках tsBrowse - 100% твой случай

Andrey: Haz пишет: Пример условный т.к. не ясно что за массив Приблизительно так: AADD( aDim, { 0 , "---" } ) AADD( aDim, { 1 , "Новичок" } ) AADD( aDim, { 2 , "Руководство" } ) AADD( aDim, { 3 , "Специалисты" } ) AADD( aDim, { 4 , "Опытные пользователи" } ) AADD( aDim, { 5 , "Администратор БД" } ) AADD( aDim, { 90, "Уволенные с фирмы" } ) AADD( aDim, { 99, "Удаленные записи" } ) FOR nI := 1 TO LEN(aDim) AADD( aCod, aDim[nI,1] ) AADD( aNum, aDim[nI,2] ) NEXT DATA FieldWBlock( "KGROUP", Select() ) ; // как здесь определить ?

Haz: для колонки 1 по полю KGROUP примерно так oBrw:SetData( 1, ComboWBlock( oBrw, "KGROUP", 1, aArr ) ) в бровсе будет отображаться значение из массива только aArr := { aNom, aCod } нужно заменить на aArr := { aCod, aNom } все ж есть в примерах

Andrey: Haz пишет: все ж есть в примерах Спасибо БОЛЬШОЕ ! Кое что не получалось.... А как назначить блок выбора из массива ? oBrw9:aColumns[6]:bPrevEdit := { || MyDimGroup(), FALSE } // как здесь сделать вызов ? Если делаю напрямую, без oBrw9:aColumns[6]:bPrevEdit := .... ...... EDITABLE MyDimGroup() то справочник вызывается....

Haz: Andrey пишет: А как назначить блок выбора из массива ? oBrw9:aColumns[6]:bPrevEdit := { || MyDimGroup(), FALSE } // как здесь сделать вызов ? А какова цель этого ^^^ ? При чем тут блок выбора и :bPrevEdit ?

Andrey: Haz пишет: А какова цель этого ^^^ ? Хочу при нажатии на этой колонке, осуществлять выбор из справочника. Я не понимаю как делать отдельный выбор (вызов функции обработки) по колонке. Для мемо-поля (или другой отдельной функции) такой вариант проходит, а для выбора из ComboWBlock( oBrw, "KGROUP", 1, aArr ) почему то нет. Вот например эти функции нормально вызываются (по клавише ENTER): oBrw9:aColumns[4]:bPostEdit := {|| SeekLogin(), FALSE } // проверка после ввода oBrw9:aColumns[7]:bPrevEdit := { || SavePassword(), FALSE } // запись пароля А так не вызывается: (почему ? ) ADD COLUMN TO oBrw9 HEADER "Группа" ; ALIGN DT_CENTER,DT_CENTER,DT_RIGHT ; EDITABLE oBrw9:aColumns[6]:bPrevEdit := { || MyDimGroup(), FALSE } // вызов справочника Нужно делать только так (без блока): ...... EDITABLE MyDimGroup() Функция MyDimGroup() - переделана из примера \MiniGUI\SAMPLES\Advanced\Tsb_config FUNCTION MyDimGroup() LOCAL nI, aDim := {}, aArr:={},aCod := {}, aNom := {} LOCAL cPCode := "KGROUP" // поле записи в базу LOCAL nVal := 6 // номер колонки в таблице AADD( aDim, { 0 , "---" } ) AADD( aDim, { 1 , "Новичок" } ) AADD( aDim, { 2 , "Руководство" } ) AADD( aDim, { 3 , "Специалисты" } ) AADD( aDim, { 4 , "Опытные пользователи" } ) AADD( aDim, { 5 , "Администратор БД" } ) AADD( aDim, { 90, "Уволенные с фирмы" } ) AADD( aDim, { 99, "Удаленные записи" } ) FOR nI := 1 TO LEN(aDim) AADD( aCod, aDim[nI,1] ) AADD( aNom, aDim[nI,2] ) NEXT aArr := { aNom, aCod } // показ справочника (вариант 1) // oBrw:SetData( nVal, ComboWBlock( oBrw, cAlias+"->"+cPName, nVal, aDim ) ) // показ справочника (вариант 2) oBrw9:SetData( nVal, NIL, aArr) oBrw9:aColumns[nVal]:lEdit := .t. // Редактирование поля nI разрешено // oBrw9:aColumns[nVal]:bEditing := { |uVar,oBrw| CreateHelpLabel(), oBrw9:aColumns[oBrw9:nCell]:oEdit:LButtonDown() } oBrw9:aColumns[nVal]:bEditing := { |uVar,oBrw| oBrw9:aColumns[oBrw9:nCell]:oEdit:LButtonDown() } oBrw9:aColumns[nVal]:bEditEnd := { |uVal,oBrw,lSave| SaveOp(uVal,lSave,cPCode) } RETURN .T.

Haz: Andrey пишет: Функция MyDimGroup() - переделана из примера С этого и надо было начинать ... (с исходника) Вот это тоже переделано от туда же -> oBrw9:aColumns[6]:bPrevEdit := { || MyDimGroup(), FALSE } Тогда какого художника там делает FALSE ? Читаем справку по TSBrowse из поставки Minigui ============== читаем ОТ сюда ======================== <bPrevEdit> ( OPTIONAL ) Code Block that will be evaluated before starting the bData editing. This Code Block combined with bPostEdit, will be of great help when need to update the variable used in the Footer of the column, without going through the entire database. It also conditions the editing during run time, if it returns a False value, then the cell editing does not take place. TSBrowse passes as parameter to this Block the value of the variable before editing. ============== читаем ДО сюда ======================== И осмысливаем почему редактирования не происходит Andrey пишет: Для мемо-поля (или другой отдельной функции) такой вариант проходит,а для выбора из ComboWBlock( oBrw, "KGROUP", 1, aArr ) почему то нет. Потому что там редактирование у тебя сделано не в самой ячейке а во внешней фунции, а непосредственного редактирования ячейки также не происходит. PS. месье знает толк в извращениях. Сначала сам себе создает проблему на ровном месте, а потом трахается с ней неделю и тже сам

Andrey: Всем привет ! Подскажите пожалуйста как сделать следующее: 1) Редактирование ячейки по формату (см.картинку) 2) При нажатие редактирования 8-строки сделать вызов отдельной функции, которая прописана в поле PICTURE ? Файл программы 2DBF.7z здесь - https://cloud.mail.ru/public/5d315f972a72/MiniGui-Error

Dima: picture "@R 9(999) 999-999-99" picture "@R 999.999.999.999.999"

Andrey: Dima пишет: picture "@R 9(999) 999-999-99" picture "@R 999.999.999.999.999" Не всё так просто. Если сразу добавить, то и отображаться так будет. А мне надо только при редактировании.

Dima: Andrey пишет: А мне надо только при редактировании. [pre2] proc main local a:=space(12) local b:=space(15) cls @ 10,10 get a picture "@R 9(999) 999-999-99" @ 11,10 get b picture "@R 999.999.999.999.999" read return [/pre2]

Andrey: Dima пишет: @ 10,10 get a picture "@R 9(999) 999-999-99" @ 11,10 get b picture "@R 999.999.999.999.999" Dima это для терминалки подойдет. А для МиниГуи нет. См. пример: Файл программы 2DBF.7z здесь - https://cloud.mail.ru/public/5d315f972a72/MiniGui-Error

Dima: Andrey Ну видать в Минигуи такие шаблоны не реализованы

Haz: Dima пишет: Ну видать в Минигуи такие шаблоны не реализованы Дима , вопрос про TsBrowse и там ( и в MiniGui ) все реализовано более того там шаблоны можно задавать не только символьной строкой , но и блоком кода ( который оценивается во время выполнения и возвращает нужную строку) Andrey Задача решается как два пальца ... ... Если нужен шаблон на просмотр и редактирование то oBrw:aColumns[x]:cPicture := "какой то шаблон" ( или := { || какой-то блок который вернет нужный шаблон } ) Если нужен особый шаблон только редактирование то перед тем как это редактирование начнется (создастся Get и получит фокус ввода ) в Классе предусмотрен блок DATA bPrevEdit // Action to be performed before editing cell. в котором можно переопределять шаблон на нужный ( не забывая его потом восстанавливать на общий для показа в блоке bPostEdit или bEditEnd ). Короче выше тут описал алгоритм , и он займет всего две строки кода :bPrevEdit := {|| :cPicture := ....} :bPostEdit := {|| :cPicture := ....} Второй вопрос (тоже bPrevEdit) уже раз сто в ветке обсуждался

Andrey: Haz пишет: Задача решается как два пальца ... Это для тебя как два пальца... А я еще не въеду в это (часть понял, часть не понял)... Из-за этого и маленький пример сделал, чтобы понять можно было бы. Если есть возможность, то большая просьба показать на этом примере как это делается. Заранее БОЛЬШОЕ СПАСИБО !

Haz: Andrey пишет: Если есть возможность, то большая просьба показать на этом примере как это делается. подмена шаблона для редактирования ( примерно так ) oBrw_2:aColumns[3]:cPicture := Replicate("X", 80) oBrw_2:aColumns[3]:bPrevEdit := { || oBrw_2:aColumns[3]:cPicture := Alltrim((Alias())->PICTURE ), .T.} oBrw_2:aColumns[3]:bPostEdit := { || oBrw_2:aColumns[3]:cPicture := Replicate("X", 80))} и что тут такого невероятного Есть правда одно НО .. нужно определиться что храним в поле PICTURE - или шаблон в виде строки ? или вызываемую функцию соответственно будет или oBrw_2:aColumns[3]:bPrevEdit := { || oBrw_2:aColumns[3]:cPicture := Alltrim((Alias())->PICTURE ), .T.} или oBrw_2:aColumns[3]:bPrevEdit := { || oBrw_2:aColumns[3]:cPicture := Alltrim(Eval((Alias())->PICTURE )), .T.}

Andrey: Haz пишет: Есть правда одно НО .. Вот и я о том же. Можно выкрутиться тогда с помощью функции без параметров - типа: MyFunc() и анализировать тогда строку на "()": oBrw_2:aColumns[3]:bPrevEdit := { || oBrw_2:aColumns[3]:cPicture := IIF(AT("()",(Alias())->PICTURE)>0, ; Alltrim(Eval((Alias())->PICTURE )),; Alltrim((Alias())->PICTURE ), .T.} Haz пишет: и что тут такого невероятного Для тебя просто, а я пока туплю, опыта нет... Спасибо БОЛЬШОЕ ! А можно скрыть показ в таблице aColumns[4] ? Т.е. типа виртуальный 4-столбец.

Andrey: Труба ! Не работает.... Опять не работает... Исправленный файл программы 2DBF.7z здесь - https://cloud.mail.ru/public/5d315f972a72/MiniGui-Error

Haz: Andrey пишет: А можно скрыть показ в таблице aColumns[4] ? Т.е. типа виртуальный 4-столбец. Что имеешь ввиду ? Есть же метод obrw:HideColumns()

Haz: Haz пишет: Труба ! Не работает.... Опять не работает... Работает oBrw_2:aColumns[3]:cPicture := Replicate("X", 80) oBrw_2:aColumns[3]:bPrevEdit := { || oBrw_2:aColumns[4]:cPicture := Alltrim((Alias())->PICTURE ), .T.} oBrw_2:aColumns[3]:bPostEdit := { || oBrw_2:aColumns[4]:cPicture := Replicate("X", 80))} 1) в момент инициализации бровса это была колонка 3 , после появилась колонка SELECTOR и твое поле стало колонкой 4 2) Выше же писал что Replicate("X", 30) это НЕ шаблон. а ФУНКЦИЯ которую надо еще и вызвать. Правильный шаблон "XXXXXXXXXXXXXXXXXXXXXXXXXXXX" ЗЫ Вообще там этот селектор и обращение к массиву aColumns по номеру не очень дружат У себя определяю в классе TSCOLUMN новое поле данных DATA cName и присваиваю ему имя поля потом индекс колонки получаю косвенно через это имя . Криво ... зато таких сюрпризов нет

Andrey: Haz пишет: Работает СПАСИБО ! 1) Понял, где пролетел. 2) Я в новой базе подправил (убрал эту функцию и поставил шаблон). Haz пишет: Вообще там этот селектор и обращение к массиву aColumns по номеру не очень дружат У себя определяю в классе TSCOLUMN новое поле данных DATA cName и присваиваю ему имя поля потом индекс колонки получаю косвенно через это имя . Криво ... зато таких сюрпризов нет А код для этого примера можешь привести ?

Haz: Andrey пишет: А код для этого примера можешь привести ? сначала FOR n := 1 TO Len(oBrw:aColumns) oCol := oBrw:aColumns[n] IF ! __objHasData(oCol, 'cName') __objAddData (oCol, 'cName' ) oCol:cName:= (oBrw:cAlias)->(Field(n)) END END потом вместо oBrw:aColumns[n] примерно так ... oBrw:aColumns[ aScan( oBrw:aColumns, {|e| е:cName == Field(n)} )) ]:cPicture := "XXX" PS писал по памяти , не проверял но смысл понятен

Andrey: Haz пишет: PS писал по памяти , не проверял но смысл понятен Спасибо !

Andrey: Haz пишет: Задача решается как два пальца ... Опять Вроде сделал, работает... Только после вызова внешней функции - вылет: Error BASE/1122 Неверный аргумент: TRANSFORM Called from TRANSFORM(0) Called from TSBROWSE:DRAWLINE(2862) Called from TSBROWSE:GOUP(6049) Called from TSBROWSE:KEYDOWN(6377) Called from TSBROWSE:HANDLEEVENT(7084) Called from EVENTS(75) Called from _DOMESSAGELOOP(0) Called from _ACTIVATEWINDOW(1374) Called from HANDBOOKS(80) Called from (b)MAIN(43) С такой ошибкой точно не справлюсь ! Исправленный исходник 2DBF-2.7z здесь - https://cloud.mail.ru/public/5d315f972a72/MiniGui-Error Может вообще обработку сделать в отдельной функции ? Типа - oBrw_2:aColumns[3]:bPrevEdit := { || MyEditCol3() } Только как в этой функции задавать форматы на обработку - не представляю.... Вообще то задачка становиться не совсем простой....

Haz: Andrey пишет: Вообще то задачка становиться не совсем простой.... задачка была и осталась примитивной : 1 перед редактированием присвоить переменной новое значение 2 после редактирования восстановить старое 3 при этом эти значения должны быть в ФОРМАТЕ ПРАВИЛЬНОГО ШАБЛОНА PICTURE ВСЕ! ошибка в программе связана с невыполнением п.3

Andrey: Haz пишет: ошибка в программе связана с невыполнением п.3 Понял. Спасибо !

Andrey: Сделал так - Работает ! oBrw_2:aColumns[3]:cPicture := Replicate("X", 180) oBrw_2:aColumns[3]:bPrevEdit := { || MyEditCol3() } oBrw_2:aColumns[3]:bPostEdit := { || oBrw_2:aColumns[4]:cPicture := Replicate("X", 180) } .......... //////////////////////////////////////////////////////////// FUNCTION MyEditCol3() LOCAL lRet := .T. , cPicture IF (Alias())->KRUN == 1 EVAL( hb_macroBlock( Alltrim( (Alias())->PICTURE ) ) ) cPicture := Replicate("X", 180) lRet := .F. ELSE cPicture := Alltrim( (Alias())->PICTURE ) ENDIF oBrw_2:aColumns[4]:cPicture := cPicture RETURN lRet Спасибо БОЛЬШОЕ Haz !

Andrey: А как сделать в этом примере, чтобы формат сразу отображался ?

Andrey: А, просто оказывается. oBrw_2:aColumns[3]:cPicture := { || Alltrim( (Alias())->PICTURE ) }

Andrey: Andrey пишет: А, просто оказывается. Не фига, не просто. После первой правки - форматы ВСЕ слетают... Как быть ?

Haz: Andrey пишет: Как быть Писать Григорию чтоб в TGetBox METHOD New вставил код if ValType( cPict ) == "B" cPict := Eval( cPict ) end ну или самому ручками т.к. TGetBox:New не понимает если пикча задана блоком, в то время как TsBrows при показе блоки глотает на ура

gfilatov2002: Haz пишет: TGetBox:New не понимает если пикча задана блоком Благодарю за наводку Поправил для следующей сборки...

Andrey: gfilatov2002 пишет: Поправил для следующей сборки... Большое СПАСИБО ! А ПОКА - какой исходник можно самому подправить и к себе в проект поставить ?

gfilatov2002: Andrey пишет: какой исходник можно самому подправить Вот этот: click here

Andrey: Спасибо БОЛЬШОЕ !!! Работает.... 2DBF-3.7z - https://cloud.mail.ru/public/5d315f972a72/MiniGui-Error

Andrey: У меня в задаче есть меню с ДВУМЯ вкладками Можно ли объект TBROWSE (созданный на 1-ой вкладке) скопировать на вторую вкладку ? PAGE ' 1-я вкладка ' DEFINE TBROWSE oBrw8 ; AT nHTabW,2 ; WIDTH 510 HEIGHT GetClientHeight(hWnd)-(nHButt-1*2) - nHTabW -3 ; ON CHANGE { || MyChangeBrowse8("oBrw8") } ; ON GOTFOCUS MyChangeBrowse8("oBrw8") ; BACKCOLOR aBackColor ; SELECTOR .T. ; CELL END TBROWSE END PAGE PAGE ' 2-я вкладка ' .............. END PAGE

Andrey: Есть ли возможность в МиниГуи копировать объект и располагать на другой форме ? Может мой вопрос неправильный, так скажите пожалуйста...

Dima: Drag and Drop что ли ?

Andrey: Dima пишет: Drag and Drop что ли ? Нет в коде. Чтобы не писать дублирующий код - типа так: PAGE ' 1-я вкладка ' DEFINE TBROWSE oBrw8 ; AT nHTabW,2 ; WIDTH 510 HEIGHT GetClientHeight(hWnd)-(nHButt-1*2) - nHTabW -3 ; ON CHANGE { || MyChangeBrowse8("oBrw8") } ; ON GOTFOCUS MyChangeBrowse8("oBrw8") ; BACKCOLOR aBackColor ; SELECTOR .T. ; CELL END TBROWSE END PAGE PAGE ' 2-я вкладка ' DEFINE TBROWSE oBrw7 ; AT nHTabW,2 ; WIDTH 510 HEIGHT GetClientHeight(hWnd)-(nHButt-1*2) - nHTabW -3 ; ON CHANGE { || MyChangeBrowse8("oBrw7") } ; ON GOTFOCUS MyChangeBrowse8("oBrw7") ; BACKCOLOR aBackColor ; SELECTOR .T. ; CELL END TBROWSE END PAGE Есть ли команды - скопировать объект и разместить на форме ?

Haz: Andrey пишет: Чтобы не писать дублирующий код оформляй его в виде функции или процедуры один раз и вызывай сколько и где хош

Andrey: А как привязать этот объект из функции на 1-ю и 2-у вкладку.

gfilatov2002: Andrey пишет: как привязать этот объект из функции на 1-ю и 2-у вкладку Посмотри рабочий пример ниже [pre]/* * MINIGUI - Harbour Win32 GUI library Demo * */ #include "minigui.ch" #include "TSBrowse.ch" #translate dbcreate(<file>, <struct>) => hb_dbcreatetemp(<file>, <struct>) Function Main dbcreate('test',{{'nazwa','C',30,0},; {'ilosc','N',12,2},; {'cena','N',14,2}}) if select('test') == 0 dbusearea(.t.,,'test') endif for i := 1 to 100 test->(dbappend()) test->nazwa := "Item " + hb_ntos(i) test->ilosc := test->(recno()) test->cena := (test->ilosc * HB_Random(100)) next test->(dbgotop()) define window tabsample at 0,0 width 400 height 300 title 'Add control test' main DEFINE TBROWSE Brw_1 AT 10, 10 OF o_dlu ALIAS "test" WIDTH 330 HEIGHT 120 ADD COLUMN TO Brw_1 DATA {|| test->nazwa } ALIGN DT_LEFT, DT_CENTER, DT_CENTER ; TITLE 'Nazwa' SIZE 100 ADD COLUMN TO Brw_1 DATA {|| test->ilosc } ALIGN DT_RIGHT, DT_CENTER,DT_CENTER TITLE 'Ilosc' SIZE 70 ADD COLUMN TO Brw_1 DATA {|| test->cena } ALIGN DT_RIGHT, DT_CENTER, DT_CENTER TITLE 'Cena' SIZE 70 Brw_1:SetColor( { 2 }, { { | | IIf( test->(OrdKeyNo()) % 2 == 0, RGB(255,255,255), RGB(230, 230, 230) ) }}) Brw_1:nHeightCell += 6 Brw_1:nHeightFoot += 4 Brw_1:nWheelLines := 1 Brw_1:nHeightHead := 14 END TBROWSE tabsample.Brw_1.Hide define tab tab1 at 10,10 width 370 height 220 define page 'Page1' define button b1 row 30 col 10 caption 'Press here to add a control' width 180 action addnewcontrols({'lbl1','text1'}) end button end page define page 'Page2' define button b2 row 30 col 10 caption 'Press here to add a control' width 180 action addnewcontrol2('Brw_1') end button end page end tab on key escape action thiswindow.release() end window tabsample.center tabsample.activate Return nil function addnewcontrols(actrl) local c1, c2 c1 := actrl[1] c2 := actrl[2] if iscontroldefined(&c1,tabsample) tabsample.&(c1).release endif define label &c1 parent tabsample row 50 col 10 width 40 value 'label' end label if iscontroldefined(&c2,tabsample) tabsample.&(c2).release endif define textbox &c2 parent tabsample row 50 col 50 width 100 end textbox tabsample.tab1.addcontrol(c1,1,84,10) tabsample.tab1.addcontrol(c2,1,80,50) return nil function addnewcontrol2(ctrl) if iscontroldefined(&ctrl,tabsample) tabsample.&(ctrl).Show endif tabsample.tab1.addcontrol(ctrl,2,80,10) return nil[/pre]

Andrey: gfilatov2002 пишет: Посмотри рабочий пример ниже А сразу объект TBROWSE на 1-ю и вторую вкладку можно разместить ? Без кнопочек открыть ?

gfilatov2002: Andrey пишет: А сразу объект TBROWSE на 1-ю и вторую вкладку Да, по команде ниже <Имя формы>.<Имя TAB>.addcontrol(<Имя TBROWSE>,<Номер вкладки TAB>,<Номер ряда>,<Номер колонки>)

Andrey: gfilatov2002 пишет: Да, по команде ниже Спасибо БОЛЬШОЕ ! Буду разбираться...

Andrey: Andrey пишет: Только до редактирования же НЕ ДОХОДИТ !!! Я колёсиком вверх-вниз и алиас уже слетает !!! Т.е. стоя на 5-7 записях в справочнике уже видно что база отвалилась !!! Andrey пишет: цитата: Сделал новый тест в функции MyFieldEdit() до начала редактирования при слёте базы: MsgDebug(oBrw_1:nLen, ALIAS(), oBrw_1:cAlias ) MsgDebug( "RLock()=", (oBrw_1:cAlias)->(RLock()) ) Т.е. колёсиком подергал вверх-вниз на 5 записях, функция MyChangeBrowse(cAlias) показывает 0/0 начинаю редактировать: 1. MsgDebug показывает 5, "", "STREET" 2. MsgDebug показывает "RLock()=" .T. Т.е. АЛИАС по всей задачи ALIAS() = "" - убит !!! Кем ? На экране таблица есть (в объекте) а все связи разорваны ! А вот еще облом, если записей много колёсиком-мышки нужно подергать вверх-вниз (просто на экране, не на всю длину) и то же вылетает .... 0/0 записей.... Возвращаюсь опять к предыдущей теме. Теперь прога стала "сваливаться" на редактирование базы, то нормально редактирует, то нет. Закономерностей нет. После некоторого анализа, дошло до меня.... После запуска программы, на главной форме я повесил таймер для перечитывания(открытие/закрытие) базы-журнала работающих в программе... Может дело в этом ?

Andrey: Haz пишет: не убит, где-то сработал Select(0) вот и стал текущим пустой алиас. На 99% уверен что если твой RecLock() вызывать из алиасного выражения STREET->(RecLock()) то ошибка уйдет. Но это костыль, а не исправление ошибки. По уму надо найти "виновника" Виновник найден ! Совсем мало прошло, чуть больше месяца....

SergKis: Простая конструкция TsBrowse не включает корректировку (удаление работает) : [pre2] @ 10,10 TBROWSE oBrw5 ALIAS "Test" OF Form_1 ; WIDTH 350 HEIGHT 380 CELLED; HEADERS "Code","First","Last","Birth","Bio" ; WIDTHS 50,150,150,100,200 ; FIELDS Test->Code,Test->First,Test->Last,Test->Birth,Test->Bio ; VALUE 1 ; BACKCOLOR YELLOW ; FONTCOLOR BLUE ; LOCK ; DELETE ; EDITABLE добавление доп. манипуляции исправляет ситуацию корректировки: k := len(oBrw5:aColumns) FOR i := 1 TO k oBrw5:aColumns[ i ]:lEdit := ( i < k ) NEXT но это лишние телодвижения ... Отключение корректировки - результат не передачи в методе Default() параметра ::lEditable h_tsbrowse.prg (line 1779) ::AddColumn( TSColumn():New( ::aHeaders[ nI ], bBlock, ::aFormatPic[nI], { ::nClrText, ::nClrPane, ; ::nClrHeadFore, ::nClrHeadBack, ::nClrFocuFore, ::nClrFocuBack }, ; {aJustify[ nI ], 1}, ::aColSizes[ nI ],::lEditable, ; // здесь не задан параметр ValType( Eval( ::bLine )[ nI ] ) == "B",,,,,,, ; 5,, {.F., .T.},, Self, cBlock ) ) [/pre2] это неточность или задумано специально ?

SergKis: SergKis пишет:{aJustify[ nI ], 1}, ::aColSizes[ nI ],::lEditable, ; // здесь не задан параметр немного промахнулся в запятых, надо так:[pre2] ::AddColumn( TSColumn():New( ::aHeaders[ nI ], bBlock, ::aFormatPic[nI], { ::nClrText, ::nClrPane, ; ::nClrHeadFore, ::nClrHeadBack, ::nClrFocuFore, ::nClrFocuBack }, ; {aJustify[ nI ], 1}, ::aColSizes[ nI ],, ; (::lEditable .or. ValType( Eval( ::bLine )[ nI ] ) == "B"),,,,,,, ; 5,, {.F., .T.},, Self, cBlock ) ) [/pre2] так работает

SergKis: Продолжаю мучить простой вариант TsBrowse, добавил [pre2] @ 10,10 TBROWSE oBrw5 ALIAS "Test" OF Form_1 ; WIDTH 350 HEIGHT 380 CELLED; HEADERS "Code","First","Last","Birth","Bio" ; WIDTHS 50,150,150,100,200 ; FIELDS Test->Code,Test->First,Test->Last,Test->Birth,Test->Bio ; VALUE 1 ; BACKCOLOR YELLOW ; FONTCOLOR BLUE ; READONLY {.T.,.T.,.T.,.T.,.F.} ; LOCK ; DELETE ; EDITABLE [/pre2] и ... упс ... READONLY подвешен в воздухе, упоминается в Function _DefineTBrowse (...) как HB_SYMBOL_UNUSED( readonly ) и все, т.е. вынесено из define ... "как трудно жить" (c), перевести простой browse, на простой TBrowse

gfilatov2002: SergKis пишет: Простая конструкция TsBrowse не включает корректировку Благодарю за помощь. Уже включил это исправление в следующую сборку

SergKis: SergKis пишет:перевести простой browse, на простой TBrowse победил так ( h_tsbrowse.prg):[pre2] Function _DefineTBrowse ( ... ) ... LOCAL i, j, k, n // BK 18.05.2015 ... if ValType(aColSel) != 'U' .and. ValType(aColSel) =='A' IF ValType(aColSel[1]) =='A' aColSel := aColSel[1] endif endif IF valtype(uWhen) == 'B' // BK 18.05.2015 IF valtype(readonly) != 'A' // readonly := eval(uWhen) // ENDIF // uWhen := Nil // иначе снятие ENDIF // IF valtype(valid) == 'B' // valid := eval(valid) // ENDIF // BK if ( FontHandle := GetFontHandle( FontName ) ) != 0 ... oBrw := TSBrowse():New( ControlName, nRow, nCol, nWidth, nHeight,; bFields, aHeaders, aWidths, ParentFormName,; change , bDblClick, bRClick, fontname, fontsize, ; hCursor, aTmpColor , aBmp, cMsg, update, uAlias, uWhen, value, cell,; nStyle, bLClick, aFlds, aHeadClick, nLineStyle, lRePaint,; Delete, aJust, lock, appendable, lEnum,; lAutoSearch, uUserSearch, lAutoFilter, uUserFilter, aPicture, ; lTransparent, uSelector, lEditable, lAutoCol, aColSel, tooltip) IF ( k := len(oBrw:aColumns) ) > 0 // BK 18.05.2015 IF valtype(readonly) == 'A' // sets oCol:bWhen n := Min(len(readonly), k) // FOR i := 1 TO n // j := readonly[ i ] // IF valtype(j) == 'B' // oBrw:aColumns[ i ]:bWhen := j // ELSEIF j == NIL .or. ! empty(j) // oBrw:aColumns[ i ]:bWhen := {||.T.} // oBrw:aColumns[ i ]:cWhen := '{||.T.}' // ELSE // oBrw:aColumns[ i ]:bWhen := {||.F.} // oBrw:aColumns[ i ]:cWhen := '{||.F.}' // ENDIF // NEXT // ENDIF // IF valtype(valid) == 'A' // sets oCol:bValid n := Min(len(valid), k) // FOR i := 1 TO n // IF valtype(valid[ i ]) == 'B' // oBrw:aColumns[ i ]:bValid := valid[ i ] // ENDIF // NEXT // ENDIF // ENDIF // BK ... ControlHandle := oBrw:hWnd IF ValType(gotfocus) != "U" ... Работает: @ 10,10 TBROWSE oBrw5 ALIAS "Test" OF Form_1 ; WIDTH 350 HEIGHT 380 CELLED; HEADERS "Code","First","Last","Birth","Bio" ; WIDTHS 50,150,150,100,200 ; FIELDS Test->Code,Test->First,Test->Last,Test->Birth,Test->Bio ; VALUE 1 ; BACKCOLOR YELLOW ; FONTCOLOR BLUE ; VALID {{|v,o| myValid(1, v, o)}, {|v,o| myValid(2, v, o)} } ; READONLY {{|o| myROnly(1, o)},.T.,.T.,.T.,.F.} ; LOCK ; DELETE ; EDITABLE @ 10,10 TBROWSE oBrw5 ALIAS "Test" OF Form_1 ; WIDTH 350 HEIGHT 380 CELLED; HEADERS "Code","First","Last","Birth","Bio" ; WIDTHS 50,150,150,100,200 ; FIELDS Test->Code,Test->First,Test->Last,Test->Birth,Test->Bio ; VALUE 1 ; BACKCOLOR YELLOW ; FONTCOLOR BLUE ; WHEN {{|o| myWhen(1, o)}, {|o| myWhen(2, o)}, {|o| myWhen(3, o)}, {|o| myWhen(4, o)}, .F.} ; VALID {{|v,o| myValid(1, v, o)}, {|v,o| myValid(2, v, o)}, , , } ; LOCK ; DELETE ; EDITABLE [/pre2]

gfilatov2002: SergKis пишет: Работает: Все хорошо, но я инвертировал в двух местах логику обработки READONLY, поскольку по определению readonly := ! eval(uWhen) Добавил такое описание в текущий changelog: [pre2] * Updated: Adaptation FiveWin Class TSBrowse 9.0 in HMG: - Fixed: EDITABLE clause at a simple TBROWSE definition is respected now. - Updated: Added implementation of READONLY and VALID clauses similar to a standard BROWSE control. Contributed by SergKis. (see proc Brw_5() at demo.prg in folder \samples\Advanced\TSBrowse) [/pre2]

Andrey: Сделал простой тестовый пример на TBROWSE из нескольких столбцов. Делаю так: oBrw9:lCellBrw := .F. // маркер на всю таблицу Как назначить ОДНУ функцию по нажатию Enter и мышки ? Маркер же большой, не известно на каком столбце стоишь.. Все остальные клавиши нужно игнорировать. Я знаю что нужно вешать обработчик, типа: oBrw9:bKeyDown := { | nKey | MyKeyAction(nKey,oBrw9, ThisWindow.Name, 0), lOk := nKey != VK_ESCAPE } oBrw9:bLDblClick:= { || MyAction(oBrw9, ThisWindow.Name, 0) } // Двойной клик мышки на МАРКЕРЕ А по другому, попроще нельзя ?

Haz: Andrey пишет: Маркер же большой, не известно на каком столбце стоишь.. есть же oBrw9:nCell в нем и стоишь .....

Andrey: Haz пишет: есть же oBrw9:nCell в нем и стоишь ..... Где прописать обработку ENTER ? Если на каждом столбце делаешь ADD COLUMN .... ...... EDITABLE то НЕТ никакой реакции на весь маркер при нажатии ENTER или мышки ! Получается только просмотр таблицы. Что нужно написать для редактирования по всему маркеру ?

SergKis: Andrey пишет: Что нужно написать для редактирования по всему маркеру ? Т.е. по нескольким колонкам, входящих в маркер ? Не пробовал, но думаю надо включить режим Cell и с нужной колонки нажать мышу для редактирования и ... после последнего редактирования Cell выклюить

Haz: SergKis пишет: то НЕТ никакой реакции на весь маркер при нажатии ENTER или мышки ! по даблклике мышки работает если обьявить при инициализации бровса DEFINE TBROWSE ... ... ON DBLCLICK DblClickProcedurе() ... END TBROWS по ENTER если изменить обработку :KeyDown() я просто добавляю в исходник метода :KeyDown() строки перед Otherwise Case !::lCellbrw .And. (nKey == 13 .Or. nKey == 32 ) If ::bLDblClick != Nil Eval( ::bLDblClick ) EndIf и получаю вызов процедуры даблклика и по ENTER и по SPACE

SergKis: Haz пишет:SergKis пишет: цитата: то НЕТ никакой реакции на весь маркер при нажатии ENTER или мышки ! это не я пишу, а Andrey. Как я понял, он имеет TsBrowse c lCell := .F. (маркер на всю строку) и при нажатии Enter или Click хочет включать корректировку как lCell := .T. с какой то определенной колонки, после всех коректировок опять lCell := .F. (маркер на всю строку) и конечно с обработкой Dn,Up,... и кликом мыши за пределами окна коректировки.

Haz: SergKis пишет: это не я пишу, а Andrey. Опять цитату не проверил , извиняюсь - конечно это к Андрею SergKis пишет: хочет включать корректировку как lCell := .T. с какой то определенной колонки возможно и так , я подумал он хочет просто подвесить вызов функции на даблклик при длинном маркере. По любому при желании и то и то выполнимо. Подсвечивать текущую колонку можно меняя цвет фона в колонке :nCell по bOnDraw

Andrey: Haz пишет: возможно и так , я подумал он хочет просто подвесить вызов функции на даблклик при длинном маркере. Да, я это имел ввиду. Haz пишет: ON DBLCLICK DblClickProcedurе() Понял, СПАСИБО ! SergKis пишет: Как я понял, он имеет TsBrowse c lCell := .F. (маркер на всю строку) и при нажатии Enter или Click хочет включать корректировку как lCell := .T. Нет ! Просто корректировку ТОЛЬКО ОДНОЙ функции ! Допустим MyEditEnter() и всё. Haz пишет: по ENTER если изменить обработку :KeyDown() Кроме как изменения :KeyDown() (это я делал, я помню) можно как то назначить обработку по ENTER или нельзя. Это как то в ON CHANGE нужно прописывать ?

SergKis: Andrey пишет:Нет ! Просто корректировку ТОЛЬКО ОДНОЙ функции ! Допустим MyEditEnter() и всё. раньше: Сделал простой тестовый пример на TBROWSE из нескольких столбцов. Делаю так: oBrw9:lCellBrw := .F. // маркер на всю таблицу Как назначить ОДНУ функцию по нажатию Enter и мышки ? Маркер же большой, не известно на каком столбце стоишь.. Если на каждом столбце делаешь ADD COLUMN .... ...... EDITABLE то НЕТ никакой реакции на весь маркер при нажатии ENTER или мышки ! Получается только просмотр таблицы. Что нужно написать для редактирования по всему маркеру ? Как написано, так и понято

Andrey: SergKis пишет: Как написано, так и понято Ну извиняюсь, за своё косноязычие...

Haz: Andrey пишет: Кроме как изменения :KeyDown( это самый простой способ. а on change отрабатывает когда меняется текущая строка

Andrey: Haz пишет: это самый простой способ. а on change отрабатывает когда меняется текущая строка Понял. Спасибо !

Andrey: Всем привет ! Как объединить в одном столбце 3 разных поля базы ?

Haz: Andrey пишет: Как объединить в одном столбце 3 разных поля базы ? :bData http://clipper.borda.ru/?1-1-0-00000427-000-10001-0-1432482733 твой пост N 4138

Andrey: Haz пишет: твой пост N 4138 Это через кодовый блок. Я это помню. bBlock := "{ || MEMOLINE("+ALIAS()+"->"+cField+","+HB_NTOS(LEN(cStr))+",1) }" oBrw:aColumns[nJ]:bData := &( bBlock ) А как написать для такой конструкции, которая в примерах (хотя потом там тоже будет кодовый блок): // создать 2-ю колонку ADD COLUMN TO oBrw3 HEADER "Номер" + CRLF + "заказа" ; DATA FieldWBlock( "NNZA", Select() ) ; PICTURE "@Z 9999/99" ; SIZE 100 ; ALIGN DT_CENTER,DT_CENTER,DT_RIGHT ; // cells, header, footer COLORS CLR_BLACK, MyRGB(aBack2) // создать 3-ю колонку ADD COLUMN TO oBrw3 HEADER "Дата" + CRLF + "заказа" ; DATA FieldWBlock( "DATEZA", Select() ) ; PICTURE "99.99.99" ; SIZE 90 ; ALIGN DT_CENTER,DT_CENTER,DT_RIGHT ; // cells, header, footer COLORS CLR_BLACK, MyRGB(aBack2) // создать 4-ю колонку ADD COLUMN TO oBrw3 HEADER "Время" + CRLF + "заказа" ; DATA FieldWBlock( "TIMEZA", Select() ) ; PICTURE "99:99" ; SIZE 80 ; ALIGN DT_CENTER,DT_CENTER,DT_RIGHT ; // cells, header, footer COLORS CLR_BLACK, MyRGB(aBack2)

Haz: Andrey пишет: А как написать для такой конструкции так и писать - через блок кода

Andrey: Сделал так: ADD COLUMN TO oBrw3 HEADER "Номер" + CRLF + "Дата" + CRLF + "Время" ; SIZE 120 ; ALIGN DT_CENTER,DT_CENTER,DT_RIGHT ; // cells, header, footer COLORS CLR_BLACK, MyRGB(aBack2) ; DATA { || TRANSFORM( (Alias())->NNZA, "9999/99" ) + CRLF + ; DTOC( (Alias())->DATEZA ) + CRLF + ; TRANSFORM( (Alias())->TIMEZA, "99:99" ) + CRLF } // multi-line feature on cells Почему то третью строчку не показывает ? Может еще что-то включить нужно ? PS. TIMEZA - это числовое поле, 4 знака чч:мм

Dima: Andrey пишет: Почему то третью строчку не показывает ? не влезла видимо , поширше сделай высоту строки.

Andrey: Dima пишет: не влезла видимо , поширше сделай высоту строки. Не знаю как ? Там только ширину можно делать: SIZE 120 Где в TBROWSE задается высота строк ?

Dima: возможно это oBrw:nHeightCell

Andrey: Dima пишет: возможно это oBrw:nHeightCell Точно ! Нашел у себя в коде, добавил 50 и всё показывается ! Спасибо Дима, выручил !

Andrey: Всем привет ! Работаю с Excel из Tbrowse. // вызов стандартой функции МиниГуи \MiniGUI\SOURCE\TsBrowse\h_tbrowse.prg &oBrw:Excel2(cFile, lActivate, NIL, "_"+Space(70)+cTitle, lSave ) Как получить высоту строки таблицы и изменить её на нужную ?

Haz: так nHeight := oSheet:Rows(1):RowHeight oSheet:Rows(1):RowHeight := 40 PS: Правда это касается Excel объекта открытого по OLE

Andrey: А как достучаться до этого oSheet: ? &oBrw:Excel2(cFile, lActivate, NIL, "_"+Space(70)+cTitle, lSave ) в этой функции Excel2() файл автоматом открывается: If lActivate ShellExecute( 0, "Open", If( lSave, cFile, cWork ),,, 3 ) EndIf Т.е. я к нему доступ уже не имею ? Как тогда поступить ?

Haz: Andrey пишет: Как тогда поступить не открывать автоматом, а просто сохранять сохраненный файл открыть олей

Andrey: Спасибо Haz ! Там еще есть интересный метод ExcelOle(). Буду пробовать его....

Haz: Andrey пишет: Там еще есть интересный метод ExcelOle() Интересен в нем подход, позволяющий существенно ускорить вывод. Сам по себе ОLE сильно задумчивый если по одной ячейке обрабатывать , этот метод работает блоками, т.е. за один вызов оля обрабатывает много ячеек. В остальном - обычная работа через олю



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