BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
HGimenez
Obsidian | Level 7

 

Hi everybody!

 

i want to read rows from a dataset and pass them to a macro. In the macro, I need to create files. This code works OK:

 

%macro getAccount (file=, accountID=);
filename request &file;
data _null_;
file request;
put '<accountID>' &accountID '</accountID>';
run;
%mend getAccount;

OPTIONS MPRINT;
%getAccount (file='c:\1234.xml', accountID='1234');
%getAccount (file='c:\5678.xml', accountID='5678');

 

However, when I try to read the variable from a dataset and pass them to the macro, it fails:

 

DATA accounts;
    INPUT accountNumber BEST4. fileString $ CHAR12.;
DATALINES4;
1234 c:\1234.xml
5678 c:\5678.xml
;;;;

%macro getAccount (file=, accountID=);
	filename request 'C:\request.xml';
		data _null_;
		file request;
		put '<accountID>' &accountID '</accountID>';
		run;
%mend getAccount;

OPTIONS MPRINT;
data _null_;
	set accounts;
	accountString = put (accountNumber, 4.);
	%getAccount (file=fileString, accountID=accountString);
	run;
	

any ideas?? Thanks a lot!!!

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
gamotte
Rhodochrosite | Level 12

Hello,

 

Your macro contains a data step. You are already in a data step when calling it

so this can't work.

The "call execute(string)" instruction allow to put the string in argument on a stack

that will be executed at the end of the data step. This way, you can generate sas programs

using data from an input dataset.

 

Not tested :

data _null_;
	set accounts;
	accountString = put (accountNumber, 4.);
	call execute(cats('%getAccount (file="',fileString, '", accountID="',accountString,'");'));
run;

View solution in original post

6 REPLIES 6
Reeza
Super User

Look up CALL EXECUTE() instead.

The documentation example is what you're looking to accomplish.

 


@HGimenez wrote:

 

Hi everybody!

 

i want to read rows from a dataset and pass them to a macro. In the macro, I need to create files. This code works OK:

 

%macro getAccount (file=, accountID=);
filename request &file;
data _null_;
file request;
put '<accountID>' &accountID '</accountID>';
run;
%mend getAccount;

OPTIONS MPRINT;
%getAccount (file='c:\1234.xml', accountID='1234');
%getAccount (file='c:\5678.xml', accountID='5678');

 

However, when I try to read the variable from a dataset and pass them to the macro, it fails:

 

DATA accounts;
    INPUT accountNumber BEST4. fileString $ CHAR12.;
DATALINES4;
1234 c:\1234.xml
5678 c:\5678.xml
;;;;

%macro getAccount (file=, accountID=);
	filename request 'C:\request.xml';
		data _null_;
		file request;
		put '<accountID>' &accountID '</accountID>';
		run;
%mend getAccount;

OPTIONS MPRINT;
data _null_;
	set accounts;
	accountString = put (accountNumber, 4.);
	%getAccount (file=fileString, accountID=accountString);
	run;
	

any ideas?? Thanks a lot!!!

 

 


 

HGimenez
Obsidian | Level 7

Thanks a lot! Yes, call execute () is the best solution. The reply I marked as solution is based on call execute ()

 

Thanks again for your help

gamotte
Rhodochrosite | Level 12

Hello,

 

Your macro contains a data step. You are already in a data step when calling it

so this can't work.

The "call execute(string)" instruction allow to put the string in argument on a stack

that will be executed at the end of the data step. This way, you can generate sas programs

using data from an input dataset.

 

Not tested :

data _null_;
	set accounts;
	accountString = put (accountNumber, 4.);
	call execute(cats('%getAccount (file="',fileString, '", accountID="',accountString,'");'));
run;
Astounding
PROC Star

Untested, but should work ... and much simpler once you have the information in a DATA set.

 

data _null_;

set accounts;

file dummy filevar=fileString;

put '<accountID>' accountNumber '<accountID>';

run;

 

I couldn't tell if you wanted to adjust the number of blanks before or after AccountNumber, but that part is pretty easy.

HGimenez
Obsidian | Level 7

Thanks a lot!!

 

This is a viable solution. However, my actual macro is way longer than the one I posted. 

 

The problem is that I put a data _null_ step inside another data _null_, and they don't seem to share variables. Another solution would be to remove the data _null_ from the macro

 

Thanks again for your input

Tom
Super User Tom
Super User

@HGimenez wrote:

Thanks a lot!!

 

This is a viable solution. However, my actual macro is way longer than the one I posted. 

 

The problem is that I put a data _null_ step inside another data _null_, and they don't seem to share variables. Another solution would be to remove the data _null_ from the macro

 

Thanks again for your input


It is not that they don't share variables. It is that they don't overlap in TIME. SAS runs one step at a time.  When the compiler see that your code is starting a new step (DATA or PROC statement) then it knows that you have finished defining the previous step and it is time to run it.   When you placed your macro call in the middle of a data step it was the same thing as if you placed the code that that macro generated in the middle of the data step.

 

So if you write code like this:

 

data _null_;
  set xxxx ;
  %mymacro;
run;

And your macro generates a PROC step what the SAS compiler sees is:

 

 

data _null_;
   set xxxx ;
proc ...

So it sees the PROC step starting and stops compiling the data step and runs it. Then it compiles the PROC step and runs that.

 

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 6 replies
  • 4447 views
  • 3 likes
  • 5 in conversation