Page 1 of 1

Colorear celdas conforme a condicion externa

Posted: Tue Nov 19, 2019 7:37 pm
by FranciscoA
Amigos del foro.
Alguien puede postear un ejemplo de como dar colores de fondo diferentes a celdas diferentes en un xBrowse con array, cuya condicion proviene de otro xBrowse/array?

Me explico: El primer xBrw/array contiene dos columnas para Valores y Colores. El segundo xBrw/array solo contiene valores.
La idea es que el Browse 2 coloree sus celdas acorde a los valores y colores en el Browse 1.

He visto en el foro bastantes ejemplos, y aunque algunos funcionan bien, no encontré ninguno con las caracteristicas que expuse, aunque he tratado de ajustarlos a mis necesidades, pero sin resultados.

Aqui expongo el codigo que estoy escribiendo. ( Auto contenido para que puedan compilarlo )

Gracias.

Code: Select all

#include "fivewin.ch"
#include "xbrowse.ch"

static aMe, aRu 

//--------------------------------------------//
FUNCTION XBrwArrays()
local NN, n, oDlg, oBrw1, oBrw2, cCol, aPos

    CreaArrays()

   DEFINE DIALOG oDlg SIZE 540,200 PIXEL

   @ 10, 10 XBROWSE oBrw1 SIZE 120,-10 PIXEL OF oDlg  DATASOURCE aRu ; 
   COLUMNS 2,3  HEADERS  "Numero", "Color" 

   oBrw1:CreateFromCode()

   @ 10, 140 XBROWSE oBrw2 SIZE 120,-10 PIXEL OF oDlg  DATASOURCE aMe ; 
   COLUMNS 1,2,3  HEADERS "Col1","Col2","Col3" ;
   CELL LINES NOBORDER

   oBrw2:nMarqueeStyle  := MARQSTYLE_HIGHLCELL
   oBrw2:lColChangeNotify := .t.

   For NN := 1 to 2
      For n := 1 to len(oBrw2:aCols)
         if !Empty(oBrw2:aCols[n]:Value)
            oBrw2:aCols[n]:bClrStd := ColorCelda( oBrw2, n )
         endif
      Next 
      oBrw2:GoDown()
   Next 
   oBrw2:CreateFromCode()

   ACTIVATE DIALOG oDlg 
Return nil

//--------------------------------
Function ColorCelda(oBrw2, n)
local uValue, nPos, ncNum, cClr, nColor

   uValue := oBrw2:aCols[n]:Value
   nPos:= aScan(aRu, { | a | a[2] == uValue } )
   ncNum := aRu[nPos,2] 
   cClr  := aRu[nPos,3] 

   if cClr == "VERDE"
      nColor := RGB(0, 215, 0)
   elseif cClr == "ROJO"
      nColor := RGB(225, 0, 0)
   elseif cClr == "NEGRO"
      nColor := RGB(0, 0, 0)
   endif
 
RETURN {|| { CLR_WHITE, nColor } }

//-----------------------------
Function CreaArrays()
local n, aNms, aClr

  aNms := {'1', '2', '3', '4', '5'}
  aClr := {'V', 'N', 'R', 'V', 'R'}
  aRu := {} 

  For n := 1 to Len(aNms)
      aadd( aRu, {,,} )
      aRu[n,1] := n                                     
      aRu[n,2] := aNms[n]                               
      aRu[n,3] := if(upper(aClr[n]) ="V","VERDE" ,;     
                  if(upper(aClr[n]) ="R","ROJO"  ,;
                  if(upper(aClr[n]) ="N","NEGRO",)))
  Next

   aMe := Array(2)
   aMe[1] := {'1',  '2',  ''} 
   aMe[2] := {'3',  '4',  '5'} 

Return nil

 
Saludos.

Re: Colorear celdas conforme a condicion externa

Posted: Tue Nov 19, 2019 8:24 pm
by cnavarro
Y si intentas construir el codeblock "a mano"?, algo asi
Ojo con el Str( nColor )

