Sending an ALERT using ODS in SAS - sas

I'm trying to send an alert only if a macro variable value is not 0 and another alert all times, both in same script.
I want to send this only if variable value is not 0.
filename myfile1 email To=&ToAddress
subject="ALERT for &tday." TYPE="text/html";
ODS LISTING CLOSE;
ODS HTML BODY=myfile1 style=BarrettsBlue;
OPTIONS NOCENTER LINESIZE=256;
Proc print data=Counts_6days noobs label;
title "monitoring by Score Date";
run;
ODS html close;
ods listing;
I want to send this all times.
filename myfile email To=&ToAddress
subject="monitoring for &tday." CONTENT_TYPE="text/html";
ODS LISTING CLOSE;
ODS HTML BODY=myfile style=BarrettsBlue;
OPTIONS NOCENTER LINESIZE=256;
Proc print data=COUNTS noobs label;
title "monitoring by Score Date";
run;
ODS HTML CLOSE;
ODS LISTING;

In SAS conditional macro statements need to be wrapped in a macro. For example:
%macro example(arg);
%if &arg. ~= 0 %then %do;
/* Your conditional code here */
%end;
%mend example;
%let var = 0;
%example(&var.)
This code creates a macro called %example which expects one parameter. The macro is called with %example(), at which point it evaluates the code inside the macro. The %if %then %do; %end; block allows you to choose whether some code is run or not based upon whether the condition evaluates to true or false.
In your case you could wrap your first block in a macro similar to this, while leaving the second block outside.

Related

Conditional Formatting in SAS with Macros

Hi I'm trying to apply conditional formatting to a table in SAS. The conditional formatting will be highlighting data in columns (variables). If the field is "Y" then highlight green, else if the field is "N" then red.
The input table looks like this:
My goal is to have it looks something like this
I currently have this code in my macro:
%LET NVARS= 6;
%LET to_date= '01SEP2022'd;
%macro cf();
PROC REPORT DATA=work.process /*the data set input */ OUT=work.test1;
COLUMN SKU HIGH PRI COST_CTR
%DO i = 1 %TO &NVARS.;
SUPPORT&i.
%END;
%DO i =1 %TO &NVARS.;
DEFINE SUPPORT&i. / DISPLAY
STYLE (column)={just=center};
%END;
%DO i =1 %TO &NVARS.;
COMPUTE SUPPORT&i.;
IF SUPPORT&i. ='Y' THEN CALL DEFINE (_col_,'style','style={background=vilg}');
IF SUPPORT&i. ='N' THEN CALL DEFINE (_col_,'style','style={background=viypk}');
ENDCOMP;
%END;
RENAME
%DO i =1 %TO &NVARS.;
SUPPORT&i. = %SYSFUNC(INTNX(month,&to_date.,&I-1),monyy7)
%END;
RUN;
%MEND;
%cf();
For some reason it's erroring out and not doing the conditional formatting. I then want to export the output in excel. Any help is greatly appreciates from SAS gurus.
Personally, I would use PROC PRINT to do this instead of PROC REPORT.
Create a format to format Y as green, N as red
Use PROC PRINT to display information
Create labels dynamically instead of rename to display the months name dynamically.
Use ODS EXCEL to pipe the formatted output including colours directly to Excel (tested and it works).
proc format;
value $ support_fmt
'Y' = 'vilg'
'N' = 'viypk';
run;
ods excel file = '/home/fkhurshed/Demo1/demo.xlsx';
%macro cf;
%LET NVARS= 6;
%LET to_date= '01SEP2022'd;
proc print data=have label noobs;
var sku high_pri cost_ctr ;
var support1-support6 / style={background=$support_fmt.};
%do i=1 %to &nvars;
label support&i. = %sysfunc(intnx(month, &to_date, %eval(&i-1)), monyy7.);;
%end;
run;
%mend;
%cf;
ods excel close;

Execute proc step only if it doesn't cause log error (inside macro) SAS

I'm trying to test different covariance structures inside macro with Proc Mixed.
%macro cov(type);
proc mixed data=tmp order=data;
class sub trt visit;
model var = trt visit trt*visit / S cl;
repeated visit /subject=sub type=&type.;
FitStatistics=min_var_&type.;
run;
%mend;
Some of the covariance structures I need to fit in model causes errors and I'm trying to find a way to execute this proc mixed statement only, if it doesn't cause error with value of &type.
I have been working with %sysfunc and but haven't been able to resolve this yet.
%IF %SYSFUNC(EXIST(min_var_&type.)) %THEN %DO;
data help_&type.;
set min_var_&type.;
run;
%end;
This produces these datasets correctly, but still log errors exists in log for those macro variables that can not be fitted.
You can redirect the log to a file like that :
filename logfile "\\SERVER\LOG\mylog.log";
proc printto log=logfile new;
run;
And then when your PROC MIXED is finished, you can filter on the log file for the string "ERROR" :
....YOUR PROC MIXED...
/*come back to normal log*/
proc printto;
run;
/*check the log file*/
DATA CHECKLOG;
LENGTH ROWS $200;
LABEL ROWS = 'Messages from LOG';
INFILE "\\SERVER\LOG\mylog.log" TRUNCOVER;
INPUT ROWS &;
LINE = _N_;
IF SUBSTR(ROWS,1,5)='ERROR' /*OR SUBSTR(ROWS,1,7)='WARNING'*/ THEN
OUTPUT;
RUN;
You will have all the ERROR and (or WARNING if needed) in a dataset.
Then you have to check if the table is empty.
If YES, you can continue your script.
You can do it via this method
proc sql;
select * from checklog;
run;
%put n=&sqlobs;
If sqlobs is greater than 0, then you have errors.
You can check the sqlobs via a macro function like this :
%macro checklog;
proc sql;
select * from checklog;
run;
%if (&sqlobs>0) %then ...
%else ...
%mend checklog;

SAS Proc Report Title Error

I have an issue where by the do loop creates my reports however the title page where the macro is listed doesn't reflect the correct naming convention each time.
It works for each of the bookmarks in PDF as well as the proc report itself. However the titles don't reflect correctly.
%macro PDF_T2(year=, age= );
proc sql noprint;
select distinct region, bh_type
into :region1 - :region14, :bh_type1 - :bh_type14
from table2_IP
;
quit;
/*%put &region1 &region2;*/
/*%put &bh_type1 &bh_type2;*/
ods escapechar '^';
ods pdf file="C:\PDFS\Table2.pdf" pdftoc=2 style=Custom;
options orientation=landscape missing=' '
topmargin=.25in
bottommargin=.25in
leftmargin=.25in rightmargin=.25in ;
ods proclabel " Inpatient Analysis By Plan ";
%do i=1 %to 4;
TITLE "^{style [JUST= C ]Table 2. Inpatient Utilization By Plan,}";
TITLE2 "^{style [JUST= C ]&&region&i. }" ;
Title3 "^{style [JUST= C ]Adult (21 to 64)}";
Title4 "^{style [JUST= C ]&&bh_type&i. Analysis}" ;
PROC REPORT DATA = Table2_IP contents="&&bh_type&i. Table: Inpatient`enter code here`
I would try making sure that you are using %local macro variables. If you have global macro variables floating around that could cause some surprising results.
I would also turn on MPRINT and look at the log to see what code is being generated. It will show the TITLE statements that the macro is generating.
Titles do not clear themselves, but every time your TITLE statement executes it will clear any existing titles.
I modified your code a bit to work on sashelp.prdsale, and it seems fine:
%macro titletest(dummy);
%local i region1 region2;
proc sql noprint;
select distinct region
into :region1 - :region2
from sashelp.prdsale
;
quit;
%put region1=&region1 region2=&region2;
%do i=1 %to 2;
title1 "Results for &&region&i";
proc print data=sashelp.prdsale;
where region="&&region&i";
run;
title1;
%end;
%mend;
options mprint;
%titletest()

SAS-Writing Multiple Tables to one XLSX Workbook w/ 2 tables per sheet

I am new to SAS and am having some issues exporting data. I have written a macro to generate some summary tables based on a certain ID. The macro creates two tables for each ID identified in a particular proc sql query. I can write out the last two tables but it overwrites all tables. I was wondering if there is a way to generate one sheet, containing the two summary tables, for each ID identified in my query. Below is the code I have to date for exporting data:
%macro output(x);
ods tagsets.excelxp file="W:\user\test.xls" options(sheet_interval='none');
proc print data=prov_&x;
run;
proc print data=prov_revcd_&x;
run;
ods tagsets.excelxp close;
%mend;
/*Run a loop for each IDcode. Each code will enter the document generation loop*/
%macro loopit(mylist);
%let else=;
%let n = %sysfunc(countw(&mylist)); /*let n=number of codes in the list*/
data
%do I=1 %to &n;
%let val = %scan(&mylist,&I); /*Let val= the ith code in the list*/
%end;
%do j=1 %to &n;
%let val = %scan(&mylist,&j); /*Let val= the jth code in the list*/
/*Run the macro loop to generate the required tables*/
%runtab(&val);
%output&val);
%end;
run;
%mend;
/*Run the macro loop over the list of significant procedure code values*/
%loopit(&varlist);
Any help for correcting this issue would be greatly appreciated! Thanks!
I would rewrite %output like so.
%macro output(x);
ods tagsets.excelxp options(sheet_interval='none' sheet_name="&x");
proc print data=prov_&x;
run;
proc print data=prov_revcd_&x;
run;
%mend;
Then as Reeza suggests put the original ods tagsets.excelxp file= ... and close outside the whole macro.
ods tagsets.excelxp file="c:\temp\test.xlsx";
%loopit(&varlist)
ods tagsets.excelxp close;
If you use PROC EXPORT, that does allow apending to a workbook without this step (and no ODS at al).
%macro output(x);
proc export data=prov_&x outfile="c:\temp\test.xlsx" dbms=excel replace;
sheet="&x._prov";
run;
%mend;
However, this only allows one dataset per sheet - so either you append them together first as a single dataset, or you use 2 sheets in this solution.
Move the ods tagsets.excelxp file= and ods tagsets.excelxp close to outside of the macro otherwise you're recreating the file each time.
You may want to explicitly name the sheets as well.

Opening SAS datasets for viewing from within a .sas program

Is there a way to open a SAS dataset for viewing (i.e., in the "ViewTable" window) from within a .sas file?
I think this will do what you want:
dm log "vt sashelp.air";
Just change the "sashelp.air" part to your lib.table combo.
dw.mackie's answer is right on the money. That works great when submitted from the SAS editor window.
But I just want to caution you to be careful if you attempt it in batch mode (that is, having SAS run a .sas program directly from command-line using the -sysin option). It will indeed attempt to pop open the interactive SAS window environment upon execution.
But, if your batch code also attempts to build some graphs/charts, you'll be required to use the -noterminal option. And the -noterminal option isn't compatible with the dm command. You'd spot it right away in the log, but I just wanted to give you a heads-up.
Because of the size of some of my datasets I just do a simple proc print and limit the output to only 50 observations. I do this so often that I created the following macro that dumps the output to a html file.
%Macro DPrt(Dset, obs=50, vars=, w=, Path="C:\output\");
%LET BKPATH = &Path;
%PUT BKPATH= &BKPATH;
options obs = &obs.;
title;
ods listing close;
ods html
path = &BKPATH.
body = "Debug-&Dset..htm"
style = THEME;
proc print data = &Dset n u split=' ';
%if &vars NE %THEN %DO;
var &vars.;
%END;
%if &w NE %THEN %DO;
&w;
%END;
Run;
ods html close;
ods listing;
options obs = MAX;
%Mend Dprt;
Sample call for dataset test looks like
%dprt(test)