Wiki Home

Report Metadata

Namespace: WIN_COM_API
A Wednesday Night Lecture held on 2001/04/04 with John Koziol Visual FoxPro Mv P.

Report Metadata - How It's Stored and Interpreted

[21:00] {Evan Delay} The Wednesday Night Lectures is a weekly series of chats on topics of interest to VFP developers. The log for tonight log will be posted from a link off of Thanks to Cindy for editing and posting these each week.

[21:00] {Evan Delay} John is also a Microsoft Visual FoxPro Most ValuableP rofessional and a lead Technical Contributor for both the Distributed and Desktop VFP MS MCP exams. And, as of March 27, 2000 an MCSD. Owner of digital elite services. He also worked on both SQL Server 2000 exams

[21:01] {Evan Delay} Tonight's topic is Report Meta Data with the VFP Report Designer.

[21:01] {JohnKoziol} As some of you may know I spent a lot of time last year taking apart the FRX file, the main report metadata file

[21:01] {JohnKoziol} There were two results of that research: FRX2Word and an August 2000 Fox Talk article

[21:02] {JohnKoziol} Apparently, with VFP7, the FRX is not changing

[21:02] {JohnKoziol} It still will be used the same and interpreted the same

[21:02] {JohnKoziol} So when Evan asked if I wanted to do a topic, I thought it might be interesting to discuss the FRX since it will still be around when 7 ships

[21:03] {JohnKoziol} There are two main areas of concern when studying the way the FRX works and is put together: 1) The physical structure and what is stored where and 2) how ther values stored are used

[21:03] {JohnKoziol} I'd like to start by going over the physical structure a bit

[21:04] {JohnKoziol} The record layout for an FRX file is comprised of the following fields (and values):

[21:04] {JohnKoziol} 1) PLATFORM C(8) -- Always contains WINDOWS. This is a holdover from when Fox ran on multiple platforms

[21:05] {JohnKoziol} 2) UNIQUEID C(10) -- Simliar to SYS(2015) -- a unique value

[21:05] {JohnKoziol} 3) TIMESTAMP N(10,0) -- Timestamp for the last time the record was changed

[21:06] {DenisChasse} Is it too soon to ask a question?

[21:06] {JohnKoziol} 4) OBJTYPE N(2,0) - The type of report object that the current record is describing. Examples would be 7 for Shape, 23 for font object, 8 for field, etc.

[21:06] {JohnKoziol} No, Denis, ask away!

[21:06] {DenisChasse} Why a TIMESTAMP?

[21:07] {JohnKoziol} I would speculate that this is used for compile decisons (SET DEVELOPMENT). The value seems to be mainly the same for all records in the same FRX

[21:08] {JohnKoziol} Back to the list.....

[21:08] {CarlKarsten} how about a hold over from the multiplatform transporter days?

[21:08] {JohnKoziol} 5) OBJCODE N(3,0) -- Sort of a subtype depending on what the OBJTYPE is.

[21:08] {JohnKoziol} Could be, Carl....

[21:08] {CarlKarsten} (never midn that - it is what came to mind, but I don';t know why)

[21:10] {JohnKoziol} 6) NAME M -- Contains the variable name for variables, contains the type of object described if the dataenvironment or a DE object

[21:11] {JohnKoziol} 7) EXPR M -- For the report definition record (objtype=1) contains printer driver and setup information. For group headers, contains the group expr. For labels contains caption. For report vars, contains value to store. For DE and DE objects, contains properties and values

[21:11] {JohnKoziol} (I'm not going to list all of the fields, just the important ones)

[21:12] {JohnKoziol} VPOS N(9,0) -- Contains the number of columns in the report def record, for report objects, the vertical position. For fonts, character height in pixels

[21:13] {JohnKoziol} HPOS N(9,0) -- Left margin in report def record. For fonts, avg. character width in pixels. For report objects, relative horizontal position (relative to band the obj is in)

[21:14] {JohnKoziol} HEIGHT N(9,0) -- For bands, absolute height of band. For fonts, character ascent in pixels. For report objects, absolute height

[21:15] {JohnKoziol} WIDTH N(9,0) -- In report def record, width of each column. Report objects = absolute width. Font objects = maxium char width

[21:15] {JohnKoziol} ....there are a whole bunch more fields but we'll focus on these for now.

[21:16] {JohnKoziol} Any questions so far?

[21:16] {DenisChasse} no

[21:16] {CarlKarsten} n

[21:17] {JohnKoziol} BTW, this is documented in detail in my August 2000 FT article, available free at the Fox Talk website.

[21:17] {JohnKoziol} Now, the trick to working with FRX files is knowing how it positions objects, that is, how to interpret the height and width and position coordinates

[21:18] {JohnKoziol} The way the information is stored is - to say the least - a bit counterintuitive

[21:18] {JohnStAndria} Agreed

[21:18] {JohnKoziol} All coordinate values are either stored as 1/10,000 of an inch or 1/1,000 of a cm depending on your ruler

[21:19] {JohnKoziol} The ENU runtime defaults to inches; foreign versions default to cm basis

[21:19] {CarlKarsten} the table is not normalized - get used to that...

[21:19] {CarlKarsten} ENU?

[21:19] {JohnKoziol} English language - sorry -- jargon watch :-)

