×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

How to populate grid rows with array
2

How to populate grid rows with array

How to populate grid rows with array

(OP)
Hello colleagues!

How can I populate rows in a grid with an array of values, like in the picture bellow:





Thank you,
SitesMasstec

RE: How to populate grid rows with array

Recordsourcetype tells you there is no way to populate a grid with an array, or even many.

You can define a cursor, though, and set controlsources to (Item(RECNO("alias"))) or (med(RECNO("alias"))).

Bye, Olaf.

RE: How to populate grid rows with array

And, having created the cursor, you can fill it with the array values as follows:

CREATE CURSOR csrGrid (Item I, Med I)
APPEND FROM ARRAY laMyArray
THISFORM.Grid1.RecordSource = "csrGrid"


then as per Olaf's code for setting the ControlSources.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: How to populate grid rows with array

Well,yes. Actually by using the controlsources the way I descibed you just use the line number to address array elements.

It's okay to simply append the array into the cursor and then disregard the array, it's harder to merge two array this way.

But you might actually like to display how arrays changes without rewriting code acting on the arrays to act on a cursor instead. There is a difference in displaying array elements vs copying them into a cursor.

Bye, Olaf.

RE: How to populate grid rows with array

That's not a problem if the grid is read-only. But if the grid is meant to update the array, you would have to copy the cursor back to the array (which you can do using SELECT * FROM csrGrid INTO MyArray).

And in that case, you wouldn't need to explicitly set the control sources (assuming that the columns of the grid map one-to-one with the colunmns of the array). It would be enough to set the RecordSource.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: How to populate grid rows with array

You're misunderstanding. The way I proposed an update of the array would reflect in the grid, not the grid would update the array. You still don't see what I did, The controlsource I propose fill the grid cells with array items from the array itself, not with cursor record fields. And changing the array would change the grid (with refresh). Also: The screenshot shows two arrays are used to populate columns. That's not solvable with a single APPEND FROM ARRAY.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)
Hello colleagues!

I followed Olaf's advice in the first answer to this post and I got the Grid populated witrh data from a table, so at first my problem was solved.

But as I need to use array as I deepen in the whole problem, I searched in the Kilofox, and found a whole chapter dedicated to it, and as Tamar named the chapter "Grids: The Misunderstood Controls", and "What's New in Nine" book provided no further info about Grid, I've decided to abandon Grid and use Text controls instead:



Thanks for all your help.
SitesMasstec

RE: How to populate grid rows with array

You most likely only got to the level of the grid, you have to set individual controlsources of the columns to get the arrays displayed:
Maybe you also fail on arrays scope, if your arrays are local, they only exist during the method you create them.

Here's a demo:

CODE

#Define cnSize  3
PUBLIC ARRAY item[cnSize]
PUBLIC ARRAY med[cnSize]

CREATE CURSOR crsGrid (c1 c(1),c2 c(1))
FOR lnCnt = 1 TO cnSize
    APPEND BLANK
ENDFOR
GO TOP

item[1] = "item1"
item[2] = "item2"
item[3] = "item3"

med[1] = "med1"
med[2] = "med2"
med[3] = "med3"

_screen.AddObject("Grid1","Grid")
_screen.Grid1.recordsource = "crsGrid"
_screen.Grid1.column1.width=100
_screen.Grid1.column1.controlsource = '(item(RECNO("crsGrid")))'
_screen.Grid1.column2.width=100
_screen.Grid1.column2.controlsource = '(med(RECNO("crsGrid")))'
_screen.Grid1.Visible = .t. 

What's true is, this is using very much trickery to get this to work.
It's 10 times easier to populate a grid with a cursor, why don't you put your data into a cursor? It's the natural way to use VFP, not arrays.

Bye, Olaf.

RE: How to populate grid rows with array

The most important question I have is: Where are your arrays coming from? If you create them manually as I did, it's even shorter to define a cursor and populate it's two columns with the data you want to show, as I already said and as my sample code shows you need a cursor anyway, with the number of records you want to show. There is no other way to get three grid rows but having three records in a cursor the grid is bound to.

I would, for example, use this, if I need to show data from an OLE Object array property that's controlled by the OLE control and would likely change during its usage to not need a cursor I would need to sync with all actions, that happen in the OLE array. As said it is quite some trickery, you do need a cursor with the right amount of records and need to override what the grid puts as column controlsources automatically when you assign the cursor as recordsource. Then you need to know about a glitch of the controlsource with expressions, that are not simply field names.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)
Hi, Olaf!

Quote (Olaf)


Where are your arrays coming from?
My array will come from a table, with just one record:


This table will be used to populate PART of a Grid in a Form.

The the user clicks on Med field, he/she will be expecting to type a value.
After the value is typed, a calculation will be performed and:
The contents of COLUMN 1 (Item(1)...,Item(2)...) of record (unique record) in the table INFONUT.DBF above PLUS the value entered by the user PLUS the value from the calculation performed must be copied in a entirely new record, for later visualization.

Thank you,
SitesMasstec

RE: How to populate grid rows with array

Can you show a browse of that one record in infonut.dbf?
What you show looks as 8 records, obviously.
How do you create the item and med arrays from this one record? If you're using a query INTO ARRAY, please just make it INTO CURSOR. Also create both "arrays" as the two columns of that cursor and you have your datasource for the grid.

Bye, Olaf.



RE: How to populate grid rows with array

