0% found this document useful (0 votes)
10 views

Caroline Bahler, Meridian Software, Inc., Raleigh NC Eric Brinsfield, Meridian Software, Inc., Raleigh NC

Uploaded by

dileep
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

Caroline Bahler, Meridian Software, Inc., Raleigh NC Eric Brinsfield, Meridian Software, Inc., Raleigh NC

Uploaded by

dileep
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

SUGI 27 Beginning Tutorials

Paper 61-27

Report Creation Using Data _NULL_


Caroline Bahler, Meridian Software, Inc., Raleigh NC
Eric Brinsfield, Meridian Software, Inc., Raleigh NC

ABSTRACT COMPONENTS
Reports and tables can be created using PROC REPORT, PROC
PRINT and other procedures. However, there are times when the Output printer/external file location definition:
standard procedure output cannot meet the report requirements.
In those cases, reports creation using the DATA _NULL_ step is § FILE – this statement defines the destination for PUT
the solution. The objective of this paper is to discuss the statement output. FILE can point to PRINT, LOG, or a
techniques used to create a data _NULL_ report. physical location to write the report to along with any
properties of that file or a printer1. FILE is used only within
INTRODUCTION: THE _NULL_ DATA STEP the DATA step and can utilize the FILEREF defined within a
FILENAME1 or the ODS 2 statements.
Report creation within base SAS® can be accomplished through
the use of multiple procedures such as PROC REPORT and § The FILE statement deserves special study by beginning
PROC PRINT. The choice of procedure is dependent upon the SAS programmers. Examine all of the options available in
needs of the report. In general, the strength of reporting the FILE statement, because it can provide valuable
procedures is to present data in a tabular form and allows information, such as the number of lines left on the page
summarization of the data and formatting of the output. Although (LINESLEFT=).
capable of handling about 90% of typical report requests, these § FILENAME (optional) – this statement is used to define a
procedures do have limits. There are cases when the report physical location of an external file. A FILEREF is defined
requirements are not satisfied by any of the standard reporting within the statement and used later within a FILE statement.
procedures. The solution in those cases is to use the _NULL_ This statement is specified outside of a DATA step.
DATA step.
§ ODS (optional) – the ODS (Output Delivery System)
The _NULL_ DATA step is a specialized case of the DATA step. statement is used to define the type of file that will be written
When you use the _NULL_ key word, the DATA statement to the defined physical location. This statement is specified
processes all statements within the DATA step without data set outside of a DATA step.
creation1.
Some of the uses of DATA _NULL_ are: Report Output Definition
§ To create customized reports with and without ODS. The
reports can be routed to the Output window, directly to a § PUT – this statement defines the information written to the
printer, to an external file, or any destination that can be file defined within the FILE statement1. A PUT statement
defined by the FILE and FILENAME statement. can contain both variables and text contained within quotes.
The PUT statement is similar to the INPUT statement and
§ To create macro variables based on values obtained from an the same options apply1. Multiple PUT statements can be
input SAS data set or external file. used within the DATA step. The following example
§ To create ASCII data (flat) files for importing into MS Excel, illustrates the use of the PUT statement to create a report
MS Access or other programs and databases. row containing a label and variable value:
§ To execute special functions or call routines available within
the DATA step, such as CALL EXECUTE. DATA step statements …………
The objective of this paper is to discuss the major aspects of PUT @01 ‘Total Sales’
creating a custom report using the DATA _NULL_ step. @15 sales dollar10.2;

CREATING CUSTOM REPORTS In the example above, the text will be written starting in the
first column of the file being created and the actual sales
PREPARATION amount will be written starting in the 15th column.
Specification of the actual column to write the report
A custom report needs a set of requirements that define precisely information is not necessary but useful in certain situations.
how the report should be laid out. The requirements should § BY – is used to define data display, paging, and
identify:
summarization order within a report. This statement is used
§ Type of output needed: printed, viewed in Web browser, or with previously sorted data sets and contains a list of
routed to a file variables in the specific sort order1. Use of the BY statement
§ Titles, footnotes causes the creation of FIRST. and LAST. variables or each
variable listed within the BY statement3. These variables
§ Summary lines can be used to determine summarization points and when to
§ Columns within the report and how the columns should be output data to the report file or printer.
summarized FIRST.variable – defines the first occurrence of a BY
§ Placement of information on the report “page” and timing of variable value within the data set3.
page breaks LAST.variable - defines the last occurrence of a BY variable
§ Depending on the type of report being created preparation value within the data set3.
may include creating a mock-up of the report that contains For example the following statement,
column placement for each element in the report. BY STATE;
defines the variables LAST.STATE and FIRST.STATE.

1
SUGI 27 Beginning Tutorials

OPTIONS o Using a FILENAME statement –


FILENAME RPT ‘D:\OUTPUT\RPT1’
§ RETAIN – this statement changes how the DATA step
handles a variable’s value. Normally, the value of every § Creating special output files – the ODS statement can be
variable is reset for each new observation. The RETAIN used to create external files that are in specific output
statement tells the DATA step not to reset the specified formats. For example –
variables value. The main use of the RETAIN statement is o ODS HTML – creates HTML output
to create totals or to compare variable values on the current
row to values from an earlier row. o ODS PRINTER – creates postscript files.

§ SET – there are several options of interest that can be used o ODS RTF –creates rich text format files (used by
to create reports. word processors).
o END = var - this option create a variable that To create an HTML file, for example –
contains an identifier that specifies the end of the ODS HTML BODY=”D:\HTML\RPT.HTM” ;
file.
data _NULL_;
§ _N_ - this is an automatic counter variable created by the set salesdata;
DATA step. It can be used to output information at specific FILE PRINT ODS=options;
observations.
put _ods_;
For example, when generating HTML, several statements run;
need to occur at the top of the file only. The following
statements will write the information only for the first Note: The FILE statement specifies the PRINT fileref and
observation. ODS keyword. This indicates that an ODS destination has
been defined.
data _NULL_;
set salesdata; EXAMPLE REPORTS
file RPT;
EXAMPLE1: SIMPLE CASE WITH NO INPUT DATA
if _N_ = 1 then
put @01 “<HTML>” ……..; As a simple example that shows the use of many of the
run; components described above, the following program creates a
daily calendar for any time period specified in the do-loop. More
sophisticated uses would utilize the FILE statement’s HEADER=
§ Formats – PROC FORMAT can be used to create custom for controlling the page headers and column labels and
formats that can be used to label variables within a report. LINESLEFT= to control the paging and construct the footnotes.
Program comments have been removed from all sample code to
REPORT OUTPUT ROUTING save space in this document.

The DATA _NULL_ step can be defined to route its output to a


printer or external file. The following is a list of destinations: %let startdate=01apr2002;

§ Sending output to the OUTPUT window – using the FILE %let stopdate =30apr2002;
PRINT statement when in Display Manager will send the options linesize=76 pagesize=74;
report output to the OUTPUT window. This behavior is %let col1=16;
useful for previewing the report. For example:
%let col2=26;
DATA _null_;
data _NULL_;
file print notitles;
set salesdata;
do date="&startdate"d to "&stopdate"d;
FILE PRINT;
page+1;

PUT …….. pagec=left(put(page,3.));

run; if page > 1 then put _page_;


put ///;
§ Sending output directly to a printer – this requires definition
of the printer within a FILENAME statement. For example: put @&col1 date weekdate37.
@&col2 +40 'Page: ' pagec

FILENAME PRINTER1 PRINTER options ; / @&col2 50*'-' @&col2 +50 '*';

data _NULL_; do time='6:30't to '19:45't by '0:15't;

set salesdata; if time=hms(hour(time),0,0) then

FILE PRINTER1; put @&col2 +2 48*'-'

……………. @&col2 +50 '|';

PUT ……… put @&col2 +2 time time5.

run; @&col2 +50 '|';


end;

§ Sending output to an external file – the report output is sent put @&col2 +2 48*'-' @&col2 +50 '*';
to an external file by either specifying an external file location end;
within the FILE or FILENAME statements. For example: run;
o Using a FILE statement –
FILE ‘D:\OUTPUT\REPORT1’;

2
SUGI 27 Beginning Tutorials

