2

I need to store a value from a table into a variable. I've tried let, symputx, and select into. In the current version I try to use symputx, but the variable is not being updated. The products table contains type, price_floor, price_tier1, price_tier2.

%global price1;
%global price2;

%macro container();
DATA _null_;
    SET products;
    IF type = "Single" THEN DO;
       CALL SYMPUTX('price1', price_floor,'g');
    END;
    IF type = "Multi" THEN DO;
       CALL SYMPUTX('price1', price_tier1,'g');
       CALL SYMPUTX('price2', price_tier2,'g');
   END;
%PUT &=price1;
%PUT &=price2;
%mend;

Both price1 and price2 are null.

SYMBOLGEN: MACRO variable PRICE1 resolves to PRICE1=
SYMBOLGEN: MACRO variable PRICE2 resolves to PRICE2=
Pᴇʜ
  • 56,719
  • 10
  • 49
  • 73

3 Answers3

1

You don't have a run statement on your datastep, so your %put statement is being written to the log before the data step executes - so, the variables don't exist yet. It won't be run until you do provide a run statement or step boundary, or SAS might do that politely for you when the program is finished, but either way it's not being run before the %put.

Usually, this kind of program is an anti-pattern in SAS; you don't provide sufficient context, so maybe it's okay, but this will only work if you have only one row in the dataset - otherwise it probably won't do anything useful. The key word that's triggering me to write this is that you called this a "variable" - not a "macro variable" - in your question; SAS macro variables are not really "variables" and not meant to be used like a C variable or Python variable.

Joe
  • 62,789
  • 6
  • 49
  • 67
  • That was an error in my recreating the query for the post. There was a run, but I didn't know that about %put so thank you. – Tyler Hoeck Aug 13 '21 at 00:21
0

FYI to anyone interest, I decided to restructure the program as a whole. The original plan was to pass elements of a user defined array into %container, then use the assigned macro variables price1 and price2 as parameter in another macro call.

Instead of imbedding this data step in a macro, I created a table to contain all of the inputs I planned to pass into %container. Then I just used executes with the table variables concatenated within instead of direct macro calls.

data _null_;
    SET products;
    IF type = "Single" THEN DO;
       CALL execute('%split_prod('||price_floor||');');
    END;
    IF type = "Multi" THEN DO;
       CALL execute('%select_prod('||price1||','||price2||');');
    END;
run; 
0

There isn't anything wrong with the code besides the RUN.

%global price1;
%global price2;

data products;
infile cards dlm=',';
input Type $ price_floor price_tier1 price_tier2;
cards;
Multi, 40, 20, 60
;;;;;


%macro container();
DATA _null_;
    SET products;
    IF type = "Single" THEN DO;
       CALL SYMPUTX('price1', price_floor,'g');
    END;
    IF type = "Multi" THEN DO;
       CALL SYMPUTX('price1', price_tier1,'g');
       CALL SYMPUTX('price2', price_tier2,'g');
   END;
RUN;

%mend;

%container();

%PUT &=price1;
%PUT &=price2;

LOG:

 96         %PUT &=price1;
 PRICE1=20
 97         %PUT &=price2;
 PRICE2=60

You never showed your call for %container() so not sure what the underlying issue is, but CALL EXECUTE is a better method as debugging macros is painful.

Reeza
  • 20,510
  • 4
  • 21
  • 38