Using the SAS Display Manager to Create HTML

Một phần của tài liệu web development with sas by example, 2nd edition (2006) (Trang 65 - 70)

Chapter 3 Creating Static HTML Output 51

The underlying source code for this page is somewhat easier to understand after some Web programming practice. For the moment, it is sufficient to note that there is a whole lot more stuff in this page than we have seen until now. (The folks at SAS have obviously been keeping busy.) You should be able to see that this page does not use the <pre> and </pre> tags like

%OUT2HTM. Instead, an HTML table is created, with a number of formatting instructions determined by the CSS style selected.

The header for the page also includes some JavaScript functions, enclosed in <SCRIPT></SCRIPT>

tags, that are called when the page is loaded and unloaded. In this case, since no special formatting was requested, the function bodies are empty, except to figure out whether the client browser is on Windows or not. (As will be discussed in Chapter 5, “Web Applications Programming,” JavaScript usually executes on the client system, so the client OS matters.)

Note that the HTML generated does not conform to the XHTML standard, but it does work in most Web browsers. (See the discussion of the ODS MARKUP statement in the section later in this chapter, “Using the ODS Markup Statement to Create XHTML,” for information about how to create XHTML using SAS.) Note that an internal CSS file is created by default. The following example shows only the first of these generated style tags—.ContentTitle. The remaining ones are omitted from the listing for reasons of space.

Example 3.10 SAS Display Manager HTML Source

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML><HEAD><TITLE>SAS Output</TITLE>

<META content="MSHTML 6.00.2900.2802" name=GENERATOR sasversion="9.1">

<META http-equiv=Content-type content="text/html; charset=windows- 1252">

<STYLE type=text/css>.ContentTitle {

[... a whole bunch of CSS styles omitted ...]

}

</STYLE>

<SCRIPT language=javascript type=text/javascript>

<!--

function startup(){

}

function shutdown(){

}

//-->

</SCRIPT>

<NOSCRIPT></NOSCRIPT></HEAD>

<BODY class=Body onload=startup() onunload=shutdown()>

<SCRIPT language=javascript type=text/javascript>

<!--

var _info = navigator.userAgent var _ie = (_info.indexOf("MSIE") > 0 && _info.indexOf("Win") > 0

&& _info.indexOf("Windows 3.1") < 0);

//-->

</SCRIPT>

<NOSCRIPT></NOSCRIPT>

<DIV class=branch><A name=IDX></A>

<TABLE class=SysTitleAndFooterContainer cellSpacing=1 cellPadding=1 rules=none width="100%" summary="Page Layout" border=0 frame=void>

<TBODY>

<TR>

<TD class="l SystemTitle">Retail Sales In Millions Of $</TD></TR></TBODY></TABLE><BR>

<DIV>

<DIV align=left>

<TABLE class=Table borderColor=#000000 cellSpacing=1 cellPadding=7 rules=groups summary="Procedure Tabulate: Table 1" border=1 frame=box>

<COLGROUP>

<COL></COLGROUP>

<COLGROUP>

<COL>

<COL>

<COL>

<COL>

<COL>

<COL></COLGROUP>

<THEAD>

<TR>

<TH class="c m Header" scope=col>Year</TH>

<TH class="c Header" scope=col>Total Sales</TH>

<TH class="c Header" scope=col>Overall Percent</TH>

<TH class="c Header" scope=col>Number of Sales</TH>

<TH class="c Header" scope=col>Average Sale</TH>

<TH class="c Header" scope=col>Smallest Sale</TH>

<TH class="c Header" scope=col>Largest Sale</TH></TR></THEAD>

<TBODY>

<TR>

<TH class="l t RowHeader" scope=row>1994</TH>

<TD class="r b Data">$1,874</TD>

<TD class="r b Data">5.97</TD>

<TD class="r b Data">2</TD>

<TD class="r b Data">$937.00</TD>

<TD class="r b Data">$876</TD>

<TD class="r b Data">$998</TD></TR>

[... repeated lines omitted ...]

<TR>

<TH class="l t RowHeader" scope=row>Total</TH>

<TD class="r b Data">$31,374</TD>

<TD class="r b Data">100.00</TD>

<TD class="r b Data">58</TD>

<TD class="r b Data">$540.93</TD>

<TD class="r b Data">$220</TD>

<TD class="r b Data">$998</TD></TR>

</TBODY></TABLE></DIV></DIV><BR></DIV></BODY></HTML>

But, as all good SAS programmers know, you cannot always run everything from the Display Manager window (although this would certainly be the method of choice for developing and debugging static Web output). It is not difficult to learn how to use the available ODS commands in batch mode to create Web pages of almost any format.

Chapter 3 Creating Static HTML Output 53

The ODS HTML Statement in SAS®9

Up to and including Release 6.12 of SAS, pretty much every procedure had its own routines for handling printed output. Many of these dated back to the original versions of SAS developed in the early 1970s, when the only output devices available were line printers and TTY terminals. As each new release of SAS appeared, the basic output formatting code was rewritten, but every procedure still managed its own layout. SAS users learned to use PROC PRINTTO, DDE triplets, and other exotic solutions in order to impose their own formats on output, or to select specific portions of the results for further processing.

One of the prime directives of object-oriented software development is “Thou shall not mix Data with Presentation.” Starting with SAS 7, the Output Delivery System was introduced to manage all the SAS procedure output in a consistent way. One or more output objects are created by each DATA step or procedure; these output objects each contain two basic components.6 The data component includes the raw data values that comprise the results of the procedure or the contents of the Program Data Vector (PDV), while the table template (also called a table definition) describes how the data should be formatted. SAS has supplied a number of standard templates.

You can modify these and even create your own using PROC TEMPLATE.7 As the online SAS System Help points out:

ODS removes responsibility for formatting output from individual procedures and from the DATA step. The procedure or DATA step supplies raw data and the name of the table definition that contains the formatting instructions, and ODS formats the output. Because formatting is now centralized in ODS, the addition of a new ODS destination does not affect any procedures or the DATA step. As future destinations are added to ODS, they will automatically become available to all procedures that support ODS and to the DATA step.

The Create HTML check box selection described previously in fact just uses ODS. The drop- down menu shows you the list of the production style templates stored in the

SASHELP.TMPLMST item store, so that you can pick the presentation style of the resulting output file. You can easily create your own HTML in batch mode, using a few simple ODS statements that will accomplish the same effect. Example 3.11 shows how to do it; the HTML output and page source code are identical to that shown in Display 3.6 and Display 3.7.

Example 3.11 Using the ODS HTML Statement

filename OUT "Example 3-11.html";

ods listing close;

ods html body=OUT;

proc tabulate data=SASHELP.RETAIL;

title "Retail Sales In Millions of $";

class YEAR/descending;

var SALES;

table YEAR="" all="Total", SALES="" * (sum="Total Sales"*f=dollar8.

pctsum="Overall Percent"*f=8.2

6This discussion borrows heavily from Chris Olinger, "ODS for Dummies" (Paper 25-64, Proceedings of the Twenty-fifth Annual SAS Users Group International Conference. Cary, NC: SAS Institute Inc., 2000).

7C++ users should note that SAS uses the term "standard template" in a way that is quite different from what they may be used to. For more information about working with SAS templates, see the PROC TEMPLATE FAQ and Concepts at http://support.sas.com/rnd/base/topics/templateFAQ/Template.html.

n="Number of Sales"*f=8.

mean="Average Sale"*f=dollar8.2 min="Smallest Sale"*f=dollar8.

max="Largest Sale"*f=dollar8.)/

box="Year" rts=8;

run;

ods html close;

ods listing;

ODS statements open and close specified destinations. In this example, ODS HTML and ODS LISTING statements are used to manage the output process. It is still necessary to call ODS twice, once before and once after the procedure. But with the earlier approach, the first invocation of the macro turned on a routine to capture the printer output from the procedure. The second call to the macro then added HTML tags and copied the result to the specified output location. In this example, however, the first ODS HTML statement opens the output location, and from that point on, all procedure and data step output are sent to the file specified in the BODY= option until it is explicitly closed. The two ODS LISTING statements are used to suppress the standard output listing while the ODS process is underway, and to restart it afterwards.

From the point of view of the user, ODS appears to work in a way that is very similar to the

%OUT2HTM macro. In fact, what is under the hood is completely different, as the generated page source code illustrates. Instead of using preformatting, ODS dynamically generates the output in the specified style. But that's just the beginning of what you can do with ODS. Although this book is not an ODS tutorial, the Output Delivery System is so much a part of Web

programming that it is important to point out a few of the most notable features.

Creating Multiple Pages with a Single Program

One of the most important improvements in ODS of previous approaches is its ability to manage multiple output objects. The following example shows the code to create a single new HTML page for each procedure.

Example 3.12 Creating Multiple Web Pages

ods listing close;

ods html body="../public_html/example3-12.html" newfile=proc;

***** Step #1 ****;

proc print data=SASHELP.RETAIL;

title "1994 Sales Total by Month";

where YEAR gt 1990;

var MONTH SALES;

id YEAR;

run;

***** Step #2 ****;

proc means data=SASHELP.RETAIL n mean min max

nonobs fw=8 maxdec=2;

title 'Retail Sales In Millions Of $';

class YEAR/descending;

var SALES;

run;

Chapter 3 Creating Static HTML Output 55

***** Step #3 ****;

proc tabulate data=SASHELP.RETAIL;

class YEAR/descending;

var SALES;

table YEAR='' all='Total', SALES='' * (sum='Total Sales'*f=dollar8.

pctsum='Overall Percent'*f=8.2 n='Number of Sales'*f=8.

mean='Average Sale'*f=dollar8.2 min='Smallest Sale'*f=dollar8.

max='Largest Sale'*f=dollar8.)/

box='Year' rts=8;

run;

ods html close;

ods listing;

The ODS HTML statement in this example differs from the one in Example 3.11 in that the ODS NEWFILE= option is used to indicate that a new HTML file should be started for each procedure.

ODS automatically increments the filename for each new procedure. It is useful to recognize that ODS increments the rightmost number that it finds. For example, if the above example instead had used the statement ods html body=”example3-12_f1.html” then the subsequent files would have been named as follows:

example3-12_f1.html example3-12_f2.html example3-12_f3.html

For this reason, the file name must be specified in the BODY= option; a file reference cannot be used.

Display 3.8 shows a portion of the resulting SAS log file. As the SAS Notes indicate, three output HTML files are created, one for each of the three procedures.

Một phần của tài liệu web development with sas by example, 2nd edition (2006) (Trang 65 - 70)

Tải bản đầy đủ (PDF)

(361 trang)