In this case, the programmer assumes that all lines for one day
will fit on one page; so intelligent paging was not necessary. The if first.region then regtot=count;
output is routed to the default print file, which is the OUTPUT
else regtot+count;
window in Display Manager. When writing custom report
programs, you have to coordinate the number of lines you want to
print on each page and the number of columns with the SYSTEM In this usage, the values of REGTOT are automatically
OPTIONS PAGESIZE and LINESIZE. retained, because of the missing equal sign in the statement:

EXAMPLE 2: GENERATING HTML else regtot+count;

Hypertext Markup Language (HTML) can be generated within a


_NULL_ DATA step by either specifying the HTML tags within the § Use the PUT statement to write HTML to the specified file.
PUT statement or using ODS. The following examples will The HTML created in the mock up can be cut and paste into
describe the steps needed to use both approaches. a set of put statements to create the report. Appendix A has
The report generated contains regions, count areas, and counts the complete code for this example. Note that _N_ is used
for Mallard ducks in North Carolina. to define the top of the HTML file.
if _n_ = 1 then
HTML Code Generation put @01 "<html>"
/@01 '<body bgcolor="#C0C0C0">' …
A HTML file is essentially a file that contains tags that tell a
browser how to format the text within the file.
FIRST. logic is used to define the first row of each region.
if first.region then do;
put @01 '<tr>'
/@01 '<td width="32%" ……

To end the HTML the END = option was used to define the
end of file.
if eof then
put @01 '</table>'
/@01 '</body>'
/@01 '</html>'
;

EXAMPLE 3: HTML CODE GENERATION WITH ODS

Figure 1 HTML Report Mockup To generate the same report using ODS, the PROC TEMPLATE
statement will be used to specify the special formatting for total
The report in Figure 1 has total lines in blue text and lines with lines (in blue) and counts below 6,000 in red.
counts below 6,000 in red. To generate the HTML for this report
PROC TEMPLATE is a procedure that can be used to specify
within the DATA _NULL_ step:
how different portions of a HTML file should be rendered in
Summarize the data and perform any other manipulations needed HTML. A set of default templates has been defined for all
before going into the last DATA step. procedures and the DATA step. In this example, PROC
Totals can be created within the DATA _NULL_ step so make TEMPLATE will be used to define custom column styles.
sure that the data is sorted appropriately. In this case, by region
and area. Note that a BY statement is needed after the SET
statement.
data _null_;
set mallard end=eof;
by region area;
Create the DATA _NULL_ step.
§ Define the file where the HTML will be written:
File ‘H:\HTML\MALCOUNT.HTM’;
§ Create the totals using a RETAIN statement1 and FIRST.
and LAST. logic1.
retain regtot;
if first.region then regtot=count;
else regtot=regtot + count;

Figure 2: Report Generated Using ODS to Generate HTML


Note: the RETAIN statement will tell the DATA step to keep the
value of REGTOT instead of resetting it with the next observation. Summarize the data and perform any other manipulations needed
The FIRST. logic tell the DATA step to set the value of REGTOT before going into the last DATA step.
to COUNT when a new value of REGION occurs. Totals can be created within a DATA step so make sure that the
Or, you can use an alternative method using a SUM statement: data is sorted appropriately. Other summarization methods can

3
SUGI 27 Beginning Tutorials

also be used. REPORT CREATION TIPS


Use PROC TEMPLATE to create specialized HTML formatting. § A complete set of requirements for the report is extremely
To define a custom style for a table the DEFINE TABLE is used. useful when creating a custom report. The requirements
proc template; should include the type of output created, summarization
define table shared.cellstyle; levels and page breaks (if any).
§ Create a mock-up of the report. The mock up needs to
identify all the elements of the report. A mock-up should
Character variables are formatted by the following statement: include title and footnote placement. In some cases the
define column char_var; creating a ruler with column numbers at the top of the mock-
generic=on; up is both useful and necessary.
blank_dups=on; § ODS use – ODS should be used when the report needs to
end; be read by either a word processor or a printer.
§ Generating HTML – whether to use ODS to generate HTML
depends upon the report. ODS does not handle situations
The following statement is used to define two levels for the where the report requires the use of specialized tags. In
numeric column (count) and a description. those cases, using the PUT statement to generate the HTML
nmvar low 'Use default style.' is necessary.
high 'Use blue text and a bold font.';
classlevels=on; SUMMARY
Report creation can be accomplished through the use of many
Numeric variable format is defined by the following statement: procedures. However, there are cases when the procedures
cannot produce the report request. In those cases, the _NULL_
define column num_var;
DATA step is the solution.
generic=on;
justify=on;
REFERENCES
1. SAS Institute Inc. 1999. Statements. Dictionary of Language
CELLSTYLE defines the format for numeric values below above Elements, SAS Language Reference, Base SAS Software.
the cutoff values. SAS OnlineDoc®, Version 8, Cary, NC: SAS Institute Inc.
cellstyle _val_ < low as data 2. SAS Institute Inc. 1999. Using the Output Delivery System in
{foreground=red
the DATA step, Guide to the Output Delivery System,
Reference, Base SAS Software. SAS OnlineDoc®, Version
font_weight=bold}, 8, Cary, NC: SAS Institute Inc.
_val_ <= high as data,
3. SAS Institute Inc. 1991. SAS Language and Procedures:
/* format for regional totals */ Usage 2, Version 6, First Edition, Cary, NC: SAS Institute
1 as data Inc. pp 294-296.
{foreground=blue font_weight=bold} 4. SAS Institute Inc. 1991. SAS Language and Procedures:
; Usage 2, Version 6, First Edition, Cary, NC: SAS Institute
Inc. pp 246.
end;
5. SAS Institute Inc. 1991. SAS Language and Procedures:
end;
Usage 2, Version 6, First Edition, Cary, NC: SAS Institute
run; Inc. pp 311.
Specify the physical location of the file using the ODS HTML
statement and BODY option. CONTACT INFORMATION
Create the HTML using a DATA _NULL_ step. Macro variables Caroline Bahler
that have the same names as the values of NMVAR within PROC
TEMPLATE are used to specify the cutoff values for each group. Meridian Software, Inc.
/* set the cutoff for the low and high values */ 12204 Old Creedmoor Road
%let low=6000; Raleigh, NC 27613
%let high=60000; (919) 387-6735
In addition, within the FILE PRINT ODS statement the Template [email protected]
and Columns options are specified. The Columns option is used
www.meridiansoftware.com
to specify which variables to used within the report and to identify
the variable type (character or numeric).
data _null_; Eric Brinsfield
set mallard1; Meridian Software, Inc.
file print 12204 Old Creedmoor Road
ods=(template='shared.cellstyle'
Raleigh, NC 27613
columns=(
(919) 847-6750
char_var= reglabel(generic=on)
[email protected]
char_var=arealab(generic=on)
num_var=count(generic=on) ));
www.meridiansoftware.com
put _ods_;
run;

4
SUGI 27 Beginning Tutorials

TRADEMARKS /@01 ' <td width="30%" height="10"