[21:20] {JohnKoziol} In my article, I called these units of measure FRU (FoxPro Report Units) .. I'll use that definition here for brevity

[21:20] {JohnKoziol} So how are they used?

[21:21] {JohnKoziol} Well ... in the report defintion record, WIDTH is the width of each column in these FRUs.

[21:21] {JohnKoziol} If the report contains one column, then it's the entire printable width

[21:22] {JohnKoziol} For report bands, only HEIGHT is stored in FRUs (as an absolute value)

[21:22] {JohnKoziol} All 4 coordinates (HEIGHT, WIDTH, VPOS, HPOS) are used for report objects (labels, fields, et al)

[21:22] {JohnKoziol} This is wheer is gets REALLY fun:

[21:23] {JohnKoziol} For report objects the 4 coordinates are used as follows:

[21:23] {JohnKoziol} VPOS = Absolute measurement of the object with the value of the graphical separator bands in the Report Desinger added in (!)

[21:24] {JohnKoziol} HPOS = Leftmost position of the object relative to the left margin of the current column

[21:24] {JohnKoziol} HEIGHT = Height of the object in FRU; WIDTH = Width of the object in FRU

[21:25] {JohnKoziol} Now here comes another number into the equation.

[21:25] {JohnKoziol} As I mentioned the VPOS value factors in the graphical separators between the bands in the Report Desinger, so you have to subtract those out to get a good relative placement value

[21:26] {CarlKarsten} to similivry that: VPOS is the placement you see in the GUI report tool

[21:26] {JohnKoziol} What are the graphical band heights? With inches, the FRU height is 1979.16666666, with cm it's 502.7083333

[21:26] {JohnKoziol} Carl: Yes

[21:26] {JohnKoziol} Thanks for the clarification

[21:27] {CarlKarsten} which you have to then do nutty things if you try and use it

[21:27] {JohnStAndria} Why such an odd value?

[21:27] {JohnKoziol} I think that's just the way it works out between pixels and the FRU, John

[21:27] {JohnKoziol} It took me close to forever to nail it down exatcly, I can tell you!

[21:29] {JohnKoziol} So what you have to do to interpret where the report objects are is to determine the starting VPOS for each band and the ending VPOS. Then subtract out the separatoir for each object, then compare the VPOS of the object to the range for each band

[21:29] {DavidStevenson} One more heckler has arrived...

[21:29] {JohnKoziol} Hi Dave...

[21:30] {JohnKoziol} Anyway, the result is that you have to establish the bounds of the bands by one passs though all the band OBJTYPEs and then another pass for each report object to determine actual band and position relative to the band

[21:30] {JohnKoziol} Any questions?

[21:30] {DenisChasse} n

[21:31] {Evan Delay} Just dazzled

[21:31] {JohnStAndria} What can you do with all this info?

[21:31] {JohnKoziol} Sorry -- but it is a heavy topic :-)

[21:31] {JohnKoziol} Well, John, you can do a lot of things. You can take the report apart and lay it out in another application, such as Word or even Visio

[21:31] {CarlKarsten} perhaps a 'simple' example of what you can do

[21:32] {JohnKoziol} You can emulate the repor engine with external output, such as what I did in FRX2Word

[21:32] {RandyJean} Did anyone mention the \VFP98\Filespec folder. All metadata is documented in there with reports, etc.

[21:32] {JohnKoziol} Randy: Yes...but it's not always right

[21:32] {DenisChasse} About the FRX: Why make something simple when you can make it complicated :-)

[21:32] {CarlKarsten} lol

[21:32] {JohnKoziol} Randy, for example the MS docs say that NAME holds the filename for bitmap objects ... WRONg

