I'm working with a SAS program that needs to extract the month name in Italian (e.g., "Dicembre") from a macro variable containing a date (`&DATA_PERIO = 31Dec2024`). I need this to dynamically build Excel filenames. I've tried several approaches but encounter errors:
/* Creating format for month names in Italian */
PROC FORMAT;
VALUE mese_ita
1 = 'Gennaio' 2 = 'Febbraio' 3 = 'Marzo' 4 = 'Aprile' 5 = 'Maggio' 6 = 'Giugno'
7 = 'Luglio' 8 = 'Agosto' 9 = 'Settembre' 10 = 'Ottobre' 11 = 'Novembre' 12 = 'Dicembre';
RUN;
/* Attempt 1: Using inputn and PUT */
%LET DATA_PERIO_NUM = %sysfunc(inputn(&DATA_PERIO, date9.));
%LET MESE_NUM = %sysfunc(MONTH(&DATA_PERIO_NUM));
%LET MESE_TEXT = %sysfunc(PUT(&MESE_NUM, mese_ita.));
ERROR: The PUT function referenced in the %SYSFUNC or %QSYSFUNC macro function is not found.
I need to obtain a macro variable `&MESE_TEXT` containing the Italian month name to use in this pattern:
%let filename = Analisi Crediti &MESE_TEXT &ANNO&file_suffix..xlsm;
Could someone suggest the correct approach to extract the Italian month name from a date variable within a macro context? What are the appropriate functions to use with %sysfunc for this operation?
Thank you in advance for your help!
Hello @cepp0,
Use PUTN instead of PUT with %SYSFUNC.
Also note that you can simplify your code substantially: Assuming an Italian LOCALE system option setting, you can apply the SAS-supplied NLDATEMNw. format directly to a SAS date value, so you don't need to extract the month number and create your own format for it. The SAS date value, in turn, can be a date literal such as
"&DATA_PERIO"d
So, assuming that you have this
options locale=IT_IT;
%let DATA_PERIO=31Dec2024;
you can simply define
%let MESE_TEXT = %sysfunc(putn("&DATA_PERIO"d, nldatemn));
to obtain the value Dicembre.
Or, alternatively:
%let MESE_TEXT = %sysfunc(int("&DATA_PERIO"d), nldatemn);
Hello @cepp0,
Use PUTN instead of PUT with %SYSFUNC.
Also note that you can simplify your code substantially: Assuming an Italian LOCALE system option setting, you can apply the SAS-supplied NLDATEMNw. format directly to a SAS date value, so you don't need to extract the month number and create your own format for it. The SAS date value, in turn, can be a date literal such as
"&DATA_PERIO"d
So, assuming that you have this
options locale=IT_IT;
%let DATA_PERIO=31Dec2024;
you can simply define
%let MESE_TEXT = %sysfunc(putn("&DATA_PERIO"d, nldatemn));
to obtain the value Dicembre.
Or, alternatively:
%let MESE_TEXT = %sysfunc(int("&DATA_PERIO"d), nldatemn);
And if you want Italian even if that is not your Locale setting there is an explicit format for that, ITADFMN.
Here is a simple way to check what DATE formats exist.
data date_format;
set sashelp.vformat;
where fmttype='F' and fmtinfo(fmtname,'cat')='date';
where also fmtname ^=: '$';
length min def max $100;
min=putn(date(),cats(fmtname,minw));
def=putn(date(),cats(fmtname,defw));
max=putn(date(),cats(fmtname,maxw));
keep fmtname min def max;
run;
proc print width=min;
run;
Thanks, @Tom, for the reminder.
Yes, I would say using
%let MESE_TEXT = %sysfunc(putn("&DATA_PERIO"d, itadfmn));
is even better than my suggested nldatemn, as it doesn't rely on the LOCALE setting.
It just seems that SAS discourages us from using those language-specific format names. First, they are a bit hard to find in the documentation: They are not contained in the "Dictionary of Formats" and not mentioned in the "Dictionary of Formats for NLS" either. A few occurrences (including itadfmn) can be found in the "Example" sections of the documentation of the EUR... formats such as EURDFMNw. in the appendix "Additional NLS Language Elements". But the introductory section of that appendix says:
The following EUR language elements have been replaced with NL language elements. The EUR elements are supported in SAS 9.3 [sic!], but SAS recommends that you use the NL elements.
Check out this tutorial series to learn how to build your own steps in SAS Studio.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.