Форум » 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:....

Ответов - 300, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 All

Andrey: Опять непонятки... Делаю: [pre2] AEval(oBrw1:aColumns, {|oCol| oCol:nClrBack := { |a,b| MyColorTsb(a,b) } } ) .... //////////////////////////////////////////////////////////// STATIC FUNCTION MyColorTsb(nA,nB) .... nColCount := oBrw1:nColCount() ? "a,b=(",nA,nB,")", "nColCount=", nColCount[/pre2] Получаю:[pre2] a,b=( 1 18 ) nColCount= 18 a,b=( 1 2 ) nColCount= 18 a,b=( 1 3 ) nColCount= 18 a,b=( 1 4 ) nColCount= 18 a,b=( 1 5 ) nColCount= 18 a,b=( 1 6 ) nColCount= 18 a,b=( 1 7 ) nColCount= 18 a,b=( 1 8 ) nColCount= 18 a,b=( 1 9 ) nColCount= 18 a,b=( 1 10 ) nColCount= 18 a,b=( 1 11 ) nColCount= 18 a,b=( 1 11 ) nColCount= 11 a,b=( 1 1 ) nColCount= 11 a,b=( 1 2 ) nColCount= 11 a,b=( 1 3 ) nColCount= 11 a,b=( 1 4 ) nColCount= 11 a,b=( 1 5 ) nColCount= 11 a,b=( 1 6 ) nColCount= 11 a,b=( 1 7 ) nColCount= 11 a,b=( 1 8 ) nColCount= 11 a,b=( 1 9 ) nColCount= 11 a,b=( 1 10 ) nColCount= 11[/pre2] У меня таблица из 11 колонок. Откуда берётся 18 ?

SergKis: Andrey пишет nColCount := oBrw1:nColCount() У меня таблица из 11 колонок. Откуда берётся 18 ? метод простой METHOD nColCount() INLINE Len( ::aColumns )

Andrey: SergKis пишет: метод простой METHOD nColCount() INLINE Len( ::aColumns ) А почему он сначала выдает 18 ? У меня 11 колонок в таблице. Кажется, я понял почему у меня 18 столбцов сначала выдаёт ! Я же таблицу пере создаю на основе готовой: [pre2]oBrw1:DeleteRow( .T. ) // Delete All oBrw1:aArray:={} // очистить массив[/pre2] Первоначально таблица была из 18 столбцов. Т.е. этот параметр нужно тоже где-то переопределять в исходниках h_tbrowse.prg Григорий посмотри пожалуйста, где его нужно переопределить до выхода новой версии !


SergKis: Andrey :Reset()

Andrey: SergKis пишет: :Reset() Делаю. Не срабатывает !

Haz: Andrey пишет: Я же таблицу пере создаю на основе готовой: oBrw1:DeleteRow( .T. ) // Delete All oBrw1:aArray:={} // очистить массив Не надо ничего переопределять в новой версии , надо пересоздавать таблицу ( как бы это сказать ... по литературно ) ... творчески от того что ты в бровсе убил все строки и массив данных, количество колонок в нем не изменится. Андрюха, тебя уже пятый год посылают исходники глянуть, хотя бы ознакомительно . в следующий раз так переопределишь таблицу по DBF и будешь удивляться кто тебе базу грохнул

Haz: Чуть дополню Andrey пишет: oBrw1:DeleteRow( .T. ) // Delete All oBrw1:aArray:={} // очистить массив ну во первых ::DeleteRow(.T.) для бровса по массиву сам делает ::aArray := {} т.е. вторая строка бессмысленна. во вторых ::DeleteRow(.T.) при бровсе по массиву проверяет длину этого массива и если она нулевая восстанавливает пустую строку ::aArray := { AClone( ::aDefValue ) } ( это чтоб не было ошибки времени исполнения при доступе к массиву по индексу ). всякие ::aArray := {} как недокументированные инструменты бровса желательно использовать когда есть понимание как это работает, для остальных есть только методы класса. К слову сказать ::DelColumn() и тот не трогает ::aArray, так как считает это источником данных ( иначе при бровсе по базе надо было бы в базе удалять поле ... ). ну и ради чего я это написал , ради следующего предложения Перед использованием любого метода желательно влезть в исходники и посмотреть что этот метод делает , а перед использованием недокументированных возможностей в исходники лезть обязательно. Тем более, что скорее всего какая то часть кода выльется в пример для новичков. Новичкам будет крайне неприята потеря данных из-за копирования стиля из примера.