[21:33] {JohnKoziol} The STYLE field is also incorrectly documented

[21:33] {JohnKoziol} TAG field as well...

[21:33] {DenisChasse} ROFL

[21:33] {JohnKoziol} ....shall I go on? :-)

[21:33] {JohnStAndria} yes

[21:33] {RandyJean} No! I get the idea {g}

[21:33] {JohnStAndria} oops - no

[21:34] {JohnKoziol} I wasn't trying to be facetious....I could list more errors is what I meant :-)

[21:34] {Evan Delay} Yes

[21:34] {JohnKoziol} The RESOID field. What the hell is it?? I dunno...not documented and I never figured it out

[21:34] {CarlKarsten} may I drop in my simple example?

[21:35] {JohnKoziol} Sure thing!

[21:35] {CarlKarsten} if you waned to know what all the fields were that a report used

[21:35] {CarlKarsten} you could click on e3ach objec in the GUI and write it down

[21:35] {CarlKarsten} or suck them from the FRX

[21:36] {CarlKarsten} I have a few more, but now you know that there are things that you can do t hat are not a major undertaking

[21:37] {CarlKarsten} Ill dig them up and drop them on the wiki later. (the end)

[21:37] {JohnKoziol} You could actually "suck out" anything. Let me list what the OBJTYPES are:

[21:37] {JohnStAndria} Are there any guidelines on adding an object to a given band in the FRX/

[21:38] {JohnKoziol} 1 = Report def record. 5 = Label. 6 = Line. 7 = Shape. 8=Field. 9 = Band record. 17 = Bitmap. 18 = Report var. 23 = Font object. 25 = Dataenvironment record. 26 = DE object

[21:39] {JohnKoziol} John...simply that the VPOS coordinate has to be *right* .. that is, in the band's range with the separators factored out

[21:39] {JohnKoziol} BTW, if OBJTYPE = 9 (Band), then OBJCODE defines the band object type

[21:40] {JohnKoziol} 0 = Title. 1 = Page header. 2 = Column header. 3 = Group header. 4 = Detail. 5 = Group footer. 6 = Column footer. 7 = Page footer. 8 = Summary

[21:41] {JohnKoziol} Any other questions?

[21:41] {JohnKoziol} Thinking lots about this?

[21:42] {JohnKoziol} Anyway, alluding to John's question, it would seem to me that a much nicer report writer could be written that exports out an FRX file.

[21:42] {JohnStAndria} What role does the record order play in this?

[21:42] {JohnKoziol} John: Good question. I have moved reocrds around as an experiment and it seemed to have no effect on output

[21:43] {DenisChasse} I was thinking the same. I could'nt do it though. Right now I know just enough to get myself in trouble

[21:43] {JohnKoziol} It is also apparent that the report engine can interpret more values from FRX fields than is supported by the Report Designer

[21:44] {JohnKoziol} Intriguing, hmm?

[21:45] {JohnStAndria} What do you mean more values that supported by RD?

[21:45] {JohnKoziol} I think this functionality is what Markus Egger took advantage of to a degree in his GENREPOX

[21:45] {RandyJean} (which I keep telling myself I will implement one of these days {g})

[21:45] {JohnKoziol} For example, the FONTSTYLE value of 128 = Strikeout ... the Report Desinger doesn't have that as an option

[21:46] {JohnStAndria} Did you determine that based on experimentation?

[21:46] {JohnKoziol} John: To a degree. But also noticed that some values matched up to Word enumerated constants and tried those values and, for the msot part, they worked

[21:49] {JohnKoziol} If you want to see how this all comes together in an app, look at FRX2Word ... it's freeware and all the source is there

[21:51] {JohnKoziol} What's even harder than figuring out the values and how they work is how it's interpreted at runtime (oy veh!)

[21:52] {JohnKoziol} One of the hardest things I had to overcome with FRX2Word was duplicating crummy Report behavior when I didn't want to.

[21:52] {RandyJean} hehe!

[21:53] {JohnKoziol} For example, the weird things it will do with group footers and summary bands when runnin out of space.

[21:53] {RandyJean} It's a beast, but it can be tamed. {g}

[21:53] {JohnKoziol} Yes.

[21:54] {JohnKoziol} Well -- I think this is the end of the formal discussion .. everyone is welcome to hang out and drink a few virtual beers and chit chat

[21:54] {RandyJean} Anyone ever try working with Access report writer? I shudder to think about it. Maybe it's better and I just don't know it.

[21:54] {JohnKoziol} It ain't much better

