color in grid

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

franco
Posts: 200
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 6 times

color in grid

Post by franco » Sun Oct 01, 2017 7:21 pm

I have a inventory order system.... In the order table I have a field SIZE.... This is used to order package sizes.
On my editing grid I have a cell called SIZE.
What I would like to do is in my savecell function, set this cell to a different color when the SIZE > 1.
Should be easy but can not figure out.
Thanx in advance .... Franco ;)

User avatar
BeGeS
Posts: 85
Joined: Fri Jul 14, 2017 10:45 am
DBs Used: DBF
Location: La Mancha, Spain
Has thanked: 16 times
Been thanked: 17 times

Post by BeGeS » Sun Oct 01, 2017 7:43 pm

The Grid control is one of many topics that I have not yet touched on my "path of studies". :mrgreen:

But, despite my inexperience, I would suggest you try the DinamicBackColor property. Maybe that's what you're after.

You can find examples in the folder \samples\controls\grid
I get by with a little help from my friends

User avatar
mol
Posts: 2841
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 118 times
Been thanked: 64 times
Contact:

Post by mol » Mon Oct 02, 2017 5:41 am

aBColors := array(nColumnCount)
aFill(aBColors, NIL)
aBColors[nSizeColumnIndex] := {|| if this.value>1, YELLOW, RED) }

Remember to add aBColors to DynamicBackColor property of grid

franco
Posts: 200
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 6 times

Post by franco » Wed Oct 04, 2017 5:55 pm

Still can not get it.
If I have 3 cells in grid. ITEM COST SIZE
grid onchange ch()

function ch
if size > 1
thiscell backcolor := red
else
thiscell backcolor := (180,180,200) ... original color
endif
return

Another problem I see is when I use on change it will go to the ch function as many times as it returns to the grid and the next cell columnwhen
is .T. . It can keep looping though the ch function untill end of cell line.
I think this happens because on return the values have changed so there is another on change. This could also cause large grids to be slow .
How can I just make It go to ch just once and return with the grid updates.
I may have create a sample if I have not explained this properly.
Franco ;)

User avatar
mol
Posts: 2841
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 118 times
Been thanked: 64 times
Contact:

Post by mol » Wed Oct 04, 2017 8:27 pm

You can't change color within onchange event.
Simply, create array of color blocks, in these blocks you will check cell walue and return requested color.

User avatar
andyglezl
Posts: 839
Joined: Fri Oct 26, 2012 7:58 pm
Location: Guadalajara Jalisco, MX
Has thanked: 7 times
Been thanked: 22 times
Contact:

Post by andyglezl » Thu Oct 05, 2017 3:34 am

Hello Franco
This is an excerpt from a routine I have where I use DYNAMICBACKCOLOR ...


fColor := { || if ( This.CellRowIndex/2 == int(This.CellRowIndex/2) , IF( DELETED() , CLRERROR , WHITE ) , IF( DELETED() , CLRERROR , NJAPAST ) ) }
AFILL( afColor, fColor )
DYNAMICBACKCOLOR afColor


Code: Select all

