Why my macro is not resolving
%Macro georg(srv_st_dt,srv_en_dt,pst_dt1,pst_dt2 );
/*%let pst_dt1 =01/01/2009;*/
%put &pst_dt1;
data _null_ ;
%put &pst_dt1;
call symput ('pst1', put(input(&pst_dt1,mmddyy10.),date9.));
*call symput ('pst1', put(input("&pst_dt1",mmddyy10.),date9.));
call symput ('pst2',put(input("&pst_dt2",mmddyy10.),date9.));
call symput ('srv_st_dt',put(input("&srv_st",mmddyy10.),date9.));
call symput ('srv_en_dt',put(input("&srv_en",mmddyy10.),date9.));
run;
%put &pst1;
%mend georg;
%georg (01/01/2009 ,06/31/2009 ,01/01/2009 ,06/30/2009);
I guess you want to do something like this:
%Macro georg(srv_st,srv_en,pst_dt1,pst_dt2 );
%global pst1 pst2 srv_st_dt srv_en_dt;
data _null_ ;
call symput ('pst1', put(input("&pst_dt1", mmddyy10.),date9.));
call symput ('pst2', put(input("&pst_dt2", mmddyy10.),date9.));
call symput ('srv_st_dt', put(input("&srv_st", mmddyy10.),date9.));
call symput ('srv_en_dt', put(input("&srv_en", mmddyy10.),date9.));
run;
%mend georg;
%georg (01/01/2009, 06/30/2009, 01/01/2009, 06/30/2009);
%put &pst1;
%put &pst2;
%put &srv_st_dt;
%put &srv_en_dt;
The complexity of macro variable scope rules is just another reason why I stay away from macro programming.
I guess you want to do something like this:
%Macro georg(srv_st,srv_en,pst_dt1,pst_dt2 );
%global pst1 pst2 srv_st_dt srv_en_dt;
data _null_ ;
call symput ('pst1', put(input("&pst_dt1", mmddyy10.),date9.));
call symput ('pst2', put(input("&pst_dt2", mmddyy10.),date9.));
call symput ('srv_st_dt', put(input("&srv_st", mmddyy10.),date9.));
call symput ('srv_en_dt', put(input("&srv_en", mmddyy10.),date9.));
run;
%mend georg;
%georg (01/01/2009, 06/30/2009, 01/01/2009, 06/30/2009);
%put &pst1;
%put &pst2;
%put &srv_st_dt;
%put &srv_en_dt;
The complexity of macro variable scope rules is just another reason why I stay away from macro programming.
Your commented out line has the right idea:
*call symput ('pst1', put(input("&pst_dt1",mmddyy10.),date9.));
Without the quotes means something entirely different:
call symput ('pst1', put(input(&pst_dt1,mmddyy10.),date9.));
In that statement, 01/01/2009 means 1 divided by 1 divided by 2009. Then SAS has to take that result and convert it to character, before applying the DATE9 informat.
It would be more helpful in the future if you were to actually show what results you are getting.
Use CALL SYMPUTX.
The third parameter allows you to specify local or global.
Currently your creating local macro variables that don't exist outside your macro. Creating global macro variables mean they exist for your entire program.
Macros are RUN or CALLED or EXECUTED. Macro VARIABLES are RESOLVED.
Are you worried that your macro variables are not getting set right?
Or are you worried that they are not available after the macro itself has finished running?
To see if your macro CALL is RUNNING you can turn on the MPRINT option. You will lines like this in your SAS log.
01/01/2009
MPRINT(GEORG): data _null_ ;
01/01/2009
MPRINT(GEORG): call symput ('pst1', put(input(01/01/2009,mmddyy10.),date9.));
MPRINT(GEORG): *call symput ('pst1', put(input("&pst_dt1",mmddyy10.),date9.));
MPRINT(GEORG): call symput ('pst2',put(input("06/30/2009",mmddyy10.),date9.));
WARNING: Apparent symbolic reference SRV_ST not resolved.
MPRINT(GEORG): call symput ('srv_st_dt',put(input("&srv_st",mmddyy10.),date9.));
WARNING: Apparent symbolic reference SRV_EN not resolved.
MPRINT(GEORG): call symput ('srv_en_dt',put(input("&srv_en",mmddyy10.),date9.));
MPRINT(GEORG): run;
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
1:6
NOTE: Invalid argument to function INPUT at line 3 column 27.
NOTE: Invalid argument to function INPUT at line 3 column 218.
NOTE: Invalid argument to function INPUT at line 4 column 31.
_ERROR_=1 _N_=1
NOTE: Mathematical operations could not be performed at the following places. The results of the operations
have been set to missing values.
Each place is given by: (Number of times) at (Line):(Column).
1 at 3:27 1 at 3:218 1 at 4:31
NOTE: DATA statement used (Total process time):
real time 0.04 seconds
cpu time 0.00 seconds
Are there particular parts of that they you want to work differently?
If so you need to explain what you want.
There are a numer of issues in your code.
call symput ('pst1', put(input(&pst_dt1,mmddyy10.),date9.));
The first CALL SYMPUT() call is using the macro parmeter PDT_DT1 as if it contained a string literal or the name of character variable. But you past in just the bare text 01/01/1990. SAS will see that as a numeric equation to be evaluated and then converted to a string for the INPUT() function to operate on.
The second CALL SYMPUT() call fixes that issue by enclosing the macro variable's value inside of double quotes so that it will look like a string literal to the SAS compiler.
call symput ('srv_st_dt',put(input("&srv_st",mmddyy10.),date9.));
call symput ('srv_en_dt',put(input("&srv_en",mmddyy10.),date9.));
The third and fouth CALL SYMPUT() calls are referencing a macro variables, SRV_ST and SRV_EN, that are not defined in the piece of code you posted. It might work ok if the variables exist and have a value that looks like a valid MM/DD/YYYY value.
All four of the CALL SYMPUT() calls are assigning values to macro variables that you have not defined anywhere in the code you posted. If they exist before the macro is called then they will have their values replaced. Otherwise they will be created as local to the macro GEORG and disappear when it ends. If you want to use the value after GEORG finishes then you should either just create them first.
%let pst1=;
%let pst2=;
%let srv_st_dt=;
%let srv_en_dt=;
%georg (01/01/2009 ,06/31/2009 ,01/01/2009 ,06/30/2009);
Or modify the macro to make sure they exist before writing to them. Note you could use CALL SYMPUTX() and force them into the GLOBAL symbol table, but that will fail if they already exist inside some other macro that is call GEORG as a submacro.
%macro georg(srv_st_dt,srv_en_dt,pst_dt1,pst_dt2 );
%if not %symexist(pst1) %then %global pst1;
%if not %symexist(pst2) %then %global pst2;
%if not %symexist(srv_st_dt) %then %global srv_st_dt;
%if not %symexist(srv_en_dt) %then %global srv_en_dt;
...
%mend georg;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.