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

How to interactively change control source of a grid at runtime?

Rifi59

Programmer
Joined
Jul 3, 2025
Messages
2
Hello everyone, I hope i can explain this well, so here it goes.
I have a folder, I've set it to be the default directory while i use fox.
Now I'm building a program that will have form1 as main screen
In that form users will be able to create new directories, in which they will work. (so someone who owns lets say 15 stores would open 15 directories)
I'm currently writting a code that will create tables in those new directories whenever they create a new one.
Form 2 is where they will be able to select other forms depending on what they wanna do (take care of quantity of stuff, accounting etc)
The part i struggle with is how to than set path to that new folder ive created with MKDIR().
So if i start from form 1 and select/create (example) as my directory, i want that to be the directory for the rest of their time using the program and only use tables from that folder, until they turn the program off/or i state in another code that they will open another or close this directory.
Here is the code i have for creating the folders if it means anything :
LOCAL direktorijum, putanja
direktorijum = ALLTRIM(ThisForm.Grid1.Column1.Text1.Value)
putanja = "C:\Trafika\" + direktorijum

* Create the directory if it doesn't exist
IF !DIRECTORY(putanja)
MKDIR (putanja)
ENDIF


ENDIF
DO FORM GLAVNA
And here is the code that i tried putting under this code, in an attempt to set path to that folder

LOCAL putanja1
putanja1 = 'C:\Trafika\' + ALLTRIM(firme.nazivfirme)
SET PATH TO (putanja1)
Currently i do have a code in there that creates 1 table, and it does save it to the path. But when i go further and open the form2
 
Also Its currently set to C:\Trafika but of course that will change to somehow letting them select their own default directory, currently i wanna get this part to work...
 
Last edited:
Is there a control source on the grid? You can set the control source in the LOAD event of the form.

I believe we need more info to understand what you are doing.
 
Hi

first store the full path to your desired directory by :

desireddir = fullpath(curdir()) + desireddirname
desireddir = addbs(desireddir) && adds a backslash to the full path of the directory

then :
set default to (desireddir)

let me know if this works for you

Regards
Ravi
 
SET DEFAULT or CD (change directory) is what you use to set the directory FoxPro first looks into for tables, for example. I see many legacy developers prefer SET DEFAULT, but CD actually does the same and simply resembles what you may know from DOS, just like MKDIR does.

