Hi, expert
Most of the time when I come to CALL SMPUT() in daily programming work, I always get unexpected macro errors. Please help to correct me.
I always need to set a macro to store the exact days of certain month in financial report and retrieve them in data steps. But the newly created variables yy, mm and dd are all in 20178 (ie 2015-3-31), not 2015-3-1, 2015-3-2....... and 2015-3-31 as I expect.
e.g.
%macro report;
data report;
do loop=mdy(3,1,2015) to mdy(3,31,2015);
call symput("x",loop); /* where &x in dates need to be referred in later part */;
xx=&x;
cyear=year(&x);
cmonth=month(&x);
cdate=day(&x);
output;
end;
run;
%mend report;
%report;
regards
jones
This is the correct behaviour. SAS stored dates as numbers, where 1 is Jan 1, 1960 and 2 is Jan 2, 1960 and so forth.
If you want a specified display format you need to apply a format. Note that it will have leading zeros, ie 04 and 01 in month/day values
For a year month day format, such as 2014-04-01 use
call symput("x",put(loop, yymmddd10.);
Hi:
In SAS dates, 0 is January 1, 1960 and 1 is January 2, 1960 and -1 is Dec 31, 1959. You can run this program to see that 0 is Jan 1, 1960.
Cynthia
data whatdate;
infile datalines;
input thedate;
put "Internal value " thedate= 'Now formatted: ' thedate= mmddyy10.;
return;
datalines;
0
1
2
-1
-2
-3334
18439
19912
;
run;
Thanks for the correction!
Thanks for your help.
regards
jones
Maybe that error be generated by blank in macro variable. Try call symputX() .
Hi,
I am not sure on the point of your macro. You are going to hit problems as you are generating a macro variable with a datastep loop. So the macro pre-processor gets your code, it does a search and replace on the &x. and finds nothing delclared for X so it throws an error, it never gets to the stage where the datastep is actually run to create X.
In your example X always referencing the last mdy, this is because the loop goes over each time and only the last iteration sets the date.
So first question, what is it your trying to achieve? Is it to find all dates within that range and use them to select data, if so then store to dataset and use this in your code, e.g.:
data dates;
attrib mydate format=date9.;
do loop=mdy(3,1,2015) to mdy(3,31,2015);
mydate=loop;
output;
end;
run;
/*later on */
proc sql;
create table DATA_TO_WORK_ON as
select *
from DATA_I_HAVE
where DATE in (select MYDATE from WORK.DATES);
quit;
That's great ! Thank you all of you.
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.
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.