günther
3rd March 2003, 17:06
I recently had to customize a report in a special way: A hint had to be placed *on top* of the report if any of the detail lines below contains special data. Hmm. I was not willing to read the data twice from the database.
1st idea: after.receive.data; fails because that comes *after* the first header!!!
2nd idea: since the report sorts the data, the data are written to a file; what can we do with that? The function that writes one line is called "r.write.seq.file()".
Here is my solution:
|**
|* Report Script
|**
declaration:
|**
|* rename the function that will be generated by bic_repgen
|**
#define ORIGINAL.FUNCTION() originally.generated.r.write.seq.file()
#define r.write.seq.file() ORIGINAL.FUNCTION()
domain tcbool delivery.contains.dangerous.material
before.program:
delivery.contains.dangerous.material = false
before.tdsls045.orno.40:
before.layout:
|*
|* just an example:
|* >> Warning: Delivery contains dangerous material! <<
|*
if not explosive then
lattr.print = false
endif
functions:
#undef r.write.seq.file()
function extern r.write.seq.file()
{
|**
|* call the original function and do some additional stuff
|**
ORIGINAL.FUNCTION()
if "this item is dangerous" then
delivery.contains.dangerous.material = true
endif
}
Your could also use it to calculate totals and so on.
askajale
3rd March 2003, 20:12
I can think of one alternate of using the flags.
1. Declare one additional field say rep_flag
2. In your select statement loop in the program script where you write the record to report, set this flag as 2.
3. When you encounter the special condition, send additional record with rep_flag set to 1 and one message field "YOUR MESSAGE" to print.
4. For all detailed records, this message field can be reset to BLANK.
5. Now in report i/p fields, include this rep_flag and put it as SORT field above the "before field" field. So that you will get this field before receiving the detail fields and you can print it.
6. Here you can avoide reading the table twice.
Hope this will help you.
-- Avinash
evertsen
3rd March 2003, 23:01
"1st idea: after.receive.data; fails because that comes *after* the first header!!!"
Are you sure this is the case? Even if it is, why not put your logic there and then put the "hint" in a before.field.
askajale
4th March 2003, 04:42
I think what eversten is saying could be possible only if the first record received indicates the condition which needs to be put as "hint". If there are multiple records on report and one of the records may be causing to print the HINT, then it may not work.
-- Avinash
günther
4th March 2003, 08:04
Avinash,
I used to do it like you menitioned your steps 1 - 6; thanks for your clarification.
What I wanted to show was just another way of customizing reports; sometimes you just have the report, not the script. And some of the programmers don't know the benefits of the preprocessor.
PeterC
7th September 2011, 01:13
Gunther,
This works great at sorting the report using a function of existing data, thank you! I have been using the idea you posted here to do something very similar: http://www.baanboard.com/baanboard/archive/index.php/t-16042.html
My problem is, though, that I need to create an after.field layout for the new variable I created. The after.field layout is printing at each detail, as if the value is being reset every time. I've tried only setting the value if it differs, but to no avail.
It is sort sequence 2, and is a part of the field in sequence 3.
Any suggestions?
Thanks!
günther
12th September 2011, 08:11
Hi Peter,
sorry for the delay; I've been on vaccation till yesterday.
Your new variable: I think you should define it as input variable (though it does not get its value from the session script). Then you should set it via "my" method. And if that does not work, I would use the debugger (t <your variable> to get notified when the variable chnages).
Hope that helps!
Günther
PeterC
13th September 2011, 19:14
Hi Gunther,
Thanks for the reply. Hope you had a nice vacation!
I ran through in debug, and the value is being set at the right times. It seems it's just the report engine that's calling the after.variable layout at each rprt_send() call. Do you know if there's some way to suppress this? I can't do so using booleans because the booleans wouldn't be set until after I need them to. (This is the reason the after.variable layouts are so valuable!)
I assume this will require some trickery, I'm just used to having the flexibility of the program script, not just the report script!
I'd appreciate any suggestions. Thanks again for your help
-Peter
PeterC
13th September 2011, 19:18
wait, i'm sorry. it doesn't change the value at ORIGINAL.FUNCTION(). completely disregard that last post.
it seems to be setting the values at the right time, so i'm not sure why it's calling the after.variable layout each time rprt_send() is called.
-peter
PeterC
13th September 2011, 21:14
Could it be the scope of the variable perhaps? Right now because it's declared as an input variable it is not in the report script, and because I don't have access, it's not in the program script either. Should I declare it in the report script or elsewhere?
günther
14th September 2011, 09:30
Hi Peter.
Now I'm a bit confused about your current state.
First: The scope of an input field is identical to a globale variable.
I've tried to create a simple version to check your problem (but I can't see the problem). Maybe you will check this as well? Basic idea: create a new session with one form (with one input field), session script and report with script. The only real input field is 'i'; 'j' and 'k' are input fields of the report, but are normally not set by the session script (only if you set the form's input field to Yes). So you can set j and k either in session script or in report script.
The report layouts: before.program reports the setting of j.k.in.report; after.field.j and after.field.k (both with output expression = lattr.break) report their name and j, j and k. But: I'dont see any difference, hmh!
|******************************************************************************
|* sample session script
|******************************************************************************
declaration:
| Form-Field
extern domain tcyesno j.k.in.report
| Report Input Fields
extern long i
extern long j | only used if j.k.in.report = No!
extern long k | only used if j.k.in.report = No!
choice.cont.process:
on.choice:
execute(print.data)
choice.print.data:
on.choice:
if rprt_open() then
for i = 1 to 10
if j.k.in.report = tcyesno.no then
j = i / 3
k = i / 5
endif
rprt_send()
endfor
rprt_close()
endif
|******************************************************************************
|* sample report script
|******************************************************************************
declaration:
#define ORIGINAL.FUNCTION() originally.generated.r.write.seq.file()
#define r.write.seq.file() ORIGINAL.FUNCTION()
before.program:
e = 0 | just for debugging
after.j.1:
before.layout:
e = 0 | just for debugging
after.k.1:
before.layout:
e = 0 | just for debugging
functions:
#undef r.write.seq.file()
function extern r.write.seq.file()
{
if j.k.in.report = tcyesno.yes then
j = i / 3
k = i / 5
endif
ORIGINAL.FUNCTION()
}
Günther
ben.kansas
23rd October 2014, 00:16
Peter C. & Gunthor,
I have a virtually identical problem.
In BaanIVc4, I've duplicated the "WIP (Summarized)" report attached to tisfc0450m000. We needed the Summarized report but with the Item Group as the primary sort followed by the Production Number.
Following your brilliant discovery, Guthor, I've added mitm.citg as an input variable and used your method for setting its value.
This report doesn't have a detail layout, but rather uses after.tisfc001.pdno.1 to calculate the sum of amt.wip for the Production Number.
It appears that the report thinks that both mitm.citg and tisfc001.pdno are being reset with every rprt_send(). Though a trace reveals that they are only being set once and the values never change from that initial value.
Did you guys ever find a way around this?
günther
23rd October 2014, 11:06
Hi Ben.
I could imagine that the sort order of your report input variables is not what you expect.
As in my last example, I would suggest to create a simple test program to generate the report input data in a way that "my" workaround is not necessary in the report. If that works, reduce the generated report input data and add them by the workaround. It should still work as expected then.
Regards
Günther
mark_h
23rd October 2014, 16:54
When I had to change a sort on report without the session script I had to use the after.receive.data to add the field and do a sort. Not something I really recommend.
ben.kansas
17th November 2014, 17:08
Hi Guys,
Sorry for not getting back with you earlier.
I did manage to get this working, but had to use manual suppression of layouts. I actually used a hybrid of your methods to get it working. I added the new sort field via Gunther's method, but after looking at Mark's method I used it to scan the sequence file and make decisions on when to suppress/allow layouts to print.
I've attached my code for you guys to look at. It's not ground breaking, but since I was the second person with this problem in this thread hopefully it will help others out.
Thanks,
Ben