Stop SAS execution - sas

Quick question
Is there a one-liner (or something rather short) method of cancelling the execution of further SAS statements from withing the windowing environement.
These are the methods I know of but they get tiresome, espeacially in huge programs with a lot of comments.
I tried the ABORT and STOP statements but they close the windowing enviroment yet all I want is to stop execution at a certain point and go on my merry way.
Thanks

This is something that comes up on SAS-L every so often. The answer is that it depends on what you're doing, largely.
The run cancel method is probably best if you are hoping to stop execution because of an error. At the top of your program you do:
%let cancel =; *or any macro variable name, but cancel is most logical;
Then in every run step you have:
data whatever;
... do stuff ...;
run &cancel;
And each time you have some potential error, you check the error condition and then if it hits,%let cancel=cancel; and you're good.
If you are using macros, you can exit a macro smoothly with %abort as long as you either use no options or only use cancel. Depending on what you're doing, you might set up your code to run in a macro (or macros) and use this option (although with the disadvantage of losing some log clarity).
Finally, if you're just interesting in being able to run a subset of your code, I recommend writing the code in multiple SAS programs for the bits you might want to run separately, then using %include from a master program to group them all together along with any macro variables you might want set that are shared. This is similar to how in EG you would construct many smaller programs and then group them using the process flow diagram.

I have used the following
%abort cancel;

i've been searching for this too - documentation is not good on this one. Trial and error (sigh...). This, amazingly, undocumented feature worked for me:
data _null_ ;
ABORT CANCEL ;
run ;
Pretty simple! Nothing after that executed, and yet the SAS application remained open.

Related

Process flow gets stuck on table creations

