Excel and HTML output in same stored Process possible? - sas

I have a stored Process which returns an Excel as Download (with long loading time because of big data). This works correct, but after download it leaves a blank page. So i want to put some html text in the blank page, best would be a loading icon before, and a "finished" information after downloading the excel. But when i use a ods html after/Before the excel output, instead of downloading the excel it puts the excel as HTML-TextOutput as well, is there a way to do both outputs in one Process?
Code Sample:
/* something like:*/
ods html body=_webout;
data _null_;
file _webout;
put '<img src="loading.gif" />';
run;
ods html close;
/*here is the Exceloutput which i use at the moment without htmloutput*/
%let RV=%sysfunc(appsrv_header(Content-type, application/vnd.ms-excel));
%let RV=%sysfunc(appsrv_header(Content-disposition,%str(attachment; filename=myExcel.xls )));
ods tagsets.excelxp file=_webout options(embedded_titles='yes' embedded_footnotes='yes'
sheet_interval='none' sheet_name='Result') ;
PROC PRINT DATA=AUSDRUCK UNIFORM NOOBS LABEL;
OPTIONS DATE NUMBER;
TITLE1"myExcel ";
VAR var1 var2 var3 var4 var5;
RUN;
ods tagsets.excelxp close;
/*and then something like:*/
ods html body=_webout;
data _null_;
file _webout;
put 'Excel download finished successfull';
run;
ods html close;

Related

Sending an email from SAS with report AND text in the body

I've created a report in SAS EG 7.2 and have got SAS to email it in the body of the email, however I can't seem to add any text. I have got this code:
filename mymail email
to=('mail#email.com')
subject='Report'
from='mail#email.com'
Content_type="text/html";
ods _all_ close;
ODS ESCAPECHAR='^';
ods html body=mymail style=minimal;
proc report data=data…
…
run;
ods html close;
ods _all_ close;
This sends my email perfectly. And I can do this to add some text
filename mymail email
to=('mail#email.com')
subject='Report'
from='mail#email.com'
Content_type="text/html";
ods _all_ close;
ODS ESCAPECHAR='^';
ods html body=mymail style=minimal;
DATA _null_;
file mymail;
Put "Hello,"//
"You are recieving this mail because:"//;
if &warn1=1 then do;
put "&w1." //; end;
if &warn2=1 then do;
put "&w2." //; end;
put
"Regards,"//
"Chris";
run;
ods html close;
ods _all_ close;
But I can't seem to do both? If I include the text step and the proc report, I only see the report in the resulting email. Any ideas?
Thanks in advance :)
If anyone is interested I managed to solve this by adding in the following line directly before the proc report:
ods html text="<div>Please find below the Reports </div> <br><br> There are &&totalwarnings. warnings for the last hour:<br><br>";
%if &warn1=1 %then %do;
ods html text="&&w1."; %end;
%if &warn2=1 %then %do;
ods html text="&&w2."; %end;
Your solution of adding the text into the HTML file itself sounds best.
Your original code has a couple of issue.
First you have an access conflict. The DATA _NULL_ step is trying to write to the same file that the ODS HTML process is still writing to. Didn't you get an error message? or perhaps two separate emails?
Second even if you succeeded in writing text into the same file as the ODS HTML was producing it would be either before or after the <HTML>..</HTML> tags around the report generated by ODS HTML. As such it would probably be ignored by the recipient.

SAS- Supress Results view on some, but not all, proc print ods outputs

I want to be able to print all of my reports to external files but only display a select few in the results viewer. In the below example I want reportA and reportB to be displayed AND printed (file.xls) but reportC to be printed to a separate file (file2.csv) and not displayed in the results viewer. Any ideas?
ods msoffice2k file="/file/file.xls";
proc print data=reportA;
run;
proc print data=reportB
run;
ods msoffice2k close;
ods csvall file="/file/file2.csv";
proc print data=reportC;
run;
ods csvall close;
You can also use ODS EXCLUDE and ODS SELECT to target specific destinations.
For example, ods html select none; will turn off the HTML destination temporarily, but not actually close it - it just won't get any results for a while. You can then use ods html select all; to turn it back on.
You can also use ods html exclude all; to do the same thing and then turn it back on with ods html exclude none;.
With either statement, you can also use a where statement in the ods select/exclude to filter to only affect one specific part of an output. See the documentation for more details.
Close the list output which is the default. OR the HTML if that is the default results window in your system. Re-open the output after the file is created.
ods msoffice2k file="/file/file.xls";
proc print data=reportA;
run;
proc print data=reportB
run;
ods msoffice2k close;
ods listing close;
ods html close;
ods csvall file="/file/file2.csv";
proc print data=reportC;
run;
ods csvall close;
ods listing;
ods html;
I actually found a better solution through using the proc export feature for suppressing display of the csv output.
ods msoffice2k file="/file/file.xls";
proc print data=reportA;
run;
proc print data=reportB
run;
ods msoffice2k close;
proc export data=reportC
outfile="/file/file2.csv"
dbms=dlm
replace;
delimiter=",";
run;
Thanks for the help #Reeza I'll keep those settings in mind for future projects.

