There is no way to have application-wide routines. Application Programming only runs when the application is first started--the routines do not remain available.
On the other hand, each form has its own Global Code section, so when you switch forms you won't have access to code that is in another form just by using a procedure name.
FormRunCustomProgram can be used to run code in a different form, but that's usually poor programming practice. Someone changing the code in the other form is not likely to check every other form for cross-form dependencies. If the form that calls the other form's code is rarely used, it could be months or even years before the broken dependency is discovered, and at that point it might not be possible to determine what the former functionality was. Also, the form called must be open. And you can't use FormRunCustomProgram to run code in the current form.
Let's say you have a group of subroutines that reference fields in a particular form, e.g., [fields] FirstName, Surname, City. If you put that code in a separate program file and #include it in the Global Code section of some other form that does not contain those fields, when you load that form the code won't compile. With Sesame, either everything compiles or nothing compiles.
You can use one central external program file and #include it from various forms. For subroutines that are specific to particular forms, in the Global Code of the calling form #define something, e.g.:
(Global Code section) #define FORM_IS_EDUCATION_INFO "Education"
#include "Central_Program_Code_File.pgm" if not FileExists("Central_Program_Code_File.pgm") @MsgBox("","Can't find Central Program Code Include file","")
Then in the central program file use:
#ifdef FORM_IS_EDUCATION_INFO
(SBasic specific to that particular form)
#endif
(whatever)
----------------------------------------------------------------
Several caveats:
If you have multiple procedures in the code file, remember that ALL variables outside a particular procedure declaration must be defined before ANY commands. For purposes of compilation, the #include file is simply read in at that point. So, you can't perform a command and then #include a file that starts with variable definitions and then procedure definitions because from the compiler's perspective you are defining variables after code is run.
If you can, group all procedures specific to a specific form in a single #ifdef section.
In the procedure heading block it helps to mention which form calls that procedure, e.g.:
#ifdef FORMNAME_IS_STATUS // FORM: Status // ====================================================================== // SET SEARCH READABILITY [FORM-SPECIFIC] // Set the writability of the Search tab LE's // ====================================================================== Subroutine SetSearchReadability(vWritability as Int, vReadabilityPopup as Boolean) var vFieldStatus as String
ReadOnly(Search_File_No, vWritability) ReadOnly(Search_Account_No, vWritability) ReadOnly(Search_Related_Files_Info, vWritability)
If vReadabilityPopup { vFieldStatus = @Select(vWritability + 1, "Writable", "Read-only (grayed)", "Read-only (not grayed)") @MsgBox("","Search Tab Fields: " + vFieldStatus,"") } End Subroutine // SetSearchReadability
// FORM: Status // ====================================================================== // SET SEARCH TEXT COLOR [FORM-SPECIFIC] // Set the text color of the Search tab LE's // ====================================================================== Subroutine SetSearchTextColor(UpdateMode as Boolean) var fgRed as Int = 0 var fgGreen as Int = 0 var fgBlue as Int = 0
End Subroutine // SetSearchTextColor
// (... Other procedures... )
// #ifdef FORMNAME_IS_STATUS #endif
Note that #ifdef relies on the existence of the variable, not it's value.
Of course, your procedures can be set up that one parameter passed to them will trigger different sections of the procedure, e.g.
#ifdef ALL_PERSONAL_INFO_FORMS Function BioInfo(FirstName as String, MiddleName as String, Surname as String, Birthdate as Date, BirthPlace as String, SourceForm as String) as String var Result as String = "" Result = FirstName if SourceForm = "Full Data" then Result = Result + " " + MiddleName Result = Result + " " + Surname if SourceForm = "Full Data" then (include the birth date and birth place)
Return Result End Function // BioInfo // #ifdef ALL_PERSONAL_INFO_FORMS #endif
For that function, if a "Short Data" form exists that doesn't contain MiddleName, BirthDate or BirthPlace fields, when calling the function you would have to pass it "filler" information, e.g:
(From Full Data form)
#define FORM_IS_FULL_DATA "Full Data" #define ALL_PERSONAL_INFO_FORMS "Full Data" vBioInfo = BioInfo(FirstName, MiddleName, Surname, BirthDate, BirthPlace, "Full Data")
(From Short Data form)
#define FORM_IS_SHORT_DATA "Short Data" #define ALL_PERSONAL_INFO_FORMS "Short Data" vBioInfo = BioInfo(FirstName, "", Surname, @Date, "", "Short Data")
|