COLOR codeblock

This forum is for eXpress++ general support.
Message
Author
Janko
Posts: 111
Joined: Sat Mar 20, 2010 8:36 am
Location: Cerklje

COLOR codeblock

#1 Post by Janko »

I generate a browser using a for-next loop like in this code:

Code: Select all

 bColor:= {|| if(val(DC_GetColArray(2,oBrowse)) <val(DC_GetColArray([b]k[/b] ,oBrowse)) ,,{GRA_CLR_WHITE,GRA_CLR_DARKBLUE}  )}

for k:=3 to 14
DCBROWSECOL ELEMENT k   HEADER "Razlika v %" + aHead[k]  PARENT oBrowse  FOOTER str(k,2)   WIDTH 8  PRESENTATION  bPres ;
              EVAL { |o|o:colorBlock := bColor }  // COLOR Bcolor
 next k

Of course, this code is not working. Index 'k', which is used in color block definition (to compare the content of the cell with
DC_GetColArray(2,oBrowse) is not recognised as valid.

If each DCBROWSECOL is added line by line using hard numbers an not variable 'k', everything Works as expected.

I beleive you there is a simple solution, but I am loosing hours without succes.

Any hint is appreciated

Regards
JAnko

skiman
Posts: 1183
Joined: Thu Jan 28, 2010 1:22 am
Location: Sijsele, Belgium
Contact:

Re: COLOR codeblock

#2 Post by skiman »

Hi,

This way it should work.

Code: Select all


for k:=3 to 14
bColor:= &("{|| if(val(DC_GetColArray(2,oBrowse)) <val(DC_GetColArray("+str(k,2)+" ,oBrowse)) ,,{GRA_CLR_WHITE,GRA_CLR_DARKBLUE}  )}")
DCBROWSECOL ELEMENT k   HEADER "Razlika v %" + aHead[k]  PARENT oBrowse  FOOTER str(k,2)   WIDTH 8  PRESENTATION  bPres ;
              EVAL { |o|o:colorBlock := bColor }  // COLOR Bcolor
 next k
Best regards,

Chris.
www.aboservice.be

User avatar
rdonnay
Site Admin
Posts: 4722
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: COLOR codeblock

#3 Post by rdonnay »

Janko -

When creating code blocks in a FOR..NEXT loop that are bound to the value of k, you must "anchor" each value of k. Chris showed you that this anchoring can be done with a macro, however macro expressions require that all elements are public functions and public or private variables.

Anchoring using a Macro:

Code: Select all

bColor :=  &("{|| if(val(DC_GetColArray(2,oBrowse)) <val(DC_GetColArray("+str(k,2)+" ,oBrowse)) ,,{GRA_CLR_WHITE,GRA_CLR_DARKBLUE}  )}")
This macro technique would require that oBrowse must be a private or public variable. It cannot be local. It would also fail because the color definitions cannot be resolved by the macro compiler and converted to numeric values. Macro compiling in a loop is not advised.

A better technique is to anchor each value of k by using "detached locals". This is accomplished with a call to a function that will build the code block. All resolutions of variables, functions and defines will be accomplished by the XPP compiler rather than the macro compiler and will allow k and oBrowse to be declared as LOCAL.

Anchoring using detached locals:

Code: Select all

bColor := ColorAnchor(k,oBrowse)

STATIC FUNCTION ColorAnchor(k,oBrowse)

RETURN {|| if(val(DC_GetColArray(2,oBrowse)) <val(DC_GetColArray(k ,oBrowse)) ,,{GRA_CLR_WHITE,GRA_CLR_DARKBLUE}  )}
Also, you don't need to use the EVAL clause in your DCBROWSECOL command. Simply the COLOR bColor clause will work.

Macros have some advantages in Xbase++, but not in this case. They require that every element of the expression exist in the "symbol table". To be added to the symbol table, they must be private or public. They cannot be static or local. DC_GetColArray() is a public function, so that is not a problem. If you use the anchoring technique I advise, then any element of the expression can be static, local, public or private. Even function calls can be to static functions. This allows you to safely encapsulate your variables and functions. The XPP compiler can warn you if you make a coding error and will not allow the .EXE to be created. The macro is compiled at "runtime" and therefore coding errors are often discovered by the user of the program not the programmer. This is a bad idea.
The eXpress train is coming - and it has more cars.

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: COLOR codeblock

#4 Post by Eugene Lutsenko »

Roger and Clifford told me a long time ago how to do something like this. Everything works fine. Look for context: "Anchor" in the source test:" http://lc.kubagro.ru/__AIDOS-X.txt"

Janko
Posts: 111
Joined: Sat Mar 20, 2010 8:36 am
Location: Cerklje

Re: COLOR codeblock

#5 Post by Janko »

Dear Chris, Roger and Eugene,

it is obvious that handling macros is not so simple than I thought. I remember Chris helped me already one time.
Roger, special thanks for your simple and detailed explanation. I only write software for my bussines, I do not resell it and of course, time spent on understanding of some problems is not sufficient. Your forum is an excellent opportunity.

Eugene, thanks to you too.

Happy and healthy new year
JAnko

Janko
Posts: 111
Joined: Sat Mar 20, 2010 8:36 am
Location: Cerklje

Re: COLOR codeblock

#6 Post by Janko »

Dear Roger,

after many attempts trying to use 'anchor technique', I can't make it work as desired:

Code: Select all


 for k:=3 to 14
   bColor := ColorAnchor(k,oBrowse)
   DCBROWSECOL ELEMENT k   HEADER "Razlika v %" + aHead[k]  PARENT oBrowse  FOOTER str(k,2)   WIDTH 7  COLOR bColor

 next k

…….
STATIC FUNCTION ColorAnchor( k, oBrowse)
RETURN {|| if(val(DC_GetColArray(2,oBrowse)) < val(DC_GetColArray(k ,oBrowse)) , ,{GRA_CLR_WHITE,GRA_CLR_DARKBLUE}  )  }

or colors are not OK or runtime error is generated.

Could you be so kind to help me out?

BR JAnko

User avatar
rdonnay
Site Admin
Posts: 4722
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: COLOR codeblock

#7 Post by rdonnay »

Try this:

RETURN {|| if(val(DC_GetColArray(2,oBrowse)) < val(DC_GetColArray(k ,oBrowse)) ,{nil,nil} ,{GRA_CLR_WHITE,GRA_CLR_DARKBLUE}

If that doesn't work, then give me a sample program that I can compile and run.
The eXpress train is coming - and it has more cars.

Janko
Posts: 111
Joined: Sat Mar 20, 2010 8:36 am
Location: Cerklje

Re: COLOR codeblock

#8 Post by Janko »

Roger,

no it is not working. I'll prepare a sample.

Kind regards
Janko

Janko
Posts: 111
Joined: Sat Mar 20, 2010 8:36 am
Location: Cerklje

Re: COLOR codeblock

#9 Post by Janko »

Roger,

attached is a zip file with prg and arr( array) with data which is retrived in the begining of the program.

I hope you do no need more to test.

Kind regards
JAnko
Attachments
basicData.zip
(17.56 KiB) Downloaded 714 times

User avatar
rdonnay
Site Admin
Posts: 4722
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: COLOR codeblock

#10 Post by rdonnay »

Your problem was that the oBrowse object was not created until after the Anchoring code block was created.

Change this: bColor := ColorAnchor(k,Browse)
to this: bColor := ColorAnchor(k,@oBrowse)

Here is another method:

bColor := ColorAnchor(k)

STATIC FUNCTION ColorAnchor(k)

RETURN {|a,oColumn,oBrowse|oBrowse := oColumn:parent, ;
if(val(DC_GetColArray(2,oBrowse)) ;
<=val(DC_GetColArray(k,oBrowse)) , ;
{nil,nil},{GRA_CLR_WHITE,GRA_CLR_DARKBLUE} )}
The eXpress train is coming - and it has more cars.

Post Reply