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

Switching Sql statements fails on 2nd statement

Status
Not open for further replies.

stanlyn

Programmer
Sep 3, 2003
945
US
Hi,

The last browse below is failing with a "No table is open in the current work area". I'm changing the SqlCmd statement and reissuing the cursorfill() method and there is no 2nd cursor...

Code:
set
SET CLASSLIB TO '............\Classes\_Data_Deedroom.vcx'
lnHandle = Sqlstringconnect('DRIVER=SQL Server;SERVER=abc;UID=sa;PWD=password6;DATABASE=MyDB')

o=CREATEOBJECT('_ca_partyname')
o.UseCursorSchema = .F.
o.SelectCmd ="Select * from PartyName where party_name like 'Comb%'"
o.DataSourceType = 'ODBC'
o.DataSource = lnHandle 
o.cursorfill()
browse        * This works...

o.CursorSchema = 'PAGE_TYPE V(40),PARTY_NAME V(52)'
o.SelectCmd ="Select page_type, party_name from PartyName where party_name like 'Lewi%'"
o.cursorfill()
BROWSE       * and this does not work...

What am I doing wrong?

Using VFP9sp2 and SQL Server 2012,

Thanks, Stanley

 
I'm not going to pretend to know the answer but I have a question:

Why are you populating CursorSchema when you've set UseCursorSchema=.f. ?
 
Also, you're misusing a cursoradapter for a connection. Cursoradapters can be bound to backend data, if you switch schema and sql, even if you also set CursorSchema=.f. you're not making any use of the two way connection CAs offer to read AND WRITE BACK data.

A cursor adapter adapts to e remote table via a cursor. Operations you do in VFP on the cursor can then be forwarded to the backend. If you set SelectCMd, vfp builds UpdateCmd, InsertCmd, DeleteCmd, to let a TABLEUPDATE() do all changes done with the cursor buffer in the remote database.

The detail reason of your query not working may be, that the real field names of the remote table you querry in SQL server contain spaces, and so you'd need to select [page type], [party name]. Simply take a look into the SQl server Database with SQL Serve3r Management Studio, it will give you the real field names. I don't know, but I have the strong feeling this is the reason. You cen right click on a table node in SQL Server Management Studio and let it create a SELECT Query for a table in a query window or clip text. You can than use that SQL in VFP. The SelectCmd has to contain SQL in the dialect of the remote database with names of the remote database.

Bye, Olaf.
 
Sorry for the typos and raw text overall, I was not really finished with this... so again, better:


Besides what Dan said, you're misusing a cursoradapter for a connection. Cursoradapters can be bound to backend data, but you're not making any use of the two way connection CAs offer to read AND WRITE BACK data, if you switch schema and SelectCmd, even if you would also set CursorSchema=.T.

A cursor adapter adapts to e remote table via a cursor. Operations you do in VFP on the cursor can then be forwarded to the backend. Therefore one cursoradapter for one table, like one view is for one view cursor. If you set SelectCMd, vfp builds UpdateCmd, InsertCmd, DeleteCmd, to let a TABLEUPDATE() do all changes done with the cursor buffer in the remote database, and that won't work, if you do several queries into several cursors. In fact there are advanced possibilities, using CursorDetach/CursorAttach and create a series of cursors, but that would then also involve changin the alias property and some more. It's much easier to use on CA for each cursor you want too generate.

The detail reason of your query not working may be, that the real field names of the remote table you query in SQL Server contain spaces, and so you'd need to select [page type], [party name]. Simply take a look into the SQL Server database with SQL Server Management Studio, it will give you the real field names. I don't know, but I have the strong feeling this is the reason. You can right click on a table node in SQL Server Management Studio and let it create a SELECT query for a table in a query window or clip text or text file.... You can then use that SQL in VFP. The SelectCmd has to contain SQL in the dialect of the remote database with names of the remote database. VFP renames fields with spaces by using underscores instead.

If you took the two field names page_type, party_name from the first result you got, you relied on that being the names as they are in SQL Server. You have to be cautious with such assumptions, also about field types etc. SQL Server Management Studio is your friend in generating T-SQL (the dialect MS SQL Server speaks), inspect tables, indexes, contraints, etc etc etc.

Bye, Olaf.
 
Hi Dan,

>> Why are you populating CursorSchema when you've set UseCursorSchema=.f. ?

In an effort to get this to work, however I have a question pertaining to this...


1. Do I always have to match the CursorSchema to the Select Commands results. The CA's default schema and select statement has all fields listed. Now, lets say that I issue a select statement that has only 2 fields listed, so do I have to change the schema to the same two fields that the select returns?

2. If UseCursorSchema=.f., is the cursor updateable? What are the do and do nots when doing ad-hoc statements?

3. More...

Thanks, Stanley
 
Hi Olaf,

>> Also, you're misusing a cursoradapter for a connection.

I don't think so, because I creating a connection and getting the handle before creating the CA, and I'm setting the CA's connection properties just as if I was using the builder, but instead I'm doing it in code.


>> Cursoradapters can be bound to backend data, if you switch schema and sql, even if you also set CursorSchema=.f. you're not making any use of the two way connection CAs offer to read AND WRITE BACK data.

Then how do I do all my ad-hoc stuff without creating a CA for all possible incarnations of my select statement? In a .prg, i may need to use this "PartyName" cursor a dozen different ways such as:
a. select * from PartyNames
b. select count(*) from PartyNames
c. select party_name, page_type, party_type from PartyNames
d. select PartyNames.party_name, PartyNames.page_type, PartyNames.party_type from PartyNames with joins...
e. select with where and order by clauses
f. and on and on...

I understand the CA automatically creates this 2-way connection by providing correct values for the Tables, KeyFieldList, UpdatableFieldList, and UpdateNameList properties, and also setting the AllowInsert, AllowUpdate, and AllowDelete properties to True. This comes from the document " page 4.


>> If you set SelectCMd, vfp builds UpdateCmd, InsertCmd, DeleteCmd, to let a TABLEUPDATE() do all changes done with the cursor buffer in the remote database.

Thats what I thought too, however after setting the SelectCmd and CursorSchema to a new one that matches each other, it fails, hence my question being posted here. What am I doing wrong here?

>> The reason your query not working may be, that the real field names of the remote table you querry in SQL server contain spaces, and so you'd need to select [page type], [party name].

I never use spaces in field or table names as its a bad idea to do so. I created the entire sql database, tables and indexes with my VFP export routine. I just now added the [] brackets to the field names with same behavior. Also note that the vfp datasession window is showing the cursor and at the same time it is presenting the Open Table dialog and the debugger is at the last browse statement.


>> I don't know, but I have the strong feeling this is the reason. You cen right click on a table node in SQL Server Management Studio and let it create a SELECT Query for a table in a query window or clip text. You can than use that SQL in VFP. The SelectCmd has to contain SQL in the dialect of the remote database with names of the remote database.

I just copied my 2nd select statement to SSMS and it works as expected. So, i don't know what to do...

Thanks, Stanley
 
Hi Olaf,

>> You have to be cautious with such assumptions....

Agreed, see my message above that states that I copied it verbatim into SSMS and it works as expected. The exact command was: "Select [page_type], [party_name] from PartyName where [party_name] like 'Lewi%'" without the surrounding double quotes.


>> It's much easier to use on CA for each cursor you want too generate.

I want a CA for PartyNames, one for Documents, one for Users and ............ If I'm working on the Documents form, I want to load the Documents CA into the Document form's DE.

Next I do NOT want to fetch all the data (3 million records) into the local cursor where I can do all the fox stuff that I'm very familiar with.

Now lets say that the document form has a pageframe where each page has a different grid populated with results from a select statement tailored to the page's grid thats fired from the page's activate event.

There is so many places that this sort of ad-hoc queries are necessary to mimic working directly with VFP tables, only now I'll be working with a SQL subset of the data.

Thanks, Stanley
 
> I copied it verbatim into SSMS and it works as expected.
Okay, then the reason must be something else.

>I want a CA for PartyNames, one for Documents, one for Users and
That design choice is understandable, but still. You can have one CLASS for Partynames, Documents, Users. But you should have one INSTANCE per cursor, otherwise you're not making good use of CAs. And that's all you need to change perhaps. Also make sure the Alias property of the cursor adapter is used to determine a unique result name for each instance. You stay with one instance per table, but then you can't make use of the two way nature of CAs.

>Next I do NOT want to fetch all the data (3 million records) into the local cursor
Nobody said you should do that. You can query partly data. Adapting doesn't mean you pull in all data. The essential tool is the CA cursors buffer, that is used in the same as is used in tables USED natively or in Views, local or remote, or in SPT cursors, with appropriate CursorSetProps.

