Terminate whole process flow instead of single program - sas

Is there a way to stop the process if certain criteria in any of the programs in this process is met?
I have a process consist of 5 SAS programs. This process is scheduled to run at 8am every morning. However, sometimes the database is not refreshed and this process will send out weird figures.
I need to have "exception control".. In 2nd program I check the database with some criteria. If no error, then keep running the rest of the code. Otherwise, send out an notification email and STOP running the 2nd program and all the subsequent programs.
I try %abort cancel but it only terminate the current program. The subsequent programs are not affected.. I can do checking in every single program but that make the code redundant...
I also try google "terminate SAS process" but most of them refer to abort statements which doesn't help...

If you're using Enterprise Guide, this is built into the program via logic gates.
First, in the program that determines whether the database file passed/failed ("gate program"), assign a macro variable a value based on that test. Presumably this program will do only things you're happy for it to do even if it fails.
On the process flow page, you right click on the program that determines if the database file passed/failed, and select 'Condition -> Add'.
Then add a condition based on a Macro Variable, and use 'equals' and the value you're looking for (or 'greater than' or whatever makes sense). Then select the next task after "Then run this task"; and put the other option after Else run this task.
Then, whichever of the two is forward-moving, should then have links to the rest of the programs you want run; the one that's not should end the process.
SAS gives an example of how to do that in KB Sample 39995 including a sample project you can download.
Second, you can set OBS=0 if you reach the error condition. This will let SAS continue working, but it in most cases won't be able to do anything (since OBS=0, then it can only affect 0 records of any dataset). I'm not sure that's a guarantee that it won't do anything, but in everything I've done that's been sufficient. I also have used OPTIONS ERRORABEND which works fine if you do all of your processing with external libnames which won't automatically reconnect when SAS is reconnected.

My understanding is that this is a batch process. You don't specify Operating System you are running your process on. Let's suppose you are running it on UNIX/Linux (I am hoping it is similar on Windows). Let's assume that your 5-programm process is run by the following shell script:
sas /program1.sas
sas /program2.sas
sas /program3.sas
sas /program4.sas
sas /program5.sas
If you want to stop your remaining process after program2.sas completes with ERRORs or WARNINGs you can modify your script to be
sas /program1.sas
sas /program2.sas
if [ $? -ne 0 ]
then
exit
fi
sas /program3.sas
sas /program4.sas
sas /program5.sas
In this script code a special shell script variable $? status code is passed from the previous command from SAS (0 means successful completion). If it is not 0 then the whole script stops due to the exit command.
For more information and code examples see How to conditionally terminate a SAS batch flow process in UNIX/Linux SAS blog post.

Related

Start .exe file and automatically "press enter for "Save"" in SAS

I have a SAS program I would like to schedule, so we don't have to run it manually.
In the program we call an excecutable (reg.exe), like this:
X CALL "K:\reg.exe";
The executable opens a standard windows save-dialog and all we need to do is press save, which will save an xml-file. The save-dialog already opens in the correct directory.
What I would like is to somehow pass the instruction on, using code, to "press save", so the program can move on and work with the saved xml-file.
Is this possible somehow?
Thanks for your help!
Thomas:
There are numerous Windows utilities for scripted control of an interactive program. For example: AutoIt (my favorite), MouseRobot and AutoHotKey to name a few.
The statement
options xmin noxwait noxsync;
will cause the external program to run, not wait for the command session to exit, and not wait for the command to complete.
If your SAS programs needs to wait for the side effects of the scripting use of reg.exe to occur before occurring, use:
options xmin noxwait xsync;
These settings affect other operating system interfacing features, such as:
X command
CALL SYSTEM routine
%SYSEXEC statement
The use of your reg.exe might require your login to have admin rights.
The SYSTASK statement can also run external commands.
If you find that you are unable to run external commands, it is probably because the system setting NOXCMD is active. This setting is on by default in SAS server environments.

Completely stop Enterprise guide on condition

So, I have a simple project with one Program (user-writen code) and then one Add-Inn (custom task) (it is very useful System Command executor add-inn, about you can read here)
So, when I get some condition in Program step, I want to stop my Project. I could stop Program, for example, using
ENDSAS
or
Abort abend
but, even if Program immediately stops (with error message in log), Add-Inn is execute! How disable executing of Add-Inn on condition (on error or any other)?
Thanks
P.S. Project will be execute in batch mode
If you're using an EG process flow, as you presumably are, then you need to set up a condition to run the add-in task.
Right click on your one program, select 'condition', add. Let's say you have a macro variable that is set to 0 if you have no problems or (some value) if you have a problem. (Could also use any of the automatic SYSERR type macro variables.)
Then, put your add-in task under "Then, run this task". You can add an Else or Else If if you want, or just leave that as None.
Then, EG won't run your task unless the macro variable is successful.