[21:55] {JohnKoziol} But at least *it* has an object model that can be manipulated

[21:55] {RandyJean} I finally figured out how to do what I needed, but it wasn't easy.

[21:55] {JohnStAndria} Is that object model documented?

[21:55] {JohnKoziol} Yes it is

[21:55] {JohnKoziol} MS Press Office 2000 VBA Programmers Language Reference

[21:56] {JohnStAndria} I use Access to prototype a report. Sure would be nice to convert to VFP.

[21:56] {DenisChasse} Thanks for that presentation John. You gave me a real good reason to look at FRX2WORD

[21:56] {RandyJean} I mainly didn't like the positioning tools OR the way if you drag an object too far, your report dimensions change automatically.

[21:56] {JohnStAndria} JohnK: Thanks for that reference - will look into it.

[21:56] {JohnKoziol} Thanks Denis

[21:56] {JohnKoziol} Thanks John

[21:56] {CarlKarsten} found my list of frx tricks

[21:56] {CarlKarsten}

[21:57] {JohnKoziol} Randy: But it's fitting with the behavior that Access tried to shieldf the users from themselves

[21:57] {JohnKoziol} Carl: Post that on the Wiki!

[21:57] {JohnStAndria} RandyJ: Also, when you copy/paste, the object pastes at the left margin. What a bummer.

[21:58] {JohnStAndria} Beging able to resize/change properties on multiple objects at once is a plus

[21:58] {RandyJean} John: agreed! I hate that about FRX writer

[21:59] {DenisChasse} Any chance of Crystal Reports coming with VFP7?

[21:59] {JohnKoziol} BTW: The printer properties in the EXPR record map to the same enumerated constants as found in VB ... not Office so you have real fun when exporting to Office

[21:59] {JohnStAndria} JohnK: The format of VPOS is N(9,3). Is this rounded() - you said FRU was 1979.166666 or something like that.

[21:59] {RandyJean} The other nice thing in Access is that there are actual events you can code in in the report object.

[21:59] {JohnKoziol} The graphical separator band in the screen is 1979.1666666

[22:00] {RandyJean} Can be accomplished with UDF's mostly, I suppose.

[22:00] {JohnKoziol} If you don't use the whole value, you;ll get creeping placement errors

[22:00] {JohnStAndria} Right, but didn't you say you have to add that value to get VPOS?

[22:00] {JohnKoziol} Subtract it our to get the band's VPOS

[22:01] {JohnKoziol} Yes, and you will get fractional values that *work* -- trust me on this

[22:01] {JohnKoziol} Strange but true

[22:01] {JohnStAndria} {blush} - I'm confused.

[22:01] {JohnStAndria} Is Crystal reports any better at all of this?

[22:02] {JohnKoziol} John: DL my article from Fox Talk ... explains it better than I can here in the Chat environment

[22:02] {RandyJean} Carl, if you could make a Windows version of that FRXDUMP, that would be cool! hehe

[22:02] {JohnStAndria} I read that article. It was deep there too!

[22:02] {JohnKoziol} Craig Berntson swears by CR. But I haven't used it in a long time

[22:02] {CarlKarsten} might work...

[22:02] {JohnKoziol} John: Yeah, but I give examples.

[22:02] {JohnStAndria} Agreed.

[22:03] {JohnKoziol} John. You have to go that deep with the decimals to let rounding take over with cumulative graphical bands

[22:04] {JohnKoziol} You want a progression of .167, .333, and .500 with rounded numbers or the comparison with the stored VPOS numbers will fail

[22:05] {JohnStAndria} I understand more now. I need to go re-read your article and play a bit.

[22:05] {JohnKoziol} If you start with .166000 you'll get .166, .332, .498 --- see?

[22:05] {JohnStAndria} Right.

[22:05] {JohnKoziol} Those .001s make a difference if a Line is right on the very bottom margin of a band

[22:06] {JohnStAndria} You could probably cut the top of a field off as well.

[22:06] {JohnStAndria} DenisC: You mentioned Crystal Reports. Have you had good luck with it and VFP?

[22:06] {JohnKoziol} Well, no. Because you are traversing downwards, any error would be to th elower bands

[22:07] {DenisChasse} JoshS - I never used it.

[22:07] {DenisChasse} JohnS - I'm just wondering if it'll come with VFP7

[22:07] {JohnKoziol} Denis: No

[22:07] {CarlKarsten} JohnS - once you 'need' to understand an object's VPOS, it will make much sense

[22:08] {CarlKarsten} here is an example:

