DATA Step, Macro, Functions and more

Year and month in a production process. Help needed.

Accepted Solution Solved
Reply
Frequent Contributor
Posts: 122
Accepted Solution

Year and month in a production process. Help needed.

Hi,

 

I have a process that uses previous months data for the current month's run. How can I check if the data set for previous month is avaialble?

Required data set is named in this format: File1612  othewise File<2 digit year><2 digit month>.

 

How can I check the existance of the file in the begining of a month and also the begining of a new year?

(If I dont check the year part in the begining of a new year then it will read last years data)

 

Please let me know.


Accepted Solutions
Solution
‎02-08-2017 01:32 PM
Super User
Posts: 11,343

Re: Year and month in a production process. Help needed.

Please post code in a code box using the {i} icon. It gets hard to read after after the forum strips out formatting.

Also, when debugging macros use the OPTION MPRINT so the error has a chance of appearing near the code that generated it.

 

First please examine this code:

%macro checkds(dsn);
   %global f_stat_flag;
   %let f_stat_flag= %sysfunc(exist(&dsn));
%mend;

%checkds(sashelp.class);  /* or other data set you know exists*/
%put &f_stat_flag;
%checkds(work.class);
%put &f_stat_flag;

And then alternately :

 

%macro checkds2(dsn);
    %sysfunc(exist(&dsn))
%mend;


%put %checkds2(sashelp.class);
%put %checkds2(work.class);

Proliferation of global macro variables is something to limit when possible.

 

 

Note that you have two different macro variables:

call symputx('Target_File',fname);

call symputx('TargetFile',compress(fname));

 

There is also absolutely no need for the checkds macro, use the FEXIST function in the data step:

data _null_;
   lastmonth= intnx('month',today(),-1,'B');
   put lastmonth;
   length fname $ 43;
   fname = catt('cmdr.eligy',put( lastmonth, yymmn4.));
   put fname;
   if exist (fname) then  call symputx('Target_File',fname);
   Else DO;
      put 'Previous month file not ready, so using the file prior to previous month';
      lastmonth= intnx('month',today(),-2,'B');
      fname = catt('cmdr.eligy',put( lastmonth, yymmn4.));
      call symputx('TargetFile',compress(fname));
   END;
run;

The error also is related to time of data step construction. The external macro %checkds was called when the data step was compiled not after the value of fname was constructed. Run with MPRINT and you may see some additional information.

 

View solution in original post


All Replies
Super User
Posts: 19,789

Re: Year and month in a production process. Help needed.

INTNX allows you to increment a date.

Format it according to what you need.

 

Check for existence of a dataset:

http://support.sas.com/kb/24/670.html

Super User
Posts: 11,343

Re: Year and month in a production process. Help needed.

<Rant on>

Did NO ONE pay attention to Y2k? Yet again we have 2 digit years just waiting to be a problem

</Rant off>

 

Example 1: Verifying the Existence of a Data Set 
This example verifies the existence of a data set. If the data set does not exist, then the example displays a message in the log: 

%let dsname=sasuser.houses;
%macro opends(name);
%if %sysfunc(exist(&name)) %then
   %let dsid=%sysfunc(open(&name,i));
%else %put Data set &name does not exist.;
%mend opends;
%opends(&dsname);

One question: How are you getting the date to base "previous" on?.

 

Once you have an actual date value to look for (INTNX) then use the formatted value for that date using a YYMMn4. format.

Frequent Contributor
Posts: 122

Re: Year and month in a production process. Help needed.

Thanks.

 

I am getting the previous date as of run time.

 

For eg: If I am running the process today then I am checking if last month's file is available.

Super User
Posts: 11,343

Re: Year and month in a production process. Help needed.

This may get you started.

 

data _null_;
   lastmonth= intnx('month',today(),-1,'B');
   /* replace LIB in the next line with the LIBRARY
   the data sets should be in*/
   length fname $ 43;
   fname = catt('LIB.FILE',put( lastmonth, yymmn4.));
   if exist(fname) then do; 
      put 'File found' fname;
      call symputx('TargetFile',fname);
   Else put Fname ' not found';
