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

I want to make my code more parsimonious.  My Macro uses two variables: Y and Z and they ranges as follows:

Y = {1-4}

Z = {1-50}

When calling the MACRO I am currently doing it like this:

%MACRO One (Y, Z);

Code code code

%MEND;

%One (1,1);

%One (1,2);

%One (1,3);

....

%One (4,50);

It takes up 200 lines of code to call the macro.  There has to be a better way.  I tried using %do i = 1 %to 4 and %do j=1 %to 50 between where I mend the macro and where I call it; but it did not work.  Any ideas?  Thanks as always SAS experts!!!

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

Create another macro to loop through it.

But ideally you should change your original macro to handle it.

%macro one(ymin=1, ymax=4, zmin=1, zmax=50);

%do i=&ymin %to &ymax;

% do j=&zmin %to &zmax;

%one(&i, &j);

*OR Original  macro code goes here;

%end;

%end;

%mend;

View solution in original post

8 REPLIES 8
Reeza
Super User

Create another macro to loop through it.

But ideally you should change your original macro to handle it.

%macro one(ymin=1, ymax=4, zmin=1, zmax=50);

%do i=&ymin %to &ymax;

% do j=&zmin %to &zmax;

%one(&i, &j);

*OR Original  macro code goes here;

%end;

%end;

%mend;

Milo08
Calcite | Level 5

I went with your solution once I figured it out...  Thank you!!!  As always this forum is a great resource for relative SAS novices like myself.

art297
Opal | Level 21

The question, I think, is why you couldn't get it to work using a %do loop.  What kind of error(s) did you get?  I think the problem is probably within the macro that you wrote.  It would help if you posted it and some example data you are addressing.

Milo08
Calcite | Level 5

%MACRO BIGfile (form, Version);

data _null_;

    set List;

    file "&winsteps.\Project_V&version._&form..big" Lrecl=50000;

    if _n_ = 1 then do;

    put '&INST';

    put "TITLE=Project Anchor Run Calibration: Version &version. Form &form.";

    put "ITEM1=1";

    put "LCONV=0.000001";

    put "RCONV=0.001";

    put "DATA=Project_V&version._&form..dat";

    put "NI=38";

    put "XWIDE = 1";

    put "CODES = 0123456789";

    put "GROUPS=0";

    put 'MUCON=50';

    put 'STKEEP=Y';

    put "IFILE=Project_V&version._&form..itm";

    put "SFILE=Project_V&version._&form..san";

    put "DISFILE=Project_V&version._&form..dis";

    put "IAFILE=Project.iaf";

    put "SAFILE=Project.saf";

    put 'TFILE=*';

    put '0';

    put '3';

    put '12';

    put '14';

    put '20';

    put '*';

    put 'BATCH=Y';

    put '&END';

    end;

    put    @1 Name;

    if _n_ = 38 then put "END NAMES";

run;

data BatchFile;

    format ANC_Batch $120.;

    ANC_Batch = "c:\winsteps374\winsteps.exe Project_V&version._&form..big Project_V&version._&form..out";

run;

Proc Append Base = BatchFile2 new = BatchFile;

run;

data _null_;

    set BatchFile2;

    file "&winsteps.\Anchor Run.bat" Lrecl=50000;

    put

        @1 ANC_Batch;

run;

   

%MEND BIGFILE;

%Do i=1 %to 4;

    %Do j=1 %to 50;

%BIGFile (&j, &i);

    %end;

%end;

There is my code <for the most part>.  I am attempting to create 200 different files and then create a .bat file to run them for me.  I have everything running fine, I just figured there had to be a way I could do it differently and more efficiently.  The error I get concerns the %end statements.  It says the %end statement is not valid in open code.  

Tom
Super User Tom
Super User

You can probably eliminate the macro code completely. You can use the FILEVAR option of the FILE statement to have a single DATA step create multiple files. 

Milo08
Calcite | Level 5

My apologies Tom.  I have never used a filevar option before, thus I am unfamiliar with it.  Would it be possible for you to show me an example using my example code above?  Thank you as always for all your help!!!

art297
Opal | Level 21

I think it would be easier for Tom, or any of us, to answer the question about using the filevar option if you posted a small example file and what you were trying to do with it.

As for the errors, I'm surprised they were the only errors, as your macro also includes a couple of global macro variables that would have had to have been created before the macro could run.

Like Fareeza had suggested, you would just have to put the two %do loops at the start of your macro, and the two %end statements at the bottom of your macro.  %do can only be used within a SAS macro.

Tom
Super User Tom
Super User

Not sure if creating the dataset with the list of the lines written to the .BAT file is important.  If not then just use data _NULL_ instead.

One advantage of using DATA step to generate the files is that you have more flexibility with the DO statement than the %DO statement.

You can combine iterated lists with just lists of values. For example: DO form=1 to 5,10,20,100;

I also added code to use the NOBS option on the SET statement for the input dataset LIST so that it will output all of the names in the dataset into each of the generated BIG files and the number of records in LIST does not always have to be exactly 38.  I had it replace the 38 in the value of NI= with the number of obs from the LIST dataset.

data batchfile ;

  length filename bigfilename $200 ;

  do form=1 to 4;

    do version=1 to 50 ;

      filename = cats("Project_V",version,'_',form);

      bigfilename = cats("&winsteps\",filename,'.big');

* Write BIG file ;

      file big filevar=bigfilename lrecl=50000;

      put

  '&INST'

/ 'TITLE=Project Anchor Run Calibration: Version ' version 'Form' form'

/ 'ITEM1=1'

/ 'LCONV=0.000001'

/ 'RCONV=0.001'

/ 'DATA=' filename +(-1) '.dat'

/ 'NI=' nobs

/ 'XWIDE = 1'

/ 'CODES = 0123456789'

/ 'GROUPS=0'

/ 'MUCON=50'

/ 'STKEEP=Y'

/ 'IFILE=' filename +(-1) '.itm'

/ 'SFILE=' filename +(-1) '.san'

/ 'DISFILE=' filename +(-1) '.dis'

/ 'IAFILE=Project.iaf'

/ 'SAFILE=Project.saf'

/ 'TFILE=*'

/ '0'

/ '3'

/ '12'

/ '14'

/ '20'

/ '*'

/ 'BATCH=Y'

/ '&END'

      ;

      do p=1 to nobs;

        set List point=p nobs=nobs;

        put @1 Name;

      end;

      put "END NAMES";

* Write line to batch file. ;

      file "&winsteps.\Anchor Run.bat" Lrecl=50000;

      put "c:\winsteps374\winsteps.exe " bigfilename filename +(-1) '.out';

    end;

  end;

   stop;

run;

sas-innovate-2024.png

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.

 

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
  • 1047 views
  • 0 likes
  • 4 in conversation