by Dr. Peter Wayne
This article grew out of a discussion at the July 2002 New York Alpha Five Users' Group meeting. It started with a comment made by Mike Pesach about an application presented by Daniel Weiss, and developed into the short scripts presented here. |
Frequently the application designer (thats you!) will need to initialize a series of global variables when the application starts. Typically these variables will include the sites name, perhaps the license number of the application, the sites address, and other site-specific data that will appear on reports and forms throughout the application.
The usual way these variables are stored is to place them in a single table, sometimes called site.dbf or main.dbf, with one field for each variable. As the application designer, you enter the site-specific values into each field. For example, here is the structure of a hypothetical app_site.dbf:
Field Type Width
Site_Name C 100
Registered L
License_Num N 6,0
Version N 6,2
Telephone C 14

And we would typically fill in the fields from the default form or browse:
Our autoexec script would read the site-specific parameters into global variables, as in
dim global site_name as c
dim global license_num as n
dim global registered as l
dim global version as n
dim global telephone as c
dim t as p
t=table.open("app_site",file_ro_shared)
site_name=t.site_name
license_num=t.license_num
registered=t.registered
version=t.version
telephone=t.telephone
t.close()
Script 1. Typical application's autoexec script.
What happens if, as our application evolves, we need to add another global variable to the application? We have to change the structure of site.dbf, make the field entry in the default form, and then change the autoexec script to create the new global variable and read it from the app_site table. Although this is not very difficult with one site, if you are fortunate enough to have your application at multiple sites, then as you keep making changes at one site or another you are faced with the daunting task of either updating all your sites, or keeping track of which site has which version of app_site.dbf. Is there a more generalizable way to add new site-specific data to each database?
You betcha there is! In Application Programming for Alpha Five, published by Alpha Software, I show how you can write data directly to the applications .adb file. That method works only for Alpha Five version 5. Here I will develop a different technique, one that is equally applicable to versions 5 and 4.5.
We start by creating a new table, app_settings.dbf, with 3 fields,
my_var, my_type, and my_value:
Each field is of type Character.
I then fill the table with the variables, their types, and values specific
to the site. Each variable occupies one record in this table:

Notice that the values for the character variables are surrounded by quotation marks, and the logical field contains .T. or .F., that is, the same syntax used in Alpha Five expressions must be used in this table.
We then create a script that will read each record in the table, create global variables, and then initialize them. In v5, the process of creating global variables is made simple by a function, evaluate_template(cmd_string), which executes the code found in cmd_string. It is similar to eval() but can execute commands that cause eval() to choke. For example, we can use evalute_template() to execute
evaluate_template(dim global site_name as C)
This command cannot be executed by the eval() function.
So, in v5, we can write this autoexec script:
t=table.open("app_settings",file_ro_shared)
t.fetch_first()
while .not. t.fetch_eof()
evaluate_template("dim global "+trim(t.My_var)+" as "+trim(t.my_type))
evaluate_template(trim(t.my_var)+ "=" + trim(t.my_value))
t.fetch_next()
end while
t.close()
end
Script 2. Autoexec script for A5v5.
This simple script loops one at a time through each record in the
app_settings table, reads each record, creates the global variables and
initializes them to the appropriate values. After the script has run, we can
inspect the list of global variables (in v5, there is a special dialog box that
shows global variables):

But what if you are still working in v4? There is an old function, submit(), around since Alpha Five version 1, that accomplishes pretty much the same thing that evaluate_template() does, except that submit() requires the session handle of the A5 session in which the cmd_string will be executed. Fortunately, there is a companion function, session_get(), that returns the session handle. So in v4.5 we can write
t=table.open("app_settings",file_ro_shared)
t.fetch_first()
while .not. t.fetch_eof()
submit(session_get(),"dim global "+trim(t.my_var)+" as "+trim(t.my_type))
eval(trim(t.my_var))=eval(trim(t.my_value))
t.fetch_next()
end while
t.close()
end
Script 3. Improved Autoexec script for A5v4.5
In v4.5, you can inspect the global variables through the Xbasic Explorer:
We can see that these global variables were properly initialized.
Lets put it all together with a script that will work in either v4.5 or v5. We will call on the built-in A5v5 function version(), which returns the version number of Alpha Five. In v4.5 this function is undefined. We will place an error trap in our code so that if we are not in v5 we will execute v4.5-specific code, but if we are in v5 we will execute v5 code:
t=table.open("app_settings",file_ro_shared)
t.fetch_first()
on error goto not_5
if version()>=5 then
on error goto 0
while .not. t.fetch_eof()
evaluate_template("dim global "+trim(t.My_var)+" as "+trim(t.my_type))
evaluate_template(trim(t.my_var)+ "=" + trim(t.my_value))
t.fetch_next()
end while
end if
t.close()
end
not_5:
while .not. t.fetch_eof()
submit(session_get(),"dim global "+trim(t.my_var)+" as "+trim(t.my_type))
eval(trim(t.my_var))=eval(trim(t.my_value))
t.fetch_next()
end while
t.close()
end7/14/02
Don't forget, we need your feedback to make this site better!