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

Hello everyone,

I want to write a macro that allows to specify:

1) Title of report (Listing of Account)

2) Variable to report (Acct_ID Name Age Balance Last_Tran_Date)

3) Whether a “Total Balance” (sum of balance) row is displayed

4) Selection criteria by state: “CA”, “NY”

5) Selection criteria by age: Age <=40

6) Selection criteria by year of Last_Tran_Date: 2016

- Additionally: all macro parameters should be optional. An omitted parameter should be interpreted to mean “ALL”

- please include a few representative example of how macro in invoked

1 ACCEPTED SOLUTION

Accepted Solutions
japelin
Rhodochrosite | Level 12

How about this code?

 

 

 

%macro final (title=
             , state =
             , age =
             , tran_year =
             , var = 
             , sumvar = 
             );

data profile3;
  %if &var ne %then %do; /* I don't know if you need retain, but you can use empty parameters to make it work. */
  retain &var;
  %end;
  set profile2;
  if tran_year ne .;
  where %if &age ne  %then %do;
          age &age 
        %end;%else
        %do;
          age > 0
        %end;
        %if &Tran_Year ne  %then %do;
          and Tran_Year = &tran_year 
        %end;
        %if &State ne  %then %do;
          and (State in ("%sysfunc(TRANWRD(&state,%str(,)," "))"))
        %end;
        ;
  keep acct_ID Name Age Balance Last_Tran_Date tran_year;
run;

%if &title = %then %do;
  %let title=Detail Listing of Account;
%end;
%if &State =  %then %do;
  %let State=All;
%end;
%if &age =  %then %do;
  %let age=All;
%end;
%if &Tran_Year =  %then %do;
  %let tran_year=All;
%end;

ods rtf file = "/folders/myfolders/macro.rtf";

proc sort data = profile3 out = profile4;
  by tran_year;
run;

proc print data = profile4 noobs sumlabel= "Total Balance" grandtotal_label= "Grand Total" width=uniformby;
  by tran_year;
  %if %upcase(&sumvar)^=NO %then %do;
  sum balance; *need macro for total balance var &var;
  %end;
  title2 j=l "Title: &title" j=r "Run date: %sysfunc(date(),worddate.)";
  title3 j=l "State: &state" j=c "Age: &age" j=r "Tran Year: &tran_year";
run;

ods rtf close;

%mend final;

/* 2 sample patterns */
%final (title=Detail Listing of Account
       ,state =CA%str(,)NY
       ,age=%str(<=)40
       ,tran_year = 2016
       ,var=Acct_ID Name Age Balance Last_Tran_Date
       ,sumvar=yes
       );
%final (title=Detail Listing of Account
       ,state =
       ,age=
       ,tran_year = 
       ,var=
       ,sumvar=
       );

View solution in original post

7 REPLIES 7
japelin
Rhodochrosite | Level 12

First of all, do you have a plain program before turning it into a macro?
If you can provide test data to go along with it, I think you will get a response.

Kurt_Bremser
Super User

Step 1: have a working code without macro coding.

Please post your report code, along with some example data (in a data step with datalines). Include any TITLE and FOOTNOTE statements.

dmayurp
Calcite | Level 5

HI,

Here is what I have tried so far. Thank you for your help.

 

data Profile;
input Acct_ID 1-4 Name $ 6-11 Birthday $ 13-21 Sex $ 23-24 State $ 25-26
Cust_Type $ 28-33 Product $ 35-42 Balance 44-47 Last_Tran_Date $ 49-57;
Cards;
1001 John 1/1/1962 M CA Gold Checking 1000 9/1/2015
1002 Mary 2/1/1972 F CA Silver Saving 2000 10/1/2015
1003 Peter 3/1/1982 M NY Gold Loan 3000 10/3/2016
1004 Mary 4/1/1992 F NY Silver Checking 4000 9/17/2016
1005 Linda 5/1/1994 F WA Gold Saving 5000
1006 Susan 6/1/1997 F WA Gold Loan 1000 9/15/2016
1007 Sam 7/1/1999 M CA Gold Checking 2000 2/1/2016
1008 Thomas 8/1/1962 M CA Silver Checking 3000 7/1/2016
1009 Linda 9/1/1982 F NY Silver Saving 4000
;
run;

data profile1;
set profile;
Birthday1 = input (Birthday, mmddyy10.);
Last_Tran_Date1 = input (Last_Tran_Date, mmddyy10.);
Tran_Year = year (Last_Tran_date1);
run;

data profile2;
set profile1;
today = date();
days = today -birthday1;
age = floor (days/365);
drop today days birthday birthday1;
run;

 

*PROC PRINT--------------------------------------------------------------------------------------------------------------------------;


%macro final (title, state1 =, state2 =, age =, tran_year =, var = );

data profile3;
retain &var;
set profile2;
if tran_year ne .;
where age &age and Tran_Year = &Tran_year and (State = "&state1" or state = "&state2");
keep acct_ID Name Age Balance Last_Tran_Date tran_year;
run;

ods rtf
file = "/folders/myfolders/macro.rtf";

proc sort data = profile3 out = profile4;
by tran_year;
run;

proc print data = profile4 noobs sumlabel= "Total Balance" grandtotal_label= "Grand Total" width=uniformby;
by tran_year;
sum balance; *need macro for total balance
var &var;
title2 j=l "Title: &title" j=r Run date: "%sysfunc(date(),worddate.)";
title3 j=l "State: &state1, &state2" j=c "Age &age" j=r "Tran Year: &tran_year";
run;

