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

%let Today=%sysfunc(inputn(&sysdate9.,date9.)); 
%put &Today;

%let todayM=%sysfunc(month(&today.)); 
%put &todayM;

%let todayD=%sysfunc(day(&today.));
%put &todayD;

%let todayY=%sysfunc(year(&today.));
%put &todayY;

                      

%let StartRW=%eval(&today. - 180);
%put &startRw;

LOG:
191  %let Today=%sysfunc(inputn(&sysdate9.,date9.));
SYMBOLGEN:  Macro variable SYSDATE9 resolves to 27JUN2019
192  %put &Today;
SYMBOLGEN:  Macro variable TODAY resolves to 21727
21727
193  %let todayM=%sysfunc(month(&today.));
SYMBOLGEN:  Macro variable TODAY resolves to 21727
194  %put &todayM;
SYMBOLGEN:  Macro variable TODAYM resolves to 6
6
195  %let todayD=%sysfunc(day(&today.));
SYMBOLGEN:  Macro variable TODAY resolves to 21727
196  %put &todayD;
SYMBOLGEN:  Macro variable TODAYD resolves to 27
27
197
198  %let todayY=%sysfunc(year(&today.));
SYMBOLGEN:  Macro variable TODAY resolves to 21727
199  %put &todayY;
SYMBOLGEN:  Macro variable TODAYY resolves to 2019
2019
200  %let YearsELW=3;
201  %let nDays18M=%sysfunc(round(365.25*1.5));
202  %let StartRW=%eval(&today. - 180);
SYMBOLGEN:  Macro variable TODAY resolves to 21727
203  %put &startRw;
SYMBOLGEN:  Macro variable STARTRW resolves to 21547
21547

Program 2 with data cut date:
%let start=2019-01-31;
%let Today=%sysfunc(inputn(&start.,yymmdd10.),date9.); 
%put &Today;

LOG-Program2

204  %let start=2019-01-31;
205  %let Today=%sysfunc(inputn(&start.,yymmdd10.),date9.);
SYMBOLGEN:  Macro variable START resolves to 2019-01-31
206  %put &Today;
SYMBOLGEN:  Macro variable TODAY resolves to 31JAN2019
31JAN2019
207  %let todayM=%sysfunc(month(&today.));
SYMBOLGEN:  Macro variable TODAY resolves to 31JAN2019
ERROR: Argument 1 to function MONTH referenced by the %SYSFUNC or %QSYSFUNC macro function is not a
       number.
ERROR: Invalid arguments detected in %SYSCALL, %SYSFUNC, or %QSYSFUNC argument list.  Execution of
       %SYSCALL statement or %SYSFUNC or %QSYSFUNC function reference is terminated.
208  %put &todayM;
SYMBOLGEN:  Macro variable TODAYM resolves to .

Program 3 logfile:
227  %let Today='31jan2019'd;
228  %put &Today;
SYMBOLGEN:  Macro variable TODAY resolves to '31jan2019'd
'31jan2019'd
229
230  %let todayM=%sysfunc(month(&today.));
SYMBOLGEN:  Macro variable TODAY resolves to '31jan2019'd
231  %put &todayM;
SYMBOLGEN:  Macro variable TODAYM resolves to 1
1
232
233  %let todayD=%sysfunc(day(&today.));
SYMBOLGEN:  Macro variable TODAY resolves to '31jan2019'd
234  %put &todayD;
SYMBOLGEN:  Macro variable TODAYD resolves to 31
31
235
236  %let todayY=%sysfunc(year(&today.));
SYMBOLGEN:  Macro variable TODAY resolves to '31jan2019'd
237  %put &todayY;
SYMBOLGEN:  Macro variable TODAYY resolves to 2019
2019
238
239
240
241  %let StartRW=%eval(&today. - 180);
SYMBOLGEN:  Macro variable TODAY resolves to '31jan2019'd
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand
       is required. The condition was: '31jan2019'd - 180
242  %put &startRw;
SYMBOLGEN:  Macro variable STARTRW resolves to


Hi,

I am not able to figure out what i am doing wrong here. I have attached 2 program with logfile. The first program is the original program where the today's date is system date converted into date9 format and in program 2 when i am trying to pass data cut off date(31jan2019) and trying to convert it into date9 format then i am getting above error. I tried to pass the date in 3rd program as '31jan2019'd and its working fine when i am extracting day . month and year but when i am trying to substract 90 days from todays date then it give's me an error.

