Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Loop calling a report

Status
Not open for further replies.

Enkidou

Programmer
Sep 2, 2003
8
FR
Hello,

I've a loop on the primary key of a file which is calling a report.
If I desactivate the call to the printing procedure, the loop goes by each step of the file. But if the printing procedure is called the loop goes 2 by 2.

The loop is based on the same file that the primary file of the report. Do the report increment the position ?

Do you have any idea to help me ?
 
If by "calling a report" you mean that you are calling a Report Procedure which is filtered or ranged to print from the same file, the answer is "YES" as the Report knows that it has completed the range ONLY after it has gone to the next record and if you are also fetching the next record then it will skip 2 by 2. The login flow you are using is :

Calling Procedure :

OPEN FILE (actual opening of file)

LOOP
NEXT(FILE) or ACESSS:FILE.NEXT()

-- Record No is N

CALL REPORT PROCEDURE

--- Record No is N+1
END

CLOSE FILE (actual closing of file)

Report Procedure:

OPEN FILE (does not open the file but updates the usage count)

PRINT Report

CLOSE FILE (does not close the file but updates the usage count)

You have two choices :

Create an ALIAS of the file you are processing and use the ALIAS for the Report which makes sure that the File Buffers are different

OR

Use the POSITION() & RESET() commands to store the position before calling the Report procedure and resetting it back on return from the Report procedure.

sav:pos string(32)

set(key)
loop
next(file)

if errorcode() then break.

sav:pos = POSITION(file) OR sav:pos = POSITION(key)

call report procedure

RESET(file, sav:pos) OR RESET(key, sav:pos)

set(key,key) ; next(file) ---> these commands are optional and depends on the file driver used - check if you need them
end
 
Thanks for your quick response.

Well I've try to do this :

Code:
CDEF:NUM_CDE_FOUR = M_Num_Deb                     

SET(CDEF:K_NUMCDEFOUR, CDEF:K_NUMCDEFOUR)

LOOP Until Access:COMMANDE_ENTETE_FOUR.Next()
   IF CDEF:NUM_CDE_FOUR > M_Num_Fin THEN Break.

   SAV:POS = Position(COMMANDE_ENTETE_FOUR)
   M_Num_Edit = CDEF:NUM_CDE_FOUR
   Message('M_Num_Edit : '&M_Num_Edit&' CDEF:NUM_CDE_FOUR : '&CDEF:NUM_CDE_FOUR)

   CDEFOUR_EDITION_Report('')

   RESET(COMMANDE_ENTETE_FOUR, SAV:POS)
END

M_Num_Deb and M_Num_Fin are the min and the max of my prints.
M_Num_Edit is my module data which is used by report to positioned itself.

For POSITION and RESET, I've try to put as parameter the file and the key but at each loop, I'm always on the first record I've asked (M_Num_Deb) as the message shows it to me.

Do you have any idea ?
 
It will be better to do a CLEAR(CDEF:Record) before the SET(CDEF:K_NUMCDEFOUR, CDEF:K_NUMCDEFOUR).

If your key has only one field and it is unique that it would be easier to use the stored key field and retrieve the record again.

---------------------------------------------
CLEAR(CDEF:Record)
CDEF:NUM_CDE_FOUR = M_Num_Edit
Access:COMMANDE_ENTETE_FOUR.Fetch(CDEF:K_NUMCDEFOUR)
SET(CDEF:K_NUMCDEFOUR, CDEF:K_NUMCDEFOUR)
Access:COMMANDE_ENTETE_FOUR.Next() ---> this is required to prevent it getting the same record again.
---------------------------------------------

OR if CDEF:NUM_CDE_FOUR is Numeric

---------------------------------------------
CLEAR(CDEF:Record)
CDEF:NUM_CDE_FOUR = M_Num_Edit + 1
SET(CDEF:K_NUMCDEFOUR, CDEF:K_NUMCDEFOUR)
---------------------------------------------

Any of the above code will go after the CDEFOUR_EDITION_Report('') statement.


 
My record is a string, so I can't increment it. The problem is that Next() after Set() is like a Fetch() and take the current record if exists. So I find a not proper solution [sad] but it works.[morning]
Code:
CDEF:NUM_CDE_FOUR = M_Num_Deb
Access:COMMANDE_ENTETE_FOUR.Fetch(CDEF:K_NUMCDEFOUR)

LOOP
   IF CDEF:NUM_CDE_FOUR > M_Num_Fin THEN BREAK.
   M_Num_Edit = CDEF:NUM_CDE_FOUR
   IF Base_Test() = True THEN Message('M_Num_Edit : '&M_Num_Edit&' CDEF:NUM_CDE_FOUR : '&CDEF:NUM_CDE_FOUR).
   CDEFOUR_EDITION_Report('')

   CLEAR(CDEF:Record)
   CDEF:NUM_CDE_FOUR = M_Num_Edit
   SET(CDEF:K_NUMCDEFOUR, CDEF:K_NUMCDEFOUR)
   IF Access:COMMANDE_ENTETE_FOUR.Next() THEN BREAK.
UNTIL Access:COMMANDE_ENTETE_FOUR.Next()

So I've made a reposition just after the CLEAR() method and a double Next() after the Set(). So it's like a Fetch() and Next() but it works.

But if anybody have a better way, I'll try it.

Thanks a lot for your response.
 
You have a working solution - that's what matters.

Technically, you are accessing each record thrice (onec by the report and twice by the calling procedure). If the no of records are not too many and there is no visible speed degradation then it is OK.

I guess you are using the same KEY in the report as well and that's the reason you KEY pointer is incremented after the report. You could try the ALIAS method suggested by me.

I always believe it is important to get a working solution first and optimization is secondary and only if required.
 
you can try saving the record position before calling report, after printing just get the saved position using get instead of reset:

loop
next(file)
if anycondition then break.
pos# = position(file)
call report procedure
get(file,pos#)
end

variables with # are ulong data and they don't need to be declared, but they are valid only for your current source's embbed, anyway, you can use any ulong variable
 
Well, I've soon try this way but I had a problem.
On get(file,pos#) it goes back to the first record of the file !

Actually, there is no so much records to treat. But I'm still looking for a better way to do this.
Maybe I'll finally use an alias on the table. So I'll had to remake the report :-(
 
One thing to keep in mind is that POSITION does return a STRING, so pos# = position(file) may be inappropiate (depends on file system).
 
by this time maybe you remake your report, but anyway, one more tip, i was wrong about the use of pos# = position(file)
the command i meaned to tell is pointer(file) it returns the pointer position of the actual record, sorry for the miss (my english is bad, but i think you'll get the idea)

regards
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top