*
;
/**************************************************************/
/* This program generates an HMTL table from a SAS data set */
/* There are two separate "files" included. */
/* */
/* 1. HTMLTAB.SAS - This is the SAS code. */
/* 2. TEST1.HTML - This is the HTML file that is created */
/* */
/**************************************************************/
[HTMLTAB.SAS]
/******************************************************************/
/* HTMLTAB Generate an HTML table from a SAS data set; */
/* */
/* Author: Michael Friendly ; */
/* Revised: Mon May 20 12:18:17 EDT 1996 */
/* Version 1.0; */
/* -- made macro name/file name the same for autocall use; */
/* -- fixed bug where column labels were not ordered properly; */
/* -- Added where= option to select observations */
/* -- Added by= option for multiple tables */
/******************************************************************/
%macro htmltab(
data=_last_, /* name of input dataset */
where=, /* where clause, use where=%str(var=val) */
by=, /* separate tables for each by value */
out=FILE, /* output fileref: FILE, PRINT, STDOUT */
outfile=, /* name of output HTM[L] file */
tmpfile=table, /* name of temp file */
tabid=&data, /* table NAME= attribute */
id=, /* ID variable, or _NULL_ */
vars=, /* list of variables to be printed */
caption=, /* table caption text */
tattrib=BORDER, /* attributes */
colspec=, /* list of column alignments and widths [not used]*/
ls=80, /* output linesize */
htmlver=3 /* HTML table style */
);
/* Output is either to a file (fileref HTMLOUT) or to the listing */
/* (fileref PRINT). If FILE, try to assign default name based on */
/* operating system. Not very general here (due to wide variety of */
/* values that &sysscp can take on); */
%if %nrbquote(&out)=FILE %then %do;
%if &outfile eq %str() %then %do;
%if &sysscp = WIN
%then %let outfile = table.htm;
%else %let outfile = table.html;
%put NOTE: Output File Name was not specified, so writing to
&outfile.;
%end;
filename htmlout "&outfile";
%let out=htmlout;
%end;
%if &htmlver < 3 %then %do;
/*------------------------------------------------------- */
/* -- HTML 2: Use ,
around proc print results; */
/*------------------------------------------------------- */
%tempfile(&tmpfile,&ls);
proc printto new print=table;
options nocenter nodate ls=&ls;
proc print data=&data label;
%if &where ^= %str() %then %do;
where (&where);
%end;
%if &id ^= %str() %then %do;
id &id;
%end;
%if &by ^= %str() %then %do;
by &by;
%end;
var &vars ;
proc printto print=print;
data _null_;
file &out notitle noprint lrecl=&ls;
length string $&ls;
infile table length=len end=last;
if _n_=1 then do;
*-- Eat the first (title) line;
input @1 string $varying. len;
put /;
%if %length(&caption) > 0 %then %do;
put '' "&caption";
%end;
put / '';
end;
input @1 string $varying. len;
/*-- Handle carriage control chars in col 1; */
%if &sysscp = CMS %then %do;
cc=substr(string,1,1);
string=substr(string,2);
if cc='1' then put _page_;
%end;
put string $char.;
/*-- Finish up; */
if last then do;
put '
';
end;
%end;
/*-------------------------------------------------------*/
/* -- HTML 3: Use and other table tags */
/*-------------------------------------------------------*/
%else %do;
/*-- Get variable name, type, label & format info; */
data _tmp_;
set &data;
stop;
/*** use summary to reorder the variables in order of var list */
proc summary data=_tmp_(firstobs=1 obs=1);
id &vars &id;
output out=_tmp1_(drop=_TYPE_ _FREQ_);
proc contents data=_tmp1_(keep=&vars &id)
noprint out=_vars_(keep=name type length label format
npos);
run;
/*** sort by position of variables in the list; ***/
proc sort data=_vars_;
by npos;
run;
/* proc print; */
data _null_;
set _vars_;
/*-- Store variable info in macro variables: name1, */
/* typel, etc; */
call symput("name"||left(put(_n_,5.)),trim(name));
call symput("type"||left(put(_n_,5.)),put(type,1.));
call symput("len"||left(put(_n_,5.)),put(length,3.));
call symput("lab"||left(put(_n_,5.)),trim(label));
if format=' ' then do;
if type=1 then format="BEST.";
else format="CHAR.";
end;
call symput("fmt"||left(put(_n_,5.)),trim(format));
run;
data _null_;
set &data end=last;
length tabid $30;
%if &where ^= %str() %then %do;
where (&where);
%end;
%if &by ^= %str() %then %do;
by &by;
%end;
/* file &out lrecl=&ls; */
file &out notitle noprint lrecl=&ls;
/* -- Table header --; */
%if &by ^= %str() %then %do;
if first.&by then do;
_by_+1;
tabid = trim("&tabid" || '-' || left(put(_by_,3.)));
%end;
%else %do;
if _n_=1 then do;
tabid = "&tabid";
%end;
put '';
put " &caption" @;
%if &by ^= %str() %then %do;
put _by_;
%end;
put ' ';
%header(&id,&vars);
end;
/*-- Print the table rows; */
%row(&id,&vars);
/*-- Finish up; */
if last
%if &by ^= %str() %then %do;
| last.&by
%end;
then do;
put '
';
end;
run;
%end;
%done:;
%mend;
%macro row(id,varlist);
%global cols;
%if &htmlver >= 3 %then %do;
put ' ';
%*-- Use for ID variable --> font=bold;
%if &id ^= _NULL_ %then %do;
%if &id = %str() %then %do;
put @6 ' | ' _n_ ' | ' @;
%end;
%else %do;
put @6 '' &id +(-1) ' | ' @;
%end;
%end;
%do i = 1 %to &cols;
%let var = %scan(&varlist, &i);
type = &&type&i;
if type=1
then put ' ' &var +(-1)
' | ' @;
else put ' ' &var +(-1)
' | ' @;
%end;
put / '
';
%end;
%mend;
%macro header(id, varlist);
%global cols;
%let cols = %numwords(&varlist);
length var $40;
/*-- Output header cells for variable names or labels; */
/*-- default alignment is , so no */
/* need to specify; */
put ' | ';
%if &id ^= _NULL_ %then %do;
%if &id = %str() %then %do;
put @6 'Obs | ' @;
%end;
%else %do;
%let i=%eval(&cols+1);
var = "&&lab&i";
if var = ' ' then
var = "%upcase(&id)";
put @6 '' var +(-1) ' | ' @;
%end;
%end;
%do i = 1 %to &cols;
/* -- Use variable label if it exists; */
var = "&&lab&i";
if var = ' ' then
var = "%upcase(%scan(&varlist, &i))";
put ' ' var +(-1) ' | ' @;
%end;
put / '
';
%mend;
%macro numwords(lst,wordchar);
%let i = 1;
%if (%length(&wordchar)) %then %do;
%let v = %scan(&lst,&i,&wordchar);
%do %while (%length(&v) > 0);
%let i = %eval(&i + 1);
%let v = %scan(&lst,&i,&wordchar);
%end;
%end;
%else %do;
%let v = %scan(&lst,&i);
%do %while (%length(&v) > 0);
%let i = %eval(&i + 1);
%let v = %scan(&lst,&i);
%end;
%end;
%eval(&i - 1)
%mend;
%macro tempfile(file, ls);
%global tempfn;
%if &sysscp = CMS
%then %let tempfn=&file output a;
%else %if &sysscp = NEXT /* or many flavors of ... UNIX */
%then %let tempfn=/tmp/&file..out;
%else %if &sysscp = WIN
%then %let tempfn=c:\&file..out;
filename table "&tempfn" lrecl=&ls ;
%mend;
data test;
input xx yy zz;
label xx='First' yy='Second' zz='Third';
cards;
1 2 3
5 6 7
9 8 7
;
%htmltab(data=test, vars= xx yy zz, caption=Test Table);
========================================================================
NOTE: The sample HTML output is provided below
========================================================================
[TEST1.HTML]
Test Table
Obs | First | Second | Third |
1 | 1 | 2 |
3 |
2 | 5 | 6 |
7 |
3 | 9 | 8 |
7 |
*;