Welcome To The Home Of The Visual FoxPro Experts  
home. signup. forum. archives. search. google. articles. downloads. faq. members. weblogs. file info. rss.

  Ken Murphy
  Where is Ken Murphy?
 Ken Murphy

What is the difference between the “Private” and the “Default” data session? As strange as this may sound, there is absolutely NO difference. A data session is a data session is a data session. All data sessions are the same and no data session is “more equal” than any other data session :) The problem here is one of terminology. The wording used by VFP makes it sound like there is a “Private” data session that is somehow different from a “Default” data session. There is no difference.

When VFP starts, it gives you data session #1. Don’t believe me? In your command window try this command:
?SET(“DATASESSION”)  && display the data session ID

Before we delve into “Default” and “Private” data sessions, let’s look at what a data session is and how it works. Let us begin by opening a cursor in data session #1
CREATE CURSOR Junk (RecordID I AUTOINC, cText C(20))
INSERT INTO Junk (cText) VALUES ("One")
INSERT INTO Junk (cText) VALUES ("Two")
INSERT INTO Junk (cText) VALUES ("Three")

Just to make sure that we have that cursor created and open in the data session, bring up your data session window. In the VFP menu View->Data Session, or in the command window, issue the SET command. You will see the data session at the top of the window in the “Current Session” dropdown and you will see the cursor “Junk” open in the “Aliases” list.

Now to take it one step further, issue the following in the command window:
?SELECT(“Junk”)  && display the work area

So far, we have a cursor called “Junk” opened in work area 1 in data session number 1. Hmmmm … seems as if data sessions and work areas both have numbers attached and this is exactly correct. You can SELECT 1 to make work area 1 the currently selected work area and you can SET DATASESSION TO 1 to make Data Session #1 the currently selected data session. One would think that you should be able to SET DATASESSION TO 2, and get a new Data Session, but that won’t work – you get an error message “Session Number is Invalid.” If you wish to SET DATASESSION TO 2, you must first create that data second Data Session. So how do you create the data session?

The first thing to recognize is that a data session is simply a type of container object that holds (you guessed) cursors. If it is an object, then it must be instantiated before it exists. Let’s instantiate one.

Create a new empty modeless form and in the form properties, set the .DataSession property to 2 (Private Data Session.) (You could add tables and controls to it, but to save time, just leave it empty.) Now save that form, run it and minimize it. Now take a look at your Data Session window and you will see that you now have two data sessions in that “Current Session” dropdown. The first will be “Default(1)” and the second will be “Form1(2)” (or whatever your form is called.) Now you can go to your command window and

Now run the form again (without closing the first instance) and you will get a third data session (take a look at the data session window.) Close the first instance (the one that is minimized) and you will see that you now have data sessions 1 and 3. Close the second instance and you will be left with only data session 1.

Now go in and modify that form. Change the .DataSession property to 1 (default) save it and run it. Go to your Data Session window and you will see that you only have data session 1. Run your form again and you will find that you still only have one data session.

This is the key to using the form’s .DataSession property. If you set it to 1 (Default) you do not get a new data session. If you set it to 2 (Private) then you do get a new data session. In other words, when you see “Private Data Session” you can read this as “give me a new data session” and when you see “Default Data Session” you can read this as “do not give me a new data session, I want to move the record pointers in the existing data session.”

