Return to Snippet

Revision: 33735
at October 12, 2010 22:04 by sastechies


Updated Code
%macro recsinds(table,macvar);                                        
/*----------------------------------------------------------------------
  this macro can be used to get the count of observations in a dataset  
  into a macrovariable that you give.                                   

  usage: %recsinds(sashelp.class,macvar);                               
                                                                        
  &macvar is the observation count of your dataset                      
 ----------------------------------------------------------------------*/                                                                       

     %global &macvar;                                                   
     %local handle rc;                                                  
     %let handle = %sysfunc(open(&table)); /* open the table */         
     %if &handle %then                                                  
         %do;                                                           
        /* get the observation count into the macvar macro variable */  
            %let &macvar = %sysfunc(attrn(&handle, nlobs));             
             %let rc = %sysfunc(close(&handle)); /* close the dataset */
      %end;                                                             
     /* write the record count to the log */                            
      %put recsinds &table: &&&macvar.    &macvar=&&&macvar.;           
                                                                        
%mend recsinds; 

%macro SearchErrorsWarnings(strg,loc,dsx,mm=1);
* mm=# of lines to display before and after target lines. mm=0,1,2 ...etc.;

filename dd "&loc.\&dsx.";
%global nnn;  *nnn=# of records in dsx;

data aa (keep= filen arrow linum xx);
	infile dd length=ln end=last;
	length llprted pthru 8 arrow $3 xx $120 filen $400;
	retain llprted pthru 0;
	*LLPRTed:line # of Last Line Printed; * PThru: to be line # of the last of: * the 2mm+1 lines to be displayed;
	length %do jj=1 %to &mm; x&jj %end;	XT $ 120;
	retain filen XT ' ' %do jj=1 %to &mm; x&jj %end;;;

	filen="&dsx.";

	* These store the mm lines that are; * to be printed prior to a Find; * Next save these mm lines;
	%do jj=%eval(&mm-1) %to 1 %by -1;
		x%eval(&jj+1)=x&jj;;
	%end;

	x1=XT;
	input XT $varying120. ln;
	XT=upcase(XT);
	if index (XT,"THE SAS SYSTEM")>0 then delete;
	if index (XT,upcase("&strg"))>0 then 
    do;
		filen="========================================";linum=.; arrow='====='; xx='========================================================================================';
		output;
		filen="&dsx."; arrow='';

		* Found one!; 	* Insert a blank line between finds; 	* provided the scopes of two finds ; 	* do not overlap;
		if (_n_ > pthru + &mm + 1) & pthru > 0
		then 
		 do;
			filen="========================================";linum=.; arrow='====='; xx='========================================================================================';
			output;
			filen="&dsx."; arrow='';
		 end;
		*Output mm lines preceding the find;
		%do jj=&mm %to 1 %by -1;
			if &jj<_n_ - pthru then 
		    do;
				xx=x&jj;
				linum=_n_ - &jj;
				output;
			end;
		%end;
		linum=_n_;
		xx=XT;
		if &mm > 0 then arrow="-->";
		llprted=_n_;
		output; * Output the Found line; 		

		* Compute pthru, the line # of the ;		* last line of the scope so that the;		* next mm lines can be printed;
		pthru=_n_+&mm;
		arrow=' ';
	end;
else 
	do;
		if _n_<=pthru then 
		do;
			linum=_n_;
			xx=XT;
			output;
			* Outputting the next mm lines;
		end;
	end;
if last then call symput('nnn',left(put(_n_,5.)));
run;

proc append base=allout data=aa; run;
%mend SearchErrorsWarnings;

%macro ReportErrorsWarnings(searchstr,searchloc,searchfiles,outfile,lines2display);

proc sql;
drop table allout;
drop table aa;
drop table new;
quit;

%let dircmd0=%nrbquote(%str(dir /b /s %")%str(&searchloc.\&searchfiles.)%str(%")); 
FILENAME rootloc pipe "&dircmd0";   