How to call one macro program from another in SAS Enterprise Guide?

Is there any macro command that allows calling one program from another (the %run_program() pseudo code)?
Program "Settings":
%let myvar="HELLO WORLD!";
Program "Program":
%run_program(Settings); *Pseudo-code;
%put &myvar; *Should print *Should print "HELLO WORLD!";
This is not exact answer on your question, but if you only want to be sure that Settings is run before Program when Run Process Flow you can link them together.
Right click Settings,
choose Link Settings to...,
and pick Program from the dialog.
Run Process FLow And see the Hello World be printed in the log.
I think that you are looking for the %include function.
You would have to save 'Settings' as a stand-alone program on your server like '/myserver/somefolder/settings.sas'.
Then you could ensure that it is run via:
...some code
%include ('/myserver/somefolder/settings.sas');
... more code
The program would run exactly as it would if you copy-pasted the contents of 'settings.sas' into the current program.
In addition to the Process Flow, you also can create an Ordered List. This allows you to run programs in a single process flow in multiple different orders (or run a subset of a process flow).
You create that in New -> Ordered List, then Add programs to it, move them up/down in the order you want. Then you see the ordered list on the left in the project tree and can right click to run it (or select then F8).
There is not a macro command to run a program in enterprise guide; you can use automation via .NET if you want to do things like that. Chris Hemedinger on The SAS Dummy has a good article on EG automation.

XWait and XSync not behaving correctly

I am running SAS 9 on Windows Vista. I am using system Commands to execute some Python code in some nested macros that are passing different parameters to Python each time. Im using the XSYNC and XWAIT options in SAS.
My understanding of this is that these two options should make SAS pause until the Python script has completed running. With this option the Python Command Prompt window closes when the code completes execution and I am then prompted to type EXIT, which is what you would expect.
However, when I use NOXWAIT XSYNC the SAS code passes each Python invocation, kicks it off and keeps running. After a few minutes I have hundreds of Command Prompt windows open all trying to run at the same time.
What am I doing wrong? As a work around I have tried using x 'EXIT' and call system ('EXIT') to close the windows administrator command prompt window down but this does not seem to be being passed to the window, even though the exit command is in a separate data null step to the one that calls the Python code.
Any ideas?
Here is code I'm using:
data _null_;
x 'cd C:\Python33';
x 'start test.py';
run;
data _null_;
call system ('exit');
run;
What happens is two Command Prompt windows open. The second one is the Python script running. This closes itself and I am left with the administrator window. I have tried putting an x command of 'Exit'; in the first data null step, but this has not worked.
XSYNC tells SAS to execute an external command synchronously, meaning SAS pauses until the command completes. You would use NOXSYNC only in very specific applications.
XWAIT tells SAS to wait for you to explicitly exit the window running the command. In most cases, you would want to use NOXWAIT.
The problem you describe suggests to me that your Python commands are not properly terminated. Sorry, nut I don't know Python. But consider putting your Python statements in a script file, which closes itself with an exit command, or adding an exit command to the SAS call, something like:
data _null_;
call system('python-command;exit');
run;
If this does not help, revise your question and show the complete SAS data step code you are using. Note, using a second X command to push an "exit" statement will not work; it must be part of the initial call.

Auto Scheduled SAS Queries

I run some SAS queries monthly and they all take a fairly long time to run. I was wondering if there was any way I can schedule these to run on a certain date each month in a certain order?
Thanks for your help!
On unix you could set the programs up to run in batch mode with a cron job.
One trick you could use would be to set up a master SAS program to run everything.
Make one program that just contains any global variables that need to be changed each month and then call your monthly programs with includes.
something like:
%let globalvar1 = ThisMonth;
%let globalvar2 = LastMonth;
%include '/path/to/sas/program1';
%include '/path/to/sas/program2';
Then you run only this one program in batch...it will run them in the correct order and automatically wait for them to finish executing before moving to the next program (setting up separate cron jobs would require you to overestimate how long each one takes so they wouldn't conflict).
This will dump everything into one log file...which may be good or bad.
Another option would be to use X to call the program from the OS at each run.
I am not 100% on the syntax but this should work if you use the right syntax for your OS (this could work on unix or windows so you would only have to schedule one program).
At the end of each program just add:
X "Path/to/sas.exe" -batch -noterminal nextProgram.sas
This will let you chain the programs together so that they start the next one running after they finish. Then you just use task scheduler/cron to start "sas.exe -batch -noterminal firstProgram.sas"
Depending on what system you are working with, methods may be different.
The main idea is that you may store all queries to a SAS processing file then use system's scheduler (For example, task scheduler for Windows), to run monthly.
A quick help (for Windows):
http://analytics.ncsu.edu/sesug/2006/CC04_06.PDF