Andrey: Haz пишет: ну во первых ::DeleteRow(.T.) для бровса по массиву сам делает ::aArray := {} т.е. вторая строка бессмысленна. Не согласен с этим. Сам налетел на эти грабли. Если делаешь перечитку массива без удаления/создания нового, таблица добавляется, т.е. старые элементы остаются. Григорий предложил oBrw1:aArray:={} // очистить массив и добавление прекратилось. Если не веришь, то могу пример сделать и показать как это происходит. Haz пишет: во вторых ::DeleteRow(.T.) при бровсе по массиву проверяет длину этого массива и если она нулевая восстанавливает пустую строку ::aArray := { AClone( ::aDefValue ) } ( это чтоб не было ошибки времени исполнения при доступе к массиву по индексу ). Да это есть такое. Все пытался убрать это при перечитывании массива. В исходнике увидел и понял, что первую строчку не удалить. А всё таки после перечитки массива, oBrw:nColCount() на первом шаге возвращает 18 колонок (из старого массива), а потом нормально показывает 11. Вот листинг: [pre2] // ---- cтавим по всем колонкам ----( oCol:nClrBack = oBrw:SetColor( {2} ...) ---- AEval(oBrw1:aColumns, {|oCol| oCol:nClrBack := { |nr,nc,ob| MyColorTsb(nr,nc,ob) } } ) //////////////////////////////////////////////////////////// STATIC FUNCTION MyColorTsb( nAt, nCol, oBrw) LOCAL nColor, nColCount := oBrw:nColCount() ? nAt, nCol,"nColCount=",nColCount --------------------------------------- 1 18 nColCount= 18 1 2 nColCount= 18 1 3 nColCount= 18 1 4 nColCount= 18 1 5 nColCount= 18 1 6 nColCount= 18 1 7 nColCount= 18 1 8 nColCount= 18 1 9 nColCount= 18 1 10 nColCount= 18 1 11 nColCount= 18 1 11 nColCount= 11 1 1 nColCount= 11 1 2 nColCount= 11 1 3 nColCount= 11 1 4 nColCount= 11 [/pre2]

Haz: Andrey пишет: Если не веришь, то могу пример сделать и показать как это происходит Я тебе верю. Но в исходнике метода написано ::aArray := {} при ::DeleteRow(.T.) и исходникам я тоже верю. Так же верю что в случае с DBF ::DeleteRow() вызывает dbDelete() со всеми вытекающими. По этому, для переопределения бровса этот метод слишком рискован, надо понимать что он делает. Сам подход в снаряду не верен. Как ранее писал Сергей, самое простое это релизннуть бровс и создать новый. Но раз легкие пути не для нас, то начинать надо с изучения что делает с бровсом :: SetArray (), как устанавливаются при этом внутренние переменные, как назначаются ::nLen, ::aColumns, ::aDefValues. В случае с DBF ::cAlias, ::bLogicPos и ещё куча всего. Только после этого все корректно переопределять. Рубить сразу ::aArray := {}, а остальное само рассосётся это костыли, которые всегда ломаются в самый нужный момент. Это и есть причина твоих 18. По параметрам в MyColorTsb() вижу что ты изучил таки тему и понял что их в nClrBack должно быть три и разобраться какие. Значит не зря. Шахматку мог бы и не постить, понимая что за параметры ждёт блок, задача уже решена. Если хочешь сделать действительно стоящий пример, то избавься от костылей. К сожалению с телефона я тебе помочь не могу. После праздников выйду на работу, гляну на компе. Но уверен ты и сам справишся

Andrey: Haz пишет: По параметрам в MyColorTsb() вижу что ты изучил таки тему и понял что их в nClrBack должно быть три и разобраться какие. Значит не зря. Шахматку мог бы и не постить Параметры понял, не понял почему nColCount := oBrw:nColCount() , а дальше пошла у меня фигня от этого... Шахматку, сознаюсь не одолел - Сергей помог. Я там такой алгоритм фиговый писал, а обошлось всего 2 доп.IF Haz пишет: самое простое это релизннуть бровс и создать новый. Да это я понял. Но пример насчёт этого всё равно сделаю, уже придумал какой.

