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

Maintaining Grid Row after Editing 3

Status
Not open for further replies.

David Higgs

Programmer
May 6, 2012
392
GB
In my application when I click on a Row in my Grid the entire Row is Highlighted. Double Clicking on the Highlighted Row opens up a Form which allows Editing of the selected Record. When this form is closed irrespective of any changes to the data, the Grid ActiveRow always defaults to the last record. What do I need to do to keep the ActiveRow the same as before editing?



Regards,

David.

Recreational user of VFP.
 
The active row of the grid is determined by the record pointer in the underlying table or cursor. So to maintain the highlight, you need to store the record pointer before you open your subisdiary form, and then restore it afterwards.

Something like this:

Code:
lnRecord = RECNO("MyAlias")
DO SubsidiaryForm  && I'm assuming this form is modal
IF BETWEEN(lnRecord, 1, RECCOUNT("MyAlias"))
  GO lnRecord
ENDIF
THISFORM.MyGrid.SetFocus

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
This points out the last action done in the detail edit form is locating on the last record. A TABLEUPDATE(T,..), TABLEUPDATE(1,...), or TABLEUPDATE(2,...) saving changes of all rows would do that.

As we lately had a discussion about why for example a GOTO might cause a range error, instead of memorizing the record number I'd recommend remembering the ID of a record and to reposition to that with a SEEK. Ideally, the detail form, as it obviously works in the same datasession, should do that as part of the cleanup code. So it should initially memorize the current ID and go back to that as the last step before releasing itself. The other option is a private datasession, where the detail form would need the ID of the record to edit, would open up the table again and position on its own workarea, but would therefore not change anything for the form listing records, despite of course acting on the same DBF and record, which would also reflect after a grid.refresh. An advantage of using the same datasession is, you don't need to save buffered changes before the calling form sees them, when the two forms share the same workarea they also share that buffer. You still need to refresh controls for that to show, but in principle, you can have an editform, which edits immediately also reflect in the columns listed in a grid on the calling form. That's the one advantage, and the other is not always having the full roundtrip to the DBF, which could also mean field and table rules checking and triggers, if the DBF is part of a DBC. That's all reasons pointing out shared datasession is good for that case of editing a record. It could be integrated in one form, having it in a separate form in this case doesn't make it an independent form, so it's okay to stay in the thereby shared datasession, even though private datasessions are an easy way out of such mutual influences, it's a wanted side effect here, aside of switching the row. As you know you only edit one record, you can of course also only use TABLEUPDATE() for committing changes to the current row only.

Besides all that, there is one property of row highlighting, that controls whether the highlighting is persistent if the focus moves from the grid elsewhere or even to another form. This would never explain why the highlight moves to the bottom, though, I'm quite confident something like a TABLEUPDATE of all rows is done, which ends at the last row of a table, not just the last edited row.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Using Mike's Code, if I look at the "lnRecord" or "Browse" just after the "ENDIF" Statement (Form now released) I can see that the correct "Record" is selected yet when the "Grid" is Displayed the Highlighted Row is again the last Record in the file.

I don't think this is an "Update" Issue because I have a "Cancel Button" on my form that leaves the data "as is".

Regards,

David.

Recreational user of VFP.
 
So, you are saying that my code correctly positions the record pointer, but you nevertheless see the highlight on the last row? That's not what I would expect. Is it possible that there is some other code that is moving the record pointer after my code?

Also, you say that lnRecord is correct. But that itself doesn't mean that the record pointer has been correctly restored. Have you checked the value of RECNO() at that point?

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike Lewis said:
So, you are saying that my code correctly positions the record pointer, but you nevertheless see the highlight on the last row?

That's correct.

Mike Lewis said:
Is it possible that there is some other code that is moving the record pointer after my code?

That was my thinking, but having checked my code and Refresh etc I have yet to find anything. I will keep checking and report back.

Mike Lewis said:
Have you checked the value of RECNO() at that point?

Yes I've checked the RecNo() and also did a "Browse" to confirm the Record Pointer is looking at the correct record.

Regards,

David.

Recreational user of VFP.
 
Hmm

Is the right workarea selected?

Code:
lcOldArea = Select()
Select MyAlias
lnRecord = RECNO()
DO SubsidiaryForm  && I'm assuming this form is modal
Select MyAlias
IF BETWEEN(lnRecord, 1, RECCOUNT())
  GO lnRecord
Else
  Go Top
ENDIF
Select(lcOldArea)
THISFORM.MyGrid.SetFocus


Regards

Griff
Keep [Smile]ing

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.
 
Olaf Doschke said:
I'd recommend remembering the ID of a record and to reposition to that with a SEEK.

Again, same result. I checked (using Browse) after the SEEK to ensure the Record Pointer was pointing at the correct record, which it was. I will continue checking my code.


Regards,

David.

Recreational user of VFP.
 
GriffMG said:
Is the right workarea selected?

I've added your extra code and can confirm that the "Work Area" is the same for Before / After. I also confirmed that earlier on because I was getting "Record is out of Range" error so I added a "Select MyAlias" before the FOR/ENDFOR.

Regards,

David.

Recreational user of VFP.
 
Having checked my code all that I could find is that if I replace "my Form" with a "new form" containing just a single "Command Button" with "thisform.release" I have the same symptoms i.e Highlighting Last Record.

Code:
lnRecord = RECNO("cLogbook")

DO FORM Log_Entry

SELECT cLogbook

IF BETWEEN(lnRecord, 1, RECCOUNT("cLogbook"))
	GO lnRecord 
ENDIF

thisform.MyGrid.SetFocus

