I am using SAS version 9.2 and have the following piece of code that aborts a job run through based upon some conditional input from the end user:
%WINDOW flowmng
ICOLUMN= 15 IROW= 10
COLUMNS= 80 ROWS= 20
"<Have you checked that all three Flow Manager jobs have completed successfully?>"
#5 #15 "Type 'Yes' for yes or 'No' for no, THEN press
[ENTER]"
#9 #23 "Flow Manager jobs run?" #48 resp 3
ATTR=UNDERLINE REQUIRED=YES
;
%MACRO macronam ;
%LET null = ;
%LET resp2 = %UPCASE(&resp);
%DISPLAY flowmng ;
%IF (&resp2 eq YES) %THEN %DO;
%END;
%IF (&resp2 eq NO) %THEN %DO ;
%ABORT;
%END ;
%MEND macronam ;
%macronam;
This all works great apart from the fact that when I reopen the window, the user input from the last job is still there. I've tried looking for the %WINDOW option to reset all fields, but I cannot seem to find it in the documentation I have read.
Does anyone have the syntax for this?
Thanks
It's using the value of &resp, so just add
%let resp=;
before the %WINDOW call.
Related
Any idea why this stop execution code doesn't work?
There is no observation in table1, but proc print still runs.
%macro execute (inputdata=work.table1);
data _null_;
if 0 then set &inputdata. nobs=n;
call symputx('totobs',n);
stop;
run;
%if &totobs. = 0 %then %put exit;
%else %do;
%put execute further;
%end;
%mend execute;
%execute(inputdata=work.table1)
proc print data= work.table1;
run;
Your Proc PRINT occurs after the macro execution, and thus there is nothing preventing the proc from being submitted. The %put exit only causes a message from the macro system to be displayed in the log window.
There are some tricky things you could do, but shouldn't
definitely not this: have the macro emit source code ;* when there are no observations. The semi-colon asterik (;*) will cause a null statement (or complete an open one), and then start a comment statement in the source code (being handled by the submit processor) that ends at the next semi-colon. %if &totobs. = 0 %then %str(;*);
When totobs is zero the submit processor will see source code
;*proc print data= work.table1;
maybe this: halt all further execution of the currently submitted source code. Inside the macro an %abort cancel will do this.
%if &totobs. = 0 %then %abort cancel;
The best answer is the question "What do you want to happen?"
This code will be part of process in SAS data Integration Studio.
I want to achieve something like:
%macro conditional_start();
%let check_condition = 0;
%if check_condition eq 0 %then %do;
%send_email_that_condition_has_been_met(); /* this I have made */
/*Below run some kind of built-in macro probably, to stop execution of the whole code below */
%end;
%mend;
/*More macros end code I don't want to execute*/
I cannot pack everything below in big "if" statement because they are built in blocks.
Is it possible?
Thanks in advance!!
Have you tried to put your code into "precode" (leave macro open) and "postcode" (rest of the macro) sections of your job's properties?
For example:
precode:
%macro the_whole_job();
postcode:
%mend the_whole_job;
%macro conditional_start();
%let check_condition = 0;
%if check_condition eq 0 %then %do;
%send_email_that_condition_has_been_met(); /* this You have made */
/*do some kind of built-in macro meaning failure, not executing the whole code above*/
%end;
%else %do;
%the_whole_job;
%end;
%mend;
I have to different statements in one code. For example:
First:
data step2;
set ste1;run;
proc print data=step2;quit;
Second:
data step6;
set ste5;run;
proc print data=step5;quit;
Is it possible to choose by PROMPT variable which one of them I need to Execute?
Assuming you mean a stored process prompt variable, you can simply build a macro:
%macro choose;
%if &mypromptvar=1 %then %do;
data step2;
set ste1;run;
proc print data=step2;quit;
%end;
%if &mypromptvar=2 %then %do;
data step6;
set ste5;run;
proc print data=step5;quit;
%end;
%mend;
%choose;
where mypromptvar is the name of your promptvariable...
I have a dataset naming error_table as follows. All the variables are character
Errorno Error Resolution
001 login check
002 datacheck check
I wanted a logic that executes a sas program If the Errorno is not in 001 and 002. Else stop execution and display the error_table.
I tried the following
%macro test();
proc sql;
select trim(Error_No) into: num from error_table;
quit;
%if &num. not in ("001","002") %then %do;
%include "/path/dev/program.sas";
%end;
%else %do;
proc print data = error_table;
run;
%end;
%mend;
%test;
But, it is throwing an error.
Can anyone please correct the logic.
You need to watch out for the case when the SELECT returns zero rows. You should set a default value to the macro variable NUM.
Is your dataset variable numeric or character? Use the TRIMMED or SEPARATED BY clause instead of the TRIM() function to prevent spaces in the macro variable that is generated by the INTO clause.
%let num=NONE;
select Error_No into: num trimmed from error_table;
Remember that to the macro processor everything is a string so don't but quotes around the values you are trying to match unless they are actually part of the value.
%if NOT (&num. in (001,002)) %then %do;
Also to use the IN operator in macro code you need to make sure you have set the MINDELIMITER option.
I would sugest moving condition with error codes to proc sql.
proc sql;
select count(*) into :num_errors
from error_table
where Errorno in ("001", "002");
quit;
Then in macrovariable you have number of errors that are 001 or 002.
Next step is to check macro-condition:
%if &num_errors. > 0 %then %do;
%include "/path/dev/program.sas";
%end;
%else %do;
proc print data = error_table;
run;
%end;
%mend;
Ever had a problem with a SAS session, but been unable to close the session due to having critical files in your remote work library (RWORK)??
I certainly have! So how do you access that library from another (new) session?
Here's a macro I wrote to assign a multiple libref to all remote work directories owned by you :
rsubmit ;
%MACRO DOUBLELIB(USER=&SYSUSERID,LIB=double) / des="Assign libname of double for multiple SAS sessions for the same user";
options nosymbolgen nomprint ;
%LET WRK = %SYSFUNC(pathname(work)) ;
%LET WRKDIR = %SYSFUNC(scan(&WRK,-1,/)) ;
%LET SASTEMP = %SYSFUNC(tranwrd(&WRK,&WRKDIR,)) ;
filename mywork pipe "ls -ls &SASTEMP" ;
data zwork ;
infile mywork lrecl=512 recfm=v pad ;
input #1 char $512. ;
if index(upcase(char),upcase("&USER")) and ^index(char,scan("&WRK",-1,'/')) and index(char,'SAS_work');
path = scan(char,-1,' ') ;
n + 1 ;
call symput('PATH'||compress(n),"&SASTEMP"||strip(path)) ;
call symput('PATHN',compress(n)) ;
run ;
%NOBS(zwork) ;
%IF &NOBS > 0 %THEN %DO ;
libname &LIB (
%DO I = 1 %TO &PATHN ;
"&&PATH&I"
%END ;
) access=readonly ;
%END ;
options symbolgen mprint ;
%MEND DOUBLELIB;
%DOUBLELIB(LIB=dblwork) ;
endrsubmit ;
/* Assign local libref to new remote dblwork libref */
libname rdouble slibref=dblwork server=myserver ;
not sure of the ethics of asking a question you know the answer to, but hopefully others will find this useful!
%macro serverpath;
%put NOTE:; %put NOTE-; %put NOTE-;
%put NOTE- libname OldWork "%sysfunc(pathname(RWORK))" server= remote %str(;);
%put NOTE- rsubmit%str(;);
%put NOTE- libname OldWork "%sysfunc(pathname(RWORK))"%str(;);
%mend; %serverpath;
This will put the code you need in the log. The bit you may need to change is the server= option - this should be the name of the environment you have logged onto (not sure how to reference this programmatically - does anyone else know?)
Obviously the original session needs to remain open (to prevent RWORK from being wiped) and the second session needs to be logged onto the same server...
response to Chris J's response - missing macro..
rsubmit ;
%macro nobs(dsn);
%local dsnid rc;
%global nobs;
%let nobs=.;
%* open the data set of interest ;
%let dsnid=%sysfunc(open(&dsn));
%* If the open was successful get the nobs and CLOSE &dsn ;
%if &dsnid %then %do;
%let nobs=%sysfunc(attrn(&dsnid,nlobs));
%let rc =%sysfunc(close(&dsnid));
%end; %else %do;
%put WARNING: Unable to open &dsn - %sysfunc(sysmsg());
%let nobs=0;
%end; %mend nobs;
endrsubmit;