2
votes

First let me say that I am very, very new to FoxPro and finding just the basics a bit of a learning curve.

I am attempting to create a program file (.prg) that has some public functions that I can call from my main code. I have added the program file "publicfunctions.prg" and included a simple function that returns a hard coded literal (just trying to make the mechanics work)

*!* This function is in the publicfunctions.prg file
FUNCTION GetFieldValue
    RETURN 'This is the value'
ENDFUNC

Then in my main program I attempt to use it but I am getting the error that the file does not exist. Here is the entirety of the code in the main program

*!* This is the main program logic    
SET PROCEDURE TO publicfunctions.prg

PRIVATE sFieldValue = ''

sFieldValue = GetFieldValue()

The error that I am getting is on the 'SET PROCEDURE TO publicfunctions.prg' statement. It is: "File 'publicfunctions.prg" does not exist."

I'm guessing that it can't find it because the default directory is not set to the path where the file exists. I tried adding the "SET DEFAULT TO" statement prior to the "SET PROCEDURE TO" statement but it didn't change the outcome at all.

I don't want to hard code the path so I guess my questions are these:

  1. Is my assumption correct about the default directory?
  2. If #1 is true then how can I set the default directory to the directory where the main program file is?
  3. Am I calling the function correctly? (If it can find it of course)

UPDATE
Per Hank's questions below I have added this additional information: The file "publicfunctions.prg" was added to the project using the "New" button on the Project Manager and the physical file is sitting right next to the "Main.prg" file in the file system folder.

enter image description here

enter image description here

I am using Microsoft Visual FoxPro 9.0

Any and all help will be truly appreciated.

Thanks,
Doug

5

5 Answers

4
votes

VFP maintains a search path (which is separate from the Windows/DOS search path), which it will search for any PRGs, DBFs, etc that you reference in your code.

You can check its current setting with the SET('PATH') function, and set it with SET PATH TO. These places are searched in addition to whatever the current default directory (which you can verify with the SET('DEFAULT') and CURDIR() functions.

This will show what these currently are:

WAIT WINDOW 'Path: ' + SET('PATH') + CHR(13)+CHR(10) + 'Default drive: ' + SET('Default') + CHR(13)+CHR(10) + 'Current directory: ' + CURDIR()

These are documented well in VFP's help - check there for a much better explanation.

3
votes

One other comment here. Since you're new at VFP, you might as well start off on the right foot. Most VFP experts recommend not using procedure files. Put each function or procedure in a separate PRG file with the routine name as the file name. For example, your GetFieldValue function should be in GetFieldValue.PRG.

SET PROCEDURE goes back to early Xbase days before there was a Project Manager.

2
votes

As Tamar has mentioned about trying to avoid using such "SET PROCEDURE" file, I would STRONGLY recommend having a well structured directory for your project. Having all the files all in one place can be a total pain... Historically, I've done something like

C:\SomeFolder\MyProject
C:\SomeFolder\MyProject\classes
C:\SomeFolder\MyProject\data
C:\SomeFolder\MyProject\forms
C:\SomeFolder\MyProject\graphics
C:\SomeFolder\MyProject\prgs
C:\SomeFolder\MyProject\reports

Then, respectively put your files in their respective locations. Your add them to your project manager the same way and keep the "relative" path to the files.

As noted above, having your "Data" for the application separate makes for easy copy/paste of backup, simulate, debug testing of data sets over and over when needed. When trying to open your files, you can reference opening files based on a qualified path + table name INSTEAD of using "SET PATH". Too many times in the past have I had systems that relied on "SET PATH", and would choke, or find a file that was an old version to something and NOT be the one expected. My approach is... If I can't find it WHY. Find it, put it in the proper location and then continue.

As mentioned with the data, say you have tables "customers" and "orders" in the "data" directory. You could have a variable and refer to that in both querying, or opening files...

PUBLIC myDataPath as String
myDataPath = "Data\"

use ( myDataPath + "Customers" )
select 0
use ( myDataPath + "Orders" )

If trying to query, you could do something like

select ;
      c.FirstName, ;
      c.LastName, ;
      o.OrderID, ;
      o.OrderDate ;
   from ;
      ( myDataPath + "Customers" ) c ;
         JOIN ( myDataPath + "Orders" ) o ;
            on c.CustomerID = o.CustomerID ;
   into ;
      cursor C_SomeSampleResult READWRITE

This way you'll NEVER have an ambiguous WHICH table version does it THINK its trying to get data from. Again, if it can't find the file, you have a bigger problem to resolve first.

2
votes

If you want your application to run anywhere you want to put in the programs and table.

You just have to add this...

SET DEFAULT TO SYS(5)+CURDIR()
SET PATH TO SYS(5)+CURDIR()

PS. Take note that this would only take effect when the project is in distributive (.exe) code only. You have to set the path and default at the development stage of the program.

1
votes

With FoxPro, the file 'has' to be in the search path. So if your building a project, add the file publicfunctions.prg to the project file under the code tab, if you're not building a project make sure that in the Options you have the folder where the prg located can be seen.

Also it helps if we know what version of Fox you're using.