Was File{PROP:Label} ever fixed?
Im not sure fixed is the right word, but as of writing this table{prop:field} is not documented to return anything (and it doesnât).
A topic and question lacking in details Is it FILE what you were asking about as âFâ could also be âFieldâ or âFEQâ ?
My tip for dealing File{PROP:Label}
not working is to use NAME(File)
or File{PROP:Name}
but âŚ
Name is sometimes blank (the likely cause of the error) so I use the Label of the First Field so you have the Prefix: giving at least some idea. I did this in the Legacy CheckOpen() generated code.
CheckOpen PROCEDURE(FILE File, ...)
NameOfFile PSTRING(256),AUTO !Name(File) or Prop:Label of 1st field
CODE
NameOfFile=CLIP(NAME(File))
! NameOfFile=SUB(NameOfFile, 1+ INSTRING('\',NameOfFile,-1,SIZE(NameOfFile)),255) !Cutoff path:
IF ~NameOfFile THEN NameOfFile='Name=Blank [' & File{Prop:Label,1} &']'.
...
OF InvalidFileErr !Invalid Record Declaration
IF StandardWarning(Warn:InvalidFile,NameOfFile).
The first field will often be be Pre:AutoNo
so probably should append the first 2 or 3 fields to help a bit more to id the file.
A sore subject with me after going through a lot of testing. Whether it be:
Field{PROP:Name}
File{PROP:Name,Field#}
File{PROP:Label,Field#}
Consider code to loop and generate a string of a column names in an sql table.
First, I certainly do not want READONLY or WATCH, I want only the external name of the field.
Second, if an external name is not specified, I want the field name WITHOUT the prefix.
Unless I missed something, for each PROP above, I do not believe these 2 simple requirements are possible.
Sorry, it was File{PROP:Label}. I didnât want to use NAME or {Prop:Name} as the label doesnât match the name.
File{Prop:Label} is âhardâ because the FILE structure, once compiled, does not include the Label. The reasons for that are historical, but the Compiled File Structure (FCB) happened before âpropertiesâ were a thing. They go back to the DOS days. And in those days memory was at a premium, so unnecessary things like âlabelâ were excluded. (Indeed, if the CREATE attribute was off, the labels of fields and keys was also excluded.)
So given that the properties are a function of the File Driver (ie the file driver returns them) and because the Label âdoesnât existâ - it canât be returned. So since the label doesnât exist anywhere itâs necessary to âsetâ it ourselves. This can be done, in Clarion 10 and later, using System properties.
System{'Label-' & Instance(Customers,1)} = 'Customers'
And then elsewhere;
whatever = System{'Label-' & Instance(Customers,1)}
Obviously you could make trivial 1 line functions to make this code a little bit more readable.
The nice thing about system properties is that they permeate through the system. So you can set it once, in say the exe, and then in all your code elsewhere (even in pre-compiled DLLâs) they are visible.
If I wanted this for all my tables (and I likely do) Iâd make a small extension template to generate the calls to set the labels. (Let me know if you need help with that.)
Update: Changed Address to Instance. This then works across threads if the FILE the Threaded
(and it likely is). Also fixed a couple typos.
(Iâve been experimenting in Clarion 11.1, but no idea if itâs different in earlier versions.)
Firstly, File{PROP:Name,Field#}.
In the SQL drivers, this returns the Name attribute (before the | char) if it exists, or the Label (without prefix) if it does not. I believe this conforms to what you are looking for.
ISAM Drivers (Topspeed, Clarion) behave differently.
What I do incorrectly?
test1.clw (1.3 KB)
Sounds reasonable and what I expected, but unfortunately not true. Just tested again and it returns blank when the Name attribute does not exist. Prompts me to wonder how the driver is different.
Hi Alexy,
youâre doing
Q.Label = F {PROP:Label, i}
which works fine
Ron is asking for
TableLabel = F {PROP:Label}
ie the Label for a FILE not a FIELD.
Hi Doug,
What Clarion, and what Drivers are you testing with?
Iâm testing in 11.1.13855 using the ODBC, MSSQL and SQLite drivers.
Cheers
Bruce
Yes, testing with v13855 using ODBC.
Impossible. The FILE structure (FCB) does not contain the label of a FILE in the program. If a FILE is declared locally in some procedure or routine, the compiler generates its FCB as private - without the public name. The program can associate desired string with particular FILE using TIE() or user-defined properties.
cool, Iâll make a small test you can compile and run tomorrow to see if you get different results to me.
yes, impossible with the current FCB structure. Of course if the compiler and FCB structure were updated, then⌠possibleâŚ
As I mentioned above, user-defined properties do work, obviously at the cost of having to set themâŚ
Here is a simple version of my test.
LOOP Ndx = 1 TO File{PROP:Fields}
IF Ndx = 1
SelStr = 'SELECT ' & File{PROP:Name,Ndx}
ELSE
SelStr = SelStr & ',' & File{PROP:Name,Ndx}
END
END
Nice idea! I would change 'Label-'
to some else like 'FileLabel-'
. This could be added to the Templates so it would be in all projects.
You could try using the Instance(File,1)
as the Index into one Property named âFile-Labelâ (note the Ampersand is now a Comma Instance() so an Index ):
System{'File-Label' , Instance(Customers,1) } = 'Customers'
I changed my template Standard.TPW the %StarndardWindowOpening to set 0{'Proc_Name'}='%Procedure - %Application'
so I can show the Procedure Name and App Name using WindowLabel{'Proc_Name'}
.
The âSystem Propertiesâ are called âUser Defined Propertiesâ in the documentation in this October 2015 Clarion Sharp Blog post.
The Readme.txt for that release
/--- Clarion 10.11975 --- October 27, 2015 ----- Fixes/Changes/Features--/ FEATURE: Implemented user-defined properties: A user-defined property allows you to associate a string value with any entity's standard properties for example: built-in variables (SYSTEM, PRINTER, TARGET), WINDOWs, REPORTs, controls, bands, etc. The syntax of user-defined properties is the same as for standard properties but string (constant or expression) is used to identify the property rather than property number: [target $] object {property-name [, index]} The name of the user-defined property is case insensitive. It cannot be equal to the name of any standard PROP:* property with or without "PROP:" prefix. The name also can't begin with Numeric digits. For OLE controls names of user-defined properties cannot be equal to any of the OLE/OCX's properties. If the index is missing or equal to 0, it is treated as 1. Examples: SYSTEM {'User-Name'} = 'Frank Sinatra' !Set the name of the current user MESSAGE('the user is: ' & SYSTEM{'User-Name'}) !displays the text 'Frank Sinatra'
From the Clarion Docs
Multi-Use File Structure Properties
PROP:Label
Returns the label of a declaration statement.
Means: listed properties can be used for different structures. Properties usable for particular structures are listed separately.
Read the text after this sentence. There are none mentions that the PROP:Label property can be used for FILEs. It is usable for keys, memos, blobs and fields.
Hi Douglas,
So I wrote a small example based on your code above. And got the same results as you. But since my test app gave different results I dug a bit deeper.
It seems that it matters if the file is Open or Closed, and incidentally if CREATE has been called or not.
If CREATE has been called, or the file is open (My Driver string is blank in the dict) then the prop:name behaves as I suggested. If the table is closed (ie this is first access) then prop:name returns blank if the external name is not set.
Obviously itâs trivial to make a function converting the label into the name (and setting prop:name if you like) and I expect there is such a function in the driver somewhere which does this. In your case itâs likely best to write such a function yourself, and call it on program startup or whatever.
But interesting to see it behave differently âŚ