BookmarkSubscribeRSS Feed
deleted_user
Not applicable
Hi again.

I'm looking to create something akin to functions from other programming languages using a macro. I want to perform some manipulations on input values, and return a value.

The following works:

%macro test(val=1);
%local t;
%let t=%eval(&val+3);
&t;
%mend test;

%let x=%test();
%put &x;

and gives a value of 4 for &x as expected.

However when trying it with the following proc sql step. I keep getting errors.


%macro dist_vals (dataset=work.sms,var=analyte_name,delim='*');
proc sql noprint;
select distinct &var
into :dist
separated by &delim
from &dataset;
quit;
&dist;
%mend dist_vals;


Errors:

NOTE: Line generated by the macro variable "DIST".
1 LMS189254
---------
180
MPRINT(DIST_VALS): LMS189254;
ERROR 180-322: Statement is not valid or it is used out of proper order.


Can someone please help.

Thanks
3 REPLIES 3
deleted_user
Not applicable
Okay, think I got I see whats going on now.

For the first one, the macro compiler will execute all macro statements first. Or those with % in front.

Using

%let l=%dist_vals();
%put &l;


It will then assign the first line up to the first semicolon as l. This explains why l had the value of "proc sql noprint;". It also explains why the first one worked.

Still doesn't solve my problem of returning variables. The only way I have managed to do this is by declaring &dist as a global variable to allow referencing from outside. If anyone knows of a better way, please let me know.

Thanks
Cynthia_sas
SAS Super FREQ
Hi:
There's a lot of good information in the Macro Facility reference guide on how Macro variable scope works -- both inside and outside macro programs. SAS has one GLOBAL symbol table and then makes LOCAL symbol tables, as needed, so that LOCAL macro variables do not collide, accidentally, with GLOBAL macro variables. Putting a macro variable from one macro program into the GLOBAL symbol table is an appropriate way to make sure the macro variable is available for use outside of the macro environment where it was created.

cynthia
Koos
Calcite | Level 5

Hi kdt, 6 years later but it may be useful to others.

If you want to use a macro to return a value to a datastep you can do that:

%macro retval;

    %let retval=Barbara;  

    &retval.

%mend retval;

data tmp;

    set sashelp.class;

        where name="%retval";

        %put "%retval";

run;

You can also use a macro to return a value to a macro:

%macro retval;

    %let retval=Barbara;  

    &retval.

%mend retval;

%macro useretval;

    %let newretval=%retval;

    %put &newretval.;

%mend;

%useretval;

You can also use a macro as a datastep function, but be mindful not to use any macro assignments, i.e. anything with a %:

%macro retval;
    *The macro is resolved before the code is send to the datastep compiler;
    Barbara;
%mend retval;

data tmp;
    set sashelp.class;
        where name="%retval";
run;

or a combination of stangeties:

%macro retval(passval, ageval, retval);
    *The macro is resolved before the code is send to the datastep compiler;
    if &passval=1 then retval="Mrs. Owen";
    if &ageval=14 then grade9='Y';
%mend retval;

data tmp;
    set sashelp.class;
        %retval(1, age, teachername);
run;

However always remember as you stated above, that the macro processor first resolved any variables. So if you want to use it in a datastep/proc, make sure that it is plaintext that will be inserted into the datastep/proc.

In your example abovce, it effectively tried to insert the proc sql into the datastep.

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!

New Learning Events in April

 

Join us for two new fee-based courses: Administrative Healthcare Data and SAS via Live Web Monday-Thursday, April 24-27 from 1:00 to 4:30 PM ET each day. And Administrative Healthcare Data and SAS: Hands-On Programming Workshop via Live Web on Friday, April 28 from 9:00 AM to 5:00 PM ET.

LEARN MORE

Discussion stats
  • 3 replies
  • 2417 views
  • 0 likes
  • 3 in conversation