OK – so far, so good – I understand this so far, but so what? What does this give me? Why do I want to use a private data session and why do I want to have multiple data sessions? Let’s use a concrete example. Your company’s customer service department has a number of people who answer customer service telephone calls. When they are not on the telephone, they might be dealing with customer mail or email. One of your customer service reps is reading a letter from one of your customers. Of course, the first thing he/she does is to look up that customer in your Customer Maintenance form. Just as your customer service rep gets deeply involved in that customers record, what happens? Yup – you guessed it – the phone rings and it is a customer on the phone. (Murphy’s Law happens.) You do not want to make your customer service rep move off of the record he/she is working on. Instead, you want to allow that rep to open another instance of your Customer form. If you are using the “Default” data session, both instances of your Customer form will use the Customer table that was opened in Data Session 1. When the customer service rep looks up the telephone customer, the record pointer will move off of the customer he/she was originally working on. When he/she gets off the phone and goes back to that original customer record, you are going to get a telephone call – “THIS FORM OF YOURS JUST LOST ALL THE CHANGES I MADE!!!!!!” Private Data Session to the rescue!!! Set the form’s .DataSession property to 2 (private) and now you have two data sessions to work with. The record pointer in the first instance of that form is still with the original customer. The record pointer in the second instance is on the telephone customer’s record. When your customer service rep gets off the phone, and goes back to the first instance of your Customer form, his original record is still there safe and sound.

OK, now that you have a use for this private data session, what do you need to watch out for? Most developers run into problems with commands that are scoped to the data session. For example, SET DELETED ON is a command that is scoped to a data session. Go back into your form, make sure that the .DataSession property is set to 2 (Private) and in the .Load()
CREATE CURSOR Junk2 (RecordID I AUTOINC, cText C(20))
INSERT INTO Junk2 (cText) VALUES (“Junk1”)
INSERT INTO Junk2 (cText) VALUES (“Junk2”)
INSERT INTO Junk2 (cText) VALUES (“Junk3”)

Now, just to make sure that DELETED is indeed ON, in your command window:

You should see record 1 and record 3 in your browse window. Now run your form to create that second data session. When your form runs, the .Load() fires, you create the “Junk2” cursor and delete the second record. Minimize the form and go to your data session window. Select the “Form1 (2)” data session and you should see the Junk2 cursor. Click the “Browse” button. You would expect to see something similar to what you see in your first browse window – record 2 should not be there, but when you browse Junk2, you can see that deleted record! Close the browse and the form, go back into the form’s .Load() and add a SET DELETED ON as the first line of code. Re-run the form, minimize it; select the second data session in your data session window and browse Junk2. Now you will see that the second record is gone.

SET DELETED is not the only command that is scoped to the data session. Go into the VFP Help file and look up “Commands that Scope to a Data Session” for a complete list. OK, so how do you handle this? You can (as we did in the example) simply enter commands like SET DELETED ON into the .Load(), but doing that for each form would be a bit of a pain. A better way to do this is to use a custom class. In your form’s .Load()
LOCAL loSetup 
loSetup = CREATEOBJECT(“MyFormSetupClass”)
WITH loSetup
   .cDeleted = “ON”

Of course, you will need to define your class. Start with this:
DEFINE CLASS MyFormSetupClass AS custom
   cdeleted = "ON"
   Name = "myformsetupclass"
   PROCEDURE setupmethod
      LOCAL lcDeleted
      lcDeleted = This.cDeleted 
      SET DELETED &lcDeleted

(Note that I created this class visually and then simply copied the code out of the class browser to post it here. You can create your class visually too.)

Go ahead and create this class. When the form runs, the .Load() will instantiate your “MyFormSetupClass”, set the .cDeleted property and then run the .SetupMethod. When your .SetupMethod() runs, it looks at that .cDeleted property and uses it to SET DELETED. Run your form, minimize it, go into the data session window, select data session 2 and browse Junk2. You should only see records 1 and 3. If you were to use this type of class with your base form class, then you would never need to enter another SET DELETED ON for any of your forms ever again. (Of course you might want to check the form’s .DataSession property to see if it is private before calling the .SetupMethod().) Oh yes, you can also use this class in your Main.Prg too. Running it there will set up the environment for Data Session 1.

I did mention that there are other commands that are scoped to the data session. Go ahead and modify the class to handle those other commands. Create a property for the setting and then issue the SET command the same way you did for DELETED. There is your homework. Have fun. :)


subhankar pandey @ 3/27/2008 6:01:36 AM
Excellent !
I've also same problem with .DataSession(), Now Clear. and also very good example, in my end yr example(Customer Service) is exactly work here

Your Name: 
Your Feedback: 

Spam Protection:
Enter the code shown: