06-22-2016 05:11 AM
I wanna try to automatize my macro code by using some macro variable values and its names. Current stiuation like that:
%let datasets=dsn1 dsn3 dsn2 dsn4; %let datasets_labels=label1 label3 label2 label4; %macro prog_Loop; %let i=1; %do %while(%scan(&Datasets.,&i.,%str( ))~=); %prog (%scan(&Datasets.,&i.,%str()),%scan(&Datasets_labels.,&i.,%str( ))); %let i=&i.+1; %end; %mend; %prog_Loop; ......
There are lots of macro program(prog1,prog2,prog3,etc.) and structure is same. I wanna package some of these macro programs. So, I wanna go one step forward to automatize structure. User should only define the label and corresponding dataset as separate macro variables at once( beginining of package).The required ones for each macro program is collapsed in each code as below.(User is not a party in this step) .My desired structure is at below:
%let label1=dataset1; %let label2= dataset2; %let label3= dataset3; %let label4= dataset4;
After macro variables are defined by user then code collapse them within datasets and datasets_labels macro variables. I can create datasets macro variable from macro varables defined, however, i cannot create datasets_labels macro variables because the macro variable names are required instead of macro varible values.I think I need to read macro variables name in somewhere. How can i create datasets_labels macro variable from macro varaibles shown in top?
%macro prog1_Loop; %let datasets=&label1 &label3 &label2; %let datasets_labels=label1 label3 label2; /*I need to define macro variables names here*/ %let i=1; %do %while(%scan(&Datasets.,&i.,%str( ))~=); %prog (%scan(&Datasets.,&i.,%str()),%scan(&Datasets_labels.,&i.,%str( ))); %let i=&i.+1; %end; %mend; %macro prog2_Loop; %let datasets=&label4 &label3 ; %let datasets_labels=label4 label3 ; /*I need to define macro variables names here*/ %let i=1; %do %while(%scan(&Datasets.,&i.,%str( ))~=); %prog (%scan(&Datasets.,&i.,%str()),%scan(&Datasets_labels.,&i.,%str( ))); %let i=&i.+1; %end; %mend; ..... %macro package(); %prog1_loop; %prog2_loop; ..... %mend package; %package();
06-22-2016 05:28 AM
Why no do it like that:
data datasets; length dsname $32 dslabel $100 ; infile cards dsd dlm=' '; input dsname $ dslabel $; cards; dataset1 "Label for dataset1" ; run; data _null_; set datasets; call execute('%prog('!!trim(dsname)!!','!!trim(dslabel)!!');'); run;
This avoids complicated macro programming and makes it much easier for the user to insert the list in the cards; block instead of entering a long list of %put statements.
06-22-2016 05:38 AM
I agree with @KurtBremser, you appear to be making a whole ton of macro coding for no benefit. Not to mention that someone at some point in the future will have to maintain that - and being one of those people who have done that I can tell you it is the worst role possible. Tennet one of making re-usable code, keep it simple - then refine it to make it even simpler. The simpler the code and process you make, the simpler it is to make and maintain and macro code almost never makes code simpler.
Document, document, makes simple code, make it simpler, test it, maintain it, retire it.
06-22-2016 08:40 AM
Thanks for your quick response. Actually, I thinked about that at first, but it is diffucult to deal with data step code for users because they are not familiar with sas code. So I try to minimize the interaction of users with code. That’s why I use some of %let statements instead of creating dataset by users.
Is there any way to display macro variable name? (Using functions, catalog etc.).
For example VNAME function gives us the variable name however i could’nt find any logic for macro names . On the other hand; I am open to any other methods that are easy to use for non-familiar SAS users.
Thanks in advance
06-22-2016 03:55 PM
<Spock>But this is not logical!</Spock>
When your users have still problems coping with data steps, bombarding them with macro code makes no sense at all.
Just looking at my call execute vs. your snakepit of macro references that causes your problems makes it very clear (at least to me) which one is more readable and maintainable.
06-22-2016 04:32 PM
I cannot tell from your post what you are attempting to automate, but let me give you some advice on using lists of values of in macro variables.
If you want to list dataset names or variable names in a macro variable then space delimited is preferred. You can then use the list in SAS code or pass the value in other macro calls without much trouble.
%let dslist=table1 table2 table3 ; data all ; set &dslist ; run; %let varlist=var1 varB varZ ; proc print ; var &varlist; run; %mymacro(keyvars=&varlist)
But if you want to list labels or other values that could contain spaces then you are better off to use another delimiter, such as |. Otherwise how can you tease them back out again?
%let datasets=dsn1 dsn3 dsn2 dsn4; %let datasets_labels=label for ds1|label for ds3|label for ds2|label for ds4;