Haz: Andrey пишет: е понял почему nColCount := oBrw:nColCount() , а дальше пошла у меня фигня Затрахался на смарте пример набирать. Не проверял разумеется. Взял за основу тест Григория. В примере тупо подмена массива в бровсе. При простом переприсвоении ::aArray был бы вылет по типам данных. Здесь надеюсь все работает. [pre2] #include "minigui.ch" #include "tsbrowse.ch" Procedure Main () Public oBrw1 Public aDatos_origen DEFINE WINDOW Form1 ; AT 0,0 ; WIDTH 640 ; HEIGHT 480 ; TITLE "TsBrowse Array Test" ; MAIN ; FONT 'Tahoma' SIZE 9; ON INIT Sample1() END WINDOW ACTIVATE WINDOW Form1 RETURN *-------------------------------------------------------------- Function Sample1() Local bColor := { || If( Val(oBrw1:aArray[oBrw1:nAt,4]) < 200, CLR_RED, CLR_WHITE ) } Local aNew := {} Local lNew := .T. aDatos_origen := {} AADD( aDatos_origen, {"Ena ", "Art01", "Mod01", "200"} ) AADD( aDatos_origen, {"Dyo ", "Art02", "Mod01", "200"} ) AADD( aDatos_origen, {"Tria ", "Art03", "Mod01", "200"} ) AADD( aDatos_origen, {"Tessera ", "Art04", "Mod01", "200"} ) AADD( aDatos_origen, {"Pente ", "Art05", "Mod01", "200"} ) AADD( aDatos_origen, {"Exi ", "Art06", "Mod01", "200"} ) AADD( aDatos_origen, {"Epta ", "Art07", "Mod01", "200"} ) AADD( aDatos_origen, {"Okto ", "Art08", "Mod01", "200"} ) AADD( aDatos_origen, {"Ennea ", "Art09", "Mod01", "100"} ) AADD( aDatos_origen, {"Deka ", "Art10", "Mod02", "200"} ) AADD( aDatos_origen, {"Enteka ", "Art11", "Mod02", "200"} ) AADD( aDatos_origen, {"Dodeka ", "Art12", "Mod02", "200"} ) AADD( aDatos_origen, {"Dekatria ", "Art13", "Mod02", "200"} ) AADD( aDatos_origen, {"Dekatessera ", "Art14", "Mod02", "200"} ) AADD( aDatos_origen, {"Dekapente ", "Art15", "Mod02", "200"} ) AADD( aDatos_origen, {"Dekaexi ", "Art16", "Mod02", "200"} ) AADD( aDatos_origen, {"Dekaepta ", "Art17", "Mod02", "200"} ) AADD( aDatos_origen, {"Dekaokto ", "Art18", "Mod02", "200"} ) AADD( aNew, {"A1", "B1", .T., "D1", 1 , date() } ) AADD( aNew, {"A2", "B2", .F., "D2", 2 , date() } ) AADD( aNew, {"A3", "B3", .F., "D3", 3 , date() } ) AADD( aNew, {"A4", "B4", .T., "D4", 4 , date() } ) AADD( aNew, {"A5", "B5", .F., "D5", 5 , date() } ) AADD( aNew, {"A6", "B6", .T., "D6", 6 , date() } ) AADD( aNew, {"A7", "B7", .F., "D7", 7 , date() } ) AADD( aNew, {"A8", "B8", .T., "D8", 8 , date() } ) DEFINE TBROWSE oBrw1 ; AT 60,10 ; OF Form1 ; WIDTH 530 ; HEIGHT 340 ; FONT "Verdana" ; SIZE 9 ; GRID oBrw1:SetArray( aDatos_origen ) ADD COLUMN TO TBROWSE oBrw1 ; DATA ARRAY ELEMENT 1; TITLE "Rubro" SIZE 120 ADD COLUMN TO TBROWSE oBrw1 ; DATA ARRAY ELEMENT 2; TITLE "Articulo" SIZE 80 ADD COLUMN TO TBROWSE oBrw1 ; DATA ARRAY ELEMENT 3; TITLE "Marca" SIZE 80 ADD COLUMN TO TBROWSE oBrw1 ; DATA ARRAY ELEMENT 4; TITLE "M" SIZE 30 ; COLORS CLR_BLACK, bColor oBrw1:lNoVScroll := .t. End TBROWSE oBrw1:Refresh(.T.) @ 10,455 BUTTON Button_1 OF Form1; CAPTION "Change"; ACTION { || Change( IF( lNew, aNew, aDatos_origen ), lNew := !lNew ) }; WIDTH 80; HEIGHT 28 ; FONT "Arial" SIZE 9 RETURN Nil Function Change( aArray ) local aHead := {} local aSize := {} AEVAL( oBrw1:aColumns, {|oCol, x| AADD( aSize, oBrw1:aColSizes[x] ), AADD( aHead, oCol:cHeading ) } ) oBrw1:aColumns := {} oBrw1:aArray := {} if Len(aHead) < Len(aArray[1]) while Len(aHead) < Len(aArray[1]);aadd( aHead, "");end else while Len(aHead) > Len(aArray[1]); hb_ADel( aHead, len(aHead), .T.);end end oBrw1:SetArray( aArray, .T., aHead, aSize ) oBrw1:Reset() Return Nil [/pre2] Такой же фокус можно делать с подменой рабочей области используя ::SetDbf()