[22:08] {JohnKoziol} Howver, we *are* getting a replacement for the Setup Wizard. It'll be public knowledge what it is soon.

[22:09] {CarlKarsten} lets say you have an existing report, and you want to make all the colum headers bold

[22:09] {CarlKarsten} you need to find all of the lables that are on a header band

[22:09] {DenisChasse} Anybody here ever used ABC reporting?

[22:11] {CarlKarsten} JohnS - so you need to figure out what text objects are in the page header

[22:11] {RandyJean} I'm bushed. Goodnight all!

[22:11] {CarlKarsten} that would be all the objecs whos VPOS is between the top and bottem of the page header band

[22:11] {CarlKarsten} opps

[22:12] {CarlKarsten} that would be all the objecs whos VPOS is between the top and bottem of the page header band's VPOS

[22:12] {JohnKoziol} Oh it was? Great

[22:12] {JohnStAndria} This is where the "range" comes in the JohnK mentioned.

[22:12] {CarlKarsten} right

[22:12] {CarlKarsten} the bands are defined by their own height

[22:12] {JohnStAndria} That's why record placement in the FRX doesn't matter -.

[22:12] {CarlKarsten} correct

[22:12] {JohnKoziol} yes

[22:13] {CarlKarsten} hmm, exeept for the group band definitions

[22:13] {CarlKarsten} i think...

[22:13] {JohnKoziol}, I tried rearranging them, too

[22:14] {JohnStAndria} Is it my imagination, or does the Report Designer reorder those records somehow?

[22:14] {CarlKarsten} what defines their order?

[22:14] {JohnKoziol} I guess they are defined by OBJTYPE and OBJCODE at runtime

[22:14] {CarlKarsten} right, but if you have to groups

[22:15] {JohnKoziol} EXPR

[22:15] {CarlKarsten} that dosn't define which comes first

[22:15] {CarlKarsten} outer vs inner

[22:15] {JohnKoziol} Wait a, you're right....the first footer record will match up with the last I remember

[22:15] {JohnKoziol} I remember that effing me up in FRX2Word

[22:16] {JohnStAndria} So detail records must be the "innermost" records ?

[22:16] {WilliamSanders} yes JohnSt.

[22:16] {CarlKarsten} um, no

[22:16] {WilliamSanders} um, no..

[22:16] {JohnStAndria} :?

[22:16] {CarlKarsten}

[22:16] {JohnKoziol} Innermost band, yes

[22:16] {CarlKarsten} eh?

[22:17] {CarlKarsten} you can only have 1 detail band

[22:17] {JohnKoziol} I'll have to look ... can I add to it?

[22:17] {JohnKoziol} You can have MORE than one

[22:17] {CarlKarsten} ummm

[22:17] {CarlKarsten} what?

[22:17] {JohnKoziol} Yes you can

[22:17] {JohnStAndria} What's that? You can have more than one detail band?

[22:17] {CarlKarsten} you can have a big band, but it is still only one

[22:17] {JohnKoziol} But ( but BUT here) it totally weirds out the output and the report designer

[22:18] {CarlKarsten} back to my example of bolding the colum headers

[22:18] {CarlKarsten} to get the range of page header objects, add up the height of

[22:18] {CarlKarsten} all the bands above the page header

[22:19] {CarlKarsten} hmm, thats just the title

[22:19] {CarlKarsten} that wasn't much of an example

[22:19] {JohnStAndria} Bolding the labels in the third group header is a valid example.

[22:20] {CarlKarsten} yea, do that.

[22:20] {CarlKarsten} :)

[22:20] {JohnStAndria} Thanks Carl. I will download the frx tips article you mentioned earlier.

[22:20] {CarlKarsten} gota run.

[22:20] {JohnKoziol} See ya Carl

[22:20] {CarlKarsten} later gonz

[22:21] {JohnStAndria} Thanks JohnK

[22:21] {JohnKoziol} I must run too before my wife sues for divorce....any questions on this, feel free to email me at

[22:21] {JohnKoziol} You're welcome, John

[22:21] {Evan Delay} Thanks John.

[22:23] {Evan Delay} Well, that's if folks. Thanks for coming

See also: Frx Constants
Aug 2000 Fox Talk article: Demystifying Visual FoxPro Report Files by John Koziol
Contributors: John Koziol, Evan Delay, Cindy Winegarden
Category Wednesday Night Lectures Category VFP Meta Data
( Topic last updated: 2001.04.07 06:24:54 PM )