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

Hi guys,

I'm not that good at macro, still learning and haven't found the solution to my problem.

 

I have created two variables VarName and VarDate

 

data have;
input VarName
$ VarDate :ddmmyy10.;
format VarDate ddmmyy10.;
datalines;
A_10 14/06/2020
A_11 12/06/2020
B_10 30/06/2020
B_11 30/06/2020
C_10 31/05/2020
C_11 29/05/2020
D_10 30/04/2020
D_11 30/04/2020
E_10 31/03/2020
E_11 31/03/2020
F_10 29/02/2020
F_11 28/02/2020
G_10 31/12/2021
G_11 31/12/2021
;

run;

 

Put the values of VarName to a macro variables(thanks to @ed_sas_member :))

 

data _null_;
set have;
call
symputx(VarName, put(VarDate,ddmmyy10.));
run;

 

Then I Run a macro which modifies dates with the parameter=ddata:

%macro newDates(ddata);
	%global &ddata._txt &ddata._dash; data _null_; 
set have; 

call symput("&ddata._TXT", "'"!!compress(put(&ddata.,yymmdd10.),'-')!!"'"); 
call symput("&ddata._DASH", "'"!!put(&ddata.,yymmdd10.)!!"'"); 

run;
 %put ********** &dato._TXT: &&&dato._TXT; 
%put ********** &dato._DASH: &&&dato._DASH; 
%mend;

And here comes my problem:

Instead of naming all parameters separately, is it possible to pass a list of parameters to my %macro newDates?

 

Instead of writing this(in my real program I have near hundred of parameters to write):

%newDates(A_10)

%newDates(A_11)

%newDates(B_10)

%newDates(B_11)

%newDates(C_10)

%newDates(C_11)

and so on......

 

I am dreaming to call a macro %newDates once with list of needed parameters:

%newDates(param_list) where param_list would be all the parameters from data have column VarName

 

The results of running the %newDates(param_list)  in the log should be like this:

********** A_10_TXT:                    '20200614'
********** A_10_DASH:                 '2020-06-14'

********** A_11_TXT:                     '20200612'
********** A_11_DASH:                 '2020-06-12'

********** B_10_TXT:                    '20200630'
********** B_10_DASH:                '2020-06-30'

********** B_11_TXT:                    '20200630'
********** B_11_DASH:                '2020-06-30'

and so on for every VarName....

 

If someone could help me, it would be incredible 🙂

 

1 ACCEPTED SOLUTION

Accepted Solutions
Jagadishkatam
Amethyst | Level 16

you can try something as below

 

%macro newDates;

    data _null_; 
set have nobs=eob; 
call symputx("obs", eob); 
call symputx("ddata"||compress(put(_n_,best.)), "'"!!compress(put(VarDate,yymmdd10.),'-')!!"'"); 
call symputx("ddata_"||compress(put(_n_,best.)), "'"!!put(VarDate,yymmdd10.)!!"'"); 
call symputx("varnam"||compress(put(_n_,best.)), strip(VarName)); 
run;


%do i= 1 %to &obs;
 %put ******* &&varnam&i.._TXT : &&ddata&i. ; 
 %put ******* &&varnam&i.._DASH : &&ddata_&i.;
%end;

%mend;

%newDates

log

 

image.png

 

Thanks,
Jag

View solution in original post

7 REPLIES 7
RichardDeVen
Barite | Level 11

Maybe you should try to explain what you are trying to do.  There is probably a much cleaner approach.

 

Regardless, since macro variable names do not contain special characters, you can pass a single argument that lists all the variables separated by spaces.

Rather than rewriting your existing macro, you can create a new one that parses out each name and invokes the original macro that operates on a single variable.

There are many ways to parse out a 'word' from a space separated list of words, SCAN is one of the easiest and most accessible.

 

Example:

%macro newDatesX (names);
  %local index name;
  %do index = 1 %to %sysfunc(countw(&names));
    %let name = %scan(&names,&index);
    %newDates(&name)
  %mend;
%mend;

%newDatesX( A_10 A_11 B_10 B_11 C_10 C_11 ... hundreds more ? ... )
Rentum
Fluorite | Level 6
Thank you for you proposed solution to my problem, but in this solution I still will have to write manually all the parameters like %newDatesX( A_10 A_11 B_10 B_11 C_10 C_11 ... hundreds more ? ... )
And these parameters are changing and new ones are adding, so I wanted to make this process automatically and instead of writing all parameters manually give a one list of parameters to macro %newDatesX(list_of_parameters)
Tom
Super User Tom
Super User

Since you apparently started with the data in a dataset why not just leave the data in the dataset? For your example you would just pass the value HAVE to the macro so that it knows what dataset to use.

 

Please explain what you are trying to do.  You probably do not want to use macro logic for something that involves a lot of data.  Macro logic is for generating code, not data.

Rentum
Fluorite | Level 6
Ok, my goal is to create a bunch of global macro variables with dates which will be use in other sas programs.
First step:
create variables with dates
Second step:
Put values to a macro variables
Third step:
with %macro procedure create various types of dates, like _TXT, _DASH, and so on
Fourth step:
run %macro for all variables created in first step
RichardDeVen
Barite | Level 11

If all these *_TXT and *_DASH macro symbols are to be used to process many variables in a single data set you would be better off using arrays.  Personally, when my coding takes me down the path of "I am using a lot of symbols as if they were data" I take a step back and ask myself an old lumberjack question "Why am I trying to send these logs down the river sideways?"

 

Rentum
Fluorite | Level 6
@RichardADeVenezia I applied your example to my situation and it worked perfectly. Created a list of variables and pass it to the macro. Earlier I was confused about your example, but now it works and you were right, SCAN is very easy to use. Thanks!
Jagadishkatam
Amethyst | Level 16

you can try something as below

 

%macro newDates;

    data _null_; 
set have nobs=eob; 
call symputx("obs", eob); 
call symputx("ddata"||compress(put(_n_,best.)), "'"!!compress(put(VarDate,yymmdd10.),'-')!!"'"); 
call symputx("ddata_"||compress(put(_n_,best.)), "'"!!put(VarDate,yymmdd10.)!!"'"); 
call symputx("varnam"||compress(put(_n_,best.)), strip(VarName)); 
run;


%do i= 1 %to &obs;
 %put ******* &&varnam&i.._TXT : &&ddata&i. ; 
 %put ******* &&varnam&i.._DASH : &&ddata_&i.;
%end;

%mend;

%newDates

log

 

image.png

 

Thanks,
Jag

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 7 replies
  • 1010 views
  • 3 likes
  • 4 in conversation