This is my code so far:
options mlogic mprint symbolgen spool NOQUOTELENMAX ;
%macro schlub (num1=, num2=);
data temp;
test = %str(%')
%do i = &num1. %to 9;
%str("000&i.",)
%end;
%do i = 10 %to 99;
%str("00&i.",)
%end;
%do i = 100 %to &num2.;
%str("0&i.",)
%end; %str(%')
;
call symput("list", test);
run;
%mend schlub;
%schlub(num1=0001, num2=0101);
it produces this error:
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
1761:30
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.TEMP may be incomplete. When this step was stopped there were 0 observations and 1
variables.
WARNING: Data set WORK.TEMP was not replaced because this step was stopped.
NOTE: DATA statement used (Total process time):
real time 0.22 seconds
cpu time 0.15 seconds
It should more or less create this:
data temp;
test = ' "0001", "0002", "0003", "0004", "0005", "0006", "0007", "0008", "0009", "0010", "0011",
"0012", "0013", "0014", "0015", "0016", "0017", "0018", "0019", "0020", "0021", "0022", "0023", "0024", "0025", "0026",
"0027", "0028", "0029", "0030", "0031", "0032", "0033", "0034", "0035", "0036", "0037", "0038", "0039", "0040", "0041",
"0042", "0043", "0044", "0045", "0046", "0047", "0048", "0049", "0050", "0051", "0052", "0053", "0054", "0055", "0056",
"0057", "0058", "0059", "0060", "0061", "0062", "0063", "0064", "0065", "0066", "0067", "0068", "0069", "0070", "0071",
"0072", "0073", "0074", "0075", "0076", "0077", "0078", "0079", "0080", "0081", "0082", "0083", "0084", "0085", "0086",
"0087", "0088", "0089", "0090", "0091", "0092", "0093", "0094", "0095", "0096", "0097", "0098", "0099", "0100", "0101"';
call symput("list", test);
run;
I know I need to add a little logic to remove the comma at the last number, but I am trying to resolve this error first.
Thanks,
Paul
data _null_;
length list $1000.;
do i=1 to 101;
list=catx(',',list,quote(put(i,z4.)));
end;
call symputx('list',list);
run;
%put &list;
data _null_;
length list $1000.;
do i=1 to 101;
list=catx(',',list,quote(put(i,z4.)));
end;
call symputx('list',list);
run;
%put &list;
You generally don't need comma's between characters for IN clauses so you can skip that step.
Shenglin's solution is better and you can macrotize that if required.
What are you actually trying to do?
%macro schlub (num1=, num2=,len=4);
%local i sep;
%do i=&num1 %to &num2 ;
%*;&sep."%sysfunc(putn(&i,Z&len))"%*;
%let sep=,;
%end;
%mend schlub;
%let list=%schlub(num1=1, num2=101);
%put &list;
Hi Tom,
I am intrigued by the trailing %*; in your macro. I've seen the leading %*; as a way to avoid white space, but never seen the trailing %*;.
I thought it must be unnecessary, but then found when I removed it the macro wouldn't compile. But interestingly if I changed to &sep"%sysfunc(putn(&I,Z&len))" it would compile. So removing the extraneous (in a sense) dot after &sep makes the trailing %*; unnecessary. This seems like an odd macro compiler bug to me, do you agree? Any understanding of what causes it?
Below is some sample code, where I replicate the problem, then test different workarounds. Seems to me like the problem only happens when you have a macro var reference with traling dot followed but a string in double quotes which includes a macro invocation. Ugh.
I put it there because it made it work. Originally I had the %DO;...%END all on one line and it worked. But when I reformatted it to look pretty it broke.
I am not sure why. Perhaps it is stuck looking to see there is going to be a letter after the quote to indicate a literal type? Ie "01JAN1960"d
Sigh, was hoping you'd be able to make my head stop hurting over this. : ) I don't think it's just looking for a date literal. That wouldn't explain why removing the dot after the macro variable reference avoids the problem. Thanks for mentioning %do/%end. Definitely seems like white space after the closing quote is part of the problem. Very odd. Will think more on Friday, maybe start a new thread.
%macro doesnotcompile(dummy);
&sep."%upcase(q)" %mend;
*remove dot;
%macro compiles(dummy);
&sep"%upcase(q)" %mend;
*with dot but remove white space after closing quote;
%macro compiles(dummy);
&sep."%upcase(q)"%mend;
Thank you all . Both Tom and Shenglin's methods perfectly accomplish what I am trying to do. I wanted to easily create a macro list from a range of codes, inputting two numbers. In this case, 0001 through 0101.
Yes, there is no need to use macro code at all:
data want;
length test $2000;
do i=1 to 101;
test=catx(",",test,put(i,z4.));
end;
run;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: