BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Piku
Obsidian | Level 7
Folks, I have a problem regarding calling a macro from data step. This data step is inside another macro. But fundamentally , it is not possible to get macro value in ‘data step’, although some alternate like ‘call execute’ can be used. But I am not able to get it done. I have below code which is not working and making data variable set empty instead of returning value. Is there any alternative to achieve so ? %Macro Set_nestedval2(TaskID,Status,Section,DSNameP,DSVarP,DSVarP1); /*%let location_1=%location('Train'); */ Data &DSNameP; Set &DSNameP ; &DSVarP=call execute('%nrstr(%location(type=Train));'); /* &DSVarP=& location; */ Run; %put &location_1; %mend; %macro location(type,location=); %if &type='Airplane' %then %let location=Airport; %if &type='Train' %then %let location=Railway_Station; /*%put type is &type.; */ &location; /* this line is effectively the "return value" */ %mend location; %Set_nestedval2(1,2,3,’DM’,’Entity_name’,’’); Thanks,
1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

You got a lot of the pieces right.  First, the small piece:  you do have an extra semicolon here:

 

&location;

 

The %LOCATION macro should return &location without a semicolon.

 

Second, it's not clear what value you want to assign in your DATA step.  Do you want:

 

&DSVarP = Railway_Station;

&DSVarP = "Railway_Station";

 

Using the version with the quotes, you would simply use:

 

&DSVarP = "%location('Train')";

 

Remove the double quotes if you don't need them.

View solution in original post

6 REPLIES 6
Kurt_Bremser
Super User

First of all, use proper code formatting and a code window ({i} or "little running man" button) for posting code. This spaghetti-code is an eyesore.

 

You can't insert code from a dynamically called macro back into the datastep. The datastep is compiled and cannot be changed once it starts running.

 

What is the purpose of this honorable mention for the Obfuscated SAS Code Contest?

RW9
Diamond | Level 26 RW9
Diamond | Level 26

What is it your trying to achieve?  Follow the guidance by the post button:

Post example test data, in the form of a datastep, using the code window - its the {i}.

Post what you want out at the end.

Post any logs or logic which may help explain.  

 

After parsing the unformatted text you provide below, I don't see the point in any of the code.  Why not just format the given variable and avoid all this unecessary obfuscation?  I.e. have a format type where Airplane=Airport,... and then put type into a new variable with that format.

 

To demonstrate the code window (again the {i} above the post are):

%Macro Set_nestedval2(TaskID,Status,Section,DSNameP,DSVarP,DSVarP1); 
/*%let location_1=%location('Train'); */ 
  Data &DSNameP; 
    Set &DSNameP ; 
    &DSVarP=call execute('%nrstr(%location(type=Train));'); 
    /* &DSVarP=& location; */ 
  Run; 
  %put &location_1; 
%mend; 

%macro location(type,location=); 
  %if &type='Airplane' %then %let location=Airport; 
  %if &type='Train' %then %let location=Railway_Station; 
  /*%put type is &type.; */ &location; /* this line is effectively the "return value" */ 
%mend location; 
%Set_nestedval2(1,2,3,’DM’,’Entity_name’,’’);;
Piku
Obsidian | Level 7

Hello All,

 

Reposting the simple modified code.

 

Here what I want is that datastep in first macro named 'Set_nestedval2' must be able to fetch the value returning from second macro ‘location’. And this location returned must be set as value in one of the column of above ‘dm’.

 

Would like to mention that without outside datastep, I am able to get the returning value.

 

%Macro Set_nestedval2(TaskID,Status,Section,DSNameP,DSVarP,DSVarP1); 
Data dm; &DSVarP=call execute('%nrstr(%location(type=Train));'); Run; %mend;
****** Macro 2 ******* %macro location(type,location=); %if &type='Airplane' %then %let location=Airport; %if &type='Train' %then %let location=Railway_Station; &location; %mend location;

********* calling parent macro ************ %Set_nestedval2(1,2,3,’DM’,’Entity_name’,’’);

 

RW9
Diamond | Level 26 RW9
Diamond | Level 26

As I mentioned above, there is no value in this code.  All you are doing is fighting the software when a simple format will do.

 

%Macro Set_nestedval2(TaskID,Status,Section,DSNameP,DSVarP,DSVarP1); 
  Data dm;
    &DSVarP="%location(type=Train)";  
  Run; 
%mend; 

%macro location(type,location=); 
  %if &type.=Airplane %then %let location=Airport; 
  %if &type.=Train %then %let location=Railway_Station; 
  &location. 
%mend location; 

options mprint symbolgen mlogic;
%Set_nestedval2(1,2,3,DM,Entity_name,);

It works, but I really advise against it.

Astounding
PROC Star

You got a lot of the pieces right.  First, the small piece:  you do have an extra semicolon here:

 

&location;

 

The %LOCATION macro should return &location without a semicolon.

 

Second, it's not clear what value you want to assign in your DATA step.  Do you want:

 

&DSVarP = Railway_Station;

&DSVarP = "Railway_Station";

 

Using the version with the quotes, you would simply use:

 

&DSVarP = "%location('Train')";

 

Remove the double quotes if you don't need them.

Piku
Obsidian | Level 7

&DSVarP= "%location('Train')"

 

Above is the solution. Adding double quotes give me the result.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 6 replies
  • 5416 views
  • 5 likes
  • 4 in conversation