FUNCTION Modifica_DB( )
	LOCAL nCpos := LEN( aCpos1 ), aReadOnly := ARRAY( nCpos ), afColor := ARRAY( nCpos ), aColCtrls := { }, aColWhen := ARRAY( nCpos )
	LOCAL fColor  := { || if ( This.CellRowIndex/2 == int(This.CellRowIndex/2) , IF( DELETED() , CLRERROR , WHITE ) , IF( DELETED() , CLRERROR , NJAPAST ) ) }
	PRIVATE lDel := .F., cWinName, cCtrolName
	
	AFILL( aReadOnly, .F. )
	AFILL( aColWhen, { | | .T. } )
	AFILL( afColor, fColor )
	FOR i1 = 1 TO nCpos
		IF aTips[ i1 ] = "N"
			IF aDec[ i1 ] = 0
				AADD( aColCtrls, { 'TEXTBOX', 'NUMERIC', '9,999,999' } )
			ELSE
				AADD( aColCtrls, { 'TEXTBOX', 'NUMERIC', '9,999,999.99' } )
			ENDIF
		ELSEIF aTips[ i1 ] = "D"
			AADD( aColCtrls, { 'DATEPICKER', 'DROPDOWN' } )
		ELSEIF aTips[ i1 ] = "L"			
			AADD( aColCtrls, { 'CHECKBOX' , '  Si' , '  No' } )			
		ELSEIF aTips[ i1 ] = "C"			
			AADD( aColCtrls, { 'TEXTBOX', 'CHARACTER' } )
		ELSEIF aTips[ i1 ] = "M"			
			AADD( aColCtrls, { 'TEXTBOX', 'CHARACTER' } )			
		ENDIF
	NEXT
	
	DEFINE WINDOW Form_GridCtes AT 0 , 0 WIDTH 1024 HEIGHT 600 TITLE '| ABC CLIENTES |' MODAL NOSIZE ON RELEASE ( SET( _SET_DELETED, .T. ), Form_Main.Restore )  ;
			BACKCOLOR { 0, 33, 38 }  ON INTERACTIVECLOSE ( IF( MSGYesNo( "Desea Guardar los"+CRLF+"útimos cambios ?", "A V I S O" ), Press2Keys( VK_ALT, VK_S ), nil ) )

		@ 005 , 005 LABEL LB_CodNom OF Form_GridCtes VALUE '' WIDTH 1024 HEIGHT 18 FONT "Verdana" SIZE 12 FONTCOLOR WHITE 		BACKCOLOR { 0, 33, 38 }
		@ 005 , 870 LABEL LB_Activo OF Form_GridCtes VALUE '' WIDTH 140  HEIGHT 18 FONT "Verdana" SIZE 10 FONTCOLOR YELLOWGREEN BACKCOLOR { 0, 33, 38 } RIGHTALIGN

		aColWhen[ 1 ] := { | | .F. }	// El primer campo es READONLY
		@ 030 , 005 GRID   Grid_2 OF Form_GridCtes WIDTH 1008 HEIGHT 505 FONT "Consolas" SIZE 11 FONTCOLOR BLACK  							;
					ROWSOURCE "Ctes" VALUE { 1, 1 } WIDTHS aLong HEADERS aCpos1 COLUMNFIELDS aCpos2 COLUMNCONTROLS aColCtrls				; 
					ON HEADCLICK { { || Ctes->( DBSetOrder( 1 ), DoMethod( 'Form_GridCtes', "Grid_2", "Refresh", .T. ) ) },  ;
								   { || Ctes->( DBSetOrder( 2 ), DoMethod( 'Form_GridCtes', "Grid_2", "Refresh", .T. ) ) } }	;
					EDIT ALLOWAPPEND ALLOWDELETE EDITOPTION GRID_EDIT_DEFAULT	    														;	// INSERTCHAR
					COLUMNWHEN aColWhen	DYNAMICBACKCOLOR afColor 	ON CHANGE OnChangeGrid( )	ON KEY OnDeleteGrid( )	ON SAVE OnSaveGrid( )

See \HMG\3.4.4\SAMPLES\Controls\Grid\GRID_40
Andrés González López
Desde Guadalajara, Jalisco. México.

User avatar
serge_girard
Posts: 1838
Joined: Sun Nov 25, 2012 2:44 pm
DBs Used: 1 MySQL - MariaDB
2 DBF
Location: Belgium
Has thanked: 278 times
Been thanked: 63 times
Contact:

Post by serge_girard » Thu Oct 05, 2017 7:34 am

Hi Franco,

I use this construction :

Code: Select all