However if I by-pass calling the form the original record is highlighted.

Code:
lnRecord = RECNO("cLogbook")

*DO FORM Log_Entry

SELECT cLogbook

IF BETWEEN(lnRecord, 1, RECCOUNT("cLogbook"))
	GO lnRecord 
ENDIF

thisform.MyGrid.SetFocus

Regards,

David.

Recreational user of VFP.
 
Set a break point right after the GO lnRecord or SEEK lnID

Single step through code and see what happens. That's the easiest way to see any code rnning, also triggered by events, the code moving the record pointer to the bottom may be in a class, inherited code or anything else you don't find directly within the form, but the debugger will show what's done.

Never used the debugger?
The two most important settings:
debugsettings_bhegpl.png


Then in code ust add a SET STEP ON, that combines stopping/pausing executeion as the SUSPEND command does too, and starting up the debugger in it's frame, that just means extra Window.

Once the debugger shows up, you'll typically mainly see the trace window with a yellow arrow pointing to the SET STEP ON line. Now execute line by line by pressing F8.

If you have two displays that makes it comfortable debugging in that extra window. There are a few things that work better with the debugger being a window inside the VFP IDE also running your program, especially if focus of controls is involved, but in general it's nicer to have an extra window, as that keeps your UI as it is without the debugger.

Bye, Olaf.


Olaf Doschke Software Engineering
 
Olaf,

Many thanks for your help once again!

Olaf Doschke said:
Never used the debugger?

I have used Debugger before but must admit I don't use it often enough!

I followed your advice and found that just after "thisform.MyGrid.SetFocus" the Forms "Activate" Code was executed. When writing my code I had incorrectly assumed that "Activate" code would only execute when selecting "MyForm" from within MyPageframe.

I will have to revisit my code.


Regards,

David.

Recreational user of VFP.
 
David, I'm not sure why triggering the Activate event should cause the problem you are seeing (unless you actually have some code in the Activate which is moving the record pointer; but that's highly unlikely).

By the way, your assumption is incorrect. Activate is also triggered when a form is opened, when its Show method is called, when control is returned to the form after a modal form closes (which is probably the case here), when the user clicks on the form, and probably some other cases as well. But I'm not sure if that takes us any further forward.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hello Mike,

Thank you for your reply.

Mike Lewis said:
I'm not sure why triggering the Activate event should cause the problem you are seeing (unless you actually have some code in the Activate which is moving the record pointer; but that's highly unlikely).

I need to re-visit my code because I do indeed have some code in there that Selects the Database and moves the Record Pointer to the last entry.

Mike Lewis said:
By the way, your assumption is incorrect. Activate is also triggered when a form is opened, when its Show method is called, when control is returned to the form after a modal form closes (which is probably the case here), when the user clicks on the form, and probably some other cases as well. But I'm not sure if that takes us any further forward.

Yes I Googled "Form Event Sequence" and found that Activate is triggered when control is returned to the form.

I will check my code to see if it can be moved elsewhere.

Code:
	SELECT cLogbook
	
	SET ORDER TO 1 IN cLogbook DESCENDING	&&	Newest entry to Top

	DO Log_alt_col		&&	Alternative Row Colours
	
	GOTO top

	THIS.grd_logbook.SetFocus

thisform.pageframe1.Logbook.grd_Logbook.refresh()



Regards,

David.

Recreational user of VFP.
 
David,

It looks like you have found the code that is causing the problem. Your GO TOP is moving the record pointer to the first record in index order. The fact that your index is descending might make you think it is moving it to the last record. But, either way, this is happening after you re-set the record pointer to where it was before you opened the form, which explains the problem you are seeing.

Also, you might like to try removing the refresh. As far as I can see from what you posted, it is not necessary here and could possibly be causing other issues.

Finally, I suggest that, before googling "Form Event Sequence" (or anything else like that), you consult the VFP Help file. That contains the definitive information about how VFP behaves. There is a page called Event Sequence that tells you what you need to know in that respect.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike Lewis said:
It looks like you have found the code that is causing the problem.

Indeed, in fact I have now removed the Code completely from "Form - Activate" and I'm pleased to report that everything seems to be working as expected. I can't remember exactly when I wrote the code, but with continual development that particular code has now become surplus. I've added AUTOFIT and SET FOCUS to MyGrid and that works ok now.

Mike Lewis said:
Also, you might like to try removing the refresh. As far as I can see from what you posted, it is not necessary here and could possibly be causing other issues.

I am never too sure when to or when not to include a "Refresh", I have in the past added a Refresh if things don't display as expected. I keep revisiting the code from time to time with a view of tidying things up in a more efficient manner. Especially after reading a thread of interest on Tek-Tips. You may have seen my comments recently where I considerably reduced the number of PUBLIC Variables in use just by making use of CURSORS.

I've been neglecting my Railway Database Project for a while now and must get round to improving the code with what I have learnt with my Logbook Project over the months. So I will no doubt be back with more questions!

Thanks again for your help and encouragement.


Regards,

David.

Recreational user of VFP.
 
Delighted to hear that you've solved the problem, David.

Regarding Refresh, in general this is only necessary when the control's underlying data has changed in some way. For example, if a control is bound to a field in a table, and the value of the field changes, or if the record pointer moves, then you need a Refresh to make the control display the new data. It is rarely needed if you just make visual changes to a control, such as changing its colours or fonts.

A grid is slightly peculiar in this respect. Most of the time, you just need to set focus to the grid, rather than refreshing it (SetFocus is also usually faster than Refresh).

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Fine to see the debugging helped. It could take very long to identify that, if not simply going through what happens in single step mode.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top