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

Hello,

about 4 years ago I saw a SAS Program that had a header and footer marcro

as well as an output (ms excel, pdf, formatting) macro all called into the program from external .sas files.

The macro´s were called in various SAS programs so it was a development focussing

on reusability and modularity.

Is there a tutorial that deals with such external "styling" macro´s, what they should contain, how they

are called?

bye

phil

1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

Is it something like below you're after?

%macro header;

  title justify=L &RepTitel;

%mend;

%macro footer;

  footnote  justify=L "&sysuserid: &RepFileName %sysfunc(datetime(),datetime.) &num. Ergebnisse";

  footnote2 justify=L link="http://www.sas.com" "Download als MS Excel";

  footnote3 justify=L link="http://www.sas.com" "Download als PDF";

  footnote4 justify=L link="http://www.sas.com" "Download als XML";

%mend;

%let REPTITEL="some title";

%let RepFileName=some name;

%let num=99;

data positives;

  set sashelp.class;

run;

title;

footnote;

%header;

%footer;

proc report data=positives;

run;

ods pdf file="C:\temp\mypdf.pdf";

title;

footnote;

%header;

proc print data=positives noobs;

run;

ods pdf close;

ods html file="C:\temp\mypdf.xls";

%let REPTITEL="some other title";

title;

footnote;

%header;

%footer;

proc print data=positives noobs;

run;

ods html close;

View solution in original post

6 REPLIES 6
Patrick
Opal | Level 21

Isn't this more about general design principles like modularisation and re-usability? Not really sure what kind of tutorial you would expect to find?

How you name such macros doesn't really matter, a good way to call them is having them stored in a SAS Autocall library.

metallon
Pyrite | Level 9

Hi Patrick,

you are right, it surely is about general design principles like modularisation and re-usability.

Now I dont know much about best practice modularisation and re-usability when it comes to SAS reports and I was hoping

there would be something out there that explains this "general" priniciples for SAS.

Thanks!

metallon
Pyrite | Level 9

Hi Patrick, RW9

I aim to modularize the footer generation so I dont have a download link on my PDF & excel as it appears

now. I only need the links on the html output (or SAS report)

proc report data=positives;

title justify=L &RepTitel ;

footnote  justify=L "&sysuserid: &RepFileName %sysfunc(datetime(),datetime.) &num. Ergebnisse"  ;

footnote2 justify=L link="http://www.sas.com" "Download als MS Excel" ;

footnote3 justify=L link="http://www.sas.com" "Download als PDF" ;

footnote4 justify=L link="http://www.sas.com" "Download als XML" ;

run;

ods pdf file="C:\temp\mypdf.pdf";

proc print data=positives noobs;

run;

ods pdf close;

ods html file="C:\temp\mypdf.xls";

proc print data=positives noobs;

run;

ods html close;

Is there a way to write the footer in a macro and maybe call it as an addition to the ODS PDF statement?

Patrick
Opal | Level 21

Is it something like below you're after?

%macro header;

  title justify=L &RepTitel;

%mend;

%macro footer;

  footnote  justify=L "&sysuserid: &RepFileName %sysfunc(datetime(),datetime.) &num. Ergebnisse";

  footnote2 justify=L link="http://www.sas.com" "Download als MS Excel";

  footnote3 justify=L link="http://www.sas.com" "Download als PDF";

  footnote4 justify=L link="http://www.sas.com" "Download als XML";

%mend;

%let REPTITEL="some title";

%let RepFileName=some name;

%let num=99;

data positives;

  set sashelp.class;

run;

title;

footnote;

%header;

%footer;

proc report data=positives;

run;

ods pdf file="C:\temp\mypdf.pdf";

title;

footnote;

%header;

proc print data=positives noobs;

run;

ods pdf close;

ods html file="C:\temp\mypdf.xls";

%let REPTITEL="some other title";

title;

footnote;

%header;

%footer;

proc print data=positives noobs;

run;

ods html close;

metallon
Pyrite | Level 9

Awesome. Thanks Patrick!

RW9
Diamond | Level 26 RW9
Diamond | Level 26

I agree with Patrick here, although I would go one further.  I would suggest the use of version control software.  Its been around for many years and is used in all large projects.  Personally I have used TortoiseSVN (SVN based) on windows.  Its simple, free, and robust.  With that you can execute a command line interaction which will pull all of the history, and compares if you like, from all committed versions of a program.  The reason I suggest this is because I feel manual headers in programs are always going to be flawed.  In most programs where I have seen headers they are wrong, i.e. changes not mentioned, wrong information etc., and even the most careful programmer will miss something.  Let the software do all the tracking and versioning for you, just like everything else in life, use the right tool for the job. 

There is the second point to your question also, styling.  This doesn't seem to really be taken up in my field, good programming practices.  Things like indentation, closing proc/datasteps with run, one line per command, consistent naming etc.  Its one of the real nightmares about picking up someones code if you find and incorrect header, then lots of commands all on one line with no indication of nesting or end points.  This is especially true with code which will be used by more than one person.  How often have you started a job to find a macro like this (note not syntactically checked!):

%_s (a,b);

     %if &a.="" %then %do; %put something; %goto exit;

     proc sort data=a out=b;

     %endif;

:exit

%mend;

Its also important to follow Software Development Life Cycle (SDLC)processes, i.e. docmentation first! then program, then validate, then follow a plan of re-assessment on a timed basis, then follow procedure to retire said item.  These should all be considered when developing any code, but essential if the code is used across groups.

Also, one final thing (on my ramble), Keep It Simple Smart (KISS), so often macros turn into vast rambling pages of code, checking everything, looping to avoid arrays, calling other macros which in turn call more.  It quickly becomes a tangled mess.  Small sections of code, easier to debug, simlpe to use, with easy to understand function that call nothing else are far easier to maintain and tend to be more flexible in the long run. 

I would also keep comments concise and to a minimum.  Helpful they can be, and I know most will say they are essential, but in my experience if code needs vast comment blocks to explain what something is doing then you are probably over complicating it in the first place.  

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
  • 6 replies
  • 2144 views
  • 6 likes
  • 3 in conversation