James,
A subprocedure in a NOMAIN module can access the program status data
structure. However IIRC, like the INFDS the PGSDS must be defined at the
module (global) level at v5rx. I don't know how those data structures
work in IBM i 6.1. Since files can be defined locally, I would think you
could have a local INFDS, but check the manual.
I used to close files when deleting and updating because the change
would not take effect otherwise (apparently at least one reason for the
level 10 warning). With help from this list I learned that specifying
Block(*No) on the file definition allows you to leave the file open
until the activation group is reclaimed if you want. In the situation
you describe, you should be able to open the files conditionally and
leave them open. If experimentation shows that need to close them at the
same recursion level you opened them, you could set a local
indicator/boolean for each file as it is opened. When the recursions
unwind, the local Close indicator will not be *ON until it reaches the
level where the file was opened.
In short: To close them as it unwinds, the suggestion below could be a
starting place (copy at your own risk).
To wait to close them until completely unwound:
1) make the Closex indicators static,
2) only call OpenFile() if the related Closex = *OFF,
3) only call the CloseFile() function when Recursion = *Zero and
4) Turn all Closex indicators *OFF after calling the related
CloseFile().
It's more coding, but it might boost performance if each call deletes
many records.
If you don't need to close the files, never call CloseFile(). That will
probably give the best performance. YMMV.
HTH,
Roger Mackie
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
H NoMain
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
FFILENAM1 UF E K Disk UsrOpn Block(*No)
FFILENAM2 UF E K Disk UsrOpn Block(*No)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
//-----Global Workfields-------------
// Define PGSDS and INFDS here
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
//----------------------------------------------------------------------
--
// Procedure: DeleteAll
// Purpose:
//----------------------------------------------------------------------
--
P DeleteAll B Export
//-----------------------------------
D DeleteAll PI N
// filekeys as parameters
D Close1 S N
D Close2 S N
D DidIt S N
D File1 C Const('FILNAM1')
D File2 C Const('FILNAM2')
D Recursion S 5U 0 Static
//-----------------------------------
/Free
Recursion += 1;
//...
// Open the first file
Close1 = OpenFile(File1);
//...
// Open the second file
Close2 = OpenFile(File2);
//...
Recursion -= 1;
CloseFile(File1:Close1);
CloseFile(File2:Close2);
Return DidIt;
/End-Free
//-----------------------------------
P DeleteAll E
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
//----------------------------------------------------------------------
--
// Procedure: OpenFile
// Purpose: Open the requested file, if needed
//----------------------------------------------------------------------
--
P OpenFile B
//-----------------------------------
D OpenFile PI N
D FileName 10A Const
D CloseIt S N
//-----------------------------------
/Free
Select;
When (FileName = 'FILNAM1') and (Not %Open(FILNAM1));
Open FILNAM1;
CloseIt = *On;
When (FileName = 'FILNAM2') and (Not %Open(FILNAM2));
Open FILNAM2;
CloseIt = *On;
EndSl;
Return CloseIt;
/End-Free
//-----------------------------------
P OpenFile E
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
//----------------------------------------------------------------------
--
// Procedure: CloseFile
// Purpose: Close a file opened by this NOMAIN module in this
iteration
//----------------------------------------------------------------------
--
P CloseFile B
//-----------------------------------
D CloseFile PI
D FileName 10A Const
D CloseIt N Const
//-----------------------------------
/Free
If CloseIt;
Select;
When FileName = 'FILNAM1';
Close FILNAM1;
When FileName = 'FILNAM2';
Close FILNAM2;
EndSl;
EndIf;
Return ;
/End-Free
//-----------------------------------
P CloseFile E
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx
[mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of James Lampert
Sent: Tuesday, June 24, 2008 11:50 AM
To: RPG programming on the AS400 / iSeries
Subject: Re: Modules with files and references to INFDS, but no MAIN,
andtheNOMAIN H-spec, was Re: Recursion and CALLB
Mackie, Roger L. (Precision Press) wrote:
I do something like David. As long as the program contains the CLOSE
opcode somewhere, it doesn't matter if it is ever invoked or not. If
you put all the Close <myfile> instructions in a subprocedure you
never call or only call when you want to collect garbage, the compiler
won't mind.
Hmm. The complaints about lack of explicit file-close operations were
all level 10 warnings.
We also had PGSDS and INFDS issues that were stopping compilation
(mainly because the relevant D-specs got moved inside the procedure
along with all the other definitions). Can a procedure in a NOMAIN
module access the PGSDS? (I'm assuming that INFDS doesn't present a
problem).
Also, with regard to opening and closing files, they're opened
conditionally on an as-needed, if-not-already-open basis. Will they stay
open when the recursions unwind and return to the original caller? Will
they still be open when the recursive routine is called again?
The situation at hand is one in which a record in one file might own
records in several other files (and those records might own records in
other files, and . . .). The object here is to have one call that
deletes a specified record in a specified file, then goes through
recursively, and finds all the records it might own (directly or
indirectly) in other files, until the entire tree that is rooted in the
specified record has been deleted.
--
James H. H. Lampert
Touchtone Corporation
As an Amazon Associate we earn from qualifying purchases.