Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Change Browe() Color Cell ? 1

Status
Not open for further replies.

olivvv

Programmer
Dec 6, 2022
8
FR
Hi everyone,

Is it possible to change a cell color after validate a cell with the browse() function ? (or the header ? )

I don't find it.


Thank you
Olivier L
 
I would recommend using a grid rather than a BROWSE function.

Although you can change the colors with something like this.

Code:
PUBLIC goForms
goForms = CREATEOBJECT("collection")


BROWSE NAME oBrowse nowait
goForms.add(oBrowse)
oBrowse.BackColor = RGB(255,0,0) 
obrowse.ForeColor=rgb(129,129,0)

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Hello Olivier and welcome to the forum.

I agree with Mike G. about using a grid rather than a browse. Not only does it give you a lot more control, it is also the more "visual" way of doing things.

In general, you can control the colours (foreground and background) of entire columns. To do that with a grid, use the column's ForeColor and BackColor properties.

If you want to change the colours of individual cells within a column, you would use the column's DynamicBackColor and DynamicForeColor properties. The idea here is that you specify a condition, and the cells within the column will then display the chosen colours, depending on whether the condition is true. So for example you could set cells that fail your validation test to appear in red.

See the VFP Help topic on DynamicBackColor and DynamicForeColor for more information.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi,

thank you for your quick response.

I have used Browse() because it was a small need. and client didn't want to pay a lot.

I know, now, that it is limited and i could tell the client .
If he wants more : we have to use a normal grid (and the form) and it will take more time :)

thank you :)
Olivier L
 
Yes, it may be true it could take more time, but you can always charge it to self-education. Learning how to use a grid could be very useful in your future projects.

Feel free to come back if you have any specific questions re the Dynamic properties or other aspects of the grid control.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi olivvv,

welcome to the forum from me, too.

I don't know, if I get the gist, you seem to be familiar with a browse and therefore used it. And now that people suggest the grid, you'd tell the customer it's possible with a grid, but that will cost more?

Actually a browse is a grid. Let me just pick up where Mike Gagnon left:

Code:
use some.dbf
Browse name oBrowse nowait
oBrowse.Top = 50
oBrowse.Left = 50
oBrowse.Column1.Backcolor = Rgb(200,200,255)
? oBrowse.Class && prints "Grid" on the screen

Once you give your BROWSE a name with the NAME clause of the browse command, you unlock all further inner structre and features of the browse, that are available as grids, because it is a grid.

So in part you already know the grid, as you know the browse, and in part you don't know everything about browse, because you don't know it is a grid.

I know, it's always easier to make a price for a job you well know how to do, or you already did and can simply take from out of your portfolio, adjusted to another customer. But be real, it will cost more and take more time, because you need to learn how to do it, no matter if you now stay with the BROWSE code and use the knowledge it is in fact a grid, or switch to a form with a grid, which you can even extend with further controls and which makes no secret of its inner workings as the BROWSE does.

Let me end it this way: Please tell me one thing you know well how to do with BROWSE and don'T think forms with grids are able to do as well? I'm not fully covered because a browse is a grid, you might know command options of the browse that are lost in old documentation or undocumented and that enable things I'd need to look into myself.


Chriss
 
To get to the core of your question, to color cells individually, you can't do this directly, as a browse and a grid don't have the cells concept a spreadsheet has, a browse or grid has the DynamicBackcolor and that can be an expression. That expression in the simplest case would need to return a different color for every recno, for example this could do it:

Code:
oBrowse.Column1.DynamicBackColor="icase(recno()=1,colro1,recno()=2,color2,....)"
Obviously that's not working for very many recnos and you'd need to adapt this expression everytime a new recno is added.