run;

%put &targetfile;

You could then use &targetfile whenever you need the name of that previously named data set.

 

If you are placing them into different libraries then it will be up to you to provide logic to find the library.

Frequent Contributor
Posts: 122

Re: Year and month in a production process. Help needed.

Thanks ballardw!

 

However when I run your code the 

%put &targetfile; 

is not getting resolved. 

Frequent Contributor
Posts: 122

Re: Year and month in a production process. Help needed.

I modified the code as  below but it is throwing some syntax errors.

 

options symbolgen mlogic merror;
%macro checkds(dsn);
%global f_stat_flag;

%if %sysfunc(exist(&dsn)) %then
%do;

data _null_;
call symputx('f_stat_flag',1);
run;

%end;
%else
%do;

data _null_;
call symputx('f_stat_flag',0);
run;

%end;

%mend checkds;
%checkds(&Target_File.);
%put &f_stat_flag.;
data _null_;
lastmonth= intnx('month',today(),-1,'B');
put lastmonth;
length fname $ 15;
fname = catt('cmdr.eligy',put( lastmonth, yymmn4.));
put fname;
call symputx('Target_File',fname);
%put &target_file.;
%checkds(&Target_File.);
if &f_stat_flag.='1' then
do;
put 'File found' fname;
END;
Else
DO;
put 'Previous month file not ready, so using the file prior to previous month';
lastmonth= intnx('month',today(),-2,'B');
length fname $ 43;
fname = catt('cmdr.eligy',put( lastmonth, yymmn4.));
call symputx('TargetFile',compress(fname));
END;
run;
%put &target_file.;
%put &f_stat_flag.;

 

eg:  if &f_stat_flag.='1' then
      if &f_stat_flag.='1' then
--
180
ERROR 180-322: Statement is not valid or it is used out of proper order.

Solution
‎02-08-2017 01:32 PM
Super User
Posts: 11,343

Re: Year and month in a production process. Help needed.

Please post code in a code box using the {i} icon. It gets hard to read after after the forum strips out formatting.

Also, when debugging macros use the OPTION MPRINT so the error has a chance of appearing near the code that generated it.

 

First please examine this code:

%macro checkds(dsn);
   %global f_stat_flag;
   %let f_stat_flag= %sysfunc(exist(&dsn));
%mend;

%checkds(sashelp.class);  /* or other data set you know exists*/
%put &f_stat_flag;
%checkds(work.class);
%put &f_stat_flag;

And then alternately :

 

%macro checkds2(dsn);
    %sysfunc(exist(&dsn))
%mend;


%put %checkds2(sashelp.class);
%put %checkds2(work.class);

Proliferation of global macro variables is something to limit when possible.

 

 

Note that you have two different macro variables:

call symputx('Target_File',fname);

call symputx('TargetFile',compress(fname));

 

There is also absolutely no need for the checkds macro, use the FEXIST function in the data step:

data _null_;
   lastmonth= intnx('month',today(),-1,'B');
   put lastmonth;
   length fname $ 43;
   fname = catt('cmdr.eligy',put( lastmonth, yymmn4.));
   put fname;
   if exist (fname) then  call symputx('Target_File',fname);
   Else DO;
      put 'Previous month file not ready, so using the file prior to previous month';
      lastmonth= intnx('month',today(),-2,'B');
      fname = catt('cmdr.eligy',put( lastmonth, yymmn4.));
      call symputx('TargetFile',compress(fname));
   END;
run;

The error also is related to time of data step construction. The external macro %checkds was called when the data step was compiled not after the value of fname was constructed. Run with MPRINT and you may see some additional information.

 

Frequent Contributor
Posts: 122

Re: Year and month in a production process. Help needed.

Thank you so much for the solution!

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 8 replies
  • 120 views
  • 0 likes
  • 3 in conversation