|  | Fuss Free Dataset Name Format Checking |  | 
                |  | upper dsname    /* Make it upper case */ dsname = STRIP(dsname,,'''')   /* Remove quotes */
 x = MSG('OFF')
 TrapON=OutTrap('ON')
 Dsnstat = SYSDSN("'"dsname"'")   /* Check dataset name */
 TrapON=OutTrap('OFF')
 x = MSG('ON')
 if word(dsnstat,1) = 'INVALID' then do
 Say 'Dataset name invalid 'dsname
 Signal dosomething
 end
 | The technique shown in this example will quickly let you know if the dataset name passed in the variable is in a
                 valid format or not. 
 You could use Case logic to trap so many more things but if you are just looking to see if
                 the format of the dataset is valid, then this technique will do nicely.
 |  | 
                                              
                 |  | 
 |  | 
        
  |  | Zeller's Congruence |  | 
                |  | day.0 = Saturday day.1 = Sunday
 day.2 = Monday
 day.3 = Tuesday
 day.4 = Wednesday
 day.5 = Thursday
 day.6 = Friday
 temp1 = ((mm+1)*26)%10
 temp2 = yy%4
 temp3 = 6*(yy%100)
 temp4 = yy%400
 temp1 = dd+temp1+temp2+temp3+temp4+yy
 if yy <  1751 then do
 temp1 = temp1 + 11
 end
 if yy =  1752 then do
 if mm <= 3 then do
 if mm = 3 then do
 if dd <= 24 then do
 temp1 = temp1 - 11
 end
 end
 temp1 = temp1 + 11
 end
 end
 temp4 = temp1%7
 temp2 = temp4*7
 temp3 = temp1-temp2
 say day.temp3 dd mm yy
 
 | Zeller's Congruence (explained here) will calculate the day of the week for a given date. 
 This sample code shows how to calculate Zeller's congruence in a way such that it is easier to
                  follow the steps. The code alongside is stripped down for example purposes but a working copy is available here
 |  | 
                
                 |  | 
 |  | 
                
  
  |  | Discovering What LPAR
		You Are Running On |  | 
                |  | CVTECVT=D2X(C2D(STORAGE(10,4))+140) lparname=STRIP(STORAGE(D2X(C2D(STORAGE(CVTECVT,4))+344),8))
 permitted_on = "SYS2SYS3" /* only allow it on these systems */
 If POS(lparname,permitted_on) = 0 then do
 say "Not allowed on "lparname
 end
 else do
 say "OK to run on "lparname
 end
 
 
 
 Example of how to use CPUCHECK
 
 cpucheck
 if rc = 0 then
 say ‘allowed’
 else
 say ‘denied’
 
 | Sometimes you may want to restrict which
		LPAR a Rexx exec can execute on. 
 This code will allow to you find
		out which LPAR the exec  is running on. The first two lines return the LPAR name and the next few lines
		show how to prevent/allow the exec to run.
 
 In this example we
		set a list of LPAR names that the exec is allowed to execute on (SYS2 &
		SYS3) so that we don't have to code lots of SELECTS just one
		simple POS. However you may have to reconsider the POS technique if you
		have an LPAR named anything that may get inadvertently matched e.g. YS2S
 
 Of course you could also flip the logic a little and make the name
		specified the name of the LPAR that this exec is not allowed to execute
		on.
 
 We have a Rexx EXEC named CPUCHECK (available here)
        that can be called by any Rexx EXEC and it will set a return code that indicates if the Rexx EXEC
        is running on an allowed system or not. An example of how to use this is shown here. It will save you having to
        repeat the checking code. Again you can always flip the logic if desired.
 
 It is important to note that CPUCHECK uses a system variable (sysname) that is set on our system. If
        you prefer you could navigate the control blocks in the example above.
 |  | 
                
                 |  | 
 |  | 
                
  
  |  | Discovering What
		Jobname Is Running The Rexx Exec In Batch. |  | 
                |  | CVT =
		STORAGE(10,4) 
 TCBP = STORAGE(D2X(C2D(CVT)),4)           /* CVTTCBP */
 
 TCB = STORAGE(D2X(C2D(TCBP)+4),4)
 
 TIOT = STORAGE(D2X(C2D(TCB)+12),4)        /* TCBTIO */
 
 job = STRIP(STORAGE(D2X(C2D(TIOT)),8))    /* TIOCNJOB */
 | This code can be used to discover the job
		name that is running the Rexx exec in batch. 
 If you do it under TSO it
		will return your own TSO name.
 Once you have the jobname you can make lots of choices based on the
		jobname...like use it for a dataset level or, if you have good naming
		standards you can take a different logic flow based on whether it is a
		production or development job. |  | 
                                
                 |  | 
 |  | 
                
  
  |  | Discovering The
		Job Number of The Job Running The Exec. |  | 
                |  | CVT =	STORAGE(10,4) TCBP = STORAGE(D2X(C2D(CVT)),4)           /* CVTTCBP */
 TCB = STORAGE(D2X(C2D(TCBP)+4),4)
 JSCB = STORAGE(D2X(C2D(TCB)+180),4)        /* JSCB */
 SSIB = STORAGE(D2X(C2D(JSCB)+316),4)        /* SSIB */
 jobnum = STRIP(STORAGE(D2X(C2D(SSIB)+12),8))    /* Get jobnum */
 | This code can be used to discover the job
		number that is running the Rexx exec in batch. 
 If you do it under TSO it
		will return your own TSO number.
 |  | 
                
                 |  | 
 |  | 
                   
  |  | Replacing a String In
		a Rexx Exec |  | 
                |  | /* Rexx */ input = 'my favorite color is red'
 input = strrepl(input,'red','green')
 say input
 exit
 
 StrRepl:
 Orig = ARG(1)
 Oldtxt = ARG(2)
 Newtxt = ARG(3)
 Newstr = ''
 Work = Orig
 Do while POS(Oldtxt,Work) > 0
 Newstr = Newstr||SUBSTR(Work,1,pos(Oldtxt,Work)-1)||Newtxt
 Work= SUBSTR(Work,pos(Oldtxt,Work)+LENGTH(Oldtxt))
 end
 Newstr = Newstr||SUBSTR(Work,1)
 return Newstr
 | We use this routine in many of our Rexx execs. 
 It will
		replace the second value with the third value in the field specified by
		the first value. The string lengths don't matter so it makes this code
		pretty slick.
 
 In the example here we replace the sting 'red' with the
		string 'green' in the field 'input' which contains the string 'my
		favorite color is red'.
 
 Note: The StrRepl routine here is a subroutine and so it
		can be copied and pasted in its entirety into any exec and be ready to
		be used.
 
 A text version of StrRepl subroutine is available from here.
 |  | 
                
                 |  | 
 |  | 
                                 
  |  | Finding The Name of The Current Exec |  | 
                |  | /* Rexx */ dialogid = sysvar(sysicmd)
 parse source Exec_String
 excnme = word(Exec_String,3)       /* Get EXEC's name          */
 say excnme ' Starting.' date() time()
 final = TIME('Reset   ')
 
 say excnme 'Finished :' date() time() 'Elapsed time 'time(e) 'seconds'
 exit
 | This snippet of code will return the name of the executing Rexx exec. 
 In
                 this sample code we also demonstrate how to display the time that the Rexx exec took
                 to execute.
 
 
 |  | 
                                                 
                                                                   
                 |  | 
 |  | 
   | Convert A Month Number To Month Name |  | |  | /* Rexx */ Mon.01="January"
 Mon.02="February"
 Mon.03="March"
 Mon.04="April"
 Mon.05="May"
 Mon.06="June"
 Mon.07="July"
 Mon.08="August"
 Mon.09="September"
 Mon.10="October"
 Mon.11="November"
 Mon.12="December"
 myDate= "1999/12/25"      /* This is a sample date in yyyy/mm/dd format */
 year = substr(myDate,1,4) /* Year portion (change as appropriate) */
 day = substr(myDate,9,2)  /* Day portion (change as appropriate) */
 mon = substr(myDate,6,2)  /* Month portion (change as appropriate) */
 monname=MON.mon
 /* translate to name */
 say day monname year      /* show the date */
 exit
 | Sometimes a date is in all numeric format and you may want the full month name
                  in this case this sample code will do the trick. 
 Any value can be placed in the 'table'. In
                   other words if you only want the first three characters, then simply enter them instead of the full
                   month name.
 
 You will need to tweak the code to accommodate the date format if it isn't yyyy/mm/dd.
 
 A text version of this code can be found here.
 |  | 
                 
                 |  | 
 |  | 
   | Building a Delay Into a Rexx Exec (Sleep) |  | |  | /* Rexx */ parse upper arg time value
 If value <> "" then do
 value = substr(value,1,1)
 /* If you don't pass a value seconds are assumed otherwise:*/
 /* use M for minutes or H for hours                         */
 if value = "M" then time = time * 60
 if value = "H" then time = time * 60 * 60
 end
 if time = "" then time = '1'
 hit = 0
 Do while hit < time
 hit = TIME('Elapsed ')
 end = lastpos('.',hit)
 hit = substr(hit,1,end)
 end
 exit
 
 | Occasionally you may want to delay an Exec for a couple of seconds or more. There is currently no inbuilt
                 Rexx function for this. This Exec will delay the execution of the calling Exec for the number of seconds, minute or hours that
                  are passed to it. 
 *** WARNING *** This Exec takes no prisoners! If you say sleep for an extended duration
                  it will do just that and will lock out the TSO id or job for that long.
 
 A text version of this code can be found here.
 |  | 
                
                 |  | 
 |  | 
   | Converting a String to Proper Name Format |  | |  | /* Rexx */ input = 'ABBYDALE'
 input = Proper(input)
 say input
 exit
 
 Proper:
 Orig = ARG(1)
 if length(orig) > 1 then do /* Ensure there is more than one char */
 UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 LOWER = "abcdefghijklmnopqrstuvwxyz"
 tempName = TRANSLATE(Orig,LOWER,UPPER)
 build = substr(tempName,2,Length(tempName)-1)
 initial = substr(tempName,1,1)
 initial = TRANSLATE(initial,UPPER,LOWER)
 newname = initial||build
 end
 else do
 newname = Orig
 end
 return newname
 | When you are dealing with proper names (People's name, place names etc.) the correct format is to start them with
                 a capital letter. Unlike some languages there is no built in Rexx function for doing this therefore we use this
                 subroutine for achieving this. 
 In the example shown the name ABBYDALE will be converted to Abbydale by the subroutine. It should
                be noted that even if the name is already in lower case this routine will work.
                Note: The Proper routine here is a subroutine and so it
		can be copied and pasted in its entirety into any exec and be ready to
		be used.
 
 A text version of Proper subroutine is available from here.
 
 A brief demonstration is available here.
 |  | 
                 
                 |  | 
 |  | 
   | Dropping the Last Level From a Dataset Name |  | |  | dsname = SUBSTR(dsname,1,(LASTPOS('.',dsname)-1)) | If you ever want to drop the last level from a dataset name, you can do it by using this code. 
 You can use this for generic LISTCATs etc.
 
 Looping through this process will drop you down more levels.
 |  | 
                                 
                 |  | 
 |  | 
   | Obtaining the Current TSO PROFILE PREFIX |  | |  | /* rexx */ prof = getprof(prof)         /* Get current prefix */
 say "Value of prof="Prof     /* Show answer        */
 "Profile noprefix"           /* Profile NOPREFIX   */
 prof = getprof(prof)         /* Get current prefix */
 say "Value of prof="Prof     /* Show answer        */
 "Profile PREFIX("userid()")" /* Set to our userid  */
 prof = getprof(prof)         /* Get current prefix */
 say "Current profile "prof   /* Show answer        */
 "Profile noprefix"           /* Set NOPREFIX       */
 "Profile"                    /* Show our profile   */
 say
 say "Value of prof="Prof     /* Show answer        */
 say
 if Prof/='N' then do         /* Prof = our userid  */
 "Profile PREFIX("Prof")"     /* Reset prefix       */
 end
 "Profile"                    /* Show our profile   */
 exit
 | It is sometimes useful to store the TSO PREFIX in use when a Rexx is executing. It is extremely useful
                 when you want to set the PROFILE to NOPREFIX but want to reset it back to what it was when the exec was called. 
 GETPROF can provide this function.
 
 The GETPROF routine is available from here.
 
 The code alongside is NOT GETPROF but a demonstration of how to use GETPROF.
 
 A copy of the code alongside is available from here.
 |  | 
                 
                 |  | 
 |  | 
   | Counting Occurances of a String |  | |  | 
 Usage x=CountStr(find,where)Sample of use: 
 x = CountStr('.','ABBYDALE.ALLFREE.REXX')
 This would return 2 as the value of x.
 
 If you need to know if this is an odd or even number you can use:
 
 x = CountStr('.','ABBYDALE.ALLFREE.REXX')//2
 if x > 0 say 'Odd'
 
 
 
 | This function will count the number of times a passed string occurs in another passed string. 
 This is useful if you want to count the number of levels in a dataset name.
 
 The COUNTSTR routine is available from here.
 |  |