<<

Interactive systems 319

SAS SCREEN CONTROL LANGUAGE: A GENTLE INTRODUCTION Jean Hardy Services Conseils Hardy Inc.

ABSTRACT • computed variables created by SCL; • system variables; SAS users that become acquainted with SAS Screen • MACRO variables. Control Language are often discouraged. What appears as a formidable task, namely learning this new language Unlike DATA step flow, statements of an SCL program and its intricacies, can be made easier by concentrating are not executed top-dawn; some execute once as the on the fundamental statements and features. first observation is displayed while others can execute many times for each observation in the SAS dataset. This paper is a tutorial to the Screen Control Language. Controlling execution flow is a major challenge in some We don't like to teach SCL in the context of SASIAF, SCL applications. intimidating by itself. We prefer to see it from within SASIFSP, disregarding details about PROC FSEDIT. STRUCTURE OF AN SCL PROGRAM Topics covered include the use of labels, field statements and functions, error trapping, use of dataset and observa­ Each FSEDIT and FSBROWSE screen include an SCL tion functions, and useful programming and debugging program that is stored with it; this program is empty by tips. default. For example, an SCL program validating the SAS dataset PERM.RESULT is created by running This paper is aimed toward intermediate level SAS users, FSEDIT with a valid screen name: new or novice in their knowledge of SCL. Those that are discouraged, disenchanted or skeptical about SCL are LIBNAME PERM 'file-or-direccory'; PROC FSEDIT DATA=PERM.RESULT especially welcomed. SCREEN=PERM.CAT.ED1.SCREEN; VAA FRENCHl FRENCH2 FRENCH3; WHAT IS SCL RUNj

SCL is a , independent but +FSEDIT PERM.RESULT------­ looking often very much like DATA step language. It is ICommand ===> 1 aimed to the development of interactive full-screen 1 applications. In the SASIFSP FSEDIT procedure, an 1 FRENCH1: 13 SCL program can be used for example to: 1 1 FRENCH2: 12 1 + validate fields using hard-coded values; 1 FRENCH3: 15 + cross-validating fields or validating using an external 1 1 table (a SAS dataset); 1 + explain to the user what the application is currently doing; Figure 1. Base screen and frrst observation + manage additional windows (value lists, etc.). To write an SCL program, use the MOD command The fundamental components of SCL language are: followe by choice 3 "Edit Program Statements and Com­ pile" - you then see the following window (figure 2): + programming statements (like ARRAY or IF); • functions and routines (like SUM or LEFf); +FSEDIT Program------• variables (various types) . ICommand ===> 1 100001 The SCL and DATA step homonymous statements play 100002 the same role; only a subset of the current DATA step 100003 statements are available. Functions convey most of the 100004 power of SCL; the DATA step homonymous functions Figure 2. SCL programming window a common syntax. Four types of variables are available: An SCL program in SASIFSP is nade if at least five different blocks having reserved names - each of them • screen variables, from the dataset currently edited; terminated by a RETURN statement:

NESUG '92 Proceedings 320 Interactive systems

FSEINlT: + SUM is the SCL sum statement; statements executed once, when beginning FSEDIT + PUT is an SCL function converting a numeric or FSBROWSE, before the fust observation is value to a character string; displayed. Typical use is to open secondary datasets + RETIJRN statement indicates the end of the block. or initialize constants and variables; Compilation of the program starts when the user issues !NIT: the END command from the program window. If the statements executed before each observation is program is error-free, it is stored in the SAS catalog as displayed. Typical use include initializing variables a part of the screen entry; the modification screen is computed for each observation or displaying initial redisplayed. An other END command give the control messages when a new observation is shown; back to the screen and enable editing data.

MAIN: The structure of the SAS dataset PERM.RESULT is not statements executed each time the user modify a modified by the SCL program: the S variable computed field and press or a function key. If by SCL is not added to the dataset. If we enter the fields does not match defined attributes (minimum, values 20, 22 et 30, the SCL program produce: maximum, required, etc.), an error is issued and the MAIN block is not executed. Typical use are +FSEDIT PERM.RESULT------­ performing extensive validation and cross-validation, ICommand ===> computing new variables or displaying error or ITotal: 72 warning messages specific to fields; I I FRENCH1: 20 I 1ERM: I FRENCH2, 22 executed when leaving an observation. Typical use I I FRENCH3: 30 include final validation or update of a secondary file; I I FSETERM: I statements executed only once, when leaving the Figure 4. Behavior of the SCL program from figure 3. FSEDIT or FSBROWSE procedure. Typical use are exporting content of MACRO valrables or closing ADDING FIELDS TO THE SCREEN secondary files. It is possible to add to the screen some fields, reflecting Figure 3 illustrates a SCL program: the content of corresponding SCL variables:

