Programming the statistical procedures from SAS

passing string argument in a datastep from one macro to another macro

Reply
New Contributor
Posts: 3

passing string argument in a datastep from one macro to another macro

Hi SAS users,

I have a simple macro (macro1) that creates a dataset with n observations of 1 string variable.

I use the string variable to construct a file name. 

Within a data step I want to pass the file name to macro2 (n times), Macro2 uses the filename as an argument to open the appropriate file and do some stuff.

But the filename is not being passed to macro2. Can someone tell me what I'm doing wrong? All help will be greatly appreciated.

SAS version 9.2

Win7

 

Code looks like this:

 

%macro macro1;

* do some stuff to create dset1 with n observations of 1 string variable ('prov');

* I have confirmed that dset1 exists, and that it has the correct string variable 'prov';

     data _NULL_; set dset1;

          f2r = 'c:\directoryname\'||trim(prov)||'_vol.dat';

          call execute('%macro2(f2r)');

     run;

%mend macro1; 

 

%macro macro2(fname);

     data dset2;

          infile dummy filevar = &fname firstobs=2;

          input name $ id_no ecoreg;

     run;

* do some stuff with dset2;

%mend macro2;

 

Super User
Posts: 5,246

Re: passing string argument in a datastep from one macro to another macro

You're passing the characters "f2r" rather than the value of the DATA step variable.  Try it this way:

 

call execute('%macro2(' || f2r || ')');

 

 

New Contributor
Posts: 3

Re: passing string argument in a datastep from one macro to another macro

Thanks for the suggestion. You're right - I was passing the string "f2r" instead of the value of the variable.

But I had tried the syntax you suggested before I posted the question - it didn't work.

The problem seems to be in how the argument is interpreted in macro2 when it's passed from macro1. Is this an issue only BETWEEN macros? I don't know.

But this works. NOTE the " " around &prov in macro2.

 

%macro macro1;
data _NULL_; set dset1;
call execute('%macro2('||trim(prov)||')');
run;
%mend macro1;

%macro macro2(prov);
data dset2;

prov = "&prov";

f2r = 'c:\directoryname\'||prov||'_vol.dat';
infile dummy filevar = f2r firstobs=2;
input name $ id_no ecoreg;
run;
* do some stuff with dset2;
%mend macro2;

Super User
Super User
Posts: 7,565

Re: passing string argument in a datastep from one macro to another macro

Sorry, its not clear to me here.  You have code generation (the call execute), happening from within code generation (the macro).  This seems very convoluted.  Also, your call execute may not function as you expect it to, macro and call execute both insert code into the pre-processor, but they only do it once, so having one inside the other is not a good idea.  Explain your problem, provide example test data, and what you want out of it.  For instance why is macro1 needed, if that serves a purpose, separate it out from other processing.  The code you have posted seems to resolve to:

data _null_;
  set dset1;
  call execute('data dset2; 
                  infile "c:\directoryname\'||strip(prov)||'_vol.dat;
                  input name $ id_no ecoreg;  
                run;');
run;

So no need for all the other bits.

New Contributor
Posts: 3

Re: passing string argument in a datastep from one macro to another macro

Thank you for your reply. I'm sorry that it was not clear to you. I posted only what I thought was necessary.

 

macro1 is called several times; each time creating a different version of dset1 (different values of the pertinent variable 'prov').

macro2 is called as many times as there are observations in dset1, and creates a version of dset2 each time.

Calling a "function" from another "function" in other programming languages is not convoluted. Perhaps doing the same with SAS macros is uncommon.

Super User
Super User
Posts: 7,565

Re: passing string argument in a datastep from one macro to another macro

Yes, first thing to remember is that SAS Macro is not like functions in other languages.  Macro language is a text generation software, i.e. it generates code, nothing else.  It is useful to avoid repeating code where only certain bits change.  It does this by passing macro logic to the pre-processor once, call execute is simlar.  As this only happens once, its not generally a good idea to be call execute generating data from inside a macro.

 

As I posted there is generally better ways of doing this.  If you can provide some test data and what you want the output to look like I can provide code, but the way it is now its messy and difficult to debug.

Ask a Question
Discussion stats
  • 5 replies
  • 275 views
  • 0 likes
  • 3 in conversation