NAME() Comes Of Age
Posted March 8 1999
Various kinds of files, such as calendars, schedules, ASCII files, accounts, or files on other drives or other machines share the characteristic that multiple physical disk files can have the same structure. It is often desirable to have a single dictionary specification to declare that structure so that a single procedure set (application) can operate on them.
Clarion builds in this capability with the Name
attribute but provides no management capabilities. It is up to the
developer to manage which file is in process at any given time.
Of Syntax and Semantics
In Clarion, there are two keywords you must not confuse,
Label and Name.
Variables and data structures (which include windows, queues,
views and files) are referred to by their Label.
Clarion code always uses the Label.
Name is an attribute. Variables and structures may
or may not have a Name; in fact, they usually do not.
The contents of the Name attribute, if any, are
for use of an external object. This could be another program, like
a database engine or the operating system, or a Clarion DLL, like a
file driver.
In the case of data files, the Name attribute
contains the fully qualified directory entry for the file. For
example, a file declared as:
Customer File,Driver('Topspeed'),Name('foobar')
will look for or create a disk file called
foobar.tps in the current directory. Your code will
never contain this, only "Customer."
Multiple Files, One Declaration
To handle multiple physical files from a single logical
declaration use a variable in the Name attribute:
Customer File,Driver('Topspeed'),Name(GLO:FileName)
You create this in the Dictionary Editor by completing the
Full Pathname field on the File Properties worksheet
(Figure 1) and pre-pending an exclamation point.
Figure 1: Global Data Properties
This is where the fun starts.
If you declare a file like that in Figure 1, your app will not compile. The compiler error makes the reason clear: the variable was not declared. Not only must you declare the variable, you must do so before the file declaration. That means that you have to use the Before File Declarations source embed because the Global Data button places variable declarations after the file declarations.
Thus, global files (files in the dictionary) require a global variable. Files declared at the module or procedure level, in hand code, require only that the variable have the STATIC attribute (though it can be at a higher scoping level).
Next, having added the STATIC attribute, if you try to run the app, it will crash and burn. The variable is empty and the app does not know the DOS name of the file it is supposed to open
File() could not be opened. Error: Invalid Filename(45). You may initialize the variable any time you wish but obviously not later than the first attempt to open the file.
SetName
The ABC FileManager class also provides the SetName method to
set the value of the Name attribute. This method
allows you to set the variable directly, without an assignment.
Moreover, you can call this method in a procedure which does not
actually use the file(s) in question (it's a property of the
FileManager, hence available any time after the FileManager has
been instantiated). The app frame comes to mind, as does the global
Procedure Setup embed.
Citing advantages of SetName, Pierre Tremblay observes (in the OOP newsgoup):
The variable in the name attribute for the file structure doesn't need to be exported [from the data app]. The FileManager class is holding a reference for that var.
So, to "initilialise" this variable without having it exported from the DLL, the SetName method is the only way to go.
Note what Pierre says: the variable "doesn't need to be exported." Yes, this means that you do not need to declare the variable in the non-data app(s).
Rules for Name-ing
- Always use the file
Labelas declared on the File Properties worksheet in Clarion language statements; - When using a variable in the
Nameattribute, initialize it before any attempt to open the file; - A variable used as a file
Namemay contain any O/S-valid string; - To use a variable, pre-pend the
Full Pathnameentry on the File Properties worksheet with an exclamation point; - The variable name must be unique (of course);
- Declare the variable in your data application, before the file declaration.
Super Files
Topspeed files support a special syntax to allow multiple tables to be stored in a single file.
By using the special escape sequence '\!' in the NAME() attribute of a TopSpeed file declaration, you can specify that a single .TPS file will store more than one table. (C4 LRM)
When using the TopSpeed driver, if you wish to store multiple tables in a single physical file, separate the file and table names with "\!," as in TUTORIAL\!ORDERS. This refers to the ORDERS table in the TUTORIAL.TPS file. (C5 On-line Help)
The format of the Name entry is
file_name\!table_name which appears to
preclude using a variable in the Name attribute of a
TopSpeed file.
Appearances can be deceiving, for this is not the case.
Designate your variable on the File Properties worksheet and
initialize it in exactly the same way as any other
Name, but use the special syntax:
Authors_ = 'cwjfil\!Authors'
to initialize the variable. In this case, Authors_
refers to the Authors table in
CWJFIL.TPS.
Multiple Locations
The executable resides in one place but you need the ability to address files anywhere. The file might be in the current directory or in another directory. The files might be on a network drive. You can even map an IP address to a drive letter and use the Internet.
Figure 2: Setting an initial value for a file name variable.
Here, there is one file (set) but multiple possible paths. In these cases, the path tends to be variable while the actual name of the file tends to be a constant. If so, it makes sense to give the Name variable an initial value when it is declared (Figure 2). If you can get the path information separately, from an INI or configuration file or from FileDialog, just concatenate the two.
FilePath = GetIni('JtMatch','FilePath',,'.\JOBTRAK.INI')
Contacts_ = Clip(FilePath) & Clip(Contacts_)
Multiple Files
You want to work on one company's accounts then another's. Or you need to update Alice's calendar then Bill's.
You do not have to leave the browse, if you do not wish to (though, obviously, you can and this would be easier to program). All you need to remember is that you must close the current file before selecting the new file. Select the new file, prime the Name variable and refresh the browse.
If you have multiple Tabs and it is your intention that each Tab show a different file in the same browse, you must close, prime and reopen in ThisWindow.TakeNewSelection (ABC) or the ?CurrentTab .. New Selection (Clarion) embed.
Multiple DLLs
Now multiple DLLs are really fun if you use variables.
Each variable must be declared in each of the project's apps.
If you're new to multiple DLLs, you should check the documentation. The important thing is that each app in the project needs to reference the files. But only one should allocate memory for them. This means that in all apps but one the files are declared and the EXTERNAL attribute added. The one app without the EXTERNAL attribute is usually referred to as the "global data DLL" and usually contains only the file declarations.
In the global data DLL, you simply declare the variable and, if desired, give it an initial value.
In every other app, you must also declare each of the variables. Each variable must also have the External and DLL attributes, similar to:
Contacts_ String(64),External,DLL(dll_mode)
to avoid compiler warnings (lots). (You do not need to do this if you use SetName).
Until C5, the method of choice was to create a text file with the necessary declarations and Include it in each application. The required file is usually created by requisitioning and modifying the data declarations from the main source file of the data DLL.
A major enhancement in the C5 Dictionary Editor makes this a thing of the past, totally automating the process.
Figure 3: Dictionary Editor Global Data settings.
Using the new Global option in the Dictionary Editor (see Figure 3) creates a file-like structure accessible in your applications as Global Data. That is, after you declare, say, GlobalData, you insert each variable in the same way you would add file fields. So, from the point of view of the Dictionary Editor this is a file but when accessed within an application, it is handled like global data, as intended.
The only restriction is that if you add several variables to this "file," grouping your Name variables, they will share a common prefix.
However, all of your declarations will be included and included correctly in each and every application. That is, your global application settings for dictionary handling (viz., the external flag) will be picked up and applied correctly without further intervention. (You still have to initialize variables, so you still have to do something.)
Note: as of C5EE SR1, Arnor Baldvinsson has discovered, this works correctly only with the ABC templates. The requisite template code was not retro-fit in the Clarion template chain. These lines are found in ABProgram.tpw, 218-37 and should be compared to Program.tpw, 90-99. He states that the new lines can be successfully substituted for the old. A copy of the modified template is available at http://www.cwicweb.com/apps/cwlaunch.dll/download.exe.0
Summary
The Clarion language has supported variable file names since its very beginning. In CDD, support was added to the Dictionary Editor and, partially, to the AppGen. But, until Clarion5, we had to hand code many, if not most, of the required declarations.
"When it rains, it pours." Now you have two methods that are about as automated as you can get. How do you choose?-This is the most difficult possible choice: two solid, reliable and easy to use techniques.
Download the demo application.
Article comments
Search ClarionMag
From the archives
The New Clarion.NET Template Language - Is It Really Microsoft's T4?
10/22/2009 12:00:00 AM
At the Aussie DevCon, SoftVelocity president Bob Zaunere demonstrated a template written in the new .NET template language. But is it a new template language? Dave Harms argues it's really Microsoft's T4, and explains why that's a good thing.




Steve
Parker started his professional life as a Philosopher but now tries to imitate
a Clarion developer. He has been attempting to subdue Clarion since version 2007 (DOS,
that is). He reports that, so far, Clarion is winning. Steve has been writing
about Clarion since 1993.