Including syntax in SAS ODS pdf file

Is it possible to include submitted syntax or even output of log file when ODS into a PDF using SAS?
For instance, give this simple code:
ods pdf file = "c:\temp\myPDF.pdf";
proc reg data = mydata;
model y = x;
run;
ods pdf close;
I can get the regression output and accompanying graph fine. But is it possible to incorporate into PDF the enclosed command like this?
proc reg data = mydata;
model y = x;
run;
It is, but it requires a couple of hoops. Luckily, you could wrap this into macros to clean up your code.
Create a temporary fileref to hold your log.
Start your PDF and output the log to the fileref.
Write code.
Stop writing log to fileref.
Print file contents to PDF using ODF TEXT=
Hope this helps
filename x temp;
ods pdf file="c:\temp\temp.pdf";
title "Cost of Power";
options source;
proc printto log=x;
run;
proc reg data=sashelp.cars;
model msrp = horsepower;
run;
quit;
proc printto;run;
title;
ods pdf startpage=now; /*Force a new page in the PDF*/
data _null_;
infile x;
input;
call execute("ods text='LOG: "||_infile_||"';");
run;
ods pdf close;
filename x ;

How can you get titles and footnotes on the table of contents page in ods rtf output?

I would like an RTF file with a table of contents, but I also want the titles and footnotes
on the same page as the table of contents. Here is code that will produce an RTF file with a table of contents that only has one TOC line per proc report table:
data testdata;
input letters $ numbers;
cards;
A 1
B 2
C 3
;
run;
data testdata;
set testdata;
dummy=1;
run;
ods rtf FILE="test.rtf" startpage=no style=analysis CONTENTS=YES toc_data;
ods escapechar="^";
title1 j=l "This title should be on every page" j=r "Page ^{pageof}";
title2 j=l "(even the first one)";
footnote1 "This footnote should be on every page, too";
ods rtf text="{\pard\page\par}";
ods proclabel 'Test Data';
proc report nowd data=testdata contents='';
column dummy ('Test Data' letters numbers);
define dummy / group noprint;
define letters / "Letters";
define numbers / "Numbers";
break before dummy / contents='' page;
run;
ods rtf close;
How can I make it so that the titles and footnote appear on the first page with the table of contents as well as the rest of the document?
This is a hack, but it's the only way I could find to make it work. The crux of it is that we are just going to alter the RTF file that is output by SAS using some SAS programming. The key is here where I read in the file, pull out the first header and footer information, then insert a copy at the beginning of the document and output to a separate file:
data edit hf;
infile "test.rtf" dlm='09'x dsd lrecl=32767 missover;
format var $200.;
input var $;
output edit;
retain head fhead ffoot 0;
if index(var,'{\header')>0 and fhead=0 then head = 1;
if head = 1 and fhead=0 then output hf;
if index(var,'{\footer')>0 then ffoot=1;
if index(var,'\pard}}\trowd\trkeep\trql')>0 and ffoot=1 then fhead=1;
keep var;
run;
data edit1 edit2;
set edit;
retain start 0;
if index(var,'\widowctrl\')>0 then start=1;
if start=0 then output edit1;
else output edit2;
keep var;
run;
data out;
set edit1 hf edit2;
run;
data _null_;
set edit1 hf edit2;
file 'test1.rtf';
put var;
run;
Of course, there was also the date and page number that SAS puts in there automatically that I didn't want, so I updated that option before creating the original RTF file. Here is all the code together in case it helps someone in the future:
data testdata;
input letters $ numbers;
cards;
A 1
B 2
C 3
;
run;
data testdata;
set testdata;
dummy=1;
run;
options nodate nonumber;
ods rtf FILE="test.rtf" startpage=no style=analysis CONTENTS=YES toc_data;
ods escapechar="^";
title1 j=l "This title should be on every page" j=r "Page ^{pageof}";
title2 j=l "(even the first one)";
footnote1 "This footnote should be on every page, too";
ods rtf text="{\pard\page\par}";
ods proclabel 'Test Data';
proc report nowd data=testdata contents='';
column dummy ('Test Data' letters numbers);
define dummy / group noprint;
define letters / "Letters";
define numbers / "Numbers";
break before dummy / contents='' page;
run;
ods rtf close;
data edit hf;
infile "test.rtf" dlm='09'x dsd lrecl=32767 missover;
format var $200.;
input var $;
output edit;
retain head fhead ffoot 0;
if index(var,'{\header')>0 and fhead=0 then head = 1;
if head = 1 and fhead=0 then output hf;
if index(var,'{\footer')>0 then ffoot=1;
if index(var,'\pard}}\trowd\trkeep\trql')>0 and ffoot=1 then fhead=1;
keep var;
run;
data edit1 edit2;
set edit;
retain start 0;
if index(var,'\widowctrl\')>0 then start=1;
if start=0 then output edit1;
else output edit2;
keep var;
run;
data out;
set edit1 hf edit2;
run;
data _null_;
set edit1 hf edit2;
file 'test1.rtf';
put var;
run;

Suppressing HTML output in SAS

I'm trying to suppress HTML output and get PROC PRINT to output only to CSV, but ODS HTML Close doesn't seem to work.
My code is:
ODS HTML close;
ODS CSV file="\\..output folder..\filename.csv";
proc print data=test;
run;
ODS CSV close;
ODS HTML;
Your approach seems a bit odd, why resort to ods csv?
SAS has a proc export procedure:
proc export data=test outfile="\\..output folder..\filename.csv" dbms=CSV replace;
run;
You can further configure it to have a different delimiter, no headers etc.: http://support.sas.com/documentation/cdl/en/proc/61895/HTML/default/viewer.htm#a000393174.htm
EDIT
In reply to your comment: i see two ways around the issues that keep you from trying proc export.
The first approach is setting the validvarname to ANY, which gives you great liberty in choosing variable names. E.g.:
options validvarname=ANY;
data test;
'Column Header Text I Want'n=1; output;
'Column Header Text I Want'n=5; output;
run;
proc export data=test outfile="\\..output folder..\filename.csv" dbms=CSV replace;
run;
Personally, i'm not a fan of the above approach, since i find that it leads to harder-to-read code when you no longer have some naming rules for variables.
A second approach - which i prefer - is to label the variable with the text you want it to have and put the label option on your proc export. E.g.:
data test;
label variable_name='Column Header Text I want';
variable_name=1; output;
variable_name=5; output;
run;
proc export data=test outfile="\\..output folder..\filename.csv" dbms=CSV replace LABEL;
run;
Note that there is a small distinction in the output: the first approach will not put quotes around your column names while the second approach will do that.
Finally, while doing some extra reading myself, i stumbled across this, which may be of help to you as well: http://www.sascommunity.org/wiki/Create_a_CSV_file_without_column_names/headers_in_row_1#DATA_NULL_with_a_PUT_statement.2C_all_fields_quoted
I'm been trying all day and finally got it for me. What I wanted suppress from the results viewer is just below here (and the end of a macro). The results I wanted in the results viewer and now called in a separate macro at the end...
Brubumski
ODS HTML close; * bsk;
ods results off; * bsk;
ods csvall file="&file1";
proc print data=tr_outds noobs; run;
ods csvall close; * bsk;
ods results on; * bsk;
ODS HTML; * bsk;
%OdsOn1(outds,outds2,tr_outds, file1, file2); * bsk;
%mend process_input_data_10_10;
%macro OdsOn1(outds,outds2,tr_outds, file1, file2);
proc freq data=outds;tables Group_nm/missing;run;
proc freq data=outds2;tables case_id/missing;run;
proc print data=tr_outds(obs=10) noobs; run;* bsk;
ods csvall file="&file2";
proc print data=cases noobs; run;
ods csvall close;
%mend OdsOn1;
Ah, I've found out the problem. The results window will still display HTML output which will really slow the program down as ODS HTML CLOSE seems to only affect ouput to a specific file, not the results window.
In order to stop that, I should have used ODS RESULTS OFF; instead.
ODS RESULTS OFF;
ODS CSV file="\\..output folder..\filename.csv";
proc print data=test;
run;
ODS CSV close;
EDIT: It seems that ODS RESULTS cannot be turned on and off at will to cause only certain PROC PRINT statements to generate outputs. This is really annoying for me, so I'm going with Shorack's PROC EXPORT methods.