Can you pl help me what step i am following wrong.

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Your first program is converting the DATE style formatted string into the number of days that SAS uses to store such a date.

Your second program is converting YMD style formatted string into a DATE style formatted string. 

Why not just leave it as the raw number of days like the first program did?

%let start=2019-01-31;
%let Today=%sysfunc(inputn(&start.,yymmdd10.));
%put &Today;

If you want to use that value as a DATE then either repeat the first step of your first program.

%let start=2019-01-31;
%let Today_date9=%sysfunc(inputn(&start.,yymmdd10.),date9.); 
%let Today=%sysfunc(inputn(&Today_date9,date9.));

Or since its value is in a format that the DATE informat can read you can use it as a date literal by adding quotes and the letter D.

%let Today="&Today_date9"d ;

Note that you cannot use values that are formatted for other date informats as date literals, just values that the DATE informat can read. To convert other style strings into actual date values you need to read them with the right informat, like in your first step of the second program.

 

View solution in original post

5 REPLIES 5
ballardw
Super User

You are getting error because you created a value that is not a valid number an then attempt to use it as a number.

Examine this part of your log:

%put &Today;
SYMBOLGEN:  Macro variable TODAY resolves to 31JAN2019
31JAN2019
207  %let todayM=%sysfunc(month(&today.));
SYMBOLGEN:  Macro variable TODAY resolves to 31JAN2019
ERROR: Argument 1 to function MONTH referenced by the %SYSFUNC or %QSYSFUNC macro function is not a
       number.
ERROR: Invalid arguments detected in %SYSCALL, %SYSFUNC, or %QSYSFUNC argument list.  Execution of
       %SYSCALL statement or %SYSFUNC or %QSYSFUNC function reference is terminated.

At the point that you make the macro variable today = 31jan2091 it can no longer be manipulated as a date value because it is text, not the SAS numeric value that corresponds to a given date.

Any time you want to use any of the date manipulation functions the value must be a valid SAS date numeric value.

%let Today=%sysfunc(inputn(&start.,yymmdd10.),date9.); 

creates a value of TODAY that can no longer be treated as numeric. the quoted form with suffixed D is a date literal. The quotes and the D tell SAS that you want to treat the string as SAS date value. If not present then it is a simple string and creates the errors.

 

Personally this many date related manipulations would likely be better performed in a data step and use CALL SYMPUTX to create macro variables, if actually needed. I personally get tired of typing %sysfunc() easily and especially so when nested functions may needed.

 

jeetendersinghc
Fluorite | Level 6
Thanks ballardw. will try to store data cut off date in macro using data step.
ballardw
Super User
A rough rule of thumb: If you need to use a date value, such as in a WHERE or IF statement comparing to a SAS date value or manipulate with the functions like INTNX, YEAR, MONTH, etc. then likely better to leave the value as the numeric representation. If you need the text value such as in a TITLE or some text that people read then create a text version. Computers don't mind making two separate variables so you don't need to switch back-and-forth. Also quotes can be pretty problematic as part of macro variables for a lot of uses. If you forget that a variable contains quotes and then use "&macrovar." for use then you can generate errors because the result the processor creates ends up looking like "" text "" (those are two double quotes)
Tom
Super User Tom
Super User

Your first program is converting the DATE style formatted string into the number of days that SAS uses to store such a date.

Your second program is converting YMD style formatted string into a DATE style formatted string. 

Why not just leave it as the raw number of days like the first program did?

%let start=2019-01-31;
%let Today=%sysfunc(inputn(&start.,yymmdd10.));
%put &Today;

If you want to use that value as a DATE then either repeat the first step of your first program.

%let start=2019-01-31;
%let Today_date9=%sysfunc(inputn(&start.,yymmdd10.),date9.); 
%let Today=%sysfunc(inputn(&Today_date9,date9.));

Or since its value is in a format that the DATE informat can read you can use it as a date literal by adding quotes and the letter D.

%let Today="&Today_date9"d ;

Note that you cannot use values that are formatted for other date informats as date literals, just values that the DATE informat can read. To convert other style strings into actual date values you need to read them with the right informat, like in your first step of the second program.

 

jeetendersinghc
Fluorite | Level 6
Thanks Tom. It's solve my purpose.

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!
Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 5 replies
  • 2978 views
  • 0 likes
  • 3 in conversation