+FSEDIT Program------+ use the MOD command and select choice 2 "Screen ICommand ===> Modification and Field Identification", I + place the field on the screen using underline charac­ 100001 FSEINIT: 100002 return; ters (" _") and add a description to the field, 100003 + issue the END command and answer Y (Yes) to the 100004 INIT: question "Did you created computational fields?", 100005 return; 100006 + provide the attributes of the added field, and issue 100007 MAIN: the END command, 100008 s=sum(french1,french2,french3); 100009 _msg_="Tocal:" II puc (s, 5.); + when asked to, place the cursor on the field and 100010 return; press to confrrm its exact position. 1000ll 100012 TERM: 100013 return; After these steps, the field reflect whatever content is in 100014 the SCL variable. Let's suppose that the TOTAL field is 100015 FSETERM: added to the screen (figure 5). We also modify the SCL 100016 return; program (figure 6) to put the sum in the TOTAL Figure 3. A basic SCL program variable, computing it only if the number of valid values (X) in FRENCHl, FRENCH2 and FRENCH3 is + FRENCH!, FRENCH2 et FRENCH3 are screen larger than l; if not, the ..MSG_ variable display a variables from the PERM.RESULT SAS dataset; warning explaining why the computation was not done. + S is an SCL computed variable; In version 6.06, computing the variable X can be made + ..MSG_ is a reserved SCL variable automatically simpler: displayed under the command line, in the message zone, after the assignment of a value; X=N(FRENCH1,FRENCH2,FRENCH3);

NESUG 192. Proceedings Interactive Systems 321

TOTAL=SUM(FRENCHl,FRENCH2,FRENCH3); +FSEDIT PERM.RESULT------­ ICommand ===> I The sum is computed ~ displaying the window and I is not computed again following modifications: not very I FRENCH1: 13 useful. Now what happens if the same statement is I I FRENCH2 : 12 placed in both !NIT and MAIN blocks? The sum is I computed before displaying the window as well as after I FRENCH3: 15 any modification (figures 9 and 10). A message will also I ======I TOTAL: be displayed when user move to a new observation: I "Enter data except for TOTAL which is computed". Figure 5. Modified data entry screen. 100004 INIT: 100005 -ffiS9_='Enter data except for TOTAL whi 100006 100006 total=sum(frenchl,french2,french3J; 100007 MAIN: 100007 return; 100008 x=(frenchl ne .J+(french2 ne .J+ 100008 100009 (french3 ne .J; 100009 MAIN: 100010 if x>l then total= 100010 total=sum(frenchl.french2.french3J; 1000ll sum(frenchl,french2,french3J; 100011 return: 100012 else -ffiS9_='Insufficient data'; 100012 100013 return: 100014 Figure 9. Computing in 2 blocks (some lines truncated) 100015 TERM:

Figure 6. Computing TOTAL conditionnally. +FSEDIT PERM.RESOLT------­ ICommand ===> Figure 7 shows the total computed with two or more I Enter data except: for TOTAL which is computed I valide values; in figure 8, only one valid value is entered I FRENCH 1 : 13 and the warning message is displayed: I I FRENCH2: 12 I +FSEDIT PERM.RESULT------­ I FRENCH3: 15 ICommand ===> I ======I I TOTAL: 40 I I I FRENCH 1 : 20 I Figure 10. Effect of the INIT block. I FRENCH2 : 22 I I FRENCH3 : 30 Would we add something by computing TOTAL in the I ======TERM block? No because TOTAL is not a variable in I TOTAL: 72 the SAS dataset. If TOTAL was in the dataset, compu­ I ting TOTAL again in TERM would be wise. Figure 7. Entry of two values or more. ADVANCED VALIDATION