Code: Select all


RETURN &("{|| {  " + Str( Rgb( 255, 255, 255 ) ) + ", " + Str( nColor ) + " } } " )
 

Re: Colorear celdas conforme a condicion externa

Posted: Tue Nov 19, 2019 8:39 pm
by FranciscoA
cnavarro wrote:Y si intentas construir el codeblock "a mano"?, algo asi
Ojo con el Str( nColor )

Code: Select all


RETURN &("{|| {  " + Str( Rgb( 255, 255, 255 ) ) + ", " + Str( nColor ) + " } } " )
 
Cristobal, gracias por tu pronta respuesta.
Lamentablemente se obtiene el mismo resultado: Aunque pinta las celdas, no lo hace con los colores correctos.
Por ejemplo, el color definido para el 1 es verde, y lo pinta en rojo, el 2 es negro y lo pinta en verde, etc.
Un abrazo.

Code: Select all

//--------------------------------
Function ColorCelda(oBrw2, n)
local uValue, nPos, ncNum, cClr, nColor

   uValue := oBrw2:aCols[n]:Value
   nPos:= aScan(aRu, { | a | a[2] == uValue } )
   ncNum := aRu[nPos,2] 
   cClr  := aRu[nPos,3] 

   if cClr == "VERDE"
      nColor := RGB(0, 215, 0)
   elseif cClr == "ROJO"
      nColor := RGB(225, 0, 0)
   elseif cClr == "NEGRO"
      nColor := RGB(0, 0, 0)
   endif
 
//RETURN {|| { CLR_WHITE, nColor } }
RETURN &("{|| {  " + Str( Rgb( 255, 255, 255 ) ) + ", " + Str( nColor ) + " } } " )
 

Re: Colorear celdas conforme a condicion externa

Posted: Tue Nov 19, 2019 8:41 pm
by cnavarro
Lo primero es que compruebes ( con un FWLOG por ejemplo ) que los valores de colores que devuelve son los correctos
Ojo, en lugar de usar variables estáticas para el array de colores, utiliza el propio aArrayData de oBrw1, porque si en el xbrowse oBrw1, se ha hecho el AUTOSORT automáticamente te vas a volver loco

Code: Select all

oBrw2:aCols[n]:bClrStd := ColorCelda( oBrw1, n )
 

Re: Colorear celdas conforme a condicion externa

Posted: Tue Nov 19, 2019 10:12 pm
by FranciscoA
Cristobal.
Me he dado cuenta, que el color es correcto, y que aunque identifica bien la celda y la pinta con el color correcto, siempre pinta toda la columna con el ultimo color obtenido.
Eso hace que parezca que no pinta con el color correcto, pero si lo hace, pero sobre-escribe todas las celdas anteriores.
Continuaré mañana.
Saludos.

Re: Colorear celdas conforme a condicion externa

Posted: Thu Nov 21, 2019 3:29 pm
by leandro
Francisco Una idea
Image

Code: Select all

#include "fivewin.ch"
#include "xbrowse.ch"

static aMe, aRu

