Okay so i want to call a separate SAS Program using a SAS Macro inside a SAS Data statement, is it possible to do this in SAS.
below is an example of ewhat i want to achieve:
%macro tempMD;
%if %sysfunc(compress(%sysfunc(upcase(&dynamicMD)))) = ON %then %do;
%include "&codepath/MDfactor_VADB.sas";
%end;
%else %do;
%put Check = &dynamicMD;
%end;
%mend tempMD;
Data test2;
set test;
Var1 = "Active"
%tempMD;
Var1 = "Inactive"
%tempMD;
run;
Is it doable in sas?
Yes, as long as the SAS code generated by the macro produces syntactically correct DATA step statements. Why don't you just try it?
Hi @SASKiwi I tried it and the macro that calls another program worked just fine but the statements i am writing after it in the data statement are giving me the following error:
ERROR 180-322: Statement is not valid or it is used out of proper order.
Do you know why am i getting this error and is there a way around it?
Thanks,
@hiteshchauhan1 wrote:
Hi @SASKiwi I tried it and the macro that calls another program worked just fine but the statements i am writing after it in the data statement are giving me the following error:
ERROR 180-322: Statement is not valid or it is used out of proper order.
Do you know why am i getting this error and is there a way around it?
Thanks,
Your macro does not create valid SAS code at the place where it is called. Use
options mprint source2;
to see the code of the %include, and the code created by the macro. This needs to fit in with the data step where you call it.
As stated by @SASKiwi , the %INCLUDE needs to create valid legal working DATA step code, and apparently it does not do so.
You need to create valid legal working DATA step code without %INCLUDE, and once you have that working, you can move part of the code to a .sas file which you can %INCLUDE. If you can't get the code to work properly without %INCLUDE, then it will never work properly with %INCLUDE.
In your example code there is a missing semicolon:
Var1 = "Inactive" <---- This needs a semicolon to end the assignment statement.
This is a very good catch, @Quentin. And it goes back to the point I was making, that first @hiteshchauhan1 has to get the code to work without %INCLUDE, then you can move part of the code to a separate .sas file and %INCLUDE it if you want.
oh that's a typo actually i am running an entirely different code and i can say it has no typo, the thing is i can't share the actual code here so i have made an example code that i put in the question i asked.
@hiteshchauhan1 wrote:
oh that's a typo actually i am running an entirely different code and i can say it has no typo, the thing is i can't share the actual code here so i have made an example code that i put in the question i asked.
Yes, but the point remains, you do not have valid working legal SAS code. You need to have that or %INCLUDE won't work. If you can't show the actual code to us, then its really hard to help you.
Makes sense.
I would suggest you make a small example which replicates the problem. And then post all of that example code (both the main code file and the file that is included).
If you can post a small full example of the code that replicates the problem, people will be able to help you figure out what is going wrong.
Often when you try to build a small example of a problem, that code ends up working, and then on your own you can look back at your original code and you realize what is wrong in the original code.
Okay, I made a little example that works. The main code is:
%macro tempMD; %global dynamicMD ; %if %sysfunc(compress(%sysfunc(upcase(&dynamicMD)))) = ON %then %do; %include "c:\junk\foo.sas"; %end; %else %do; %put Check = &dynamicMD; %end; %mend tempMD; options mprint source2 ; %let dynamicMD=ON ; data test2; set sashelp.class(obs=3); length Var1 $8 ; Var1 = "Active" ; %tempMD; Var1 = "Inactive" ; %tempMD; run;
The code in the include file c:\junk\foo.sas is:
put "include ran! " (_all_)(=) ;
It would he helpful if you could make an example like that, closer to your real code, which shows an error.
Hello,
Including a file this way is equivalent to copying/pasting the code from the included file.
Since the inclusion is made inside a data step, the included code shouldn't contain any
data steps or procs but only instructions that are valid inside a data step.
For example, the following code won't work :
filename a "c:/temp/incl.sas";
data _NULL_;
file a;
put "data b; set sahelp.class; run;";
run;
data a;
x=1;
%include "c:/temp/incl.sas";
put x=;
run;
Because the generated code will be :
data a;
x=1;
data b;
set sashelp.class;
run;
put x=;
run;
=> the "run" after "set sashelp.class" will exit the data step so we end up with a put instruction outside the data step.
Okay so i want to call a separate SAS Program using a SAS Macro inside a SAS Data statement, is it possible to do this in SAS.
Your example will generate one of two possible data step, depending the value of the macro variable dynamicMD. So either it is "ON" in which case you are going to run:
data test2;
set test;
Var1 = "Active"
%include "&codepath/MDfactor_VADB.sas";
Var1 = "Inactive"
%include "&codepath/MDfactor_VADB.sas";
run;
Otherwise you are running
%put Check = &dynamicMD;
%put Check = &dynamicMD;
data test2;
set test;
Var1 = "Active"
Var1 = "Inactive"
run;
Whether this works depends on what you are trying to do. So if the INCLUDE file only includes data step statements that could validly be placed between those two assignment statements.
Note that calling a macro "inside" of a data step is a bit backwards. The output of a SAS macro is lines of code for SAS to compile and run. The macro processor is just tool for saving you from having to type the same lines of code over and over. So in general the macro processor has finished its work generating the code BEFORE the SAS processor has compiled that data step and run it.
Using %INCLUDE is just like copying and pasting the lines of code from the file into that place in the file. So using %INCLUDE inside of a data step is normally not done. It will only work if the file only includes data step statements, like assignment statement, if statements, infile, etc . If the file includes multiple data and/or proc steps then you would include the file in between two steps in your main program.
If you really need to run some whole subprocess based on decisions based on data available in a data step you would normally do that by generating the code and then calling it. You can use CALL EXECUTE() to do that. Or just write the lines of code to a new file and %include it after the data step finishes.
If you really feel there is some value in trying to run one or more full SAS steps while a data step is actively running you will have to resort to use the DOSUBL() function. And that could potentially cause a lot of confusion, and generally is not worth the effort.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Select SAS Training centers are offering in-person courses. View upcoming courses for: