DATA Step, Macro, Functions and more

Broken automated macro list generating code

Accepted Solution Solved
Reply
Occasional Contributor P_2
Occasional Contributor
Posts: 10
Accepted Solution

Broken automated macro list generating code

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)Smiley SadColumn).

      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


Accepted Solutions
Solution
‎08-11-2015 03:00 PM
Super Contributor
Posts: 275

Re: Broken automated macro list generating code

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


All Replies
Solution
‎08-11-2015 03:00 PM
Super Contributor
Posts: 275

Re: Broken automated macro list generating code

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;

Super User
Posts: 17,898

Re: Broken automated macro list generating code

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.

Super User
Super User
Posts: 6,502

Re: Broken automated macro list generating code

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;

PROC Star
Posts: 1,235

Re: Broken automated macro list generating code

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;
Super User
Super User
Posts: 6,502

Re: Broken automated macro list generating code

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

PROC Star
Posts: 1,235

Re: Broken automated macro list generating code

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;

Occasional Contributor P_2
Occasional Contributor
Posts: 10

Re: Broken automated macro list generating code

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. 

Super User
Super User
Posts: 7,413

Re: Broken automated macro list generating code

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;

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

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