//--------------------------------------------//
FUNCTION XBrwArrays()
local NN, n, oDlg, oBrw1, oBrw2, cCol, aPos

    CreaArrays()

   DEFINE DIALOG oDlg SIZE 540,200 PIXEL

   @ 10, 10 XBROWSE oBrw1 SIZE 120,-10 PIXEL OF oDlg  DATASOURCE aRu ;
   COLUMNS 2,3  HEADERS  "Numero", "Color"

   oBrw1:CreateFromCode()

   @ 10, 140 XBROWSE oBrw2 SIZE 120,-10 PIXEL OF oDlg  DATASOURCE aMe ;
   CELL LINES NOBORDER
   oBrw2:nMarqueeStyle  := MARQSTYLE_HIGHLCELL
    oBrw2:lColChangeNotify := .t.      

    oCol  = oBrw2:AddCol()
    oCol:bStrData := {|| if(Len( aMe ) > 0 , Transform(aMe[oBrw2:nArrayAt][1],"9") ,"" ) }
    oCol:cHeader  = "Col1"
    oCol:nWidth   = 30
    oCol:nHeadStrAlign = AL_LEFT
    oCol:nDataStrAlign = AL_LEFT    
    oCol:bClrStd      = {|| {CLR_WHITE,ColorCelda(aMe[oBrw2:nArrayAt][1])}  }
    
    oCol  = oBrw2:AddCol()
    oCol:bStrData := {|| if(Len( aMe ) > 0 , Transform(aMe[oBrw2:nArrayAt][2],"9") ,"" ) }
    oCol:cHeader  = "Col2"
    oCol:nWidth   = 30
    oCol:nHeadStrAlign = AL_LEFT
    oCol:nDataStrAlign = AL_LEFT    
    oCol:bClrStd      = {|| {CLR_WHITE,ColorCelda(aMe[oBrw2:nArrayAt][2])}  }

    oCol  = oBrw2:AddCol()
    oCol:bStrData := {|| if(Len( aMe ) > 0 , Transform(aMe[oBrw2:nArrayAt][3],"9") ,"" ) }
    oCol:cHeader  = "Col3"
    oCol:nWidth   = 30
    oCol:nHeadStrAlign = AL_LEFT
    oCol:nDataStrAlign = AL_LEFT    
    oCol:bClrStd      = {|| {CLR_WHITE,ColorCelda(aMe[oBrw2:nArrayAt][3])}  }

   oBrw2:CreateFromCode()

   ACTIVATE DIALOG oDlg
Return nil

//--------------------------------
Function ColorCelda(n)
local uValue, nPos, ncNum, cClr, nColor

    n := val(n)
   if n == 1 .OR. n ==4
      nColor := RGB(0, 215, 0)
   elseif n == 3 .OR. n ==5
      nColor := RGB(225, 0, 0)
   else
      nColor := RGB(0, 0, 0)
   endif
 
RETURN nColor

//-----------------------------
Function CreaArrays()
local n, aNms, aClr

  aNms := {'1', '2', '3', '4', '5'}
  aClr := {'V', 'N', 'R', 'V', 'R'}
  aRu := {}

  For n := 1 to Len(aNms)
      aadd( aRu, {,,} )
      aRu[n,1] := n                                    
      aRu[n,2] := aNms[n]                              
      aRu[n,3] := if(upper(aClr[n]) ="V","VERDE" ,;    
                  if(upper(aClr[n]) ="R","ROJO"  ,;
                  if(upper(aClr[n]) ="N","NEGRO",)))
  Next

   aMe := Array(2)
   aMe[1] := {'1',  '2',  ''}
   aMe[2] := {'3',  '4',  '5'}

Return nil

 

Re: Colorear celdas conforme a condicion externa

Posted: Thu Nov 21, 2019 4:09 pm
by FranciscoA
leandro wrote:Francisco Una idea
Image

Code: Select all

#include "fivewin.ch"
#include "xbrowse.ch"

//--------------------------------
Function ColorCelda(n)
local uValue, nPos, ncNum, cClr, nColor

    n := val(n)
   if n == 1 .OR. n ==4
      nColor := RGB(0, 215, 0)
   elseif n == 3 .OR. n ==5
      nColor := RGB(225, 0, 0)
   else
      nColor := RGB(0, 0, 0)
   endif
 
RETURN nColor

 
Hola Leandro.
Muchas gracias por tu atención.
Efectivamente así funciona, ya lo había probado de esa manera. El caso es que, tanto los colores como los datos pueden ser muchos.
Lo que necesito es automatizarlo.

Ya lo he conseguido, aunque a medias, conforme a mi necesidad original, pero ahora se presenta otro caso extraño con el que estoy "peleando":
CASE uDato $ "0;00;1;2;3;4;5;6;7;8;9;10;11;12"...etc
El caso es que los datos son tipo caracter, y unicamente coloca bien el color cuando el dato es de 2 caracteres. Los de 1 caracter lo colorea incorrectamente.
Estoy en eso.

Gracias nuevamente.

Re: Colorear celdas conforme a condicion externa

Posted: Thu Nov 21, 2019 4:23 pm
by leandro
que bueno francisco ...

y su pruebas con la función strzero()

Re: Colorear celdas conforme a condicion externa

Posted: Thu Nov 21, 2019 4:36 pm
by FranciscoA
Leando.
Pruebo y mas tarde te comento.
Saludos.

Re: Colorear celdas conforme a condicion externa

Posted: Thu Nov 21, 2019 8:02 pm
by FranciscoA
Cristobal, Leandro.
Esta es mi solucion; espero le sea util a otros colegas.

Code: Select all

#include "fivewin.ch"
#include "xbrowse.ch"

STATIC aMe, aRu

//--------------------------------------------//
FUNCTION XBrwArrays()
local n, oDlg, oBrw1, oBrw2

   CreaArrays()

   DEFINE DIALOG oDlg SIZE 540,200 PIXEL

   @ 10, 10 XBROWSE oBrw1 SIZE 120,-10 PIXEL OF oDlg  DATASOURCE aRu ; 
   COLUMNS 2,3  HEADERS  "Numero", "Color" 

   oBrw1:nRowHeight := 24
   oBrw1:CreateFromCode()

   @ 10, 140 XBROWSE oBrw2 SIZE 120,-10 PIXEL OF oDlg  DATASOURCE aMe ; 
   COLUMNS 1,2,3  HEADERS "Col1","Col2","Col3" ;
   CELL LINES NOBORDER

   oBrw2:nMarqueeStyle  := MARQSTYLE_HIGHLCELL
   oBrw2:nRowHeight := 30

   for n := 1 to Len( oBrw2:aCols )
      oBrw2:aCols[ n ]:bClrStd := ColorCelda( oBrw2, n )
   next

   oBrw2:CreateFromCode()

   ACTIVATE DIALOG oDlg 
Return nil

//-----------------------------------------------------//
function ColorCelda( oBrw, n )
return {|| SeleccClr( oBrw:aRow[ n ] )  }

//-----------------------------------------------------//
function SeleccClr( uDato )
   local n, cClr:="", nClrBkg, nClrTxt := RGB(255,255,255)   //Blanco

   for n := 1 to len(aRu)
      if aRu[n,2] == uDato
         cClr := aRu[n,3] 
         exit
      endif
   Next
  
   if cClr == "VERDE"
      nClrBkg := RGB(0, 215, 0)
   elseif cClr == "ROJO"
      nClrBkg := RGB(225, 0, 0)
   elseif cClr == "NEGRO"
      nClrBkg := RGB(0, 0, 0)
   else
      nClrBkg := GetSysColor( 5 )
   endif

return { nClrTxt, nClrBkg }

//-----------------------------
Function CreaArrays()
local n, aNms, aClr 

  aNms := {'1', '2', '3', '4', '5','10','11'}
  aClr := {'V', 'N', 'R', 'V', 'R', 'V', 'R'}
  aRu := {} 

  For n := 1 to Len(aNms)
      aadd( aRu, {,,} )
      aRu[n,1] := n                                     
      aRu[n,2] := if(len(aNms[n])=1, aNms[n]+" ", aNms[n]) 
      aRu[n,3] := if(upper(aClr[n]) ="V","VERDE" ,;     
                  if(upper(aClr[n]) ="R","ROJO"  ,;
                  if(upper(aClr[n]) ="N","NEGRO",)))
  Next

   aMe := Array(3)
   aMe[1] := {'1 ',  '2 ',  '  '} 
   aMe[2] := {'3 ',  '4 ',  '5 '} 
   aMe[3] := {'5 ',  '10',  '11'} 

Return nil
 
Saludos.