Even if you need ad hoc data, you can instanciate ad hoc instances of CAs. You don't have to put them into the form DE to make use of them. Like you can USE a table later in Clik you can also instanciate as many CA instances as you need. Ever cursor has his seperate instance of a CA handling it.

You make all the CA instances for the same table with different full or partial schemas using the same general settings, by creating a CA class for PArtyNames, Documents, Users, as use them as many times as you need. You also don't start a form and then change it to display another form, you create as many form instances as you need. Thats simply OOP. Use OOP. Don't tell me using base classes and setting them is faster, easier to maintain, etc. It's NOT.

Bye, Olaf.
 
Ok, more testing reveals that

[Select * from PartyName... works in all cases, and
[Select page_type, party_name from PartyName... does not!

When I open the ca in the class browser, I see that the SelectCmd is empty. I used the CaBuilder9 to create the CAs and its preloading the .init method that overrides everything...

Thanks, Stanley
 
Olaf,

OK, I got something that works now in all the tests I've done so far, which is selecting, filtering and ordering. Turns out that the CaBuilder9 is stuffing the .init method with code that I could never override. Here is what I've made to work, all 4 browses...

Code:
lnHandle = Sqlstringconnect('..........')

* 1st Browse
o=Createobject('cPartyName')
o.CursorFill()
Browse

* 2nd Browse
o.UseCursorSchema = .T.
o.CursorSchema = "COUNTY_ID C(5),COUNTY_PAGEKEY C(14),PAGE_TYPE V(40),PAGE_DATE V(10),PARTY_NAME V(52),PARTY_TYPE V(14),PARTY_RACE C(1),CREATOR C(11),CREATION_TIME V(19),UPD_BY C(11),UPD_TIME V(19),SYNC_TIME V(19),IS_DELETED L,IDENTITY_ID I"
o.SelectCmd = "Select * from PartyName where party_name like 'Lewis,%' order by party_name"
o.CursorFill()
Browse

* 3rd Browse
o.UseCursorSchema = .F.
o.SelectCmd = "Select COUNT(*) from PartyName where party_name like 'Lewis,%'"
o.CursorFill()
Browse

* 4th Browse
TEXT TO aa TEXTMERGE NOSHOW PRETEXT 15
	USE [deedroom]
	select COUNT(*) from PartyName where party_name like 'Lewis,%'
ENDTEXT

lnSqlResults = SQLExec(lnHandle, m.aa)
If lnSqlResults < 0
	Strtofile(m.lcSqlStr, 'PartyName.txt')
	Messagebox('A SQL error o...', 0, 'PartyName Table')
Endif
Browse


Define Class cPartyName As CursorAdapter
	Table = 'PartyName'
	DataSourceType = 'ODBC'
	Datasource = lnHandle
	UseCursorSchema = .T.
	SelectCmd ="Select page_type, party_name from PartyName where party_name like 'S%'"
	Alias = 'curpartyname'
	CursorSchema = 'PAGE_TYPE V(40),PARTY_NAME V(52)'
Enddefine

I need to add the other properties and methods to make it updateable.

Olaf, when you say 2-way, do you mean updateable?

Thanks, Stanley
 
Yes, with 2-way I mean updatable. Glad you got it going so far. I wonder if you won't override the same alias with every new sql and cursorfill, as you don't ever change the ca.allias property. I think you have understood what I meant and decided against that. Well, it's your choice. I just recommend one cursor per CA instance. You can reuse your class. You don't need to use the builder and you could override the init code, you already have understood what you need to do to get a basic ca class running, siumply put that into your own CA class, you are nort forced to use the builder, are you? It helps you understand and then you can pick the important stuff and go your own route from there.

Think about such a simple class hierarchy:

1. a (your) base CA:
It makes a connection or reuses it. A helpful function for that besides SqlStringConnect is ASQLHandles to find already established connections. Also you can put that into a public scoped object, eg goApö.nSQLHandle and then just do This.DataSource = goApp.nSQLHandle to resuse one connection for all CA instances.

2. A CAreader class based on the base class, you use to create readonly cursors, that can be used as you do.

3. A CA class for any table or more generically each Schema of data you want to query. That's sounding like lot of work, but you will not have to take that sthat literally and you gain from that, when you subclass and derive schemes from other schemes by adding a field to what you inherit, for example.

You can also change schema and other properties dynamically and store these property values in meta data, as you like. But for gods sake, have one CA object per cursor you maintain, even for the readonly cursors. CAs are quite lightweight object instances, you can create thousands in split seconds and as I tested this just allocates about a kB per CA, what takes time is make them query data, but in themselves they are lightweight and fast to create.

Even if you don't want to make use of the updatable feature in many cases, the cursor and before anything else all the cursor properties you can read with Cursorgetprop and write with cursorgetprop have to be thought of as properties of a Cursoradapter instance, even though they are only partly reflecte din CA properties. If you want to be clean, before you create a second cursor with the same CA instance, do CursorDetach. You can then think of the detached cursor as pushed on a stack and you can later attach it back to the CA. I don't really had use for that despite in one case I wanted to change the cursor buffer without affecting the backend database.

The way you use your CA you could also just to SQLEXEC() to create some cursors, besides where you use a schema, but you could also do CursorSetProp("MapVarchar",.T.,0) to set the default in regard of retrieving varchar backend fields as foxpro varchar, before creating any CA and before any cursorfill. It's not making much sense to need a ca just for that matter. If you want to use CA, then CA and use your opportuninties to build a class hierarchy.

Bye, Olaf.
 
Hi Olaf,

>> I wonder if you won't override the same alias with every new sql and cursorfill, as you don't ever change the ca.allias property.
Yes, I intend to overwrite the alias on the fly with the same layout as that would break a grid or form controls. I'll be changing the readonly, filter and order properties and whatever else that doesn't break the layout, which should cause no problems with grigs or controls.


>> I just recommend one cursor per CA instance. You can reuse your class.
That was what I wanted, "one cursor per CA" but couldn't get the CA to respect the new SelectCmd clause.


>> You don't need to use the builder and you could override the init code,... It helps you understand and then you can pick the important stuff and go your own route...
Yes, you learn a lot doing it manually, and I'm wondering why the CaBuilder9 .prg stuffed the init method with all that code that broke the way I was trying to get it to work.


>> Think about such a simple class hierarchy:
Now that I've got the preliminary stuff working, I'll then break it apart into their own class and subs.


>> 2. A CAreader class based on the base class, you use to create readonly cursors...
Looks to me like it would be easier to set the readonly 1-way properties than to maintain a set of readonly classes (one for each table).


>> CAs are quite lightweight object instances, you can create thousands in split seconds and as I tested this just allocates about a kB per CA, what takes time is make them query data, but in themselves they are lightweight and fast to create.
Excellent info, good to know, as I've never seen any stats like this before.


>> The way you use your CA you could also just to SQLEXEC() to create some cursors, besides where you use a schema, but you could also do CursorSetProp("MapVarchar",.T.,0) to set the default in regard of retrieving varchar backend fields as foxpro varchar, before creating any CA and before any cursorfill. It's not making much sense to need a ca just for that matter. If you want to use CA, then CA and use your opportuninties to build a class hierarchy.
I understand that SPT is strictly 1-way and CA is the best 2-way solution thats out now.

Can I use enough CursorSetProp commands to make SPT updatable?

Well, I just read another article that says ADO as more flexible that ODBC. Any truth to this?

Thanks, Stanley
 
>> I wonder if you won't override the same alias with every new sql and cursorfill, as you don't ever change the ca.allias property.
>Yes, I intend to overwrite the alias on the fly with the same layout
You didn't do that yet, so I couldn't see that you planned to. Also you can't do CursorFill(), that always will break a grid, you need to REQUERY(Ca.alias), That's also why you need to reuse the same CA for the same cursor

>> I just recommend one cursor per CA instance. You can reuse your class.
>That was what I wanted, "one cursor per CA" but couldn't get the CA to respect the new SelectCmd clause.
You still don't understand what an instance is. You worked with one instance, creating 4 differen result cursors. When you want a CA to respect a new SelectCmd, you already are saying you want to produce two cursors with the same CA. That's not what one cursor per CA instance means, is it?

What you should do is

* 2nd Browse
o2 = CreateObject('cPartyName')
o2.UseCursorSchema = .T.
o2.CursorSchema = "COUNTY_ID C(5),COUNTY_PAGEKEY C(14),PAGE_TYPE V(40),PAGE_DATE V(10),PARTY_NAME V(52),PARTY_TYPE V(14),PARTY_RACE C(1),CREATOR C(11),CREATION_TIME V(19),UPD_BY C(11),UPD_TIME V(19),SYNC_TIME V(19),IS_DELETED L,IDENTITY_ID I"
o2.SelectCmd = "Select * from PartyName where party_name like 'Lewis,%' order by party_name"
o2.Alias = 'curPartyNameBySchema'
o2.CursorFill()
Browse

...

You can put all the CA objects into one collection to have code like
oCAs=Createobject('collection')
o = Createobject('yourca')
o.Alias = 'aliasneeded' && must be unique to not overwrite other ca cursors, of course
oCAs.add(o,o.alias)

And then you can use a CA as in
oCAs.item('alias').CursorFill()

>> 2. A CAreader class based on the base class, you use to create readonly cursors...
>Looks to me like it would be easier to set the readonly 1-way properties than to maintain a set of readonly classes (one for each table).
I don't understand hohw you misunderstand me, I talked about classes here, you can make as many instances of such one caReader as you want, and thus don't need to maintain one class per readonly SQL. This is really the CA class you can use multiple times even for schematic totally different cursors, as you don't need the backlink to the remote database

>Can I use enough CursorSetProp commands to make SPT updatable?
Yes, they are all there, KeyFieldList, UpdatableFieldList, etc.

>Well, I just read another article that says ADO as more flexible that ODBC. Any truth to this?
Well, point to the article. If you read about VFPODBC and VFPOLEDB, that's true, the OLEDB is simply newer. But it's pointless, as you don't use the one or the other from VFP, they are there to enable developers in other languages to connect to DBFs. You do that nativly in VFP to get the most performant data access with all types, commands and functions VFP offers.
If the article is about other databases access drivers I would have to read it to confirm or deny. With CA you can choose whatever you like. Using ADO means an overhead of creating a recordset. The CA will also create a VFP cursor that you work on as with ODBC, but the way to the backend goes from VFP cursor over the recordset to the remote datbase, that's one layer more. If an OLEDB Provider is much better than ODBC, in the sense of functionaly or speed, that can compensate for that additional layer, of course. But in general VFP works best with ODBC drivers.

And MS has committed themselves to ODBC development. SQL2012 is the last SQL Server coming with OLEDB Providers. MS has given up establishing a proprietary new way, hey have put other technoligies on top of these low level connectors, like Dataset and Entity. These DotNet classes are on a higher abstraction level, like the cursor we use in VFP is making the remote database and how we connect irrelevant to us, I't still relevant for the performance, but if you encapsulate data retrieval in a good way, you can later switch whatever backend to use and the frontend can rely on the same VFP cursors being present and all that code can stay.

Bye, Olaf.





 
Hi Olaf,

>>> I wonder if you won't override the same alias with every new sql and cursorfill, as you don't ever change the ca.allias property.
>> Yes, I intend to overwrite the alias on the fly with the same layout
> You didn't do that yet, so I couldn't see that you planned to. Also you can't do CursorFill(), that always will break a grid, you need to REQUERY(Ca.alias)

The code that I posted as working starts with a specific select statement and field list and after executing a cursorfill(), I get the expected results. Next I change the select statement along with a different filter and field list and after doing another cursorfill() I get the expected results that has a different schema and results matching the different filter. Notice that I'm doing this to the same alias as I'm not changing it, I'm only changing the schema, filter and orderby. By changing the grid.recordsource to "" before and change it back to the cursor after it gets returned does not break the grid, so long as the schema of the grid matches the cursors schema.


>>> I just recommend one cursor per CA instance. You can reuse your class.
>> That was what I wanted, "one cursor per CA" but couldn't get the CA to respect the new SelectCmd clause.
> You still don't understand what an instance is. You worked with one instance, creating 4 differen result cursors. When you want a CA to respect a new SelectCmd, you already are saying you want to produce two cursors with the same CA. That's not what one cursor per CA instance means, is it?

No, no, no, I said I wanted to override each succesive selects, each with different schema, selects, filters, orderbys and joins. I'm thinking of a single CA that represents a single table and return cursor, but change the schema and select statement and other related properties. That is what I was able to get done with what I posted as working. Browse 3 and 4 both used a count(*) function and it done it as expected. Of-course, you would not do browse 3 or 4 while working with a grid, but browse 1 and 2 should be file. I done it here to see if it would do it and it did, as this would be useful for ad-hoc queries that I normally would do in vfp's command window... And yes, I use very little classes and need to work more with them.


> What you should do is
> * 2nd Browse
> o2 = CreateObject('cPartyName')
> o2.UseCursorSchema = .T.
> o2.CursorSchema = "COUNTY_ID C(5),COUNTY_PAGEKEY C(14),PAGE_TYPE V(40),PAGE_DATE V(10),PARTY_NAME V(52),PARTY_TYPE V(14),PARTY_RACE > C(1),CREATOR C(11),CREATION_TIME V(19),UPD_BY C(11),UPD_TIME V(19),SYNC_TIME V(19),IS_DELETED L,IDENTITY_ID I"
> o2.SelectCmd = "Select * from PartyName where party_name like 'Lewis,%' order by party_name"
> o2.Alias = 'curPartyNameBySchema'
> o2.CursorFill()
> Browse

Now that would break the grid unless you iterated through all grid controls and changed their recordsources to your new and different named cursor.field names. The way I done it allowed me to get the same result as you did, except I got it back in the same alias and doesn't break the grid.


> You can put all the CA objects into one collection to have code like

I'll be expermenting with this, thanks for the suggestive code...


>>> 2. A CAreader class based on the base class, you use to create readonly cursors...
>> Looks to me like it would be easier to set the readonly 1-way properties than to maintain a set of readonly classes (one for each table).
> I don't understand how you misunderstand me, I talked about classes here, you can make as many instances of such one caReader as you want, and thus don't need to maintain one class per readonly SQL. This is really the CA class you can use multiple times even for schematic totally different cursors, as you don't need the backlink to the remote database

Why wouldn't sitting the properties of a normal readwrite cursor to readonly for readonly work instead of maintaing a set of readonly CAs. You would need one for each sql table that I plan to read or write to. This current app has 30 tables, which would have 30 readwrite CAs and 30 readonly CAs. If I'm understanding you right, thats 60 CAs that needs creating and maintaining. Changing the updateable properties on 30 just seams like a lot of less work to me to get the same result.


>> Can I use enough CursorSetProp commands to make SPT updatable?
> Yes, they are all there, KeyFieldList, UpdatableFieldList, etc.

Good to here this, as I've been leaning toward SPTs while trying to understand the pros and cons of CA, SPT and views. I kept reading that SPT requires manual updating the backend, something that the CA has automated. Just verifying, you have just stated that by adding the update properties to a spt command wrapped in a vfp text/endtext statement gives me automated crud operations...

Thanks, Stanley
 
>Now that would break the grid unless you iterated through all grid controls and changed their recordsources to your new
>and different named cursor.field names. The way I done it allowed me to get the same result as you did, except I got it
>back in the same alias and doesn't break the grid.

No, you misunderstand again. The way you used the CA for your original 2. Browse you created a totally different cursor schema with the same alias name.

I changed alias because of that. If you change sql and the result schema, it seems to me you want 4 seperate cursors. 4 sepereate cursors will need four seperate names. Indeed later on I also propose to not change alias, but create 4 CA objects (4 instances), this way you will in the end only have 1 alias you set and reuse.

But, if you change alias of the CA, that leaves already created cursors untouched, alias property just determines the name of the next cursorfill you do. What you lose this way is the connection to the previous alias name. Therefore again: One CA INSTANCE for each alias. You can have several instances based on the same CA class, but each one has to have it's own alias name, not changing. The changing of alias was jsut an intermediate step, that should show you how you could create 4 cursors with one CA instance, showing you the problem you should have had with overwriting the same alias again ad again. It was not the final step of my thinking. I try to go one step after the other to enable anyonw following.

But even if you arrive thate and want to resue an alias name insetad of creating several cursors, Cursorfill will kill your grid in the same way, in which "Select ... from table into (grid.recordsoruce)" would do, even though it creates the same alias name. To be able to reuse an alias, the first step of the vfp runtime is to close it. That unbinds the grid already. You rather REQUERY() or do CA.CursorRefresh(), not Cursorfill(). If you made different experiences with Cursorfill() I'd be surprised, that is not normal, that is killing the grid.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top