DATA Step, Macro, Functions and more

read variables from dataset and pass it to a macro

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 5
Accepted Solution

read variables from dataset and pass it to a macro

 

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!!!

 

 


Accepted Solutions
Solution
‎03-17-2018 03:56 PM
Super Contributor
Posts: 359

Re: read variables from dataset and pass it to a macro

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


All Replies
Super User
Posts: 24,012

Re: read variables from dataset and pass it to a macro

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!!!

 

 


 

Occasional Contributor
Posts: 5

Re: read variables from dataset and pass it to a macro

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

Solution
‎03-17-2018 03:56 PM
Super Contributor
Posts: 359

Re: read variables from dataset and pass it to a macro

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;
Super User
Posts: 6,934

Re: read variables from dataset and pass it to a macro

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.

Occasional Contributor
Posts: 5

Re: read variables from dataset and pass it to a macro

Posted in reply to Astounding

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

Super User
Super User
Posts: 8,279

Re: read variables from dataset and pass it to a macro


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

 

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 6 replies
  • 145 views
  • 3 likes
  • 5 in conversation