(OP)
Olaf:

I am still creating the table, and it will be finished by tomorrow. Then I will post it here.

Thank you,
SitesMasstec

RE: How to populate grid rows with array

You already have a structure in mind, don't you? From the screenshot of planned data it looks like 3 columns and 8 records. I wonder how you plan to put this into 1 record. Sounds like you are burdening yourself with problems you don't need to have.

I'll await tomorrow. Let's see, if we can find a simpler solution.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)

This is what I want to do:



In the Table INFONUT1.DBF there will be other more fields (not repeated like shown in the picture - INU_DESC01, INU_DESC02...INU_DESC10), in the record.

Similar to ONE customer record that has the fields:
- CUSTOMER CODE         Field CUSTCODE
- CUSTOMER NAME         Field CUSTNAME
- CUSTOMER PHONE        Field CUSTPHON

- BUYS IN JANUARY       Field CUSTBU01     
- BUYS IN FEBRUARY      Field CUSTBU02
- BUYS IN MARCH         Field CUSTBU03
...                     ...
- BUYS IN DECEMBER      Field CUSTBU12 

Thank you,
SitesMasstec

RE: How to populate grid rows with array

Just want to point out that I'm not an author of KiloFox. Most likely, Marcia Akins wrote that chapter.

Tamar

RE: How to populate grid rows with array

(OP)

Oh Tamar, I apologize for my mistake.

Anyway, I did not want to criticize anyone, but just to point out the complexity of the Grid control (according to the title of that Kilofox chapter...) and my difficulty to learn using it, of course.

Thank you,
SitesMasstec

RE: How to populate grid rows with array

What you need is a table with fields (desc, qtde, medi, perc), and you need 8 records per "record", that's all. You don't design tables with repeated fields, repetition always is done by storing multiple tuples of data, named records, in a separate table with that substructure.

You should know the principle by now. If you want to store an order you don't have a table order with (ordernumber, customer, orderdate, product1, qty1, price1, product2, qty2, price2, product3, qty3, price3,...), you have two tables, an order table and a table for the different orderitems:

orders: ordernumber, customer, orderdate
orderitems: ordernumber, product, qty, price

Now you can a) have as many order items as you like, b) display all orderitems in a grid simply by setting its recordsource to the orderitems dbf and filter for ordernumbre=x.
You don't need any array for that, you don't need to turn fields of one record into multiple records or array elements.

If you recognize an order as a "record" and think this must go into one table record, then you haven't understood how databases work. If you design your data the usual way, you also can cope with how controls work much easier. I think you're haviong a wrong concept about how data must be stored free of redundancy. The way order and orderitems are designed, the same ordernumber appears multiple times in all data. That's not, what's called redundance because in the order tables it's the primary key value uniquely identifying one order and in the orderitems it's the foreign key, telling to which order the item belongs.

That's how you design such data, and in that way without any further ado items become their own records, easily listed in a grid.
And that#s not all, which is getting simpler. If you want to compute the average percentages of a record of your table structure you need (Inu_perc01+Inu_perc02+Inu_perc03+Inu_perc04+Inu_perc05+Inu_perc06+Inu_perc07+Inu_perc08)/8 and it even get's complcated if not all 8 fields have a value and the average should be clculated of only 7,6,5,... values. Instead now you simply query SELECT Avg(perc) as avergaepercentage FROM yourtable2 WHERE key=x. There is no SQL command or function calculating an average on a series of fields 1,2,3,4,5,6,7,8. Anytime you write a number in your field names, think about this, you actually want to store repeating things, and that's simplest in an extra table.

Everything is so much easier if you play by the rules. If you design data the way it's intended and supported by controls and query language. Then you also don't struggle and have no hard time with the SQL queries you need. All these database design rules are not there to make it hard on non-professional developers, all the programming tools languages are designed for that design of data, everything "falls into place", if you do it right.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)

My table with the repeated fields - 01 to 10 (desc, qtde, medi, perc) - is a table with just one record. No more records will be appended later.

It is a standard table about Basic Nutrition Facts, which will be used to save additional information typed by the user in the same fields in other tables.

This approach is for the sake of clarity and simplicity, even against the best VFP rules.

Thank you,
SitesMasstec

RE: How to populate grid rows with array

SitesMasstec,

Olaf doesn't mean it is against VFP rules, he means it might be poor normalisation, like storing a long company name in ten places
instead of having a table of companies and a ref code stored in ten places (not including the table of companies).

In practice you do see situations approaching the level of normalisation you have from time to time - it's not a crime, just needs
careful handling - and a structural upgrade if you suddenly MUST HAVE 14 months - the VFP secret police will not be hunting for you.

In some ways your approach makes report design easier - if you had, say, up to 100 items which you wanted as detail items, you could
find it difficult to control the page layout (it might drift on to two or more pages).

You could use functions to pull the right 01-02 items into the right places. So you might replace your text fields control text with

GetCustBy(2)

To get the value of CUSTBU02
If the code below is visible to your report.

CODE

Function GetCustBuy
Parameters m.Month
Private m.Month,m.Temp
m.Temp = "CUSTBY"+RIGHT("00"+ALLTRIM(STR(m.MONTH,3,0)),3)
return(Evaluate(m.Temp)) 






Regards

Griff
Keep Smileing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.

RE: How to populate grid rows with array

Normalisation is the bigger picture, yes, but you can also say it's against VFP rules.
If you want to show multiple lines in a grid, you have multiple records.

You also don't use any table as input vehicle, as it's meant to be here. And even if you do, why must it be one record, you make up rules here, that don't hold true, as you see the grid doesn't support your idea as good idea. And instead of changing your mind, you blame the grid to be the problem.

In an earlier post you're working with browse in edit mode. Grids can do that, too, but the planned look rather is the normal browse/grid mode. And for that matter, you need multiple rows aka multiple records. Nothing prevents you from using multple records in a table for input/editing.

Instead of one record with fields repeated 10 times you create a table with each field once and prepopulate it with 10 records. There's nothing difficult about this.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)

I already use this, similar to Griff's Function GetCustBuy:

Reading a record: YRCO(1)= field ROR01, YRCO(2) = field ROR02, ... YRCO(20)= field ROR20

CODE -->

FOR X=1 TO 20
	strX=STR(X,2)
	IF SUBSTR(strX,1,1)=" "
		strX="0"+SUBSTR(strX,2,1)
	ENDIF

	CAMPOX="ROR"+strX
	YROR(X)=&CAMPOX 


Saving a record: field RCO01 = YRCO(1), field RCO02=YRCO(2), ... field RCO20=YRCO(20)

CODE -->

FOR X=1 TO 20
	strX=STR(X,2)
	IF SUBSTR(strX,1,1)=" "
		strX="0"+SUBSTR(strX,2,1)
	ENDIF

	CAMPOX="ROR"+strX
	REPLACE &CAMPOX WITH YROR(X) 

So, I will merge it with Olaf's advice:
I will save each element Item(1), Med(1)... till Item(20), Med(20), in a record in a Cursor, and use each record to populate each row in the Grid (total 20 records)

I will try to implement this.

Thank you,
SitesMasstec

RE: How to populate grid rows with array

You will not need this code, as your data already is 10 (20?) records in the first, if you design your table that way. You just need one additional column with an id grouping these records belonging together.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)

Olaf, I do not use Database container, just free tables...

Thank you,
SitesMasstec

RE: How to populate grid rows with array

That doesn't depend on DBC at all. Along what lines are you thinking?
Even in legacy Foxpro relations between were thought of with the SET RELATION command. You don't have the primarykey index type, but candidate. Free tables nowadays also have autoinc as feature, you don't need DBC to have it. You can't define relations between tables without a DBC, and no trigger code, but you still can make relations, and you should. Everyting is intended for that.

Quote:

Similar to ONE customer record that has the fields: ...
You don't do that.

For example seeing buys in months is a matter of a view grouping by month(purchasedate).
If you really find it advanced to need to normalize data on the fly to display it in grids instead of simply storing it that way, I fear I can't teach you anything anymore.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)

Well, I tried to populate the Grid now, but I have not got the awaited result:



Note that the array is populated as expected (please see note 1), but just the first record is copied to cursor (and showed in the Grid) (please see note 2).

Thank you,
SitesMasstec

RE: How to populate grid rows with array

You shouldn't go with that advice anyway. If the grid only shows row 1 then the grid cursor is only having one record. As the array you append is one dimensional the number of rows is always 1, no matter how large the array is.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)

Hello Olaf!

I created a one more variable:
DECLARE YINU_DESC(10), YINU_QTDE(10)

Then, in the FOR...NEXT loop:

CODE -->

YINU_QTDE(Y)="0.000" 

Then:

CODE -->

CREATE CURSOR INFONUT1A (INU_DESC C(20), INU_QTDE C(18)) 

So, what shoud be the "APPEND FROM ARRAY " command?

Thank you,
SitesMasstec

RE: How to populate grid rows with array

SitesMasstec,

Would you be able to give, in a notepad, txt file an example how your data looks and how you would like this data to be shown in your grid?
Regards,
Koen

RE: How to populate grid rows with array

(OP)

Hello Koen!

Each line has:

first element, second element
YINU_DESC(Y), YINU_QTDE(Y)

"Valor energético","0.000"
"Carboidratos","0.000"
"Proteínas","0.000"
"Gorduras totais","0.000"
"Gosduras saturadas","0.000"
"Gordura trans","0.000"
"Fibra alimentar","0.000"
"Sódio","0.000"

I want to put theses elements in the Grid, so they will appear as:
Valor energético    | 0.000
Carboidratos        | 0.000
Proteínas           | 0.000
Gorduras totais"    | 0.000
Gosduras saturadas  | 0.000
Gordura trans       | 0.000
Fibra alimentar     | 0.000
Sódio               | 0.000
 

Thank you,
SitesMasstec

RE: How to populate grid rows with array

(OP)

Quote (Olaf)


For example seeing buys in months is a matter of a view grouping by month(purchasedate).

Yes, Olaf, of course I have been using this for a long time, in all my applications. If not, I should have abandoned programming.

But the application I am working now, is quite different and somewhat complex. Maybe I was not able to express its complexity, I am just showing some part of it here.

Thank you,
SitesMasstec

RE: How to populate grid rows with array

(OP)

Dear colleagues:

I could not find an answer in the VFP 9 Help file, and in books about this:

So, I have this array, with 2 elements -- YINU_DESC(Y), YINU_QTDE(Y) --:
"Valor energético","0.000"
"Carboidratos","0.000"
"Proteínas","0.000"
"Gorduras totais","0.000"
"Gosduras saturadas","0.000"
"Gordura trans","0.000"
"Fibra alimentar","0.000"
"Sódio","0.000"