+FSEDIT PERM.RESULT------­ Let's add the character variable SEX to the screen: ICommand ===> IInsufficient data PROC FSEDIT DATA=PERM.RESULT I SCREEN=PERM.CAT.ED4.SCREEN: I FRENCH1: VAR SEX FRENCHl FRENCH2 FRENCH3; I I FRENCH2: n RUN; I I FRENCH3: +FSEDIT PERM.RESULT------­ I ======ICommand ===> I TOTAL: I I I I SEX: F Figure 8. Entry of a single value. I I FRENCH1: 13 USING I OTHER BLOCKS I FRENCH2: 12 I In Sa." the position of statements in one block or the I FRENCH3: 15 I ======other is a major concern. What happens if the previous I TOTAL: program contains, only in the !NIT block, the following statement: Figure 11. Data entry screen with SEX added.

NESUG '92 Proceedings 322 Interactive systems

When a field is validated, SCI.. can issue an error over modified would be a nice addition; never surprise the a field if data are unacceptable. The user will not be user with an action he has to figure by himself. allowed to leave the observation or application unless the field is corrected. The program in figure 12 use this Finally, validation sometimes mean issuing warning feature: the ERRORON statement issue an error over a messages regarding doubtful or abnormal values, without field while the ERROROFF statement remove the error flagging them as errors: for example, small values inside flag over a field. We also use the UPCASE function to the interval between MINIMUM and MAXIMUM bypass case-sensitivity. Fmally, the "not in" argument in attributes or non-integer values. Figure 14 illustrate these IF is equivalent to: two cases. The CURSOR statement move the cursor to the field indicated, while the ERRORON statement IF UPCASE(SEXE) NE 'M' AND UPCASE(SEXE) NE 'F'; performs this automatically. The ALARM statement produce a sound on some terminals. Let's add STUDID, Two RETURN statements are part of the MAIN block. the student identification number, to the screen: This is so because if SEX is flagged as erroneous, any other validation of other fields is useless and the block PROC FSEDIT DATA=PERM.RESULT should stop executing immediately. Execution of MAIN SCREEN=PERM.CAT.ED6.SCREEN; VAR STUDIO SEX FRENCH1 FRENCH2 FRENCH3; re-start if a field is modified and the user press a RUN; function key or . 100009 MAIN: 00004 INIT: 100010 / * VALIDATE SEX * / 100011 sex=upcase(sex); 00005 ~sg_='Enter data except fot TOTAL whi 00006 total=sum(frenchl,french2,french3); 100012 erroroff sex; 00007 return; 100013 if sex=·W· then Sex=·F-i 00008 100014 else if sexe in ('M','F') then; 00009 MAIN: 100015 else do; 00010 if upcase(sex) not in {'M','F'} 100016 erroron sex; 00011 then do; 100017 ~~='ERROR: enter M or F'; 00012 erroron sex: 00018 return; 00019 end; 00013 ~s9_=·ERROR: enter M or F·; 00014 return; 00020 00015 end; 00021 /* VALID. STUDENT IDENTIFICATION *f 00016 else erroroff sex; 00022 if studid ne int(scudid) then do, 00017 tota1=sum(french1,french2.french3); 00023 cursor studid; 00018 return; 00024 alarm; 00019 00025 ~s~='Non-integer student id'; 00026 end; 00027 Figure 12. Validating the SEX field 00028 /* VALIDATE FRENCH1-FRENCH3 */ 00029 if frenchl

In this program, values "M" and "F' are accepted, as Long SCL programs should always be documented. well as "m", "ro, "W" et own. First the value of the The two type of comments available in regular SAS field is converted to uppercase; then the value "W" is code can be use to document SeL code: recoded to "F'. A warning explaining how data was

NESUG '92 Proceedings Interactive Systems 323

* Comment beginning by a star in first column OPEN function opens the SAS dataset used as a table and ending by a semi-colon ; and assign it a number. The open mode is usually "I" /* Other style beginning by slash-star, not in for input, with no modification allowed; an update mode first column, and ended by star-slash */ ("U") is also available:

Comments. instead of documenting the use of each var=OPEN("SAS-dataset","mode"): block, should break the code in sections and explain uncommon functions. complex algorithms and the role of For example, to open the file PERM.NAMES: multiple RETURN statements in a single block.

