I have written Rexx routine to perform impact analysis . This rexx routine to search for the member pattern in the library pattern(PDS) as given by the user . I have created below three libraries with a Member (AAA) in dataset 2, 3 .
Dataset 1: AAA.PDS.COBOL (no member like "AA*")
Dataset 2: AAA.PDS.COBOLA (Member like "AA* present)
Dataset 3: AAA.PDS.COBOLB(Member like "AA*" present)
Code:
SAY "ENTER APPLICATION NAME"
PULL APP
SAY "ENTER COMPONENT PATTERN"
PULL CMTP
SAY "ENTER PATTERN FOR LIBRARIES TO BE SEARCHED"
PULL DS
ADDRESS TSO
USR = USERID()
APP = STRIP(APP)
DS = STRIP(DS)
DS = DS ||"*"
CMTP = STRIP(CMTP)
MEMBFILTER = CMTP ||"*"
IDX = 0
DSX = 0
TOTMEMBRS = 0
TOT_MEMB_LIST = 0
"ISPEXEC LMDINIT LISTID(IDV) LEVEL(&DS)"
DO FOREVER
"ISPEXEC LMDLIST LISTID("IDV") OPTION(LIST) DATASET(DSVAR) STATS(YES)"
IF RC ¬= 0 THEN
DO
LEAVE
END
ELSE DO
FIND_DSTYPE = POS('COBOL',DSVAR)
ADDRESS ISPEXEC
X = LISTDSI("'"DSVAR"'")
IF SYSDSORG = "PO" THEN
DSTYPE = 'PDS'
ELSE
DSTYPE = ' '
IF FIND_DSTYPE > 0 & DSTYPE = 'PDS' THEN
DO
SAY DSVAR
ADDRESS ISPEXEC
"LMINIT DATAID("DATID") DATASET('"DSVAR"') ENQ(SHR)"
ADDRESS ISPEXEC
"LMOPEN DATAID("DATID") OPTION(INPUT)"
EOPDS = 'N'
DO WHILE EOPDS = 'N' ;
ADDRESS ISPEXEC
"LMMLIST DATAID("DATID") OPTION(LIST) STATS(NO)",
"MEMBER(MEMNAME) PATTERN("MEMBFILTER")"
IF RC >= 4 THEN DO
EOPDS = 'Y'
ADDRESS ISPEXEC
"LMMLIST DATAID("DATID") OPTION(FREE)"
ADDRESS ISPEXEC
"LMCLOSE DATAID("DATID")"
LEAVE
END
IDX = IDX + 1
MBRLIST.IDX = MEMNAME
END ;
END
END
END
/* ADDRESS ISPEXEC
"LMFREE DATAID("DATID")" */
CALL WRITE
EXIT
WRITE:
ADDRESS TSO
X = OUTTRAP("OA.")
ADDRESS TSO
"FREE ALL"
OUTPS3 = USR||'.'||APP||'.'||COM||'.'||LIST
ADDRESS TSO DELETE "'"||OUTPS3||"'"
ADDRESS TSO
"ALLOC DA('"OUTPS3"') FI(LOG) NEW LRECL(80) RECFM(F B) TRACKS",
" SPACE(10 10) BLKSIZE(1500) DSORG(PS)"
DO I = 1 TO MBRLIST.0
SAY "MEMBER NAME ->" MBRLIST.I
END
ADDRESS TSO
"FREE F(LOG)"
RETURN
while searching (AA*) member pattern on dataset 1 , "LMMLIST command with Memberpattern" returns rc =4 as there is no member in it and it is fine but at the same time "LMMLIST option(FREE)" command fails with RC = 10 .
Again search starts on dataset2 and now the member is present but "LMMLIST withMemberpattern" fails with RC =4 even though Member is present .
Can any one help me / assist me that i have missed anything in code?
/* LMMLIST loop */
do while ($ispex(lmmlist) = 0 )
say left(_cmd,8)"- Processing "left(member,8) || ,
" From Dataset("dsnm") "
end
/* LMCLOSE */
ispserv = left("LMCLOSE",8)
zRC = $ispex(ispserv "DATAID("ID") ")
If zRC \= 0 Then Do
say left(_cmd,8)"- RC("zRC") from" ispserv dsnm
leave
End
/* LMFREE */
ispserv = left("LMFREE",8)
zRC = $ispex(ispserv "DATAID("ID") ")
If zRC \= 0 Then Do
say left(_cmd,8)"- RC("zRC") from" ispserv dsnm
End
It might work for you in this instance, but I think the DATID should be the name of the variable rather than the resolved value of the variable. It would fail if it was in a loop.
Quote:
too complicated to follow Your code ...
I also agree. Perhaps you can write a shorter program that does only the LMINIT, LMOPEN, LMCLOSE and LMFREE so you can learn the proper usage and then incorporate into your larger program.
I have verified your recommened rexx script and it is found serach is limited with respect to datasets , but if you see my rexx script is not limited to the datasets , can you refer me with any other sample.
I have writen a simple small rexx program for LMMIINIT, OPEN, CLOSE , FREE and i passed the datasets as input which actually receives RC =8, 10, 4 in the routine which i have posted earlier.
Code:
/* TRACE ?R */
DSVAR ='AA.TEST.COBOLA'
/* TRACE ?R */
ADDRESS ISPEXEC
"LMINIT DATAID("DATID") DATASET('"DSVAR"') ENQ(SHR)"
SAY RC
ADDRESS ISPEXEC
"LMOPEN DATAID("DATID") OPTION(INPUT)"
SAY RC
ADDRESS ISPEXEC
"LMMLIST DATAID("DATID") OPTION(LIST) STATS(NO)"
SAY RC
ADDRESS ISPEXEC
"LMCLOSE DATAID("DATID")"
SAY RC
ADDRESS ISPEXEC
"LMFREE DATAID("DATID")"
SAY RC
EXIT
All RC = 0 are received for all the input datasets , not sure where the logic issue which i have made in my previous code which i have posted earlier ,
I have verified your sample and i just need to change some logic in it to collect the datasets from the pattern given by the user . Its is very good example , thanks for the code .
Will try along with my code changes in your sample and will let you if any isssues i have faced .
I have verified your recommened rexx script and it is found serach is limited with respect to datasets , but if you see my rexx script is not limited to the datasets , can you refer me with any other sample
the purpose was to show a better and WORKING way of writing the process
related only to the LMMLIST part
and here is a better way of coding the DSLIST loop
Code:
000013 call $ispex "CONTROL ERRORS RETURN"
000014
000015 dslevl = "ENRICO"
000016 /* LMDINIT */
000017 ispserv = left("LMDINIT",8)
000018 zRC = $ispex(ispserv "LISTID(LSID) LEVEL("dslevl") ")
000019 If zRC \= 0 Then Do
000020 say left(_cmd,8)"- RC("zRC") from" ispserv dslevl
000021 exit
000022 End
000023
000024 dsname = ""
000025 ispserv = left("LMDLIST",8)
000026 lmdlist = ispserv "LISTID("lsid") OPTION (LIST) STATS(YES)" ||,
000027 " DATASET(DSNAME) "
000028 do while ($ispex(lmdlist) = 0 )
000029 /* skip the alias */
000030 if strip(translate(zdlvol)) = "*ALIAS" then ,
000031 iterate
000032
000033 /* skip NON PO and NON PO-E */
000034 if wordpos(translate(zdldsorg),"PO PO-E") = 0 then,
000035 iterate
000036
000037 say left(_cmd,8)"- Found "left(zdldsorg,4) || ,
000038 " Dataset("dsname") "
000039 /* skip if NON COBOL */
000040 if pos("COB",dsname) = 0 then ,
000041 iterate
000042
000043 say left(_cmd,8)"- Processing "left(zdldsorg,4) || ,
000044 " Dataset("dsname") "
000045 end
000046
000047 /* LMDFREE */
000048 ispserv = left("LMDFREE",8)
000049 zRC = $ispex(ispserv "LISTID("lsid") ")
000050 If zRC \= 0 Then Do
000051 say left(_cmd,8)"- RC("zRC") from" ispserv
000052 End
000053
000054
why is better ???
it does not indent too many nesting levels 1 only here
checks for an alias
does not use LISTDSI, but relies on the Z variables provided by ISPF
takes into account PDSe
and if You add the LMMLIST pressing it will nest only 1 more
I agree with PEDRO
the LMINIT DATAID should be a NAME, not a value
I wonder why people developing ISPF applications have not learned to use
the ISPF MODEL command
anyway the ISPF MODEL command is misleading or better WRONG
only the last code snippet is RIGHT
together with the description in the note lines
from the MODEL LMINIT command
Code:
EDIT ENRICO.ISPF.EXEC(MF002) - 01.20 Columns 00001 00072
Command ===> Scroll ===> CSR
****** ***************************** Top of Data ******************************
000001 'LMINIT DATAID('dataidvar') PROJECT('project') GROUP1('group1'),
000002 GROUP2('group2') GROUP3('group3') GROUP4('group4'),
000003 TYPE('type') PASSWORD('passwrd') ENQ(SHR) ORG('org-var')'
=NOTE= or
000004 'LMINIT DATAID('dataidvar') DATASET('dsname') VOLUME('serial'),
000005 PASSWORD('passwrd') ENQ(SHR) ORG('org-var')'
=NOTE= or
000006 'LMINIT DATAID('dataidvar') DDNAME('ddname') PASSWORD('passwrd'),
000007 ENQ(SHR) ORG('org-var')'
=NOTE= or for VM
000008 'LMINIT DATAID('dataidvar') PROJECT('project') GROUP1('group1'),
000009 GROUP2('group2') GROUP3('group3') GROUP4('group4'),
000010 TYPE('type') OWNER('owner-id') VADDR('vda'),
000011 LAM('lm') RPSWD('rpasswrd') UPSWD('upasswrd'),
000012 ENQ(SHR) ORG('org-var') RECFM('fm'),
000013 LRECL('lrl')'
=NOTE= or
000014 'LMINIT DATAID(DATAIDVAR) FILE('file-id') OWNER('owner-id'),
000015 VADDR('vda') LAM('lm') RPSWD('rpasswrd') UPSWD('upasswrd'),
000016 ENQ(SHR) ORG('org-var')'
=NOTE=
=NOTE= DATAIDVAR - The name of the variable into which the data-id
=NOTE= associated with the data set or file is to be
=NOTE= stored.
=NOTE= project - Optional, first level qualifier of an ISPF library
=NOTE= or an MVS data set with a three-level qualified
=NOTE= data set name.
=NOTE= group1 - Optional, second level qualifier of an ISPF library
=NOTE= or an MVS data set with a three-level qualified
=NOTE= data set name.
=NOTE= group2 - Optional, designates the second level qualifier of
=NOTE= an ISPF library in a concatenation sequence.
=NOTE= group3 - Optional, designates the second level qualifier of
=NOTE= an ISPF library in a concatenation sequence.
=NOTE= group3 - Optional, designates the second level qualifier of
=NOTE= an ISPF library in a concatenation sequence.
=NOTE= type - Optional, third level qualifier of an ISPF library
=NOTE= or of an MVS data set with a three-level qualified
=NOTE= data set name.
=NOTE= dsname - Optional, name of an existing MVS partitioned or
=NOTE= sequential data set.
=NOTE= ddname - Optional, data set definition name of a data set
=NOTE= that is already allocated to the TSO user prior to
=NOTE= invocation of LMINIT service.
=NOTE= serial - Optional, serial number of the DASD volume on which
=NOTE= the MVS data set resides.
=NOTE= passwrd - Optional, MVS password of the data set.
=NOTE= ENQ - Optional, choose one.
=NOTE= SHR - Default, existing data set or file may be shared.
=NOTE= EXCLU - Requirement for exclusive use of existing data set
=NOTE= or file.
=NOTE= SHRW - Permits a 'shared write' of a library.
=NOTE= MOD - More records are to be added to end of the data set
=NOTE= or file. The data set must be sequential.
=NOTE= org-var - Name of the variable into which the organization of
=NOTE= the data set or file is stored.
=NOTE= PO - Data set or file is partitioned.
=NOTE= PS - Data set or file is physical sequential.
=NOTE= file-id - Optional, the name of the existing CMS file.
=NOTE= owner-id - Optional, applies to file parameter or to an ISPF
=NOTE= library not on user's "a" disk. (VM Only)
=NOTE= The logon id of the owner of the file.
=NOTE= vda - Optional, applies to file parameter or to an ISPF
=NOTE= library not on user's "a" disk. (VM only)
=NOTE= The 3 character address of the minidisk.
=NOTE= lm - Optional, applies to file parameter or to an ISPF
=NOTE= library not on user's "a" disk. (VM only)
=NOTE= The 2 character link access mode.
=NOTE= rpasswrd - Optional, applies to file parameter or to an ISPF
=NOTE= library that is not on user's "a" disk. (VM only)
=NOTE= The read password.
=NOTE= upasswrd - Optional, applies to file parameter or to an ISPF
=NOTE= library that is not on user's "a" disk. (VM only)
=NOTE= The update password.
=NOTE= fm - Optional, specifies the record format of a new
=NOTE= member of an ISPF library that is a collection of
=NOTE= sequential files. Used only for first LMPUT.
=NOTE= Default is recfm of the ISPF library. (VM only)
=NOTE= lrl - Optional, specifies the logical record length, in
=NOTE= bytes, of a new member of an ISPF library that is
=NOTE= a collection of sequential files. Used only for
=NOTE= the first LMPUT. Default is lrecl of library.
=NOTE= (VM only)
=NOTE=
=NOTE= EXAMPLE: ADDRESS ISPEXEC
=NOTE= 'LMINIT DATAID(MYDD) PROJECT(ISPF),
=NOTE= GROUP1(TESTLIB1) GROUP2(TESTLIB2),
=NOTE= GROUP3(TESTLIB3) GROUP4(TESTLIB4) TYPE(PLI)'
=NOTE= or
=NOTE= 'LMINIT DATAID(MYDD) DSNAME(DATASET1),
=NOTE= VOLUME(VOL123) ENQ(SHR)'
=NOTE= or for VM
=NOTE= 'LMINIT DATAID(MYDD) PROJECT(ISPF),
=NOTE= GROUP1(TESTLIB1) GROUP2(TESTLIB2),
=NOTE= GROUP3(TESTLIB3) GROUP4(TESTLIB4) TYPE(PLI),
=NOTE= RECFM(F) LRECL(80) ENQ(SHR)'
=NOTE= or
=NOTE= 'LMINIT DATAID(MYDD) FILE(CMS EXEC A),
=NOTE= RPSWD('rdpass') ENQ(SHR) ORG(FILEORG)'
I have not tried it, but think the variable name has to meet ISPF naming rules. The example is too long. This snippet is also wrong, though for a different reason.