And I think that if I have to use the command "APPEND FROM ARRAY ArrayName", how can I define a name for the above array?

Thank you,
SitesMasstec

RE: How to populate grid rows with array

If a software get's more complex, it's even more important to store your data in a normalized manner.

Anyway, APPEND FROM ARRAY is a dead end.That was Mikes idea to actually bring 2d array data into the cursor and display the cursor itself.
You need a for loop, like I did in my example, appending via APPEND BLANK as many times, as the rows you need.

But again you don't need it at all, if you change your data storage to normal ways.

Even if any part of your software needs the data in the structure you now use for your DBF, that is called pivoting, and that is done on data stored in rows and transposed and aggregated into columns wheny querying data and laoding it into memory/cursor. You never store it that way, though. NEVER. EVER.

If you would stop your resistance against a much simpler solution, you would already have it.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)

Hi Olaf, happy news from me (with your valuable help):


Problem solved:

Thank you,
SitesMasstec

RE: How to populate grid rows with array

And now you actually can display the infonut1a cursor instead of the array, throw out the controlsource expressions. You don't even need the array. Don't you see you populate the array just to store it into the cursor as next step?
And if you store data that way you even don't need any code unpivoting it that or any other way.

It's good you're happy, but you could be happier with less.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)

Wow!

Right, Olaf, I do not need to use array:



Thanks again, Olaf!

Thank you,
SitesMasstec

RE: How to populate grid rows with array

Sitesmacc.

Just create a cursor

CREATE CURSOR alias_name
...[CODEPAGE=nCodePage]
(fname1 cFieldType [(nFieldWidth [, nPrecision])] [NULL | NOT NULL]
[CHECK lExpression [ERROR cMessageText]]
[AUTOINC [NEXTVALUE NextValue [STEP StepValue]]]
[DEFAULT eExpression] [UNIQUE [COLLATE cCollateSequence]]
[NOCPTRANS] [, fname2 ...])
| FROM ARRAY ArrayName

and populate your grid with that cursor.

Regards,
Koen

RE: How to populate grid rows with array

Koen, this comes very late, he already does.

Let's summarize from the start: You came here specifying you have arrays you need to display in a grid. Actually, what you designed is a single table and that's what you wanted to display in a grid. You seem to design all your data in a way you only need one record to bind to controls. That only works with single field controls like textbox and editbox, spinner, checkbox, and so on. There are several controls, not only the grid, that display and are bindable to a whole table, to a list of records.

The reasooning for your bad data design seems to me your only used to a business intelligence view of aggregated data. But that's not coming 1:1 from tables designed that way, that is a typical result of aggregating data, grouping it, and pivoting it.

Instead of your one table you need two, one for the single fields and an identifier, the second for related tuples of always the same structure, it's own identifier, the identifier of the main record and then the tuple of desc, qtde, medi, perc, so overall (id, parentid, desc, qtde, medi, perc)

And then grid can be populated from that second table using the desc and qtde fields of the table filtered for a certain id value in parentid. That's all. And you can easily switch to other parentids, if you also open the parent table, display it in another grid and have a relation between them from parent.id to child.parentid, the child table having an index on parentid.

And I know you know enough VFP to make all this. Instead you choose to go the hard route. Why?

Bye, Olaf.

RE: How to populate grid rows with array

Hi,
Why not simply use the Grid's PARTITION and VIEW properties?

CODE -->

PUBLIC go_Form
go_Form = CreateObject ("frmForm")
go_Form.Visible = .T.

WITH go_Form.grdNames
	.Readonly = .T.
	.Column1.Header1.Caption = "Name" 
	.Column2.Header1.Caption = "M"
	.Column3.Header1.Caption = "V"
ENDWITH 

go_Form.Show

READ Events
CLOSE ALL
CLEAR ALL


DEFINE CLASS frmForm As Form
  Width = 400
  Height = 360
  AutoCenter = .T.

  * Add a grid to the form
  Add Object grdNames as Grid with;
    RecordSource = "curNames", ColumnCount = 3, Visible = .t., Top = 20, Left = 20, Width = 360, Partition = 120, View = 1 
    			
  * Add cancelbutton to the form
  ADD OBJECT cmdCancel As CommandButton WITH;
    Width=60, Height=30, Left=20, Top=250, Caption="Exit"

	PROCEDURE cmdCancel.Click()
		CLEAR Events
		ThisForm.Release
	ENDPROC
  
	PROCEDURE Destroy()
		CLEAR Events
		ThisForm.Release
	ENDPROC
    
	PROCEDURE Load
		Create Cursor curNames (cName C(10), nMeters I, nVolume I)
			For li_I = 1 to 20
				INSERT INTO curNames (cName, nMeters, nVolume) VALUES ("Name" + PADL(li_I,3,"0"), li_I, li_I * 3)
			Next li_I   
		
		Go Top
	ENDPROC

ENDDEFINE 

hth
MK

RE: How to populate grid rows with array