DEFINE GRID Grid_1
   ROW 10
   COL 10
   WIDTH  560
   HEIGHT 700
   HEADERS {'Col 1',"Col 2", "Col 3 ", "Col 4", "Col 5" } 
   WIDTHS  { 120,      80,           80,        130,    130  } 
   JUSTIFY {GRID_JTFY_LEFT, GRID_JTFY_LEFT, GRID_JTFY_LEFT, GRID_JTFY_LEFT, GRID_JTFY_LEFT   }  
   DYNAMICBACKCOLOR  { { || BC_Grid_1()}, {||BC_Grid_1()}, {||BC_Grid_1()}, {||BC_Grid_1()}, {||BC_Grid_1()}} 
   ITEMS aFLD
END GRID     


STATIC FUNCTION BC_Grid_1()
/*****************************/
LOCAL a
LOCAL aColors  := {{ HONEYDEW, HONEYDEW, HONEYDEW, HONEYDEW, HONEYDEW  } }  // EQUAL TO NUMBER OF COLUMNS == 5
LOCAL aItem    := Form_1.Grid_1.Item ( This.CellRowIndex )


DO CASE 
 
CASE 'someval'  $ UPPER(aItem [2]) .OR. 'anothervalue'  $ UPPER(aItem [1]) 
   FOR a = 1 TO 4
      aColors [1] [a] := PaleTurquoise  
   NEXT a

CASE 'zzzzz'  $ UPPER(aItem [2])  
   FOR a = 1 TO 3
      aColors [1] [a] := RosyBrown  
   NEXT a

CASE 'y1'  $ UPPER(aItem [2])  .OR. 'y2'  $ UPPER(aItem [2]) .OR. 'y3'  $ UPPER(aItem [2]) 
   aColors [1] [2] := Gold  

CASE 'z1'  $ UPPER(aItem [1])  .and. 'z2'  $ UPPER(aItem [2])  
   aColors [1] [2] := Gold  
   aColors [1] [4] := Gold  

OTHERWISE
   RETURN Greenish
ENDCASE

This will allow you to manipulate every condition !
Satisfaction guaranteed

Serge

Serge

franco
Posts: 200
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 6 times

Post by franco » Sat Oct 07, 2017 7:41 pm