NF ~AMES=O PEN ( " PERM. NAMES' , • I " ) ; ARRAYS The variable NF_NAMES contents a numeric value. the The ARRAY statement group together SCL variables and enable referencing each one through array name and dataset identification, used as a parameter for many SCL functions requiring a SAS dataset. appropriate index. Figure 15 illustrates modifications to the previous program - fewer statements are needed to The VARNUM function returns the pOsition of a validate fields FRENCH1 to FREN'CH3: variable in a SAS dataset:

100001 FSEINIT: var=VARNUM(file-number, "variable"); 100002 array cst {3} frenchl french2 french3 100003 return; For example. to find the position of variable STIIDENT IN!T and beginning of MAIN block in the dataset PERM.NAMES. we could use: 100029 /* VALIDATE FRENCH1-FRENCH3 *f 100030 do i=3 to 1 by -1; NF~AMES=OPEN(·PERM.NAMES·,·I"); 100031 if tst{i}

These SCL functions are preceded by tho others enabling access to the SAS dataset: OPEN and VARNUM. The

NESUG '92 Proceedings 324 Interactive systems

and SASIFSP). Programs will be clearer. 100001 FSEINIT: 100002 array tst (3) frenchl french2 french3 100003 nf-names=open('PERM.NAMES','I'); 5) Simplify data exchange between SAS datasets and 100003 pv_student=varnum(nf-names,'STUDENT') SCL programs. 100005 return; INIT and beginning of MAIN block Use whenever possible the CALL SET function rather than GETVARN or GETVARC. ALso use 100024 ,. VALIDATE STUDIO', 100025 if studid ne lnt(studld) then do; the DROP: et KEEP: parameters in the OPEN 100026 cursor studid; function to limit the number of variables read. 100027 alarm; 100028 ~S9-='Non-integer student id-i 100029 end; 6) If possible, avoid submitting SAS code. 100030 rc=locaten(nf~ames.pv~tudent, 100031 studid, -A-) i Some functions of the SCL language can replace the 100032 if rc=O then do; 100033 erroron studid; submission of SAS steps: VARSTAT (computing 100034 JIlS!L.= ' ERROR: This student number descriptive statistics), SORT or FSEDIT. 100035 end; end of MAIN block and of the program 7) Validate functions return codes.

Figure 16. External table (some lines are truncated) Most functions provide return codes. It is much better to validate these and provide the user with an COMPn.ATION ERRORS indication about what went wrong - even the mini­ mal content of SYSMSG - rather than ignoring the Problems and errors arising during compilation are return codes and carrying on with errors. Use the indicated by one of these messages displayed in the _STATUS_ variable to stop execution when a fatal modification menu window: error is encountered.

- Compile was successful, but see LOG for warning. 8) Create a tool-box of useful routines. - ERROR: see LOG for compile error listing. Place these routines in a common catalog where The flISt one indicates a missing block or an unused they can be updated without recompiling each single variable. If the second message shows, the SCL syntax application using them. is in error; not correcting it will prevent editing the dataseL Detailed diagnostics can be found in the LOG. 9) Define your own programming standards.

10 USEFUL TIPS WITH SCL Standards cover variables. files and block naming, and distinction between SCL code and submitted I) Define the lenght of SCL character variables. SAS code (uppercasellowercase for example).

Every non-window character variable in an SCL 10) Revise programs in production. program is assigned a default length of 200 charac­ ters. This is usually far too long. During the fteSt months, youk knowledge of SCL will grow faster. Revise your most critical applica­ 2) Initialize in FSEINIT or INIT blocks. tions to integrate functions or statements you now master and pay close attention to future releases of TheINlT (SAS/AF) or FSEINIT (SASIFSP) block SAS/AF and SASIFSP for new functions that will are the best place in an SCL program to initialize simplify your coding and make it more efficient. constants, define arrays or modify normal execution flow with the CONTROL statement. AUTHOR'S ADDRESS

3) Only one RETURN per block, if possible. Services Conseils Hardy Inc. 3487 Carre de Nevers If a block contains more than one RETURN, clarify Sainte-Fay, QC. Canada their function using comments. GlX 2C9 (418) 656-1764 4) Use longer variable names.

In SCL, variable names can extend to at least 16 SAS, SAS/AF and SASIFSP are registered trademarks of characters (releases 6.04, 6.06 and 6JYl - SAS/AF SAS Institute Inc.

NESUG '92 Proceedings