Olaf,
I agree, I come only after 30+ messages, however I had a slight idea OP was looking for a pivot table in a certain way, not very sure, but it seems like that. I believe in VFP you are much better of with cursors than array's and more over for a grid a cursor is an ideal control source. Now only one needs to sort/modify the cursor in the way you would like to see it in a grid, the more a grid is nothing less than an other way of browsing your table/cursor or view but not browsing an array, which is technicaly possible but not the road one should go to construct a grid in VFP.
I also read that the (starting) table is far from in an ideal format, however this could be modified.
If OP is willing to show a his table (structure) and desired result, I am sure we can make a small procedure to convert his data for a in a grid presentation.
I also dont understand why nobody has asked the OP for his data presentation and the required presentation in a grid, that would have solved his problem is a few minutes instead of 30+ messages
Regards,
Koen

RE: How to populate grid rows with array

If you take the time to read through this thread, all you ask for is already given and talked about, Koen. SitesMasstec has shown his table design, I have proposed a better design. The initial task to show an array was not the real problem anyway, it was just SitesMasstec idea of loading data of a badly designed table into memory variable to make it available for binding. At least he saw he can go directly from the pivoted table to unpivoted cursor and show it. But even that step is unnecessary with a good and normalized table design.

SitesMasstec is finished with this, so it's futile to continue here.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)

Hello colleagues!

Olaf, this original table is just to keep all information in one table. It will never or rarely will be updated:

Field  Field Name      Type                Width    Dec   Index   Collate Nulls    Next    Step
    1  INU_DESC01      Character              20                             No
    2  INU_QTDE01      Character              22                             No
    3  INU_MEDI01      Character               5                             No
    4  INU_PERC01      Numeric                 5      1                      No
    5  INU_DESC02      Character              20                             No
    6  INU_QTDE02      Numeric                12      3                      No
    7  INU_MEDI02      Character               5                             No
    8  INU_PERC02      Numeric                 5      1                      No
    9  INU_DESC03      Character              20                             No
   10  INU_QTDE03      Numeric                12      3                      No
   11  INU_MEDI03      Character               5                             No
   12  INU_PERC03      Numeric                 5      1                      No
   13  INU_DESC04      Character              20                             No
   14  INU_QTDE04      Numeric                12      3                      No
   15  INU_MEDI04      Character               5                             No
   16  INU_PERC04      Numeric                 5      1                      No
   17  INU_DESC05      Character              20                             No
   18  INU_QTDE05      Numeric                12      3                      No
   19  INU_MEDI05      Character               5                             No
   20  INU_PERC05      Numeric                 5      1                      No
   21  INU_DESC06      Character              20                             No
   22  INU_QTDE06      Numeric                12      3                      No
   23  INU_MEDI06      Character               5                             No
   24  INU_PERC06      Numeric                 5      1                      No
   25  INU_DESC07      Character              20                             No
   26  INU_QTDE07      Numeric                12      3                      No
   27  INU_MEDI07      Character               5                             No
   28  INU_PERC07      Numeric                 5      1                      No
   29  INU_DESC08      Character              20                             No
   30  INU_QTDE08      Numeric                12      3                      No
   31  INU_MEDI08      Character               5                             No
   32  INU_PERC08      Numeric                 5      1                      No
   33  INU_DESC09      Character              20                             No
   34  INU_QTDE09      Numeric                12      3                      No
   35  INU_MEDI09      Character               5                             No
   36  INU_PERC09      Numeric                 5      1                      No
   37  INU_DESC10      Character              20                             No
   38  INU_QTDE10      Numeric                12      3                      No
   39  INU_MEDI10      Character               5                             No
   40  INU_PERC10      Numeric                 5      1                      No
** Total **                                  431
 

I understand the the above table is poor normalisation.

Then, each group of contents INU_DESCxx, INU_QTDExx, INU_MEDIxx, INU_PERCxx (xx = 01, 02 ... 10) are transformed in a Cursor with 10 records (to be possible to use them in a Grid, and also it will be normalised with VFP good rules). So each INU_DESCxx, INU_QTDExx, INU_MEDIxx, INU_PERCxx will be in just on record.

Then, I connect the Cursor INFONUT1A to the Grid (in Grid, Properties: RecordSource: INFONUT1A, RecordSourceType: 1-Alias).






Thank you,
SitesMasstec

RE: How to populate grid rows with array

(OP)

Olaf:

Yes, if I use your proposed two tables (parent + child table, interconnected) instead of the just one above, I will not even need a cursor!

I can populate the Grid with the child table! You're right!

Thank you,
SitesMasstec

RE: How to populate grid rows with array

Take a look at the crosstab wizard, you generate the pivoted data with fields 01-20 via this and not by hand.

And even if you only use this as template data, you do so in separate tables with 1+20 records instead of 1. Then you also can copy this template 1:1 into final tables. I did exactly that for templates about product testing. There was template data tables and job data created from the template data.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)

Hello colleagues!

Not working in the real application... sad



The code bellow is in the Pageframe1, Page4 (last folder), Click event:

CODE -->

SELECT 41
USE INU10000
GOTO 1

CREATE CURSOR INFONUT1A (INU_DESC C(20), INU_QTDE C(18)) 

FOR Y=1 TO 10
	SELECT 41
	strY=STR(Y,2)

	IF SUBSTR(strY,1,1)=" "
		strY="0"+SUBSTR(strY,2,1)
	ENDIF
	CAMPOY="INU_DESC"+strY
	DESCRICAO=&CAMPOY

	SELECT INFONUT1A 	
	APPEND BLANK 
	REPLACE INU_DESC WITH DESCRICAO    && first  element for the grid
	REPLACE INU_QTDE WITH "0.000"      && second element for the grid
