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

Hi all, 

I created the following macro but it is not executing as i expected. Could some one please let me know where I'm doing wrong?

 

%MACRO TEST1;

%DO ORDER = 1 %TO &MAX1.;

PROC SQL NOPRINT;
SELECT DISTINCT VAL1 INTO :VAL1 TRIMMED FROM WORK.TEST2 WHERE ORDER = &ORDER.;
SELECT DISTINCT FORM_NUM INTO :FORM_NUM TRIMMED FROM WORK.TEST2 WHERE ORDER = &ORDER.;
QUIT;

%MACRO CHK;

ODS PDF FILE = "/location/&FORM_NUM..PDF";
TITLE J=L H=5PT "&VAL1";
PROC REPORT NOWD DATA = WORK.TEST2;
WHERE ORDER = &ORDER.;
COLUMN
A B C D E F;
DEFINE A/ STYLE(HEADER) = [J =L];
DEFINE B/ STYLE(HEADER) = [J=L];
RUN;
ODS PDF CLOSE;
%MEND CHK;

%END;

%CHK;

%MEND TEST1;

%TEST1;

My intention is when order = 1 then macro variables &val1, &form_num should be generated then they will be passed along with &order macro variable in to the %chk macro and based on these variables the PROC report along with the ODS needs to be executed and generate first PDF.

The loop should be executed for order =1,2,3 ... until it reaches &max1.

/*FYI, the &max1. is 11*/

When i executed the macro looping is performed and for every loop &val1 and &form_num are generated. It looped until it reached 12(As the max value is only 11 it stopped to loop after it reached 12) then it started to execute %chk macro for order = 12. As i do not have data for order = 12 the proc report along with ODS did not generate anything and &val1 and &form_num are also not created because in the data i only have for &max1 variable is till 11.

 

It would be great if some could help me with this issue. Thanks in advance.

RD

1 ACCEPTED SOLUTION

Accepted Solutions
yabwon
Onyx | Level 15

Try like this:

%MACRO CHK;
  ODS PDF FILE = "/location/&FORM_NUM..PDF";
  TITLE J=L H=5PT "&VAL1";

  PROC REPORT NOWD DATA = WORK.TEST2;
  WHERE ORDER = &ORDER.;
  COLUMN
  A B C D E F;
  DEFINE A/ STYLE(HEADER) = [J =L];
  DEFINE B/ STYLE(HEADER) = [J=L];
  RUN;

  ODS PDF CLOSE;
%MEND CHK;



%MACRO TEST1;
  %DO ORDER = 1 %TO &MAX1.;
    PROC SQL NOPRINT;
    SELECT DISTINCT VAL1 INTO :VAL1 TRIMMED FROM WORK.TEST2 WHERE ORDER = &ORDER.;QUIT;

    PROC SQL NOPRINT;
    SELECT DISTINCT FORM_NUM INTO :FORM_NUM TRIMMED FROM WORK.TEST2 WHERE ORDER = &ORDER.;QUIT;

    %CHK;
  %END;
%MEND TEST1;

%TEST1;

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



View solution in original post

4 REPLIES 4
yabwon
Onyx | Level 15

Try like this:

%MACRO CHK;
  ODS PDF FILE = "/location/&FORM_NUM..PDF";
  TITLE J=L H=5PT "&VAL1";

  PROC REPORT NOWD DATA = WORK.TEST2;
  WHERE ORDER = &ORDER.;
  COLUMN
  A B C D E F;
  DEFINE A/ STYLE(HEADER) = [J =L];
  DEFINE B/ STYLE(HEADER) = [J=L];
  RUN;

  ODS PDF CLOSE;
%MEND CHK;



%MACRO TEST1;
  %DO ORDER = 1 %TO &MAX1.;
    PROC SQL NOPRINT;
    SELECT DISTINCT VAL1 INTO :VAL1 TRIMMED FROM WORK.TEST2 WHERE ORDER = &ORDER.;QUIT;

    PROC SQL NOPRINT;
    SELECT DISTINCT FORM_NUM INTO :FORM_NUM TRIMMED FROM WORK.TEST2 WHERE ORDER = &ORDER.;QUIT;

    %CHK;
  %END;
%MEND TEST1;

%TEST1;

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Tom
Super User Tom
Super User

I make no sense to keep redefining the macro. 

Define it once outside of the macro that is going to call it and this just call the macro where you want it to run.

ballardw
Super User

Where does &max1 come from? &Order?

 

Having macro variables pop up in the middle of code is one way to make things extremely hard to use because the macro is now completely dependent on something that 1) may not exist when run or 2) have a value that is not usable in that code if defined at a different time than expected in your code.

 

Strongly suggest having any macro variables that rely on values from outside the code to be passed into the macro as a parameter.  As a minimum it makes it much easier to test. If you have a macro do that does something for single value, such as your Order then a driver program or macro could look like:

%macro driver (Loops=);
   %do loop = 1 %to &loops;
       %somemacro( parameter=&loop);
   %end;
%mend;

Which would let you execute the inner Somemacro with the value of just 1, for testing perhaps with a call of

 

%driver (loops=1)

Then when works as expected;

%driver (loops=2)

If that works, then you try the full value you expect.

%driver (loops=11)

or so.

It will be much easier to get Somemacro to work with a single value, that is explicitly passed.

 

I cannot account for all the time spent trying to trace down problems with "magic macro variables" , the ones that just appear in the code and not a parameter to the macro, or at least the calling macro. This happens when you think "Aha! I have a macro that does something close to what I want" and grab the bit with the last details. Then spend time trying to find out what kind of values all those "magic" variable should be, or if you don't need them you have to rewrite around the dependencies after finding them

Parameters and documentation (comments) will save a lot of work later.

 

 

Kurt_Bremser
Super User

All macros exist in the global scope; therefore, nesting macro definitions makes no sense and should (IMO must) be avoided for sake of code clarity.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 1145 views
  • 6 likes
  • 5 in conversation