08-31-2017 10:59 AM
I have a dataset with NAME column in it. I want to write a process where in I can test if, else if condition to say if the NAME does not fit in the desired list then Kill SAS procedure, else proceed.
I have coded like this -
%macro validate_c (data, cols);
proc contents data= &data. out=cont_&data. (keep= NAME) noprint; run;
PROC SQL NOPRINT;
SELECT * FROM cont_&data.
%if NAME NOT in (&cols.) %then %do;
%PUT ABORT: NOT REQUIRED COLUMNS;
%else %if NAME in (&cols.) %then %do;
%PUT PROCEED: REQUIRED COLUMNS;
This gives me error -
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand
is required. The condition was: NAME NOT in (&cols.)
ERROR: The macro VALIDATE_C will stop executin
08-31-2017 11:16 AM
Use of the IN operator in macros is conditionned by the MINOPERATOR system option.
08-31-2017 11:31 AM
I still get the same error.
Can this code be tested on dataset Country_Metadata_Refdata as -
and execution as -
%validate_c (Country_Metadata_RefData, %str(Var1, Var2, Var3));
This should kill SAS procecdure as column "E" does not exists in the execution
%validate_c (Country_Metadata_RefData, %str(Var1, Var2, Var3, E));
This should proceed without error as SAS as column "E" exists in the execution and variable List.
08-31-2017 11:35 AM
Before writing a macro, you should have working base code that will terminate a process.
What does that look like now?
Then you take your macro code and make it generate that code. So comparing what gets generated to your working code is the debug process.
08-31-2017 12:03 PM
You cannot "kill" a procedure. You can use macro logic to conditionally either generate the code that runs the procedure (or other SAS statements) or not.
If you are really want to just conditionally run select procedures then you migth be able to conditionally add the keyword CANCEL to the RUN statement. Could be as simple as setting a macro variable to either empty.
%let run_cancel=CANCEL; proc print data=sashelp.class ; run &run_cancel ;
Not sure if it works for all procedures and you will get a warning message in the log.
WARNING: The procedure was not executed at the user's request.
08-31-2017 11:34 AM
You logic looks flawed. You appear to be trying to conditionally generate a call to PROC DATASETS inside the middle of an SQL statement. You cannot call another proc while one is still running.
What do you want to do?
It looks like perhaps you want to delete a dataset if it contains extra variables?
%macro validate_c (data, cols); %local extra_vars ; proc contents noprint data= &data. out=_contents ; run; proc sql noprint ; select name into :extra_vars separated by ' ' from _contents where not indexw(upcase(name),%upcase("&cols"),' ') ; quit; %if &sqlobs %then %do; %put Found extra variables in &data ; %put &=extra_vars ; proc delete data=&data ; run; %end; proc delete data=_contents; run; %mend validate_c;
So let's test it.
814 data test; 815 set sashelp.class ; 816 run; NOTE: There were 19 observations read from the data set SASHELP.CLASS. NOTE: The data set WORK.TEST has 19 observations and 5 variables. NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.01 seconds 817 options mprint; 818 %validate_c(data=test,cols=Name Age); MPRINT(VALIDATE_C): proc contents noprint data= test out=_contents ; MPRINT(VALIDATE_C): run; NOTE: The data set WORK._CONTENTS has 5 observations and 41 variables. NOTE: PROCEDURE CONTENTS used (Total process time): real time 0.01 seconds cpu time 0.01 seconds MPRINT(VALIDATE_C): proc sql noprint ; MPRINT(VALIDATE_C): select name into :extra_vars separated by ' ' from _contents where not indexw(upcase(name),"NAME AGE",' ') ; MPRINT(VALIDATE_C): quit; NOTE: PROCEDURE SQL used (Total process time): real time 0.00 seconds cpu time 0.00 seconds Found extra variables in test EXTRA_VARS=Age Height Name Sex Weight MPRINT(VALIDATE_C): proc delete data=test ; MPRINT(VALIDATE_C): run; NOTE: Deleting WORK.TEST (memtype=DATA). NOTE: PROCEDURE DELETE used (Total process time): real time 0.00 seconds cpu time 0.00 seconds MPRINT(VALIDATE_C): proc delete data=_contents; MPRINT(VALIDATE_C): run; NOTE: Deleting WORK._CONTENTS (memtype=DATA). NOTE: PROCEDURE DELETE used (Total process time): real time 0.00 seconds cpu time 0.00 seconds