Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Multiple detail band?
Message
From
17/11/2001 12:51:58
Cetin Basoz
Engineerica Inc.
Izmir, Turkey
 
 
To
17/11/2001 11:58:59
Thomas Ianuzzi
Information Security Consultants, Inc.
Florida, United States
General information
Forum:
Visual FoxPro
Category:
Reports & Report designer
Miscellaneous
Thread ID:
00583125
Message ID:
00583128
Views:
27
>I would like to design a report which would list material detail for a job followed by labor detail. Material and labor are in seperate tables. So ideally I would like report bands which were:
>
>Report Header
>Material Header
>Material Detail
>Material Footer
>Labor Header
>Labor Detail
>Labor Footer
>Report Footer
>
>Is there a way to design this?

Thomas,
There are more than one way to do it. One trick is to put all items that would be printed into an (or more) array and call UDF as the field expression in report. UDF formats the array elements as string, one detail per line and returns as a whole. Second detail band emulating field calls UDF to return next array elems and so on. Before running report a single record cursor is created (dummy with a single logical field - since it's the smallest). Report prints the detail line as number of records in the alias - once. But as array processing is done report wouldn't know in fact what it's printing :)
Another approach is similar but this time really there are grouping and as many records as total detail lines printed. This again uses a fake cursor. Here is a sample code how fake cursor might look like :
select cust_id, Company, .t. as 't1' ;
	 from customer ;
	 where cust_id = 'B' ;
	 into cursor tablo1 nofilter
afields(arrT1) && Save Structure

select order_id, emp_id, order_date, order_net, .t. as 't2' from orders ;
	where cust_id = 'C' and order_date < {^1994/07/01} ;
	order by cust_id, order_date ;
	into cursor tablo2 nofilter
afields(arrT2) && Save Structure

select emp_id as 'employeeId', first_name, last_name, .t. as 't3' ;
	from employee ;
	into cursor tablo3 nofilter
afields(arrT3) && Save Structure

dimension arrNewStruc[alen(arrT1,1)+alen(arrT2,1)+alen(arrT3,1), alen(arrT1,2)]
acopy(arrT1,arrNewStruc,1,-1,1)
acopy(arrT2,arrNewStruc,1,-1,alen(arrT1)+1)
acopy(arrT3,arrNewStruc,1,-1,alen(arrT1)+alen(arrT2)+1)

create cursor myCursor from array arrNewStruc
append from dbf('tablo1')
append from dbf('tablo2')
append from dbf('tablo3')
browse && Check what cursor holds
Here unrelated records from customer, orders and employee are selected just to show fake cursor creation. Notice that in each select there is an extra logical .t. field (as 't1', 't2', 't3'). That serves as the grouping expression. It's only true for the table where content should be printed. In report you use as a 'print when' expression. Put fields from all 3 tables overlapping (you'd want to design as separate detail lines then group fields). It's a little cumbersome to create report layout but works nice (IMHO). Superior to other approaches as you aren't forced to monotyped fonts to provide column layout. BTW here in this sample fields were few to fit in a single cursor. You might as well select into different cursors and have one fake cursor keeping relations to those cursors. Its structure woud be somethin like :

KeyId, T1 L, T2 L, T3 L,...Tn L

Where reccount is the total of reccounts of other cursors.

Yet another approach create a cursor with one memo field, put the text in memo and run report. ie:
create cursor myDummy (RepField m)
insert into myDummy values (GetText())

function GetText
lcTempFile = sys(2015)+'.tmp'
set textmerge delimiters to '%','%' && Just for the sake of HTML tags here
set textmerge on
set textmerge to (lcTempFile) noshow
select FirstDetail
\My First Header
\%padr('MyHeader',fsize('myField1','FirstDetail'))%
\\    %padl('MyNumHeader',len('999,999,999.99'))%
scan
\%myfield1%
\\    %transform(myNumField,'@Z 999,999,999.99)%    
endscan
\MyFirstFooter
\MySecondHeader
*....
set textmerge off
set textmerge to
handle = fopen(lcTempfile)
lnSize = fseek(handle,0,2)
=fseek(handle,0,0)
lcContent = fread(handle,lnSize)
=fclose(handle)
erase (lcTempfile)
And another approach is to use word automation or execl automation.
Cetin
Çetin Basöz

The way to Go
Flutter - For mobile, web and desktop.
World's most advanced open source relational database.
.Net for foxheads - Blog (main)
FoxSharp - Blog (mirror)
Welcome to FoxyClasses

LinqPad - C#,VB,F#,SQL,eSQL ... scratchpad
Previous
Reply
Map
View

Click here to load this message in the networking platform