Section 2.2: Steps and Boundaries A typical SAS command file consists of a sequence of DATA and PROC steps. DATA: a block of statements that work together to read an external data file, to write a new SAS dataset, or modify an existing dataset. PROC: a block of statements that performs a specified task (e.g., print a dataset, write formats, sort files, routine maintenance, etc.) or invokes a data analysis procedure (PROCs MEANS, CORR, REG, TTEST, MIXED, etc.). Usually a DATA or a PROC step concludes with a step boundary (see below) such as a RUN; or a QUIT; statement. The presence of the next DATA or PROC keyword is often sufficient; however, it is still a good idea to enter RUN; at the end of a DATA or PROC step. All statements that appear in each DATA or PROC step that end with a step boundary are processed before moving on to the next block of statements. For Windows, the last command of the file is not a step boundary, unless it is a RUN; statement which means it is essential at that location in the file to enter a RUN; as the final command. Steps are merely blocks of SAS statements that consist of a series of keywords with options, functions, or equations to perform the necessary data management or analysis tasks. Each step begins with either the DATA or PROC keyword followed by relevant statements: DATA ; * writes one or more SAS datasets, either temporary or permanent; < insert DATA step statements > ; PROC ; * apply specialized procedures to data stored in SAS datasets; < insert PROCedure step statements > ; STEP BOUNDARIES Step boundaries have these main purposes in a SAS program: * improve the readability of code as they clearly define the end of a DATA or PROC step and the beginning of the next one * tell SAS to print messages that appear in the log file in the proper location * place titles or footnotes to the outputs where they belong * in macro code or when ODS statements follow, it is necessary to specify that a DATA step has finished before macro or Output Delivery System instructions are issued. Among several SAS keywords that define step boundaries are DATA, PROC, RUN, ENDSAS, CARDS, CARDS4, DATALINES, and QUIT statements. When a series of steps are run sequentially, the keywords DATA and PROC are often sufficient to define the end of the previous block and the beginning of the next one. However, the RUN; (and sometimes the QUIT;) statement should be entered to indicate the end of a DATA or PROC step. Although there are some important exceptions (as explained below), it is often not necessary to insert a RUN; statement, but is a good idea if output from the final step does in the sequence does not appear. However, RUN; or QUIT; statements are a very effective aid when editing an existing program to quickly identify the end of each block of statements. Both RUN; and QUIT; statements are necessary to conclude a few PROCs steps, when writing macro variables, or when entering statements for the Output Delivery System (ODS). RUN; * specifies the end of a DATA or PROC step; * tells SAS to process all statements that appear since the most recent DATA or PROC statement; The two SAS keywords, DATA and PROC, are also called step boundaries since their appearance at the beginning of a set of commands or immediately after a semicolon, indicate the first statement of the next block. As a result, they automatically generate a RUN; statement. Either one tells SAS that the end of the current block of statements has been reached. However, to minimize puzzling error messages or output that has the titles out of place, it is good practice to place a RUN; statement as the last statement of each block of DATA or PROC steps. Important Reminder: Placing a RUN; statement or a QUIT; statement at the end of the program gives the block a sense of completeness, and should be used, especially when running the Windows version of SAS; without it, the final block of statements will not be executed! Here is an interesting situation to be aware that occurs with a few procedures. The last procedure in a PC SAS program may produce the necessary output but the enhanced editor title bar will say "PROC XXXX is running". One way to get rid of this message is to break and cancel the submitted statements. You can get around this by putting a second semicolon at the end of the last block of PROC statements, i.e. PROC MIXED DATA=junk; CLASS cls_var1 ; MODEL yvar = cls_var1 xvar2; RUN; ; This works except that when calling a macro as the last part of my program (which requires no semicolon). Adding semicolons to terminate the last call does not work. You also want to keep the windows open so do not use the ENDSAS; command. What should you do? With PROC GLM (also PLOT, CATMOD, REG, SQL, DATASETS, among others) the RUN; statement by itself does not serve as a step boundary. It acts to run the most recently entered statements. In this situation you also need to apply the QUIT; statement to stop the procedure (without it you will see PROC GLM running at the top of the editor window). The QUIT; statement is needed before you can insert ODS statements following a block of statements from these PROCs. SAS chose this interpretation for RUN; rather than the implied one of procedure completion, thus depriving the language of a common step boundary statement. The reason for the confusion is probably due to most of the example code published by SAS does not require the concept of step boundaries. The reason the RUN; statement works this way is to improve performance. PROC GLM stays in memory and "waits" for more statements to be submitted. That means, if you have additional PROC GLMs to run you can possibly bring them together into one PROC and save computing overhead. Normally that should be no problem, because SAS recognizes what when another step follows the most recent GLM statements are history (you can test that with adding a PROC PRINT after PROC GLM). If you have completed all sub-steps in PROC GLM (or any other resident PROC) you can end it with a QUIT; statement. If you need other GLM steps after that, you will need to invoke the PROC again. Perhaps if the RUN; statement came after the development of the macro facility instead of before, the situation might have been different.