NEXT Y

BROWSE     && Just to check if the values are in the Cursor

thisform.Pageframe1.Page4.Grid1.Refresh 

Thank you,
SitesMasstec

RE: How to populate grid rows with array

In a grid with 4 columns, you need a cursor with 4 columns.

RE: How to populate grid rows with array

(OP)


Hello Olaf!

I changed the code (please see bellow) but the result is the same (no display in the Grid).

Through command Browse I can see that data populated the Cursor.

CODE -->

SELECT 41
USE INU10000
GOTO 1

CREATE CURSOR INFONUT1A (INU_DESC C(20), INU_QTDE N(12,3), INU_MEDI C(5), INU_PERC N(5,1)) 

FOR Y=1 TO 10
	SELECT 41
	strY=STR(Y,2)

	IF SUBSTR(strY,1,1)=" "
		strY="0"+SUBSTR(strY,2,1)
	ENDIF
	CAMPOY="INU_DESC"+strY
	DESCRICAO=&CAMPOY

	SELECT INFONUT1A 	
	APPEND BLANK 
	REPLACE INU_DESC WITH DESCRICAO    && first  element for the grid
	REPLACE INU_QTDE WITH 0.000        && second element for the grid
	REPLACE INU_MEDI WITH "g    "      && third  element for the grid
	REPLACE INU_PERC WITH 0.0          && fourth element for the grid
NEXT Y

thisform.Pageframe1.Page4.Grid1.Refresh 

Thank you,
SitesMasstec

RE: How to populate grid rows with array

Hi,

Try this code from the the CLICK event of your page 4

CODE -->

SELECT 41
USE INU10000
*!* GOTO 1
LOCATE

CREATE CURSOR INFONUT1A (INU_DESC C(20), INU_QTDE N(12,3), INU_MEDI C(5), INU_PERC N(5,1)) 

FOR Y=1 TO 10
	SELECT 41
	strY=STR(Y,2)

	IF SUBSTR(strY,1,1)=" "
		strY="0"+SUBSTR(strY,2,1)
	ENDIF
	CAMPOY="INU_DESC"+strY
	DESCRICAO=&CAMPOY

	SELECT INFONUT1A 	
	APPEND BLANK 
	REPLACE INU_DESC WITH DESCRICAO    && first  element for the grid
	REPLACE INU_QTDE WITH 0.000        && second element for the grid
	REPLACE INU_MEDI WITH "g    "      && third  element for the grid
	REPLACE INU_PERC WITH 0.0          && fourth element for the grid
NEXT Y

WITH THIS.Grid1 && I assume that's the GRID's name
       .ColumnCount = -1
       .Recordsouce = "INFONUT1A"
       .SetAll("Sparse", .F., "Column")
       .Visible = .T.
       .Refresh() 
ENDWITH 

hth
MK

RE: How to populate grid rows with array

As a beginner of grid usage, let me tell you some rules of thumb:

1. You never recreate a cursor bound to the grid, that destroys detail info and binding, even just a CREATE CURSOR of a cursor already existing causes "grid goes blank".
2. Ideally the cursor you bind to a grid exists before the grid, so you create cursors in a forms data environment or Load() event. Last chance is the Init of a grid. If you don't have a cursor at hand to bind to, a grid will simply take the current workarea as it's recordsource, even if recordsourcetype still is 0.
3. When replacing grid cursor content with something completely new, you use a technique for which the name "Safe Select" was coined at Foxite, you have your grid cursor, you query into a separate cursor with other alias name and then empty the grid cursor with ZAP and append your new data from the other alias. That works fine, for the typical cases of up to a magnitude of 1000s of records, so for any typical practical case.
4. Views are another nice source to bind to grids, as a REQUERY("view") is capable to ZAP and repopulate a view alias the way a safe select does, without needing a second alias. The downside of this is view SQL limits you, especially thinking of your ways to unpivot another table record with lots of number suffixed fields, it's not doable with SQL, it's a hack anyway, which you should abandon overall.
5. Another simple way of showing 10 of 1000s of records is to use SET FILTER. It's also unfortunate about the scrollbar of the grid, and it works sluggish in very large tables, but for your cases it would be ideal, you would have your chunks of 10 or 20 records and switch between them with a filter instead of SKIP, you wouldn't even need to copy data over from table to grid cursor. Just to make it clear, in this case of binding to a table you never ZAP, unless your table data was just meant temporal, too.

Bye, Olaf.

RE: How to populate grid rows with array

(OP)

Dear colleagues:

I have been using Grid for the last 2 years, but only for displaying data from tables.

Using Grid for data entry and update tables (as I needed), for my level of knowlegde, is more difficult.

I think Grid is like an helicopter: you have to learn more skills to pilot it, and when learned, you can make long distances in a short time. And similarly, Textbox is like a car: it is easier to drive, but if you have to travel long distances, it will take a lot of time.

Just to share with you all (and Olaf in particular, for his great patience) who helped me a lot during the last 8 days, the solution for my problem, using Textboxes:

Thank you,
SitesMasstec

RE: How to populate grid rows with array

Well done for resolving your issue.

Regards

Griff
Keep Smileing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.

RE: How to populate grid rows with array

Hi,
Why give up that fast?
Please have a look at the code below and specifically the AfterRowColChange() procedure.
In short: Column2, entitled "ME" is the only column that accepts changes - the values of the other fields in the cursor are updated immediately.
Please consider the code as a sketch of how you could approach this problem.

