'Visual FoxPro 9. Set Grid.RecordSource to the result of SELECT
I have 2 grids and 2 tables. I want the second one to display elements that are related to the selected enement of first grid. This can probably be done in 2 ways: either have a filer on grid2 that changes according to my selection in grid1, or change the recordSource of grid2. I've settled on option 2 for now. (But if you can tell me a better way i'd be very grateful)
Here is my current code
LOCAL ssid
LOCAL num
num = thisform.grid1.ActiveRow
SELECT ids FROM scenes WHERE RECNO()=num INTO ARRAY tmp1
ssid = tmp1[1]
SELECT scenelink.amount,mesh.namem FROM scenelink,mesh;
where scenelink.ids=ssid AND scenelink.idm=mesh.idm INTO CURSOR workffs
thisform.grid2.RecordSource=workffs
This does not work, it says variable "workffs" is not found. I also tried using VIEW:
CREATE SQL VIEW workffs as ;
SELECT scenelink.amount,mesh.namem FROM scenelink,mesh;
where scenelink.ids=ssid AND scenelink.idm=mesh.idm
thisform.grid2.RecordSource=workffs
There it asks if i want to overwrite "workffs", yet it still says that such variable cannot be found
Solution 1:[1]
As @Herb pointed out, a Grid.RecordSource type always needs to be a String, so you'd put quotes around the name of your alias.
This can probably be done in 2 ways: either have a filter on grid2 that changes according to my selection in grid1, or change the recordSource of grid2. I've settled on option 2 for now. (But if you can tell me a better way i'd be very grateful)
Actually there are better ways: a classical one is using a "Parametrized SQL View", so that you can modify the content of a local variable, and then use the Requery("myView")
function, which would prevent the infamous "Grid Reconstruction" issue that @Tamar described. Another one is using Grid.RecordSourceType = 4
, and then put the SQL statement as a string directly into the RecordSource
property. Example:
LOCAL oForm as Form
oForm = CREATEOBJECT('TestForm')
oForm.Show(1)
RETURN
DEFINE CLASS TestForm as Form
AutoCenter = .T.
DataSession = 2
PROCEDURE Load
CREATE CURSOR test (test I)
LOCAL i
FOR i = 1 TO 3
INSERT INTO test VALUES (i)
ENDFOR
GO TOP IN test
ENDPROC
ADD OBJECT cmdInsert as CommandButton WITH ;
Left = 10, Height = 24, Caption = "Insert"
PROCEDURE cmdInsert.Click
INSERT INTO test VALUES (RECCOUNT('test')+1)
ENDPROC
ADD OBJECT cmdRequery as CommandButton WITH ;
Left = 150, Height = 24, Caption = "Requery"
PROCEDURE cmdRequery.Click
WITH Thisform.grdTest as Grid
.RecordSource = .RecordSource
ENDWITH
ENDPROC
ADD OBJECT cmdRefresh as CommandButton WITH ;
Left = 290, Height = 24, Caption = "Refresh"
PROCEDURE cmdRefresh.Click
Thisform.grdTest.Refresh()
ENDPROC
ADD OBJECT grdTest as Grid WITH ;
Top = 30, ;
RecordSourceType = 4, ;
RecordSource = "Select * From test Into Cursor (SYS(2015))"
ENDDEFINE
Solution 2:[2]
You have to use quotes around the name of the cursor or view.
thisform.grid2.RecordSource="workffs"
Solution 3:[3]
Your simple solution would be to quote the workffs, it needs to be a string as @Herb pointed out. Also you could use a RecordSourcetype of 4 and have your SQL as the recordsource as @Stefan Wuebbe pointed out.
In either case, you need to be careful about what is called a grid 'reconstruction'. If you simply select into that cursor again, you would lose your grid's formatting. However, as long as the resulting structure is the same as the original one, you could simply work it around by setting your recordsource to nothing temporarily. ie (based on your code):
LOCAL ssid
LOCAL num
num = thisform.grid1.ActiveRow
SELECT ids FROM scenes WHERE RECNO()=num INTO ARRAY tmp1
ssid = tmp1[1]
thisform.grid2.RecordSource=''
SELECT scenelink.amount,mesh.namem FROM scenelink,mesh;
where scenelink.ids=m.ssid AND scenelink.idm=mesh.idm ;
INTO CURSOR workffs ;
nofilter
thisform.grid2.RecordSource='workffs'
Or with SQL recordsource:
LOCAL ssid
LOCAL num
num = thisform.grid1.ActiveRow
SELECT ids FROM scenes WHERE RECNO()=num INTO ARRAY tmp1
ssid = tmp1[1]
thisform.grid2.RecordSource=thisform.grid2.RecordSource
You can download FoxyClasses and check grid samples. One of them exactly does what you are asking for. Samples was compiled back in VFP6 times as I remember, you need to recompile the project to run as an app or exe. Or you could simply run the sample forms one by one with "do form". Check its help file (Foxyclasses is in public domain for a long time now and you could use its classes, code as you see fit).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Herb |
Solution 3 | Cetin Basoz |