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

I am using a Date Prompt to get a user input month in SAS. I get the input in the following format:

  1. UserSelectedMonth = DDMMMYYYY (eg: 01JUL2022) – This is the macro variable obtained from prompt.
  2. UserSelectedMonth in the MMM-YY format
    • Selected_month = JUL-22 – This must be a macro variable
  3. From the UserSelectedMonth, I want to find the number corresponding to the month
    • Selected_month_no = 7 (eg: July is the 7th month) ---- This must be a macro variable
  4. Extract the three-letter name of the above UserSelectedMonth
    • Selected_month_name = JUL ---- This must be a macro variable
  5. Find the year from the UserSelectedMonth as a two-digit number
    • Selected_year = 22          ---- This must be a macro variable
  6. Find the same month in 2019 in the MMMYY format
    • Month_year_19 = JUL19     ---- This must be a macro variable
  7. Previous month in the MMMYY or MMMYYYY format
    • Previous_month = JUN22 or  Previous_month = JUN2022   ---- This must be a macro variable

I need to read some automatically generated files having different file name formats, so based on the user input I need all these variables to dynamically define the files names and read them inside a program.

Can someone please help me to obtain the above?

I tried and my code does not work ☹️

Sorry for the long post.

Thanks for anyone giving some help!

======================================================================================================================

My code:

data _null_;

/* UserSelectedMonth  is obtained from the Date prompt as a macro variable, but I just stated here so that that the rest of the code can be tested*/

%let UserSelectedMonth  = 01JUL2022; 

/*Try to obtain the Selected_month_no as a two digit no using the z2. format*/

%let Selected_month_no  = %sysfunc(month("&UserSelectedMonth."d), z2.);

/*Try to obtain the Selected_month_name in three letters using the monname3. format*/

%let Selected_month_name  = %sysfunc(month("&UserSelectedMonth."d), monname3.);

/*Extract the last two digits (Selected_year) using substr from DDMMMYYYY*/

%let Selected_year  = %sysfunc(substr("&UserSelectedMonth",8,2));

/*Obtain Month_year_19 by combining Selected_month_name and 19*/

%let Month_year_19  = %sysfunc(cat(&Selected_month_name,19));

/*Obtain Selected_month by combining Selected_month_name, "-" and Selected_year */

%let Selected_month =%sysfunc(cat(&Selected_month_name,-,&Selected_year));

/*Obtain previous month from */

Previous_month  = intnx('MONTH', "&UserSelectedMonth"d, -1, 'BEGINNING');

format  Previous_month  date9.;

call symputx('Previous_month ',  put(Previous_month ,date9.));

%put _user_;

run;

=======================================================================

Macro variables I am getting:

GLOBAL MONTH_NAME Jan

GLOBAL MONTH_NO 07

GLOBAL MONTH_YEAR_19 Jan19

GLOBAL SELECTEDMONTH 01Jul2022

GLOBAL SELECTEDMONTH_END 31Jul2022

GLOBAL SELECTEDMONTH_LABEL Previous month

GLOBAL SELECTEDMONTH_REL M-1M

GLOBAL SELECTED_MONTH Jan-2

GLOBAL SELECTED_MONTH_NAME Jan

GLOBAL SELECTED_MONTH_NO 07

GLOBAL SELECTED_YEAR 02

1 ACCEPTED SOLUTION

Accepted Solutions
mkeintz
PROC Star

A couple of observations.

 

  1. You don't need to use the data step.  But if you do, issue the %PUT _USER_; statement after the run; statement.

  2. Instead of repeated use of "&userselectedmonth"d, make a USERDATEVALUE=%sysevalf("&userselectedmonth"d); and then use that macrovar as the primary date source.

  3. Consider your statement    

    %let Selected_month_name  = %sysfunc(month("&UserSelectedMonth."d), monname3.);
    It does the following

    1. Gets the month number of UserselectedMonth = 7
    2. Applies the monname3. format to the value of 7.  But because the monname3. format is intended for date values, it treats the 7 as representing 08jan1960  (date values use zero for 01jan1960).  Since the month for date=7 is January, you will get JAN, even though you intended to get JUL.

Here are suggested replacements:

%let UserSelectedMonth=01jul2022;
%let userdatevalue=%sysevalf("&UserSelectedMonth"d);

%let Selected_month_no   =%sysfunc(putn(&userdatevalue,month2.));
%let Selected_month_name =%sysfunc(putn(&userdatevalue,monname3.));
%let Selected_year       =%sysfunc(putn(&Userdatevalue,year2.));
%let month_year_19       =&selected_month_name.19;
%let previous_month      =%sysfunc(intnx(month,&userdatevalue,-1),monyy7.);

The primary points here are:

  1. You can use the %SYSEVALF macro function to evaluate a date literal, as above.  As you can see, I use that underlying value in the subsequent %SYSFUNC(putn( .... expressions.
  2. Just as you can apply formats to the PUT function in a DATA step, you can use the PUTN function with formats embedded in a %SYSFUNC macro function.
--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------

View solution in original post

4 REPLIES 4
mkeintz
PROC Star

A couple of observations.

 

  1. You don't need to use the data step.  But if you do, issue the %PUT _USER_; statement after the run; statement.

  2. Instead of repeated use of "&userselectedmonth"d, make a USERDATEVALUE=%sysevalf("&userselectedmonth"d); and then use that macrovar as the primary date source.

  3. Consider your statement    

    %let Selected_month_name  = %sysfunc(month("&UserSelectedMonth."d), monname3.);
    It does the following

    1. Gets the month number of UserselectedMonth = 7
    2. Applies the monname3. format to the value of 7.  But because the monname3. format is intended for date values, it treats the 7 as representing 08jan1960  (date values use zero for 01jan1960).  Since the month for date=7 is January, you will get JAN, even though you intended to get JUL.

Here are suggested replacements:

%let UserSelectedMonth=01jul2022;
%let userdatevalue=%sysevalf("&UserSelectedMonth"d);

%let Selected_month_no   =%sysfunc(putn(&userdatevalue,month2.));
%let Selected_month_name =%sysfunc(putn(&userdatevalue,monname3.));
%let Selected_year       =%sysfunc(putn(&Userdatevalue,year2.));
%let month_year_19       =&selected_month_name.19;
%let previous_month      =%sysfunc(intnx(month,&userdatevalue,-1),monyy7.);

The primary points here are:

  1. You can use the %SYSEVALF macro function to evaluate a date literal, as above.  As you can see, I use that underlying value in the subsequent %SYSFUNC(putn( .... expressions.
  2. Just as you can apply formats to the PUT function in a DATA step, you can use the PUTN function with formats embedded in a %SYSFUNC macro function.
--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
madara155
Obsidian | Level 7

Thank you very much 🙏

madara155
Obsidian | Level 7

Following line is giving the Selected_month_no as a single digit no (for July it is giving 7 instead of 07).


%let Selected_month_no =%sysfunc(putn(&userdatevalue,month2.));


Any thoughts on how to get it as a two digit value? I tried using z2. but I think I did it incorrectly.

 

Thanks again

mkeintz
PROC Star

@madara155 wrote:

Following line is giving the Selected_month_no as a single digit no (for July it is giving 7 instead of 07).


%let Selected_month_no =%sysfunc(putn(&userdatevalue,month2.));


Any thoughts on how to get it as a two digit value? I tried using z2. but I think I did it incorrectly.

 

Thanks again


Please show what you did when you "tried using Z2.".

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

SAS Enterprise Guide vs. SAS Studio

What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.

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
  • 4 replies
  • 615 views
  • 0 likes
  • 2 in conversation