I'm trying to understand the Enterprise Guide process flow. As I understand it, the process flow is supposed to make it easy to run related steps in the order they need to be run to make a dependent action able to run and be up to date somewhere later in the flow.
Given that understanding, I'm getting stuck trying to make the process flow work in cases where the temporary data is purged. I'm warned when closing Enterprise Guide that the project has references to temporary data which must be the tables I created. That should be fine, the data is on the SAS server and I wrote code to import that data into SAS.
I would expect that the data can be regenerated when I try run an analysis that depends on that data again later, but instead I'm getting an error indicating that the input data does not exist. If I then run the code to import the data and/or join tables in each necessary place, the process flow seems to work as expected.
See the flow that I'm working with below:
I'm sure I must be missing something. Imagine I want to rerun the rightmost linear regression. Is there a way to make the process flow import the data without doing so manually for each individual table creation the first time round?
The general answer to your question is probably that you can't really do what you're wanting directly, but you can do it indirectly.
A process flow (of which you can have many per project, don't forget) is a single set of programs/tasks/etc. that you intend to run as a group. Typically, you will run whole process flows at once, rather than just individual pieces. If you have a point that you want to pause, look at things, then continue, then you have a few choices.
One is to have a process flow that goes to that point, then a second process flow that starts from that point. You can even take your 'import data' steps out of the process flow entirely, make an 'import data' process flow, always run that first, then run the other process flows individually as you need them. In fact, if you use the AUTOEXEC process flow, you could have the import data steps run whenever you open the project, and imported data ready and waiting for you.
A second is to use the UI and control+click or drag a box to select on the process flow to select a group of programs to run; select the first five, say, then run them, then select 'run branch from program...' option to run from that point on. You could also make separate 'branches' and run just the one branch at a time, making each branch dependent on the input streams.
A third option would be to have different starting points for different analysis tasks, and have the import data bit be after that starting point. It could be common to the starting points, and use macro variables and conditional execution to go different directions. For example, you could have a macro variable set in the first program that says which analysis program you're running, then the conditional from the last import step (which are in sequence, not in parallel like you have them) send you off to whatever analysis task the macro variable says. You could also have macro variables that indicate whether an import has been run once already in the current session that then would tell you not to rerun it via conditional steps.
Unfortunately, though, there's no direct way to run something and say 'run this and all of its dependencies', though.

Stop SAS from running after encountering an error

is there a simple option that will cause SAS to stop running when it encounters an error. Something similar to the option ERRORABEND, except without quitting SAS?
I have seen other questions - e.g. Stop SAS Program on Error, and Stop SAS macro execution on error however those questions seemed somewhat different in that either dealing with remote server / handling expected errors at known places. I find it hard to believe/understand that there is no simple way of stopping at errors except by placing macros throughout the code to look for errors.
I believe the thing you are looking for is the break button on the application toolbar. It is the exclamation mark with the circle around it.
Note: make sure not to hit the clear all button (which is the stylized 'X')!! It will clear all your program editor code and cannot be undone.
You can use options syntaxcheck ; to enable syntax-checking mode after an error.
So, to enable what I think you want to achieve :
options noerrorabend syntaxcheck ;
https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#base-sysop-syntaxcheck.htm

Setting MXG macro variable &SMFEXIT to CICS globally

z/OS 1.11, MXG 32.10, SAS 9.3, Batch
I'm working on upgrading MXG to 32.10 with SAS 9.3. While running a CICS report today, I received the message that MXG was taking 20x to 30x CPU processing to decompress messages because the decompression exit was not enabled. To do so, I have to set the macro variable &SMFEXIT to CICS in each run, as follows (I had already assembled and linked the exit and had it available in STEPLIB):
%LET SMFEXIT=CICS
Other options are available but they are more complex and still need set every time I want to access the CICS data. I used it in my program and it worked fine and ran much, much faster.
I figured I'd put this into AUTOEXEC. It didn't work there. AUTOEXEC seemed to process normally with no errors, meaning there was no output at all... It may have had a warning, but that wouldn't show. Only errors display from AUTOEXEC.
I found that I could specify global option ECHOAUTO, along with SOURCE, to display AUTOEXEC processing. That has to be done either in CONFIG or as an invocation parameter. I tried both options and neither worked. I purposefully misspelled it in CONFIG and that threw an error, so I know it was being found. SAS lists the invocation parameters in SASLOG, so ECHOAUTO and SOURCE were both listed there. I received no indication that those options were working and AUTOEXEC processing just didn't go to SASLOG.
I ran PROC OPTIONS RESTRICT and nothing was restricted.
All the messages kept telling me to talk to the System Administrator. I found nothing that told me who that was, what they were supposed to do or how to find out... I sit by our System Administrator and he was no help with this because I'm the one that knows SAS. Or, I thought I did...
So, how do I set &SMFEXIT to CICS globally? Bonus for information as to why ECHOAUTO totally ignored me and information about the System Administrator. Also, where can I find information about the limitations of AUTOEXEC as in what can or cannot be there. Better yet, tell me in what guide I can find this information myself. I searched for a long time and couldn't find any of that. SAS documents are many. SAS information about these questions is either scarce or just impossible to find.
Thanks...
UPDATE: I am considering setting up my MXG proc so that it has a concatenation that throws in this control card ahead of the MXG/SAS programs. Seems like an awful hack... Still would like other options and answers to the ancillary issues IAAP. Thanks again.
Ah yes, the head slap... Every issue above is easily explained by the fact that AUTOEXEC is not being called! Variables aren't set. Logic isn't added to the SASLOG.
We use Windows SAS, too. We use AUTOEXEC.SAS to extensively initialize that environment. On the other hand, on z/OS, we use JCL and parameters to initialize SAS without using AUTOEXEC, so it has never been implemented.
On z/OS, the AUTOEXEC global option defaults to the SASEXEC ddname. I added the appropriate JCL to my MXG PROC to point to my AUTOEXEC member. Voila. My variable is set. The logic is available in SASLOG. Everything appears to be working, all with one simple root cause.
Thanks...

Get the name of the SAS program being run

Are there any generic suggestions for identifying the SAS code / program that is being executed?
My code will execute within a generic macro, so could be called within a Stored Process, another macro, a client SAS program, or even SAS code generated via the mid-tier using IOM. I'd like the highest level identifier possible.. (something that will return the same result if the same program is run again - so process id would not be helpful).
The environment is not windows, so this code is not helpful:
%put %sysget(SAS_EXECFILENAME);
Also, the macro is not necessarily the first program that is called (if it is even a program) - so neither is this code helpful:
proc sql noprint;
select xpath into :progname
from sashelp.vextfl where upcase(xpath) like '%.SAS';
%put &progname;
It sounds to me like you may need to think through how this is to be be used a little more. What if the same user has two sessions open running the same code? Should that use the same file name?
Can you simply make it a requirement of your piece of code that a certain variable must have been specified before your code will run? Otherwise return an error / abort further processing?
To answer your original question though I don't think this is possible.

In SAS, what are good techniques/options for catching syntax errors?

In the enhanced editor, the coloring might give you a hint. However, on the mainframe I don't believe there is anything, in the editor, that will help you.
I use
OPTIONS OBS=0 noreplace;
The obs=0 option specifies that 0 observarions are read in from the input
dataset and NOREPLACE tells SAS not to overwite an existing SAS dataset with one of the
same name. If you are creating a new datastet, it will be created with all the attributes,
but with 0 observations. (Be sure to reset the options, if needed, to Options Obs=max replace ; when no more syntax errors are found).
I'd be interested in any other techniques.
Thanks
Explanation about options came from here.
I use the cancel option on the run statement. It will check the syntax of the data step then terminate it without actually executing it. It's the data step analog to the noexec option in proc sql.
data something;
<stuff here>
run cancel;
Lots more details in this SUGI pdf
I write all of my code on my PC with SAS on my PC and the enhanced, color coded editor. I then use SAS/CONNECT to process it on the mainframe. If the datasets are on DASD, I use SAS/CONNECT and Enterprise Guide to directly run the code onthe mainframe (no JCL!) If there is a data tape involved and therefore must be a batch run, I use SAS/CONNECT and the SAS ftp engine to send the code to the mainframe batch queue. I use the SAS email engine to email me back my output and my log. I put and ODS sandwich aound my code to have the mainframe generate a WORD document for output. I use a PROC download to download the output to my server so I can open it in WORD.
This advice is language agnostic.
I would argue that a preferable technique for catching syntax (and logic) errors is to perform a close read (or inspection) of your own code (which should catch the majority of syntax errors), followed by unit tests on small datasets (which will catch any remaining syntax errors, as well as many logic errors if your tests are well-designed).
I agree there's some worth to syntax checking in isolation, but to read and understand your code thoroughly enough before the first compile so that you know it will compile is a good ideal to strive for. Steve McConnell touches on this idea in Code Complete (see page 827 of the 2nd Edition).
P.S. You mentioned syntax highlighting in your original post; there are other editors (such as VIM) that will perform syntax highlighting on SAS files.