CODE -->

PUBLIC go_Form
go_Form = CreateObject ("frmForm")

WITH go_Form.grdNames
	.Readonly = .T.
	.SetAll("Sparse", .F., "Column")
	.Column1.Header1.Caption = "Name" 

	.Column2.Header1.Caption = "Me"
	.Column2.ReadOnly = .F.
	
	.Column3.Header1.Caption = "Sq"
	.Column4.Header1.Caption = "Vo"
	.Column5.Header1.Caption = "Fo"
ENDWITH 

go_Form.Show

READ Events
CLOSE ALL
CLEAR ALL


DEFINE CLASS frmForm As Form
  Width = 420
  Height = 360
  AutoCenter = .T.

  * Add a grid to the form
  Add Object grdNames as Grid with;
    ColumnCount = -1, RecordSource = "curNames", Visible = .T., Top = 18, Left = 18, Width = 390, Height = 270, Partition = 108, View = 1
    
    PROCEDURE grdNames.AfterRowColChange()
	    LPARAMETERS nColIndex
	    
	    GOTO RECNO()
	    REPLACE nSquare WITH nMeters * 2, nVolume WITH nMeters * 3, nForth  WITH nMeters * 4

	    THISFORM.grdNames.Refresh()

    ENDPROC 
    			
  * Add cancelbutton to the form
  ADD OBJECT cmdCancel As CommandButton WITH;
    Width=60, Height=30, Left=18, Top=300, Caption="Exit"

	PROCEDURE cmdCancel.Click()
		CLOSE ALL 
		CLEAR Events
		ThisForm.Release
	
	ENDPROC
  
	PROCEDURE Destroy()
		ThisForm.cmdCancel.Click()
	
	ENDPROC
    
	PROCEDURE Load
		Create Cursor curNames (cName C(10), nMeters I, nSquare I, nVolume I, nForth I)
		
			For li_I = 1 to 50
				INSERT INTO curNames (cName, nMeters, nSquare, nVolume, nForth) ;
							VALUES ("Name" + PADL(li_I,3,"0"), li_I, li_I * 2, li_I * 3, li_I * 4)
			Next li_I   
		
		Locate
	
	ENDPROC
ENDDEFINE 

Enjoy
MK

RE: How to populate grid rows with array

Indeed, there's no reason you need to give up. Also, I could argue if these nutrition facts you store always are about the same 10 aspects from the Energy to the Iron amount and if the units also stay, why not make these labels? What remains then is a single column for the numbers to enter. But would you go into that less flexible direction, SiteasMasstec? The information you need to record may change at any time.

Make that data! Because it is. And that means not just store the descriptions and units as you have them in a table with 10x3 fields, have a table with productid, property name, value and unit fields and you can store as many varying properties of a product, as you wish. Then bind this properties table and SET FILTER TO productID = X and the grid shows all properties of just one product. It's editable, there's nothing special to do about that. You never have to read from N fields into a grid cursor and then store the edited values back.

Your other main table will be the list of products, with their product id matching here and at minimum product name, surely much more single value information about the product, like current price or GTIN code or anything else. You still refuse to spread information about an entity like a product into multiple tables and even 1 major + multiple detail record. But that's the norm. And the grid displays multiple records at once. There is no magic. Doing it this proposed way the grid cursor will simply be the productnutricioninfo table or however you call it, and a relation from the products table to it would act as the filtering. There is no cursor recreation, no copy forth and back, no grid going blank problem, no hard problem at all, if you do it by that normal data design.

Bye, Olaf.


RE: How to populate grid rows with array

(OP)
Hello colleagues!

I have not given up! What I mean is that, for this time, I will use textboxes to solve the problem I am working on, but I try to learn step by step the use of Grid for data entry (of course I want to program in faster way).

I have lots of Hentzenwerke books about Visual FoxPro, and also the VFP 9 Help file is available, but it seems to me that every control (of any book I have VFP) are for people who already have some knowledge about the it.

Any of you know about a VFP 9 book "for dummies"?


Thank you,
SitesMasstec

RE: How to populate grid rows with array

Hi,

1000 Things you want to know about Visual FoxPro by Andy Kramek c.s. Edited by Hentzenwerke, Hardcopy out of Sale however the even more handy electronic version is still available.

It is written for VFP7 but very well usable for VFP9 also, and if you like from the same Editor What's new in VFP9 to update

Koen

RE: How to populate grid rows with array

Hi,

Don't go for "Dummies"! Go for good books if you really want to make VFP work for you.

An absolute must-have: "Hacker's Guide to Visual Foxpro 7.0" by Tamar E. Granor, Ted Roche, Doug Hennig and Della Martin. I don't know whether the hardcopy still exists, but the e-version should be around.

"Programming in Visual Foxpro 3.0" By Whil Hentzen. Although rather old, this book starts from 0 and focuses in each chapter on a different aspect of VFP (Tables and Fields, Databases, Queries, Views, Controls, Functions, Variables, Classes, Programming ...) and at the end you have an almost full demo application.

And many more ...

hth

MK

RE: How to populate grid rows with array

Hi,

Below a slightly pimped-up version of my former example-code. This one draws a sketch of how to work on the CURSOR and to UPDATE the underlying tables on the fly. The BROWSE button allows to display the two underlying tables tblNames and tblAddNames. Just move the frames.