Serge, I am lost here. I tried your sample but it is using an array where I use fields.
I am not sure how to get field unit_price value to check for zero then change only it`s background color.

Code: Select all

#include "hmg.ch"

Function Main
	PRIVATE BCOLOR
	FILS()
	set century on
	bColor := { || if ( This.CellRowIndex/2 == int(This.CellRowIndex/2) ,(BLUE), (PURPLE))}

	*IF .NOT. ISWINDOWACTIVE(FORM_2)
		DEFINE WINDOW Form_2 ;
		AT 110, 10 ;			
		WIDTH 1250 ;				
		HEIGHT 700 ;		
		TITLE 'Sales Report Screen' ;			
		MAIN ;
		NOSIZE 	;     
		ON RELEASE {||{Closer2fils()}}  
		
		
			DEFINE TEXTBOX TEXT_1 	
			ROW 150
			COL 280
			WIDTH 200 
			HEIGHT 20 
			UPPERCASE .T.
			FIELD TEMP5->DESC 
			
		END TEXTBOX

		DEFINE GRID Grid_2
			ROW	200
			COL	30        //140
			WIDTH 1190         //1100
			HEIGHT 200    //370
			*//BACKCOLOR  { 180, 180, 200}
			FONTCOLOR  { 0, 0, 0 }	
			HEADERS {"Invoice", "Item" ,"Sellprice","Desc"}
			COLUMNCONTROLS { {'TEXTBOX','CHARACTER',"!!!!!!!!"},{'TEXTBOX','CHARACTER',"!!!!!!!!!!!!!!!"},;
							{'TEXTBOX','NUMERIC','9999999.99'},{'TEXTBOX','CHARACTER',"!!!!!!!!!!!!!!!!!!!!!!!!!!"}}
			WIDTHS {80, 95, 100 ,150}
			JUSTIFY {0,0,1,0}
			COLUMNWHEN { { || .T. },{ || .T. }, { || .T. }, { || .T. }}
			ROWSOURCE 'temp5'  
			COLUMNFIELDS { 'INV_NO' , 'ITEM_NO','UNIT_PRICE','DESC'}
			VALUE {1,1}
			ONCHANGE BC_Grid_1()
			DYNAMICBACKCOLOR  {BCOLOR,BCOLOR,BCOLOR,BCOLOR}
			DYNAMICFORECOLOR  { { || BLACK}, {|| BLACK}, {|| BLACK}, {|| BLACK}} 
			ALLOWEDIT .T.
			CELLNAVIGATION .T.
			TABSTOP .F.
			*ON CHANGE CH()
		
		END GRID
 
		END WINDOW
		
		
		Form_2.Activate
		
	RETURN //NIL
*********************************************************

	

	Function Fils
		Local CF1 := {}
		CF1 := {}
		aADD(CF1,{'INV_no' , 'C' , 8,0})
		AADD(CF1,{'ITEM_NO', 'C' , 15,0})
		Aadd(CF1,{'DESC',   'C', 26,0})
		Aadd(CF1,{'UNIT_PRICE', 'N' , 10,2})

		if ! hb_dbcreatetemp("temp5", cf1)
			msgbox("Cannot create temporary table: Item")
			RELEASE WINDOW ALL
			return nil
		endif
		if select("temp5") = 0
			use temp5 new
		endif
		select temp5 
		index on inv_no to temp5
		temp := 1
		do while temp < 51
			append blank
			replace inv_no with 'IN'+alltrim(str(temp+1000))
			replace item_no with 'IT'+alltrim(str(temp+100))
			replace unit_price with temp*100
			replace desc with 'DESC '+STR(TEMP)
			temp:=temp+1
			loop
		enddo
		return

	Function CloseR2fils

		close temp5
		release temp5
	
	return

	STATIC FUNCTION BC_Grid_1()
*****************************
**** ??????????????? i AM LOST HERE
IF UNIT_PRICE = 0
*????????MAKE ONLY IT`S IT`S BACKCOLOR GREEN ?????????
ENDIF
RETURN

Thanks in advance ..... Franco ;)
Last edited by franco on Tue Oct 10, 2017 12:05 am, edited 1 time in total.

User avatar
dragancesu
Posts: 457
Joined: Mon Jun 24, 2013 11:53 am
DBs Used: DBF, MySQL, Oracle
Location: Subotica, Serbia
Has thanked: 3 times
Been thanked: 67 times

Post by dragancesu » Sat Oct 07, 2017 10:06 pm

Try this

Code: Select all

#include "hmg.ch"

Function Main

    bColor4 := { || if ( unit_price < 1000, RED, WHITE ) } 
    fColor4 := { || if ( unit_price < 1000, YELLOW, BLACK ) }

	use temp5 
	
	DEFINE WINDOW Win_1 ;
		WIDTH 1000 ;
		HEIGHT 700 ;
		TITLE 'Sales Report Screen' ;
		MAIN 

      @ 90, 10 BROWSE Browse_1 ;
         OF Win_1 ;
         WIDTH 800 ;
         HEIGHT 400 ;
         FONT "Arial" ; 
         SIZE 10 ;
         HEADERS { "INV_NO","ITEM_NO","DESC","UNIT_PRICE" } ;
         WIDTHS { 90,160,270,110 } ;
         WORKAREA TEMP5 ;
         FIELDS { "INV_NO","ITEM_NO","DESC","UNIT_PRICE" } ;
         DYNAMICBACKCOLOR { ,,, bColor4 } ;
         DYNAMICFORECOLOR { ,,, fColor4 } ;
         JUSTIFY { , , , BROWSE_JTFY_RIGHT, } 

		END WINDOW
		
		Win_1.Center
		Win_1.Activate
		
RETURN 

franco
Posts: 200
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 6 times

Post by franco » Sun Oct 08, 2017 9:18 am

This works great, but I can not get it to work with a grid.
What I need is a table not an array in a grid.
Serges idea works good but I can not get it to work with a table not an array.
Thanx .. Franco

Post Reply