SET PATH is like setting the DOS %PATH% environment variable it sets a directory (or indeed multiple directories when used with ADDITIVE, also accepts a list of directores. That's the wrong instrument to set the default or current directory.
 
Regarding your general idea of having a directory per store. Well, it won't solve the question you have per title, changing directory the grid won't change to the same table name in that other directory, just because you changed directory. Next time you start a form that does USE some.dbf after you CD it will open the table of that directory, so far so good.

If that's all you need, fine. But once a grid recordsource is set it's not depndending on the default path and doesn't switch with changing directory. The grid is bound to the alias and that workareas DBF is fixed until you close and reopen another DBF with same alias again, to which an already running grid won't react well, though.

The simplest solution, therefore, is to actually restart the form after a switch to another directory aka another store, so that store's (aka that directories) data will be used.

Also don't make use of the data environment for that strategy, as that almost fixes the path even though you can make it look in the default directory too, but only after it doesn't find a DBC or DBF that's stored in dataenvironment items in their database and/or cursorsource properties.

So a dataenvironment item will not first look into default directory but what it has been set to during development. Only after not finding them there refer to the default directory and then directories you set with SET PATH like the DOS %PATH% environment variable. And: Also important: If the paths of data environment items exists at runtime for the EXE (i.e. on your development PC, but not only there, necessarily) changing directory actually won't change what DBFs the data environment opens, as the given paths have first priority.

That way a dataenvironemt item differs from the simple usage of the USE command, which will first look into the default directory when you only specify the stem DBF name. So while a dataenvironment item is mainly like a visually designable USE command (with even more bells and whistles like also setting relations), it has other priorities of file opening. In short a DE is nice to be used when you develop locally and for yourself only, it's not well desgned for multi user and even less so multi tenant systems.
 
Last edited:
In my application framework, I define a property under the _VFP variable:

Code:
ADDPROPERTY(_VFP, "DataPath", "")

I set this to the path that contains the database that I am going to be working with. This allows me at design time to build the screens with the database tables referenced in the form's data environment (DE). In the DE's BeforeOpenTables() event I have the following code:

Code:
SetDBCPath(thisform.Dataenvironment, _VFP.DataPath, "Membership")

Where "Membership" is the name of the database. In the code for SetDBCPath() I have the following code:

Code:
FUNCTION SetDBCPath
LPARAMETERS toFormDE, tcDBCPath, tcDBCName
LOCAL lcDBCName, lcFilePath, lnNumCursors, lnNdx
lcDBCName  = FORCEEXT(tcDBCName, "DBC")
lcFilePath = ADDBS(tcDBCPath) + lcDBCName
lnNumCursors = AMEMBERS(lcProperties, toFormDE, 2)
FOR lnNdx=1 TO lnNumCursors
    IF UPPER(LEFT(lcProperties[lnNdx], 6)) = "CURSOR"
        IF ATC(lcDBCName, toFormDE.&lcProperties[lnNdx]..Database) > 0
            toFormDE.&lcProperties[lnNdx]..Database = lcFilePath
        ENDIF
    ENDIF
ENDFOR
ENDFUNC

This will change the database path to the run-time path. So, you would just set the property value _VFP.DataPath to the directory that you want to have opened. You should not have to change the form controls to point to a different location; this is taken care of for you by the DE event BeforeOpenTables().
 
Hi,

In my baseform class I have a method called SetDataBase. Code like below

Code:
Local cObjClass, cObjName, cOldDatabase, cNewDatabase, oReference
Local Array aCursors[1]


If Not (Empty(gcDrive) Or Empty(gcPath))
    = AMEMBERS(aCursors, THISFORM.Dataenvironment, 1)
    For i = 1 to ALEN(aCursors,1)
        If aCursors(i,2) = "Object"
            cObjClass = "THISFORM.DATAENVIRONMENT." + aCursors(i,1) + ".Class"

            If EVAL(cObjClass) = "Cursor"
                cObjName = "THISFORM.DATAENVIRONMENT." + aCursors(i,1) + ".DATABASE"
                cOldDatabase = EVAL(cObjName)
                cNewDatabase = AllTrim(gcDrive) + AllTrim(gcPath) + AllTrim(Substr(cOldDatabase, RAT("\",cOldDatabase) + 1))
                oReference = EVAL("THISFORM.DATAENVIRONMENT." + aCursors(i,1))
                oReference.Database = cNewDatabase
              
            Endif
        Endif
    EndFor
  
_Screen.Caption = gcCaption + " - " + gcDrive + gcPath + " - " + IIF(VARTYPE(oApp.cUser) = "C", oApp.cUser, "")
Endif

Then in each form's dataenvironment "BeforeOpenTables" event I call "ThisForm.SetDataBase".

In my menu I have a pad called "Change database" which calls

Code:
cNewPath = GetDir()

    If Empty(cNewPath)
        = MessageBox("Banque de Données n'a pas été changée!", 48, "Changer Banque de Données")
       
    Else
        If File(cNewPath + gcFile)
            = MessageBox("Le nouveau chemin est " + cNewPath, 48, "Changer Banque de Données")
            gcDrive = Substr(cNewPath,1,2)
            gcPath = Substr(cNewPath,3)
        Else
            = MessageBox("Banque de Données n'a pas été changée!", 48, "Changer Banque de Données")

        Endif
    Endif

The four variables gcCaption, gcDrive, gcFile and gcPath have of course to be defined up the hill

Et voilà!

hth

MarK
 
Last edited:

Part and Inventory Search

Sponsor

Back
Top