*
;
/**************************************************************/
/* 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 " '; %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 '
&caption" @; %if &by ^= %str() %then %do; put _by_; %end; 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
*
;