align="center"><b><font
SAS® and all other SAS Institute Inc product or service names
face="Arial"
are registered trademarks or trademarks of SAS Institute Inc. in
the USA and other countries. ® indicates USA registration. size="2">'
Meridian Software, Inc.â is a registered trademark of Meridian 'Count Area</font></b></td>'
Software, Inc. Other brand and product names are registered /@01 '<td width="38%" height="10"
trademarks or trademarks of their respective companies.
align="center"><b><font
face="Arial"
APPENDIX
size="2"> '
The data used in the following examples are Mallard duck counts.
' Count</font></b></td>'
/@01 ' </tr>'
A. GENERATING HTML
;
First summarize the data.
/* Create format for region */ /* create first row within a region – include
region label */
proc format;
if first.region then do;
value $ reg A='Eastern'
put @01 '<tr>'
B='Central'
/@01 '<td width="32%" height="19"><font
C='Western'
size="2" face="Arial"><b>' region
;
'</b></font></td>';
run;
/* if number of mallards is less than 6000 the row
is in red */
/* Sort data set Mallard by region and area */
if count < 6000 then
proc sort data=mallard;
put @01 '<td width="30%"
by region area;
height="19"><font size="2"
run;
face="Arial"color="#800000"><b>'
arealab '</b></font></td>'
data _null_;
/@01 '<td width="38%" height="19"
set mallard end=eof;
align="right"><font size="2"
by region area;
face="Arial" 'color="#800000">
format region $reg.;
<b>' count comma12.
retain regtot;
'</b></font></td></tr>'
file "g:\temp\mallard.htm";
;
else
/* create regional totals */
put @01 '<td width="30%"
if first.region then regtot=count;
height="19"><font
else regtot=regtot+count;
size="2" face="Arial">' arealab
'</font></td>'
arealab = 'Area '||put(area,best.);
/@01 '<td width="38%" height="19"
align="right"><font size="2"
/* Start HTML and create title and column headers,
face="Arial">'
HTML and BODY tags are required */
count comma12.
if _n_ = 1 then
'</font></td></tr>'
put @01 "<html>"
;
/@01 '<body bgcolor="#C0C0C0">'
end;
/@01 '<h3 align="center">
else do;
<font face="Arial"
put @01 '<tr>'
color="#008000">’
/@01 '<td width="32%"
‘Mallard - North Carolina Counts</font>
height="19"></font></td>';
</h3>'
if count < 6000 then
/* start table definition */
put @01 '<td width="30%"
/@01 '<table border="1" width="75%"
height="19"><font size="2"
bgcolor="#CCCCCC" align=center>'
face="Arial"color="#800000"><b>'
/* define column headers */
arealab '</b></font></td>'
/@01 '<tr>'
/@01 '<td width="38%" height="19"
/@01 '<td width="32%" height="10"
align="right"><font size="2"
align="center"><font face="Arial"
face="Arial"
size="2"> '
color="#800000"><b>'
'<b>Region</b></font></td>'

5
SUGI 27 Beginning Tutorials

count comma12. by region area;


'</b></font></td></tr>' retain regtot;
; format count regtot comma12.
else reglabel arealab $12.;
put @01 '<td width="30%" label reglabel="Region"
height="19"><font arealab ="Count Area"
size="2" face="Arial">' count ="Count";
arealab '</font></td>'
/@01 '<td width="38%" height="19" arealab = 'Area '||left(put(area,best.));
align="right"><font size="2" reglabel=' ';
face="Arial">'
count comma12. if first.region then do;
'</font></td></tr>' regtot=count;
; reglabel=put(region,$reg.);
end; output;
end;
/* region totals – number is in blue */ else do;
if last.region then do; regtot=regtot+count;
put @01 '<tr>' reglabel=' ';
/@01 '<td width="32%" output;
height="19"></font></td>' end;
/@01 '<td width="30%"
height="19"></font></td>' if last.region then do;
/@01 '<td width="38%" height="19" reglabel=' ';
align="right"> arealab=' ';
<font size="2" face="Arial" count=regtot;
color="#000080"><b>' output;
regtot comma12. end;
'</b></font></td></tr>' run;
;
end; /* Create a template that will be used by ODS to
format count column */
if eof then
proc template;
put @01 '</table>'
define table shared.cellstyle;
/@01 '</body>'
define column char_var;
/@01 '</html>'
generic=on;
;
blank_dups=on;
run;
end;

B. GENERATING HTML USING ODS


nmvar low 'Use default style.'
First summarize the data. high 'Use red foreground and a bold
font.';

/* Create format for region */


proc format; classlevels=on;

value $ reg A='Eastern'


B='Central' define column num_var;

C='Western' generic=on;

; justify=on;
run; cellstyle _val_ < low as data
{foreground=red font_weight=bold},
/* Sort data set Mallard by region and area */ _val_ <= high as data,

proc sort data=mallard; /* format for regional totals */

by region area; 1 as data

run; {foreground=blue font_weight=bold}


;
/* create regional totals and labels */ end;

data mallard1; end;


set mallard end=eof; run;

6
SUGI 27 Beginning Tutorials

ods html body="g:\temp\mallard1.htm";


title 'Mallard - North Carolina Counts';

/* set the cutoff for the low and high values */


%let low=6000;
%let high=60000;
data _null_;
set mallard1;
file print ods=(
objectlabel='Mallard – North Carolina Counts'

template='shared.cellstyle'
columns=(
char_var=reglabel(generic=on)
char_var=arealab(generic=on)
num_var=count(generic=on)
)
);
put _ods_;
run;

ods html close;

You might also like