Andrey: Haz СПАСИБО ! Я глянул пример, пытался подключить свою ситуацию, не получилось. Не так ты делаешь, в смысле ты правильно делаешь, а мой подход к снаряду отличается от твоего. Буду свой пример делать, только не просто так, а жизненный, по работе. Доделаю только ещё другой и займусь.

Andrey: В SetArrayTo() делаю экспорт в Excel через &oBrw:Excel2(...) Символьные поля в Экселе появляются нормально, а цифирь нет. Как так ? Или что-то с форматом цифр не то ? Блин... Опять те же Нашёл свой комментарий в MiniGUI\SAMPLES\Advanced\Tsb_config2 [pre2] //IF aPole[nI,6] <> "N" // не использовать шаблон для числовых полей, т.к. // при печати в Excel поле будет пустое !!! // oBrw:aColumns[nJ]:cPicture := aPole[nI,4] // шаблон колонки //ENDIF[/pre2] И как тогда делать ?

Haz: Andrey пишет: И как тогда делать Не пользоваться :Excel2() Метод хоть и интересный по скорости, но на деле на короткой выгрузке теряет все преимущества. Как альтернатива можно использовать как минимум 5 способoв 1. Это просто OLE. Из минусов только скорость выгрузки. Остальные способы соизмеримы по скорости с :Excel2() 2. Тот же OLE с использованием вариантного массива 3. Выгружать через ADO 4. Писать сразу в xml формат ( Excel его прекрасно понимает) 5. Испльзовать специальную библиотеку ( есть здесь на форуме ссылка)

Andrey: Спасибо Haz !

Andrey: Пока обошёлся так (если кому интересно): При построении массива для SetArrayTo()[pre2] FOR nI := 1 To oBrw:nColCount() .... IF ValType(Eval(oBrw:aColumns[ nI ]:bData)) == "N" oBrw:aColumns[ nI ]:cDataType := 'N' // не использовать шаблон для числовых полей, oBrw:aColumns[ nI ]:cPicture := '' // т.к. при экспорте в Excel поле будет пустое !!! ELSE oBrw:aColumns[ nI ]:cPicture := aPict[ nI ] ENDIF ....[/pre2] Работает отлично ! Блин, а нельзя из Fivewin тиснуть экспорт в Эксель и прикрутить к МиниГуи ?