ods rtf close;

%mend final;

%final (Detail Listing of Account, state1 = CA, state2 = NY, age <=40, tran_tear = 2016, Acct_ID Name Age Balance Last_Tran_Date);

 

dmayurp
Calcite | Level 5

Here is the data that I am working on it.

 

data Profile;
input Acct_ID 1-4 Name $ 6-11 Birthday $ 13-21 Sex $ 23-24 State $ 25-26
Cust_Type $ 28-33 Product $ 35-42 Balance 44-47 Last_Tran_Date $ 49-57;
Cards;
1001 John 1/1/1962 M CA Gold Checking 1000 9/1/2015
1002 Mary 2/1/1972 F CA Silver Saving 2000 10/1/2015
1003 Peter 3/1/1982 M NY Gold Loan 3000 10/3/2016
1004 Mary 4/1/1992 F NY Silver Checking 4000 9/17/2016
1005 Linda 5/1/1994 F WA Gold Saving 5000
1006 Susan 6/1/1997 F WA Gold Loan 1000 9/15/2016
1007 Sam 7/1/1999 M CA Gold Checking 2000 2/1/2016
1008 Thomas 8/1/1962 M CA Silver Checking 3000 7/1/2016
1009 Linda 9/1/1982 F NY Silver Saving 4000
;
run;

data profile1;
set profile;
Birthday1 = input (Birthday, mmddyy10.);
Last_Tran_Date1 = input (Last_Tran_Date, mmddyy10.);
Tran_Year = year (Last_Tran_date1);
run;

data profile2;
set profile1;
today = date();
days = today -birthday1;
age = floor (days/365);
drop today days birthday birthday1;
run;

 

*PROC PRINT--------------------------------------------------------------------------------------------------------------------------;


%macro final (title, state1 =, state2 =, age =, tran_year =, var = );

data profile3;
retain &var;
set profile2;
if tran_year ne .;
where age &age and Tran_Year = &Tran_year and (State = "&state1" or state = "&state2");
keep acct_ID Name Age Balance Last_Tran_Date tran_year;
run;

ods rtf
file = "/folders/myfolders/macro.rtf";

proc sort data = profile3 out = profile4;
by tran_year;
run;

proc print data = profile4 noobs sumlabel= "Total Balance" grandtotal_label= "Grand Total" width=uniformby;
by tran_year;
sum balance; *need macro for total balance
var &var;
title2 j=l "Title: &title" j=r Run date: "%sysfunc(date(),worddate.)";
title3 j=l "State: &state1, &state2" j=c "Age &age" j=r "Tran Year: &tran_year";
run;

ods rtf close;

%mend final;

%final (Detail Listing of Account, state1 = CA, state2 = NY, age <=40, tran_tear = 2016, Acct_ID Name Age Balance Last_Tran_Date);

 

japelin
Rhodochrosite | Level 12

How about this code?

 

 

 

%macro final (title=
             , state =
             , age =
             , tran_year =
             , var = 
             , sumvar = 
             );

data profile3;
  %if &var ne %then %do; /* I don't know if you need retain, but you can use empty parameters to make it work. */
  retain &var;
  %end;
  set profile2;
  if tran_year ne .;
  where %if &age ne  %then %do;
          age &age 
        %end;%else
        %do;
          age > 0
        %end;
        %if &Tran_Year ne  %then %do;
          and Tran_Year = &tran_year 
        %end;
        %if &State ne  %then %do;
          and (State in ("%sysfunc(TRANWRD(&state,%str(,)," "))"))
        %end;
        ;
  keep acct_ID Name Age Balance Last_Tran_Date tran_year;
run;

%if &title = %then %do;
  %let title=Detail Listing of Account;
%end;
%if &State =  %then %do;
  %let State=All;
%end;
%if &age =  %then %do;
  %let age=All;
%end;
%if &Tran_Year =  %then %do;
  %let tran_year=All;
%end;

ods rtf file = "/folders/myfolders/macro.rtf";

proc sort data = profile3 out = profile4;
  by tran_year;
run;

proc print data = profile4 noobs sumlabel= "Total Balance" grandtotal_label= "Grand Total" width=uniformby;
  by tran_year;
  %if %upcase(&sumvar)^=NO %then %do;
  sum balance; *need macro for total balance var &var;
  %end;
  title2 j=l "Title: &title" j=r "Run date: %sysfunc(date(),worddate.)";
  title3 j=l "State: &state" j=c "Age: &age" j=r "Tran Year: &tran_year";
run;

ods rtf close;

%mend final;

/* 2 sample patterns */
%final (title=Detail Listing of Account
       ,state =CA%str(,)NY
       ,age=%str(<=)40
       ,tran_year = 2016
       ,var=Acct_ID Name Age Balance Last_Tran_Date
       ,sumvar=yes
       );
%final (title=Detail Listing of Account
       ,state =
       ,age=
       ,tran_year = 
       ,var=
       ,sumvar=
       );
dmayurp
Calcite | Level 5
It worked. Thank you for your help.
Aryyyan
Obsidian | Level 7
Thank you for your help

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 7 replies
  • 1129 views
  • 1 like
  • 4 in conversation