BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
P_2
Fluorite | Level 6 P_2
Fluorite | Level 6

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

1 ACCEPTED SOLUTION

Accepted Solutions
slchen
Lapis Lazuli | Level 10

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;

View solution in original post

8 REPLIES 8
slchen
Lapis Lazuli | Level 10

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;

Reeza
Super User

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.

Tom
Super User Tom
Super User

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;

Quentin
Super User

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.

options mcompilenote=all;

*wont compile without trailing macro comment;
%macro doesnotcompile(dummy);
 
%local sep;
  &sep."%sysfunc(putn(1,Z2))"
%mend;

*Recover;
*";%mend;

*Compiles with trailing macro comment;
%macro compiles(dummy);
 
%local sep;
  &sep."%sysfunc(putn(1,Z2))"%*;
%mend;

*Compiles without trailing macro comment, no dot after &sep;
%macro compiles(dummy);
 
%local sep;
  &sep"%sysfunc(putn(1,Z2))"
%mend;

*Compiles without trailing macro comment, so quote marks are part of cause;
%macro compiles(dummy);
 
%local sep;
  &sep.%sysfunc(putn(1,Z2))
%mend;

*Compiles without trailing macro comment, so macro call is part of cause;
%macro compiles(dummy);
 
%local sep;
  &sep."HiMom"
%mend;
BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Tom
Super User Tom
Super User

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

Quentin
Super User

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;

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
P_2
Fluorite | Level 6 P_2
Fluorite | Level 6

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. 

RW9
Diamond | Level 26 RW9
Diamond | Level 26

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;

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 8 replies
  • 1370 views
  • 5 likes
  • 6 in conversation