It would be nicer, if it came from data, too, wouldn't it? If you double the columns of your data and reserve one for the cell color, i.e. you have table.field1,field2,field3 for data and table.color1,color2,color3 for colors, then each cell can get its color from the table, just like the data displayed comes from it, you just set
Code:
oBrowse.Column1.DynamicBackColor="table.color1"
oBrowse.Column2.DynamicBackColor="table.color2"
oBrowse.Column3.DynamicBackColor="table.color3"
...
Because very column has its Dynamicbackcolor and now uses a different field of the table, the table data dettermines the text and the colors. The field types would need to be integer and the values to store are just what RGB(r,g,b) returns.

And now the color fields determine the backcolor. That wold be the most gerenal way, but still quite unpractical, because of all the extra fields needed in the DBF.

I bet your idea is it would be as simple as setting some cell(row,col).color=rgb(r,g,b), but that's not available. You can perhaps find expressions that work simpler and don't need data for every single cell, an expression could make the color of a row in an amount column depend on whether the amount is positive (green) or negative (red):
Code:
oBrwose.Column3.DynamicBackColor="IIF(amount<0,rgb(255,0,0),rgb(0,255,0))"

That's how that's usually used and not for individual colors.

Chriss
 
@chris

thanks, i didn't know the browse function is a grid :)


"And now that people suggest the grid, you'd tell the customer it's possible with a grid, but that will cost more?"

yes, it is an existing project with forms.

But sometimes, they have to override some values before save it (they work directly in the DBF) .

I propose to quickly make a function to filter data (set filter to) and simplify when they want to change a value. (before this, they manually open the DBF .. search the line and manually modify the value )

They just ask me if it would great to have a different colot when they validate a modification in a cell of the browse() .

I say i will search if it would be easy to make it (because i had no idea)


Olivier L









 
Well, Oliver.

You could stick to BROWSE - which still is a command and not a function, unless you use a function that in the end executes a BROWSE command.

Or you can add a grid to the forms you already use.

And to just oclor one cell, well, think about what expression you need: grid.columnX.dynamicbackcolor="IIF(recno()=N,rgb(...the color you want...),rgb(255,255,255))".

You can use that after you know which recno N you want in which color.

I still don't get what you mean by

olivvv said:
it would great to have a different colot when they validate a modification in a cell
The user modifies a cell value, that's validated (literally by the textbix.valid method. I don't think you mean that.
Do users want to see cells they changed colored?

Then this expression would highlight that, if you start using buffering in your tables/cursors/workareas:
Code:
grid.columnX.dynamicbackcolor = "IIF(GetFldState("field","alias")=1,RGB(255,255,255),RGB(...highlightcolor...))"

The field state which GetFldState retrns is a number, you get an overview of the meaning of these values in the help about the GetFldState() function, but in short 1 is for no change and anything else is a change in some way.

But all that is only available when you use so called buffering. And that's described here:

Chriss
 
If thats what they want, just a personal opinion - nobody needs to agree - ADHD on the rise. If you don't even remember whether you made a change to what is displayed or what change you made, then I begin to pray for humanity. I hope you're after something else.

Is it a novel feature and easy enough to do? Yes, in grids that have no danymic coloring already it's easy to bring up. Is it useful? Really for those users who don't know what they did 5 seconds ago it could be useful. No text editor I know has this feature of highlighting text you change or add. They have another feature though, if you CTRL+Z you can cancel the last modification and CTRL+Y redaaplies it, i.e. you have a modification history. That actually is more useful in many situations, even if you want to keep what you wrote and just add back what you overwrote, you can copy the current text, undo changes until you see the old text again and then paste in the new text.

This would be something worth programming, it sure isn't as easy as using GETFLDSTATE(), though, or OLDVAL(), you would need to store a history of values to not just have one undo step, but many undo steps.

Chriss
 
Chriss said:
No text editor I know has this feature of highlighting text you change or add.

Actually, word processors have this and they call it revision marks. It's really handy.

I can see how it's useful in data entry. When you're working in a browse/grid, it's easy to make a mistake and then you're trying to figure out what you did. Having changed values colored differently would definitely be useful in that setting.

Tamar
 
Tamar,

I agree, I also know the mode of Word to show edits. But when you'd talk about that, it would usually be one Editbox in VFP that's either all white (no change) or all highlighted (changed) and you'd need to go deeper into it to make a useful highlight of an edit history.

If I shorten the expression (regarding the colors) for readability to [tt]IIF(GetFldState("field","alias")=1,white,highlightcolor)[/tt], you can also generalize the parameters "field" to be the conrolsource of that column and "alias" to be the grid.recordsource. You can preset that once and it will automatically become active, once you use buffering, table buffering at best, of course.

Chriss
 
And Tamar,

revisions are rather about editing history and not just the bufferchanges. To be able to see revisions of data, I find color highlightings second best choice. First you do audit trail, for example with DBC triggers, and I know you wrote about this, and then you can show a whole section of data the way it evolved, with which edits made by which users, perhaps, if you record that in your triggers in data history tables. But VFP has nothing like that atomatic, so you have to implement a data history.

That possibility also exists, olivvv, by using a DBC and insert/update/delete triggers, which are automatically called when any kind of insert/update/delete runs, not the SQL queries only, those triggers also react to browse edits and replace or append commands, but only if dbfs are part of a DBC and you defeine these triggers with CREATE TRIGGER.



Chriss
 
I might be wrong, but I think what Olivier wants is to change the colour of the cell if it fails a validation test, not simply if the value has changed.

That said, I can see the value of changing the colour of every changed cell, at least during the period between entering the value and committing the changes. This is especially true in a grid / browse, as you can sometimes lose sight of what you have changed as you scroll the grid.

(Personally, I never use a grid for directly editing data, but that's a topic for another day.)

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike,

the literal quote is (and it's not well translated obviously):
olivvv said:
when they validate a modification in a cell of the browse

They, being the users.

I already gave the feedback, that if you talk about the term validation, the technical background in VFP is that it validates input in the control.valid() event, and not users validate something. But he might not talk about the VFP technical term of validation.

I can only speak of experience, in many companies it's a workflow that important persons have to approve of something. Well, if that's the mechanism you want to highlight then I'd put up the name of approvers so far.

All in all we still don't really know what olivv wants or needs, i guess, but coloring a cell is involved and your best way to do this is making use of DanymicBackcolor in any way that is appropriate. By this technical mean of Dynamicbackcolor, it's not a natural to color individual cells by cell positions, it's a natural to color cells by condition, so find the condition you want to use to color the cell and youre good, that's the most general advice I can give about that.

But as fas as we're lost in translation this may never see the usual resolution of a thread.

Chriss
 
And just a an anecdote: In several cases I had to do this approval scheme even completely outside of the major FoxPro applications, as a mail process. Those important persons don't go into an application that's for their employees.

Chriss
 
I might be wrong, but I think what Olivier wants is to change the colour of the cell if it fails a validation test, not simply if the value has changed."


my english is not as good as i want :p

they would be no validation test. they just want to verify they don't forget to modify a cell before quiting the grid :).

 
Do they edit exactly one column?

There would be an easy interfacce for users to see what rows they already processed:
Give them a value to modify and a copy of that in the next column to it, where they edit it. So they see old vs new value side by side.
And then you could use DanamicBackcolor = "IIF(editfield==origfield,RGB(255,255,255),RGB(200,255,200))" so every value they changed in the field editfield becomes green.

You can make the origfield column readonly, so they can only edit the new one. And then as aftermath you bring their changes back to where they should be stored.

Chriss
 
No, they may modify several columns.

thanks for the idea :)
 
I concluded one column, because if its multiple columns, what is the actual goal to edit? All cells? An indicator will only help if it helps you see whether you made all necessary changes. So now I begin to think you could color the cells that need changes and make them white/neutral, when the change is made.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top