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!

Select on cursor strange behaviour

Status
Not open for further replies.

cibe86

Programmer
Sep 12, 2013
12
IT
Hi to all,
I'm a quite new programmer in VFP and I'd like to submit you a strange behaviour that I encounter using cursor.
Let's say I have a cursor (populated scanning a file, so I've no dbf) that is a record source for a grid.
This cursor has a field named selected, logical type. I use this field for controlsource of a checkbox column in the grid, so a user can select/unselect rows in the grid. The problem arises when I make a query on the cursor counting how many rows are currently selected

select count(*) as C from curRett where selected = .T. into cursor curTemp
n = curTemp.C
...

The problem is that the query return a number of selected rows that is greater than 1 of the real value.
I run this query when the column with the checkbox change value. When I deselect it seems not recognise that the row is in fact deselected.
I've tried watching value of currett.selected on current row and correctly it's false, so cursor seems to have updated values.
BUT, the code works if I write this
select curRett
browse
select count(*) as C from curRett where selected = .T. into cursor curTemp
n = curTemp.C
...

The browse, I don't know why, makes the following query works correctly. Obviously I can't use browse in real world application so I resolved in this way

i = 0
SCAN
IF currett.selected = .T.
i = i + 1
ENDIF
ENDSCAN
return i

I've tried with nofilter in select but nothing change. I can't understand what I'm missing. The data in cursor before the query are correct as browse can demonstrate but the query seems to use old value. I recently encounter another similar problem: when I query on a cursor the where doesn't filter correctly the values but if I make a browse before the query all goes right.
Thank you very much for you help!
 
Hi Cibe86, and welcome to the fourm.

I don't off-hand know what is causing this problem. No doubt someone else will explain it.

In the meantime, you could try this code:

Code:
SELECT curRet
COUNT TO lnCount FOR Selected

lnCount will then contain the required figure.

If that works, it should be faster and more elegant than the SCAN loop.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I think I know what might be causing the behaviour you are seeing.

You say you run the query (the one that does the count) when the value of the checkbox changes. It's possible that, at that point, the cursor has not yet been updated. I know you can see the updated checkbox in the grid, but the change in its value won't make its way to the cursor until you move the focus off the cell containing the checkbox. In effect, that's what you're doing when you run the browse.

I know you can see the updated value in the cursor. But the very act of looking at the cursor itself might cause focus to move off the cell.

If this is correct, then the code I gave you in my previous post won't work either, for the same reason (but try it anyway). What might work is to programmatically move the highlight to another cell, and then back again. For example, you could issue a [tt]SKIP[/tt] followed by [tt]SKIP - 1[/tt] (but you would also need to test for end-of-file). Or, maybe you could use the column's SetFocus to move focus to the adjacent column and then back to the original column.

I'm not sure if either of these suggestions will solve the problem, but I hope I have at least given you something to experiment with.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thank you very much Mike!
The code that you suggested me actually works!!
So I don't think that the problem is the focus. As I said if I print currett.selected I return false so the cursor already has the correct value.

Maybe this new similar problem could try to found a solution. If I run (in a click event of a button) this code

Code:
SELECT * FROM currett WHERE ISNULL(qtarilev)  AND !ISNULL(qtaatt) INTO CURSOR curTemp
SELECT curTemp
* browse
REPORT FORM cPath+"\Reports\ReportArNonRil.frx" TO PRINTER PROMPT PREVIEW
USE IN curTemp

in the report I see also record that doesn't match the where clause. Even in this case currett is record source for a grid. Also, depending on currently selected record on currett, I see different pages in report. I add that I don't make any change to the data in the grid before running the code.
Once again if I uncomment the command browse all works as a charm!
Bye!

 
By any chance, is the table that you are querying buffered? (That is, the Curret table?)

If so, that would also explain both issues. By default, when you run a SELECT on a buffered table, the SELECT won't see any updates the data that haven't yet been committed.

One solution would be to commit the data as soon as the checkbox has been changed. You can do that by issuing a table update, or (if row buffering is in force) by moving the record pointer.

Alternatively, add [tt]WITH BUFFERING = .T.[/tt] to the SELECT. That will ensure the query sees the uncommitted data. However, that's a fairly new feature, so only works with the most recent versions of VFP.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thank you Mike!
The cursor currett is created as follows
Code:
CREATE CURSOR curRett (Enabled L,selected L,cd_ar c(20),descrizione C(80),cd_arlotto C(20) NULL,qtaAtt N(18,8) NULL,qtaRilev N(18,8) NULL,qtaRett N(18,8) NULL)
Data are inserted into it with instruction like
Code:
INSERT INTO curRett ;
SELECT * ...
That is from other cursors (that are filled with data from files)
So i have no table at all. I thought on some buffering settings on the grid but i don't know how to look for.
It'a also strange that in the second problem I submit to you I don't change data at all on currett and it's curTemp that need to be refreshed.
Bye!

P.S.: using WITH BUFFERING = .T. has no effect
 
The problem may be the grid. You only save control.value, when Valid event is passed, thhe current row will not reflect the optical state, you have to leave grid before the checkbox state is saved to the cursor. That's how controlsource works, it set's control.value and contro.value is saved, but not in interactivechange or click, only via valid. Bye the way, it won't help calling valid from interactivechange or clik, the real valid event has to occur for the base class behaviour to write the control value back into the control source.

Bye, Olaf.
 
BROWSE worked, simply because you took away the focus off the grid. That saved the last change and you see it in the browse.

Why do wizard forms have a navbar with save button in the form? It moves focus away from the current control, if you click the save button, that way that controls valid event occurs and saves the last change.

Bye, Olaf.
 
Cibe, the thing about buffering was a bit of a long short. I mentioned it only so that it could be eliminated.

But I still think my earlier point about focus is valid: "the change in ... value won't make its way to the cursor until you move the focus off the cell containing the checkbox". Olaf's comment agrees with that.

I still think you should try setting focus out of the cell, and then back in again. I suggested you need to set it to another column, but it could be it needs to be a different control. Either way, it must be worth a try.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thank you Olaf,
you're absolutly right! You have to remove focus from grid, I've call setFocus on another control before launching querys and now I got expected behavoiur.
I also confirm that calling grid.valid() is not enough, you need to really remove the focus from it.
Thank you all!
Bye!
Riccardo
 
Well, it would be grid.columnX.check1.valid(), but that also won't work, calling valid causes the code in it to run, but not the base class behaviour of the event, that is to save value to controlsource. Also not, if you use RAISEEVENT.

What you can do is grid.columnX.check1.setfocus(), because even though that control still has focus, it will cause the control to go through the cycle of events of valid, lostfocus, when and gotfocus.

The same problem applies with a save button put on a toolbar, as toolbar buttons don't move the focus off form controls, you have a one off situation, again, as the last field change isn't saved.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top