BookmarkSubscribeRSS Feed
hiteshchauhan1
Obsidian | Level 7

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?

11 REPLIES 11
SASKiwi
PROC Star

Yes, as long as the SAS code generated by the macro produces syntactically correct DATA step statements. Why don't you just try it?

hiteshchauhan1
Obsidian | Level 7

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,

Kurt_Bremser
Super User

@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.

PaigeMiller
Diamond | Level 26

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.

--
Paige Miller
Quentin
Super User

In your example code there is a missing semicolon:

Var1 = "Inactive"   <---- This needs a semicolon to end the assignment statement.
BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
PaigeMiller
Diamond | Level 26

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.

--
Paige Miller
hiteshchauhan1
Obsidian | Level 7

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.

PaigeMiller
Diamond | Level 26

@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.

--
Paige Miller
Quentin
Super User

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.

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
gamotte
Rhodochrosite | Level 12

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.

Tom
Super User Tom
Super User

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.

 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 11 replies
  • 2057 views
  • 4 likes
  • 7 in conversation