%let firstAcademicPeriod=201810;
%let academicPeriods = %str("%eval(&firstAcademicPeriod +100)");
I'm trying to use the eval function and return it with quotes around it. It looks like %str and %eval do not play nice with each other. Am I missing something here?
Why would you want to macro quote a string like:
"201910"
Remove the %STR() macro function.
Generally, it is a poor idea to have the values of macro variables enclosed in quotes or double-quotes. I'd recommend you not do that, and then there's no issue.
%let academicPeriods = %eval(&firstAcademicPeriod +100);
If you absolutely must have the result in double-quotes (why?), then its still relatively simple to do:
%let academicPeriods = "%eval(&firstAcademicPeriod +100)";
But really, don't put numbers such as 201910, which is the output of your calculation, in quotes.
Just to complete everything here, the problem is NOT %eval doesn't play well with %str.
Try the quote function instead:
%let firstAcademicPeriod=201810;
%let academicPeriods = %sysfunc(quote(%sysevalf(&firstAcademicPeriod +100)));
Why would you want to macro quote a string like:
"201910"
Remove the %STR() macro function.
I'm creating dynamic headers for a 500 page SAS output to PDF report. The macro is used to keep the amount of repetitive code down.
/*This works*/
%let defineAnalysis1 = %str (
define _2017_18 / analysis sum '2017-18';
define _2018_19 / analysis sum '2018-19';
define _2019_20 / analysis sum '2019-20';
define _2020_21 / analysis sum '2020-21';
define _2021_22 / analysis sum '2021-22';
);
%let fAcadP=201810;
%let fAcadYS=2017;
%let fAcadYE=18;
/*earlier I used %str to execute the block as a set. Is there something similar I can use?*/
%let defineAnalysis1 =
define _&fAcadYS._&fAcadYE. / analysis sum "_&fAcadYS.-&fAcadYE.";
define _%eval(&fAcadYS. +1)_%eval(&fAcadYE.+1) / analysis sum "_%eval(&fAcadYS. +1)_%eval(&fAcadYE.+1)";
define _%eval(&fAcadYS. +2)_%eval(&fAcadYE.+2) / analysis sum "_%eval(&fAcadYS. +2)_%eval(&fAcadYE.+2)";
define _%eval(&fAcadYS. +3)_%eval(&fAcadYE.+3) / analysis sum "_%eval(&fAcadYS. +3)_%eval(&fAcadYE.+3)";
define _%eval(&fAcadYS. +4)_%eval(&fAcadYE.+4) / analysis sum "_%eval(&fAcadYS. +4)_%eval(&fAcadYE.+4)";
Why not just put the %str() (or perhaps %nrstr() instead) around the semi-colons since those are the characters you actual need to "hide" to let the %LET work.
%let defineAnalysis1 =
define _&fAcadYS._&fAcadYE. / analysis sum "_&fAcadYS.-&fAcadYE." %str(;)
define _%eval(&fAcadYS. +1)_%eval(&fAcadYE.+1) / analysis sum "_%eval(&fAcadYS. +1)_%eval(&fAcadYE.+1)" %str(;)
define _%eval(&fAcadYS. +2)_%eval(&fAcadYE.+2) / analysis sum "_%eval(&fAcadYS. +2)_%eval(&fAcadYE.+2)" %str(;)
define _%eval(&fAcadYS. +3)_%eval(&fAcadYE.+3) / analysis sum "_%eval(&fAcadYS. +3)_%eval(&fAcadYE.+3)" %str(;)
define _%eval(&fAcadYS. +4)_%eval(&fAcadYE.+4) / analysis sum "_%eval(&fAcadYS. +4)_%eval(&fAcadYE.+4)" %str(;)
;
Placing the %str only on the; worked.
I'm sure all this could have been done using custom formats and PROC REPORT, rather than variables with calendar information in the variable name and macro variables and arithmetic with the macro variables. I don't have time right now to write out the code, but I think macro variables are completely unnecessary here, and makes the whole thing unnecessarily complicated..
Since there is a lot of DEFINE code going on, one has to assume this is Proc Report code.
Here may be a reason why all the code spent in generating variable names with data in them like _2018_19 was quite possibly unneeded and can get similar output.
The data set cntlyr makes a format for a limited number of school years, start with a lower value, like 1900 and go as large as you want up to 9998. When we get past 4 digit years something else would be needed.
Cntlyr is used to create a custom format to display single values of year such as 2018 as 2018-19.
Then make small data set with random years and a variable to sum (or other summary) and some proc report code to make the Years as column headings with the summarized value under.
This would expect to have variable in your basic data with an appropriate calendar year numeric variable. Simple change if your "year" is character to make the start value and format type character.
data cntlyr; fmtname='SchoolYr'; type='N'; do start=2000 to 2050; label= catx('-',start,put(mod(start,100) +1,z2.)); output; end; run; proc format cntlin=cntlyr; run; /* create a data set with random years and a variable to summarize */ data example; do i=1 to 100; year= 2000+ rand('integer',21); value= rand('integer',25); output; end; run; proc report data=example; column year, value; define year/across format=schoolyr.; define value/analysis sum ' '; run;
Yes, I agree @ballardw, no macros needed here.
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.