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 Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

More Adding Records To A Grid

Status
Not open for further replies.

Shanachie

Programmer
Jun 18, 2000
92
US
I've got inserting records down fine. (See earlier thread.)

Is there an event associated with adding records to a grid? I need to automatically set a couple of fields in the grid whenever the user adds records at the end. How do I trap that?

Some details: the table that the grid is displaying contains the detail lines for a purchase order. It is displayed in line number order. When a record is added, I had tried to assign the line number based on the grid's activerow property but when you add a record, the uninitialized line number is 0 so the grid thinks the record is the first (activerow = 1). I need to assign the line number when adding the record. (One solution could be to have the user input the line number but that doesn't seem satisfactory.)

It seems to me that what I'm looking for is an event associated with adding a record. I could then assign line number based on the number of records in the underlying table.

Suggestions?

TIA,
Shanachie
 
Hi Shanachie,

I would assume you have your own code that enables the user to add records in the first place. Do the necessary processing within that code.

Jim
 
Well, yeah, I've got a button at the botton of the form that allows the user to insert a line, e.g., in a six-line PO, add a line after line 3. This makes line4 become line 5, 5->6, etc. I could build a button that adds records at the end (based on how many records are in the underlying table).

But grids let you add records at the end in a very natural way (if AllowAddNew = .t.) by down-arrowing to the next row. I just need to set a couple of fields for the users when that happens.

Maybe is there some way I can use BeforeRowColChange to do that? (AfterRowColChange would be too late, right?) How do I tell if it's a row change or a col change?

Again, I could make the users enter the line numbers but that just feels unnecessary. Make the machine do that grunt stuff.

TIA
Shanachie
 
Hi!

You can detect the new record inserting by following way:

Remember the current record number and record count in the grid in some property. Update them in the AfterRowColChange each time row changed, and update reccount() when adding new record elsewhere. Than check if recno() is greater than previous reccount in teh AfterRowColChange. If yes, you;re there. If you have a buffering for that table, you can also check for negative recno() - it is negative for new records in buffered alias.

What about use of the Default expression property of the field in the database? This way, each time new record is appended (either by Append bank or by grid), these exressions will be evaluated for new record. These expressions could be a functions that are loaded in the memory or just functions from the database procedures.

Another solution is to do not ever use the AllowAddNew=.T., this have alot of troubles...


Vlad Grynchyshyn
vgryn@softserve.lviv.ua
The professional level of programmer could be determined by level of stupidity of his/her bugs
 
Maybe this is an alternative:
Catch the down-arrow (using the keypress-event), and if you go past the last record, manually add a new record...
Basically, it goes like:
Code:
IF down-arrow pressed
  SKIP 1 && go to next record, simulating default behaviour
  IF EOF()
     *!* Skipped past last record, create new record
     *!* and set them values by using an UDF
     [objectreference].HandleAppendNewRecord() 
  ENDIF
ENDIF

In fact, this is a manual implementation of the AllowAddNew, but now you're in control! Diederik Vermeeren
verm1864@exact.nl
 
Hi Shanachie,

I agree with Vlad that using AllowAddNew is asking for trouble, particularly since there's no direct way to trap it. Much better, in my opinion, to have your own button perform this function.

Jim
 
Well, I finally got it working right. Diederik's basic solution did the trick. I turned AllowAddNew off although I haven't had problems with it up to now. With this approach I just didn't need it and I figured with the combined experience you guys have, I'd best not fight the tide.

One small problem in Diederik's pseudocode: the SKIP 1 is there to set the EOF() but if not EOF(), the grid skips down again, resulting in double skipping. One solution would be to ELSE SKIP -1. That didn't feel right so what I finally implemented looks like:

IF down-arrow pressed THEN
IF recno() = reccount() THEN
* Currently on last record => create new record
INSERT INTO ....etc.
THISFORM.REFRESH()
ENDIF
ENDIF

Works like I wanted it to.

Thanks to all. As usual, you've been very helpful.
Shanachie
 
There must be atleast one field such as ProductId (for example) which is a key field in the child table (i.e. Grids record source). I would suggest that the rest of the fields will accept data only when this key field is having a valid data. Assuming this.. WHEN event of this field shall have the code ...

WhenEvent.of say Column1.Text1....

IF EMPTY(id_Sno)
ThisForm.ChildSno()
ENDIF
RETURN .T.
-------------------------------------
The code for ThisForm.ChildSno...


SELECT (ThisForm.cChildAlias)
IF EOF() .OR. BOF()
LOCATE
ENDIF

LOCAL nRecNo, nCount
nRecNo = RECNO()
nCount = 1
LOCATE
IF ! EOF()
SCAN
REPLACE id_sno WITH M.nCount
M.nCount = M.nCount+1
ENDSCAN
GO nRecNo
ENDIF
IF EMPTY(id_Sno)
GATHER MEMVAR MEMO
ThisForm.ChildSno()
ENDIF
RETURN .T.
------------------------------------
This code will fix your requirement. I have a similar order processing which functions perfectly with above codes.
:)
ramani :-9
(Subramanian.G)
FoxAcc
ramani_g@yahoo.com
 
The code for ThisForm.ChildSno...

SELECT (ThisForm.cChildAlias)
IF EOF() .OR. BOF()
LOCATE
ENDIF

LOCAL nRecNo, nCount
nRecNo = RECNO()
nCount = 1
LOCATE
IF ! EOF()
SCAN
REPLACE id_sno WITH M.nCount
M.nCount = M.nCount+1
ENDSCAN
GO nRecNo
ENDIF
RETURN .T.

Replace in the earlier posting with above codes. Some invisible area while I made cut & paste .. crept in... Sorry for that...
ramani :-9
(Subramanian.G)
FoxAcc
ramani_g@yahoo.com
 
ramani, what does the unadorned LOCATE do? I've never used LOCATE so I checked the documentation and only docs the use of a FOR clause.

Whatsit do?

TIA,
Shanachie
 
LOCATE is equivalent to GO TOP. But LOCATE is faster than GO TOP.
ramani :-9
(Subramanian.G)
FoxAcc
ramani_g@yahoo.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top