/*data _null_; run;*/
data new;
length file $ 1000;
infile rootloc;
input file;
cnt=count(file,"\");
file=translate(file,' ','\');
file=scan(file,cnt+1,' ');
call symput(compress('filen'||_N_),file);
run; 

%recsinds(new,nobs);
%if &nobs gt 0 %then %do;
	%do k=1 %to &nobs;
	%SearchErrorsWarnings(&searchstr.,&searchloc.,&&filen&k.,mm=&lines2display.);
	%end;

	data allout;
	retain filen linum arrow xx;
	set allout;
	run;

	data _null_;
	file "&outfile." lrecl=32767; 
	set allout;
	if _n_ =1 then 
	do; 
		put "FILENAME" '09'x "LINE #" '09'x "ARROW" '09'x "MESSAGE";
		put "*****************************************************************************************************";
	end;
	put filen '09'x linum '09'x arrow '09'x xx '09'x;
	run;
%end;
%else 
%do;
	%put ==================;
	%put NO LOGS TO PROCESS;
	%put ==================;
%end;

%mend ReportErrorsWarnings;


%let LogLoc=C:\SASDATA;
%let cyle_runtime=10OCT2010102001;

proc printto log="&LogLoc.\example1_&cyle_runtime..log"; run;

DATA example1;
INPUT ID $ 1 SBP 2-4 DBP 5-7 GENDER $ 8 AGE 9-10 WT 11-13;
DATALINES;
1120 80M15115
2130 70F25180
3140100M89170
4120 80F30150
5125 80F20110
;
RUN;
PROC MENS;
RUN;
proc printto; run;
 
proc printto log="&LogLoc.\example2_&cyle_runtime..log"; run;
DATA CDS2;
     INPUT @1 CATEGORY $9. @10 NUMBER 3.;	 
DATALINES;
JAZZ     252
POP       49
CLASSICAL 59
RAP       21
GOSPEL    44
JAZZ      21
;
run;
ODS RTF;
PROC FREQ DATA=CDS ORDER=FREQ; WEIGHT NUMBER;
  TITLE3 'READ IN SUMMARIZED DATA';
  TABLES CATEGORY;
RUN;
proc printto; run;

%ReportErrorsWarnings(ERROR:,&LogLoc.,*_&cyle_runtime..log,&LogLoc.\error_&cyle_runtime..txt,2);

Revision: 33734
at October 12, 2010 21:59 by sastechies


Initial Code
%macro recsinds(table,macvar);                                        
/*----------------------------------------------------------------------
  this macro can be used to get the count of observations in a dataset  
  into a macrovariable that you give.                                   

  usage: %recsinds(sashelp.class,macvar);                               
                                                                        
  &macvar is the observation count of your dataset                      
 ----------------------------------------------------------------------*/                                                                       

     %global &macvar;                                                   
     %local handle rc;                                                  
     %let handle = %sysfunc(open(&table)); /* open the table */         
     %if &handle %then                                                  
         %do;                                                           
        /* get the observation count into the macvar macro variable */  
            %let &macvar = %sysfunc(attrn(&handle, nlobs));             
             %let rc = %sysfunc(close(&handle)); /* close the dataset */
      %end;                                                             
     /* write the record count to the log */                            
      %put recsinds &table: &&&macvar.    &macvar=&&&macvar.;           
                                                                        
%mend recsinds; 

%macro SearchErrorsWarnings(strg,loc,dsx,mm=1);
* mm=# of lines to display before and after target lines. mm=0,1,2 ...etc.;

filename dd "&loc.\&dsx.";
%global nnn;  *nnn=# of records in dsx;

data aa (keep= filen arrow linum xx);
	infile dd length=ln end=last;
	length llprted pthru 8 arrow $3 xx $120 filen $400;
	retain llprted pthru 0;
	*LLPRTed:line # of Last Line Printed; * PThru: to be line # of the last of: * the 2mm+1 lines to be displayed;
	length %do jj=1 %to &mm; x&jj %end;	XT $ 120;
	retain filen XT ' ' %do jj=1 %to &mm; x&jj %end;;;

	filen="&dsx.";

	* These store the mm lines that are; * to be printed prior to a Find; * Next save these mm lines;
	%do jj=%eval(&mm-1) %to 1 %by -1;
		x%eval(&jj+1)=x&jj;;
	%end;

	x1=XT;
	input XT $varying120. ln;
	XT=upcase(XT);
	if index (XT,"THE SAS SYSTEM")>0 then delete;
	if index (XT,upcase("&strg"))>0 then 
    do;
		filen="========================================";linum=.; arrow='====='; xx='========================================================================================';
		output;
		filen="&dsx."; arrow='';

		* Found one!; 	* Insert a blank line between finds; 	* provided the scopes of two finds ; 	* do not overlap;
		if (_n_ > pthru + &mm + 1) & pthru > 0
		then 
		 do;
			filen="========================================";linum=.; arrow='====='; xx='========================================================================================';
			output;
			filen="&dsx."; arrow='';
		 end;
		*Output mm lines preceding the find;
		%do jj=&mm %to 1 %by -1;
			if &jj<_n_ - pthru then 
		    do;
				xx=x&jj;
				linum=_n_ - &jj;
				output;
			end;
		%end;
		linum=_n_;
		xx=XT;
		if &mm > 0 then arrow="-->";
		llprted=_n_;
		output; * Output the Found line; 		

		* Compute pthru, the line # of the ;		* last line of the scope so that the;		* next mm lines can be printed;
		pthru=_n_+&mm;
		arrow=' ';
	end;
else 
	do;
		if _n_<=pthru then 
		do;
			linum=_n_;
			xx=XT;
			output;
			* Outputting the next mm lines;
		end;
	end;
if last then call symput('nnn',left(put(_n_,5.)));
run;

proc append base=allout data=aa; run;
%mend SearchErrorsWarnings;

%macro ReportErrorsWarnings(searchstr,searchloc,searchfiles,outfile);

proc sql;
drop table allout;
drop table aa;
drop table new;
quit;

%let dircmd0=%nrbquote(%str(dir /b /s %")%str(&searchloc.\&searchfiles.)%str(%")); 
FILENAME rootloc pipe "&dircmd0";   

/*data _null_; run;*/
data new;
length file $ 1000;
infile rootloc;
input file;
cnt=count(file,"\");
file=translate(file,' ','\');
file=scan(file,cnt+1,' ');
call symput(compress('filen'||_N_),file);
run; 

%recsinds(new,nobs);
%if &nobs gt 0 %then %do;
	%do k=1 %to &nobs;
	%SearchErrorsWarnings(&searchstr.,&searchloc.,&&filen&k.,mm=2);
	%end;

	data allout;
	retain filen linum arrow xx;
	set allout;
	run;

	data _null_;
	file "&outfile." lrecl=32767; 
	set allout;
	if _n_ =1 then 
	do; 
		put "FILENAME" '09'x "LINE #" '09'x "ARROW" '09'x "MESSAGE";
		put "*****************************************************************************************************";
	end;
	put filen '09'x linum '09'x arrow '09'x xx '09'x;
	run;
%end;
%else 
%do;
	%put ==================;
	%put NO LOGS TO PROCESS;
	%put ==================;
%end;

%mend ReportErrorsWarnings;


%let LogLoc=C:\SASDATA;
%let cyle_runtime=10OCT2010102001;

proc printto log="&LogLoc.\example1_&cyle_runtime..log"; run;

DATA example1;
INPUT ID $ 1 SBP 2-4 DBP 5-7 GENDER $ 8 AGE 9-10 WT 11-13;
DATALINES;
1120 80M15115
2130 70F25180
3140100M89170
4120 80F30150
5125 80F20110
;
RUN;
PROC MENS;
RUN;
proc printto; run;
 
proc printto log="&LogLoc.\example2_&cyle_runtime..log"; run;
DATA CDS2;
     INPUT @1 CATEGORY $9. @10 NUMBER 3.;	 
DATALINES;
JAZZ     252
POP       49
CLASSICAL 59
RAP       21
GOSPEL    44
JAZZ      21
;
run;
ODS RTF;
PROC FREQ DATA=CDS ORDER=FREQ; WEIGHT NUMBER;
  TITLE3 'READ IN SUMMARIZED DATA';
  TABLES CATEGORY;
RUN;
proc printto; run;

%ReportErrorsWarnings(ERROR:,&LogLoc.,*_&cyle_runtime..log,&LogLoc.\error_&cyle_runtime..txt);

Initial URL
http://sastechies.blogspot.com/2010/10/sas-macros-to-search-and-report-errors.html

Initial Description


Initial Title
SAS Macros to Search and Report Errors and Warnings from your SAS Logs

Initial Tags
search

Initial Language
SAS