CODE -->

PUBLIC go_Form
go_Form = CreateObject ("frmForm")

WITH go_Form.grdNames
	.Readonly = .T.
	.SetAll("Sparse", .F., "Column")

	.Column1.Header1.Caption = "Name"
	.Column1.Text1.FontBold = .T.
	.Column1.Text1.FontItalic = .T.
	
	.Column2.ReadOnly = .F.
	.Column2.BackColor = RGB(0, 180, 180)
	.Column2.Header1.Caption = "Me"
	.Column2.Text1.InputMask = "9,999.99"
	
	.Column3.Header1.Caption = "Sq"
	.Column3.Text1.InputMask = "9,999.99"
	
	.Column4.Header1.Caption = "Vo"
	.Column4.Text1.InputMask = "9,999.99"
	
	.Column5.Header1.Caption = "Fo"
	.Column5.Text1.InputMask = "9,999.99"
	
	.Column6.Header1.Caption = "Sqrt"
	.Column6.Text1.InputMask = "9,999.99"
ENDWITH 

go_Form.Show

READ Events
CLOSE ALL
CLEAR ALL


DEFINE CLASS frmForm As Form
  Width = 420
  Height = 360
  MinWidth = 420
  MinHeight = 360
  MaxWidth = 420
  MaxHeight = 360
  AutoCenter = .T.

*!*		Add a grid to the form

	Add Object grdNames as Grid with;
		ColumnCount = -1, RecordSource = "curNames", Visible = .T., ;
		Top = 18, Left = 18, Width = 390, Height = 270, Partition = 108, View = 1
    
	    PROCEDURE grdNames.AfterRowColChange()
		    LPARAMETERS nColIndex
		    
		    GOTO RECNO()
		    
		    REPLACE nSquare WITH nMeters * 2, ;
		    		nVolume WITH nMeters * 3, ;
		    		nForth WITH nMeters * 4, ;
		    		nSqrt WITH SQRT(nMeters)
		    		    
			UPDATE tblNames SET ;
					nMeters = curNames.nMeters, ;
					nSquare = curNames.nSquare, ;
					nVolume = curNames.nVolume ;
				WHERE cName = curNames.cName

			UPDATE tblAddNames SET ;
					nForth = curNames.nForth, ;
					nSqrt = curNames.nSqrt ;
				WHERE cName = curNames.cName
				
			
		    THISFORM.grdNames.Refresh()

	    ENDPROC 
    			
*!*	Add object Label

	ADD OBJECT lblInfo as Label WITH ;
		Top = 330, Left = 168, Autosize = .T., FontSize = 8, FontItalic = .T., ;
		Caption = "Only green colored items accept user input"


*!*		ADD a Browse button - allows you to see the underlying tables

	ADD OBJECT cmdBrowse As CommandButton WITH;
		Width=60, Height=30, Left=84, Top=300, Caption="Browse"

		PROCEDURE cmdBrowse.Click()
			LOCAL lcAlias
			
			lcAlias = ALIAS()  
			
			SELECT tblNames
			BROWSE TITLE "tblNames" NOEDIT NOWAIT
			LOCATE  
			
			SELECT tblAddNames
			BROWSE TITLE "tblAddNames" NOEDIT NOWAIT 
			LOCATE 
			
			SELECT (lcAlias)
			
		ENDPROC 
		
		
*!*		Add exitbutton to the form
  
	ADD OBJECT cmdExit As CommandButton WITH;
    	Width=60, Height=30, Left=18, Top=300, Caption="Exit"
    	
		PROCEDURE cmdExit.Click()
			CLOSE ALL 
			CLEAR Events
			ThisForm.Release
		
		ENDPROC
	  
		PROCEDURE Destroy()
			ThisForm.cmdExit.Click()
		
		ENDPROC
    
		PROCEDURE Load
		
			IF !FILE("tblNames.dbf")
			
				Create Table tblNames (cName C(10), nMeters I, nSquare I, nVolume I )
			
					For li_I = 1 to 50
						INSERT INTO tblNames (cName, nMeters, nSquare, nVolume) ;
								VALUES ("Name" + PADL(li_I,3,"0"), li_I, li_I * 2, li_I * 3)
					Next li_I   
			
			ENDIF 
			
			IF !FILE("tblAddNames.dbf")
			
				Create Table tblAddNames (cName C(10), nForth I, nSqrt N(6,2))
			
					For li_I = 1 to 50
						INSERT INTO tblAddNames (cName, nForth, nSqrt) ;
								VALUES ("Name" + PADL(li_I,3,"0"), li_I * 4, SQRT(li_I))
					Next li_I   
			
			ENDIF 

			SELECT tblNames.cName, nMeters, nSquare, nVolume, nForth, nSqrt ;
				FROM tblNames ;
				JOIN tblAddNames ON tblNames.cName = tblAddNames.cName ;
				INTO CURSOR curNames READWRITE 
			
			LOCATE
		
		ENDPROC
ENDDEFINE 

hth
MK


RE: How to populate grid rows with array

It's even simpler, with the table structure I propose you'd simply bind a grid or two grids 1:1 and edit the data as is. There neither is a translation from some DBF to grid cursor nor back.
You might just want to have 1 column readonly as "labels" of the values you enter in column2 and then again a readonly column3 for units.

Bye, Olaf.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close