SergKis: Haz пишет Не пользоваться :Excel2() Если метод есть, надо что бы работал или убирать. Предложение, что бы работал Excel2 такие (в моей версии работает)[pre2] METHOD Excel2( cFile, lActivate, hProgress, cTitle, lSave, bPrintRow ) CLASS TSBrowse ... nOldCol := ::nCell Local nCntCols := ::nColCount(), oCol, ; aFntLine := array(nCntCols), ; aFntHead := array(nCntCols), ; aFntFoot := array(nCntCols) Default nInstance := 0 ... CursorWait() For i := 1 To nCntCols oCol := ::aColumns[ i ] aFntLine[ i ] := oCol:hFont aFntHead[ i ] := oCol:hFontHead aFntFoot[ i ] := oCol:hFontFoot If HB_ISBLOCK(oCol:hFont) oCol:hFont := hFont EndIf If HB_ISBLOCK(oCol:hFontHead) oCol:hFontHead := hFont EndIf If HB_ISBLOCK(oCol:hFontFoot) oCol:hFontFoot := hFont EndIf Next ::lNoPaint := .F. ... hFont := ::aColumns[ nCol ]:hFontHead If hFont != Nil aFontTmp := GetFontParam( hFont ) IF AScan( aFont, {|e| e[ 1 ] == aFontTmp[ 1 ] .and. e[ 2 ] == aFontTmp[ 2 ] .and. ; e[ 3 ] == aFontTmp[ 3 ] .and. e[ 4 ] == aFontTmp[ 4 ] .and. ; e[ 5 ] == aFontTmp[ 5 ] .and. e[ 6 ] == aFontTmp[ 6 ] } ) == 0 AAdd( aFont, aFontTmp ) endif EndIf hFont := ::aColumns[ nCol ]:hFontFoot If hFont != Nil aFontTmp := GetFontParam(hFont) IF AScan( aFont, {|e| e[ 1 ] == aFontTmp[ 1 ] .and. e[ 2 ] == aFontTmp[ 2 ] .and. ; e[ 3 ] == aFontTmp[ 3 ] .and. e[ 4 ] == aFontTmp[ 4 ] .and. ; e[ 5 ] == aFontTmp[ 5 ] .and. e[ 6 ] == aFontTmp[ 6 ] } ) == 0 AAdd( aFont, aFontTmp ) endif EndIf Next If Len( aFont ) > 4 ASize( aFont, 4 ) EndIf ... For nRow := 1 To ( ::nLen ) ... For nCol := 1 To Len( ::aColumns ) uData := If( ValType( ::aColumns[ nCol ]:cHeading ) == "B", ; Eval( ::aColumns[ nCol ]:cHeading, nCol, Self ), ; ::aColumns[ nCol ]:cHeading ) If ValType( uData ) != "C" Loop EndIf ... Next If ::lDrawFooters For nCol := 1 To Len( ::aColumns ) uData := If( ValType( ::aColumns[ nCol ]:cFooting ) == "B", ; Eval( ::aColumns[ nCol ]:cFooting, nCol, Self ), ; ::aColumns[ nCol ]:cFooting ) If ValType( uData ) != "C" uData := " " EndIf uData := Trim( StrTran( uData, CRLF, Chr( 10 ) ) ) nAlign := Min( LoWord( ::aColumns[ nCol ]:nFAlign ), 2 ) nAlign := If( Chr( 10 ) $ uData, 4, nAlign ) hFont := ::aColumns[ nCol ]:hFontFoot aFontTmp := GetFontParam( hFont ) nFont := AScan( aFont, {|e| e[ 1 ] == aFontTmp[ 1 ] .and. e[ 2 ] == aFontTmp[ 2 ] .and. ; e[ 3 ] == aFontTmp[ 3 ] .and. e[ 4 ] == aFontTmp[ 4 ] .and. ; e[ 5 ] == aFontTmp[ 5 ] .and. e[ 6 ] == aFontTmp[ 6 ] } ) FWrite( nHandle, BiffRec( 4, uData, nLine - 1, nCol - 1, .T., nAlign + 1,, ; Max( 0, nFont - 1 ) ) ) If hProgress != Nil If nCount % nEvery == 0 SendMessage(hProgress, PBM_SETPOS, nCount, 0) EndIf nCount ++ EndIf Next ++nLine EndIf FWrite( nHandle, BiffRec( 10 ) ) FClose( nHandle ) For i := 1 To nCntCols oCol := ::aColumns[ i ] oCol:hFont := aFntLine [ i ] oCol:hFontHead := aFntHead [ i ] oCol:hFontFoot := aFntFoot [ i ] Next If hProgress != Nil SendMessage(hProgress, PBM_SETPOS, nTotal, 0) EndIf ... [/pre2]

Haz: SergKis пишет: метод есть, надо что бы работал Сергей, метод работает. Я о том что просто не пользуюсь им. т. к бровс у меня всегда по базе, то выгружаю из базы а не из бровс объекта. Для прямой выгрузки идеально подходит ADO, и быстро и с названием колонок русскими словами. Для отчёта в Excel Оля с вариантным массивам и быстро и красоту навести можно.

Andrey: Haz пишет: Для отчёта в Excel Оля с вариантным массивам и быстро и красоту навести можно. Что то я сомневаюсь что быстро написать можно... Быстро не у всех получается. Может класс такой в исходники добавить можно ? Это было бы хорошее подспорье для всех. Как правило отчёты бывают небольшие через SetArrayTo(), Оля с ними быстро справиться.

Andrey: SergKis пишет: Предложение, что бы работал Excel2 такие (в моей версии работает) Я за добавление этого в исходники ! Григорий, посмотри это пожалуйста.



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