0
votes

My problem is as follows - I have this piece of code that works fine and adds the character saved into the macro variable into the table:

%let year=2015;
data example;
input year $40.;
years=dequote(resolve(quote(year)));
datalines;
&year
;
run;

The output: enter image description here

Now I would like to do the same inside the macro, with the code as follows:

  %macro pokus();
  %let year=2015;
  data example;
  input year $40.;
  years=dequote(resolve(quote(year)));
  datalines;
  &year
  ;
  run;
  %mend pokus;
  %pokus;

But I get an ERROR message: enter image description here

Why is it so ? Is there some easy way how to add the macro variable into the table inside the macro ? I need that to perform this type of loop:

 %macro pokus();
 %do i=2015 %to 2017;
 %let year=&i.;
 data example;
 input year $40.;
 years=dequote(resolve(quote(year)));
 datalines;
 &year
 ;
 run;

 ....additional code .....
 %end;
 %mend pokus;
 %pokus;

Additional explanation - It is a part of more complex exercise that continues in this way:

data z;
length roky mesic mesic2 saz $100;
input roky mesic mesic2 saz; 
datalines;
2012 01 1 k
2012 02 2 h
2012 03 3 j
2012 04 4 x
2012 05 5 l
2012 06 6 m
;
run;

proc sql;
select count (*) into: pocet from z;
quit;

%macro rok();
%do i=1 %to &pocet;
data _null_;
set z (obs= &i);
call symputx("roky",roky);
call symputx("mesic",mesic);
call symputx("mesic2",mesic);
call symputx("saz",saz);
run;
...... additional code .....
%end;
%mend rok;
%rok;

and now I would like to make it dynamic, i.e. first calculate everything with the column "roky" having value 2012, than 2013,2014, e.t.c. But I am not able to build another macro above this construction changing the column "roky" in the z table.

Thank you for any help.

2
Why on earth are you dequote->resolve->quoting the macro variable?Joe
i've googled that (support.sas.com/kb/43/295.html) - for me it was the only way how to get the value stored inside the macro variable into table example defined by datalinesjiri jansa
What you're doing still doesn't make any sense; it seems like you should instead post what you really want to do ultimately not just your approach, as it's not a logical way to approach this in my opinion. Post a new question, and include the whole purpose of your program (or at least, something more than "additional code" - what is that generally doing?).Joe
I have finally found simpler solution. Thank you a lot.jiri jansa

2 Answers

3
votes

You're either not explaining some significant detail, or you're doing this in an incredibly complicated way that is entirely unnecessary.

The direct answer to your question is in the error message: CARDS or DATALINES statements cannot be used in macros.

The solution though is that you shouldn't be using datalines in this way. This isn't the right way to get a macro variable into a dataset.

%let year=2015;
data example;
  years=&year.;
run;

Much easier, isn't it? And this works fine in a macro or not.

If you are getting this macro variable from a prompt or something, you may need to %unquote(&year), but you can still do that in situ.

data example;
  years = %unquote(&year.);
run;
0
votes

You have not explained why you need to use in-line data. That is what cannot be done inside a macro.

If it is just so you can get the string '&year' into a character variable then why not just use an assignment statement? Make sure to use single quotes so that the macro processors doesn't resolve the &year before compiling the data step.

So then your first data step might look like this instead.

%let year=2015;
data example;
  year='&year';
  years=dequote(resolve(quote(year)));
run;

Of course if you just want to retrieve the value of a single macro variable it would be easier to use the SYMGET() function instead.

%let year=2015;
data example;
  years=symget('year');
run;

The rest of your question looks like you want to perhaps drive a macro from data in a metadata table? There are questions like that on SO already. One solution is to define your macro to use parameters and use CALL EXECUTE() to generate one macro call for each row in the metadata table. So something like this:

data _null_;
  set z ;
  call execute(cats('%nrstr(%rok)('
    ,'roky=',roky
    ,'mesic=',mesic
    ,'mesic2=',mesic2
    ,'saz=',saz
    ,')'
  ));
run;

Will generate calls like:

%rok(roky=2012,mesic=01,mesic2=1,saz=k)
%rok(roky=2012,mesic=02,mesic2=2,saz=h)
...