you created that report in sas!?
TRANSCRIPT
1
You Created that Report in SAS®!?:The Power of the
ODS PDF Destination
Pete Lund
Looking Glass Analytics
Olympia, WA
2
Remember When…
• “Reporting” from SAS meant
– Printing from the output window
– SAS font
– Retyping your results
– Cutting and pasting to a word processor
2
3
ODS and PDF: A Whole New World
• ODS: The Output Delivery System
– Allows us to send SAS output to any number
of “destinations”
• HTML, RTF, PDF, Excel, XML…
• …and, of course, the output window
– Allows us to control the appearance of the
output
• Styles: fonts, colors, backgrounds, sizes….
• Tables: column arrangement, data appearance….
4
ODS and PDF: A Whole New World
• PDF: Portable Document Format
– A standard for report format
– More consistent cross-platform appearance
3
5
A Quick Introduction to ODS PDF
• To create a PDF document with SAS
– “Open” the document with the ODS PDF
statement
• ODS PDF FILE=‘<file name here.pdf>’ <options>;
– Include any procedure(s) here – the output will
go to the PDF file
– “Closing” the PDF actually creates the file
• ODS PDF CLOSE;
6
Real World Examples
• All the examples we’ll look at today were created in some form of “hands-off” environment
– SAS/Intrnet
– scheduled batch job
• No after-the-fact manipulation or intervention
• All code and data driven
– No embedded graphs or images
– No preexisting components included
4
7
Making the Most of ODS and PDF
• Everything we’ll talk about today has to do with controlling the appearance of your output
• Inline styles– Procedure-level inline styles
– Data-level inline styles with ODS ESCAPECHAR
• Output from than one procedure on a page– STARTPAGE=NO
– ODS LAYOUT
• Placing text wherever you want it– ODS PDF TEXT
• Creating tables and reports in the data step
8
Procedure-Level Inline Styles
• PROCs REPORT, TABULATE and PRINT allow you to control the appearance of procedure output with the STYLE= option
• No need to use PROC TEMPLATE to change or create an ODS Style
5
9
Inline Styles: Column Grouping
• Notice the gap between the groups of columns
• Not quite as wide as the data columns, but offsets them for easier reading
• Created in a nightly batch job with PROC REPORT
• Uses the STYLE= option on a DEFINE statement to set the column width
10
Inline Styles: Column Grouping
• Use a computed column, called Blank
• Use the STYLE= option on the DEFINE statement
to specify the width of that column
column popday Bookings Releases locationgroup,(blank thisyear lastyear diff);
:define locationgroup / across ''....;
:define blank / computed '' style=[cellwidth=8mm];
compute blank / char;blank = '';
endcomp;
We’ve created a new, blank column
that will be 8mm wide - a little smaller
than the data columns
6
11
What Can STYLE= Do?
• Control the appearance of your data– fonts, colors, backgrounds, sizes
• Control the data cell– padding, spacing, indentation, margins
• Example:
STYLE=[FONT_WEIGHT=BOLD FOREGROUND=RED]
• Not all style controls are available for all ODS destinations
• Complete list can be found at the end of the paper in the proceedings
12
Where Can I Use STYLE=?
• In PROC REPORT:– PROC REPORT statement
– DEFINE statement
– COMPUTE statement
– CALL DEFINE routine
• PROC PRINT:– PROC PRINT statement
– VAR statement
– ID statement
– SUM statement
• PROC TABULATE:
– PROC TABULATE
statement
– CLASS statement
– CLASSLEV statement
– TABLE statement
– KEYWORD statement
– VAR statement
7
13
Inline Styles: Row Grouping
• Here there is a break
between groups of rows
• The blank row is a
different color and height
than the data rows
• Both of these parameters
can be controlled with
STYLE=, this time in a
COMPUTE BLOCK in
PROC REPORT
14
Inline Styles: Row Grouping
• There is a “hidden” column in the dataset, LineGroup, used to control spacing
• A COMPUTE block fires each time Line-Group changes
define LineGroup / order noprint;:
compute before LineGroup / style=[font_size=3pt background=cxBDB76B];
line ' ';endcomp;
Before each change in the value of LineGroup, a
blank line is written to the output with the desired
size and color
8
15
Inline Styles: Differential Row Styles
• Two things to notice about
this report
1 – the background color of the header column is different depending on the type of data row
2 – the three Total rows in the tables are italicized, while the data rows are not
• Uses STYLE= in both a
DEFINE statement and in a
CALL DEFINE routine
• Uses a format to control
background color
16
Inline Styles: Differential Row Styles
• Formats can be used to control styles
• The TreatmentDetail variable contains the type of treatment received
value $TxColorDetail'OPA','IOA','MOA','GCA','XXA' = 'cx52b552''OPY','IOY','MOY','GCY','XXY' = 'cx6373b5';
define TreatmentDetail / ' ' group preloadfmt order=dataformat=$TreatmentTypeDetail.style=[background=$TxColorDetail. foreground=white];
Map the data values to an RGB color code
The background color of the cell is
controlled by the format and based on
the value of the data
9
17
Inline Styles: Differential Row Styles
• One format controls data labels and another controls the color of the cell background
define TreatmentDetail / ' ' group preloadfmt order=dataformat=$TreatmentTypeDetail.style=[background=$TxColorDetail. foreground=white];
18
Inline Styles: Differential Row Styles
• Style options can be set in CALL DEFINEs as well,
changing styles for rows or columns
• Style settings are cumulative
– Notice that YouthAdult eq ‘Z’ is in both conditionals and
that the both style settings take effect
compute treatmentdetail;if YouthAdult eq 'Z' or TreatmentDetail eq :'XX' then
call define(_row_,'style',"style=[font_style=italic]");if YouthAdult eq 'Z' then
call define(_col_,'style',"style=[background=white]");endcomp;
Set the style for the entire row
Set the style for the column
10
19
Inline Styles: Differential Row Styles
• One conditional sets the values for the entire row –
all values are italicized
• The other for the column – sets background to
white, overriding the format-based color we saw in
the previous exampleif YouthAdult eq 'Z' or TreatmentDetail eq :'XX' then
call define(_row_,'style',"style=[font_style=italic]");if YouthAdult eq 'Z' then
call define(_col_,'style',"style=[background=white]");
- default
- italic
- italic and white
background
20
ODS ESCAPECHAR
• ODS ESCAPECHAR designates a character that defines the beginning of a formatting command (escape sequence)
ODS ESCAPECHAR='~';
• Escape sequences are, generally, placed inside curly braces {…} and can be used for – Inline styles
– Page numbering
– Superscripts and subscripts
– Wrapping of text
• Not specific to PDF – some are also usable with HTML, RTF and other destinations
11
21
ODS ESCAPECHAR: Inline Styles
• The STYLE= options allows for inline styles to be
used in the REPORT, TABULATE and PRINT
procedures
• The escape sequence “{style […] …}" allows for
embedding of text style information anywhere text
can be displayed
– Text attributes are listed inside the brackets
– All text inside the curly braces will be formatted
ods escapechar='~';
"...~{style [font_weight=bold]This text is bold...}"
This text would display in bold, whether part
of a title, footnote, label or data value
22
ODS ESCAPECHAR: Inline Styles
• Data-specific inline styles are used in two places in this report
1 – the Total Days note at the bottom of each section
2 – the header row at the top of each section
• Uses ~{style…} in a LINE statement in a COMPUTE block (total days note) and embedded in the data value itself (header row)
12
23
ODS ESCAPECHAR: Inline Styles
• Data-based inline styles can be used anywhere text or data values can be dispayed
compute after key / style={just=left};TotalLine = '~{style [font_weight=bold]Total DOC Days for Inmate:}'||
put(TotalDays.sum,2.);line TotalLine $100.;
endcomp;
Set the label text to bold
The data value is not inside the curly
braces for the bold font, so it will
display with the default attributes
24
ODS ESCAPECHAR: Inline Styles
• The inline styles can be part of a dataset variable
value
• The actual data value contains the style information,
but is rendered as shown here
Key = catt(Name,'~{style [font_weight=bold]BA:}',BA,'~{style [font_weight=bold]CCN:}',CCN,'~{style [font_weight=bold]Booking Date:}',put(BD,mmddyy10.),'~{style [font_weight=bold]Release Date:}',put(RD,mmddyy10.));
In this case, we’re turning bolding on for the "label"
portions of the value but not for the "data" portions
of the value
13
25
ODS ESCAPECHAR: Inline Styles
• Data-specific inline styles are versatile and can be used anywhere that data can be displayed
– Titles
– Footnotes
– Labels
– Data values
• Be creative!
26
ODS ESCAPECHAR Special Sequences
• In addition to style definitions, there are a number of special escape sequences that can be used to enhance your output – some of these are*:– ~{super n} - prints a superscript n
– ~{thispage} - prints the current page number
– ~{lastpage} - prints the number of the last page
– ~{nbspace n} - prints n blank spaces
– ~{unicode ccc} - prints unicode character ccc
*All these examples assume: ODS ESCAPECHAR='~';
14
27
ODS ESCAPECHAR: Superscripts
• It’s now easy to add superscripts to data values, labels, titles and footnotes
• This example has superscripts in both footnotes and column headers
• The superscript sequences are set in the footnote text directly and in the format displaying the column header text
28
ODS ESCAPECHAR: Superscripts
• The escape sequence for the column headers is included in the variables format
• The footnote also contains the superscript sequence
value securelocation (notsorted)1.2 = 'Main Jail - Wall St'1.4 = 'Main Jail - Oakes St'2 = 'The Ridge'9 = 'Subtotal Secure Beds~{super 1}'9.1 = 'Subtotal Community Corrections'9.2 = 'Total~{super 1}';
footnote1 '~{super 1}Totals may contain contract beds';
15
An Undocumented FeatureThe “Y” Escape Sequence
• The text in {super …} and {sub …} functions
have all the attributes of the current text, except
for size and position
• The Y escape sequence changes the vertical
position of the text cursor, without changing any
other attributes – for example:
– ~10Y moves the cursor down 10 points
– ~-10Y moves the cursor up 10 points
• In conjunction with STYLE, can be used to
create customized super- and subscripts
29
Customized Superscripts
• Two TITLE statements:
– TITLE1 uses {super }
– TITLE2 uses Y and {style […] }
30
title1 'Regional~{super title1 'Regional~{super title1 'Regional~{super title1 'Regional~{super 1111} Sales Report';} Sales Report';} Sales Report';} Sales Report';Same font attributes as title
text, just smaller
• -12Y moves the text up
• STYLE sets the attributes
• 12Y moves the text back down
title2 'All Regions~title2 'All Regions~title2 'All Regions~title2 'All Regions~----12y12y12y12y
~{style [font_size=5pt ~{style [font_size=5pt ~{style [font_size=5pt ~{style [font_size=5pt
font_style=roman font_style=roman font_style=roman font_style=roman
foreground=red]foreground=red]foreground=red]foreground=red]2222}}}}
~12y Reporting';~12y Reporting';~12y Reporting';~12y Reporting';
16
31
ODS ESCAPECHAR: Page Numbers
• One of the more
challenging additions to
SAS report output used to
be page numbers
• Now, with escape
sequences, it is easy to get
both page and “page of”
numbers on the page
• This example uses both the
{thispage} and {lastpage}
escape sequences
32
ODS ESCAPECHAR: Page Numbers
• {thispage} resolves to the current page number
• {lastpage} resolves to the last page number (“page of”)
• Most commonly used in footnotes
footnote h=8pt f=Arial j=r "Run Date:%sysfunc(today(),mmddyy10.) " " Page ~{thispage} of ~{lastpage}";
17
33
ODS ESCAPECHAR: Line Wrapping
• In the past, you’ve had little control over the line breaks in footnotes and titles without using multiple statements
• This example uses a single footnote statement, but has multiple, indented lines
• It uses the “-n” and “m” escape sequences to control line breaking
34
Line Break Sequences
• There are a few escape sequences related to inserting blank lines in text
– ~{newline n} inserts n lines which are
wrapped to the beginning of the next line
– ~m inserts a “marker” to which
subsequent line breaks can be wrapped
– ~-n inserts a single line break and
wraps to a marker (m), if one exists
Note that there is currently no {…} syntax for the marker-related sequences (m and –n)
18
35
footnote1 j=l h=7pt f='Arial''~-n~S={font_weight=bold}Not~mes: ''~-n~{super 1} Outpatient modalities include Outpatient,....'"~-n~{super 2} Certain discharges are not included in... ""include those with values in the discharge type field of... ""exhausted, 3) inappropriate admission, 4) incarcerated,... ""different facility, 7) withdrew with program advice,... ""not collected, 10) Charitable Choice and 11) other."'~-n~{super 3} Discharges where the value in the discharge... '‘~-n~{super 4} Discharges where the values in the discharge... ''amenable to treatment/lacks engagement, 2) no contact/abort,... ''withdrew against program advice''~-n~{super 5} Numerator=the number of completers... ''used in the completion calculation''~-n~{super 6} "Other" includes clients indicating multiple... ';
ODS ESCAPECHAR: Line Wrapping
• Here’s the whole footnote – notice it’s just one footnote statement
36
footnote1 j=l h=7pt f='Arial''~-n~S={font_weight=bold}Not~mes: ''~-n~{super 1} Outpatient modalities include Outpatient,....'"~-n~{super 2} Certain discharges are not included in... ""include those with values in the discharge type field of... "
:'~-n~{super 5} Numerator=the number of completers... ''used in the completion calculation''~-n~{super 6} "Other" includes clients indicating multiple... ';
ODS ESCAPECHAR: Line Wrapping
• First, notice the superscripts
Notice also that each superscript
begins on a new line, even though
we only have a single footnote
statement
19
37
footnote1 j=l h=7pt f='Arial''~-n~S={font_weight=bold}Not~mes: ''~-n~{super 1} Outpatient modalities include Outpatient,....'"~-n~{super 2} Certain discharges are not included in... ""include those with values in the discharge type field of... "
:'~-n~{super 5} Numerator=the number of completers... ''used in the completion calculation''~-n~{super 6} "Other" includes clients indicating multiple... ';
ODS ESCAPECHAR: Line Wrapping
• Use the -n escape sequence to get the line breaks
More than one escape
sequence can be used in
the same text (~-n and
{super xx})
38
footnote1 j=l h=7pt f='Arial''~-n~S={font_weight=bold}Not~mes: ''~-n~{super 1} Outpatient modalities include Outpatient,....'"~-n~{super 2} Certain discharges are not included in... ""include those with values in the discharge type field of... "
:'~-n~{super 5} Numerator=the number of completers... ''used in the completion calculation''~-n~{super 6} "Other" includes clients indicating multiple... ';
ODS ESCAPECHAR:
Marking the Line Wrap Position
• The m escape sequence marks the position to which lines will wrap
The lines wrap to the position following the
"t" in "Notes" - of course, like all escape
sequences, the "~m" does not print
20
39
Think About Those Line Breaks
• There is a limit of 10 Title statements– TITLE1 – TITLE10
• There is a limit of 10 Footnote statements– FOOTNOTE1 – FOOTNOTE10
• Now, with n or -n, the only limit to the number of footnote and title lines is the amount of space on the page
40
More than One Output Per Page
• The options available for putting output from more than one procedure on a page have always been limited– Text procedures
• OPTIONS– FORMDLIM=' '
– Graphics procedures• GOPTIONS
– HORIGIN, VORIGIN
– HSIZE, VSIZE
• PROC GREPLAY
Mixing output from text andgraphics procedures has beennext to impossible
21
41
Getting More on a Page:
STARTPAGE=NO• By default, each
procedure will start a new page of output*
• The STARTPAGE= NO option prevents the auto-matic creation of a new page
• This report contains output from two PROC REPORTS, one on top of the other
*a little more complicate, but close enough
42
ods pdf file='filings.pdf' startpage=no;
title1 j=c "King County Felony Case Processing Summary Report";title2 j=c "Based on Resolutions through August 2005";
proc report data=AJOMP2.Upper nowd;columns Type DateIndex,(Value Blank);define Type / group '' ....;define DateIndex / '' across ....;
:run;
proc report data=AJOMP2.Lower nowd;columns ResolutionGroup ResolutionCode
DateIndex,(Value Pct MedianDays Blank);define ResolutionGroup / group noprint;define ResolutionCode / 'Breakdown of~-2nResolution Dispositions'....;
:run;
Getting More on a Page:
STARTPAGE=NO
• Keep it all on a single page
22
43
Aligning Columns:
Another STYLE= Trick• One more peek
back at the STYLE= option
• In this example, the upper report has single columns that need to be aligned over a set of three columns in the report below
• Again, we’ll use CELLWIDTH= in the STYLE= option on the DEFINE statements in the two REPORTS
44
Aligning Columns:
Another STYLE= Trick
• Set the total cell widths in the two PROC REPORTS equal and the columns line up
define Value / '' sum ... style=[cellwidth=29mm];define Blank / '' computed ... style=[cellwidth=17mm];
define Value / "N" ... style=[cellwidth=12mm];define Pct / "%" ... style=[cellwidth=13mm];define MedDays / "Median Days" ... style=[cellwidth=13mm];define Blank / '' computed ... style=[cellwidth=8mm];
29 + 17 = 46mm total
12 + 13 + 13 + 8 = 46mm total
23
45
Getting More on a Page:
ODS LAYOUT• You can now specify where
your output will be placed on the page with ODS LAYOUT
• This report has the output from 10 procedures on a single page1 – PROC SQL
2-4 – PROC REPORT
5-10 – PROC GCHART
• Uses STARTPAGE=NO to keep all the output on the same page
• Uses ODS LAYOUT to position the REPORTs
• Uses GOPTIONS to position the pie charts
1
2 3 4
5 6
7 8 9 10
46
ODS LAYOUT:
The Basics
• Three commands control ODS LAYOUT
– ODS LAYOUT START – turns layout on
– ODS REGION – defines a section of the page
• You can define multiple regions per page
• ODS REGION parameters
– X=uu and Y=uu define upper left corner of the region
» uu = units (in, cm, pt, px, mm, %, em, ex, pc)
– HEIGHT=uu and WIDTH=uu define size of the region
» uu = units (in, cm, pt, px, mm, %, em, ex, pc)
– ODS LAYOUT END – turns layout off
24
47
ODS LAYOUT:
The Rules!
• Regions are defined by the “printable area” of the page – The topmost region area (y=0) begins after
whatever else is already on the page• Titles
• Procedure output not in a LAYOUT region
• Regions are not transparent– Overlapping regions will block out those
underneath
– Order is determined by the order that the regions were defined – first on the bottom, last on the top
48
ODS LAYOUT:
More Rules!
• If the region is too small to accommodate the output, the output is truncated
• ODS LAYOUT, and the specified regions, define the layout of a single page– There are currently no options to span pages, though
there are some in the works
• If the output is too big for a region, it does not span to the next page, it is simply truncated (see above)
WARNING: The absolute region was too small to accommodate the text supplied. OUTPUT WAS LOST.
25
49
Laying Out the Output
ods layout start;
ods region width=2.5in height=3in y=.1in x=0in;
{PROC REPORT code}
ods region width=2.5in height=3in y=.1in x=2.65in;
{PROC REPORT code}
ods region width=2.5in height=3in y=.1in x=5.5in;
{PROC REPORT code}
ods layout end;
Notice that the y positions are
.1in - the bottom of the PROC
SQL sets the printable area
The information at the top of the
page is from PROC SQL, which was
run before the PROC REPORTS
50
ODS LAYOUT:
Still Evolving
• ODS LAYOUT is still pre-prodution, even in v9.2
• There are many options we haven’t looked at today
• For the latest, see Dan O’Connor and Scott Huntley’s paper:
Breaking New Ground with SAS® 9.2 ODS Layout Enhancements
http://support.sas.com/resources/papers/proceedings09/043-2009.pdf
26
51
Adding Text to Any Output
• In the past there were a few ways to add text to a page
– titles and footnotes
– PUT statements in a DATA _NULL_
– graphic text with PROC GSLIDE
• The new ODS TEXT statements allow you to place nicely formatted text anywhere on the page
52
Text Anywhere on the Page:
ODS PDF TEXT• This report has notes at
the top and bottom of the
page, placed using
- ODS TEXT or
- ODS PDF TEXT
• All the inline style options
we’ve seen, using {style},
can be used in the text
• The text can be positioned
anywhere on the page
using ODS LAYOUT
regions
27
53
Text Anywhere on the Page:
ODS PDF TEXT
• Place your text anywhere on the page
ods text="PART II: INTERIM PROGRESS MEASURES";
ods text="Monthly Count of Clients Served: In August 2005, 850...";
The syntax is simple:
ODS TEXT=‘<text here>’;
54
ODS PDF TEXT:
Positioning and Wrapping
• Begins at the left edge of the page, immediately following the last non-graphical output
• Wraps to a new line when it gets to the edge of the page
• Respects escape sequences– Will wrap on {newline}
– Will wrap to a marker (m) with –n
• In an ODS LAYOUT Region– Begins at the left edge of the region
– Wraps when the text reaches the right edge of the region
28
55
Let’s Take a Closer Look
• Inline styles and macro variables can be used in the ODS text
ods region x=.5in y=0in height=.5in width=7in;
ods text="&BF.PART II: INTERIM PROGRESS MEASURES}";
This text is placed in anODS LAYOUT region
Macro variables contain theformatting code: i.e., &BF: ~{style [font_weight=bold]&IF: ~{style [font_style=italic]
56
Another Closer Look
• For maintainability of long text, consider “building” it in a number of macro variables
ods region x=.75in y=.5in height=2in width=7in;
%let MC1 = &BF.Monthly Count of Clients Served: &NF.In ... ;%let MC2 = Based on the pattern of clients served in FY 2005,... ;%let MC3 = &BFI.Thus, &CMName%str(%')s count of &CMClients... ;
ods pdf text="&MC1 &MC2 &MC3";
29
57
Overlaying Text on Graphics:
Another Use of ODS LAYOUT• In this example, the labels on
the bars could not be placed by “normal” SAS/Graph means– Axis labels limited to 32
characters
– Annotate text is just kind of clunky, and doesn’t support any ODS enhancements
• Using ODS LAYOUT regions and ODS PDF TEXT, we can place text on the page that looks like axes labels
58
Overlaying Text on Graphics:
Another Use of ODS LAYOUT
• The ODS text can be placed anywhere on the
page with ODS LAYOUT – even on a graph
ods region x=2.1in y=5.4in height=1in width=2in;
ods pdf text="Fiscal Year 2006 Goal~n(July 1, 2005-June 30, 2006)";
ods region x=4.7in y=5.4in height=1in width=2in;
ods pdf text="Clients Served~nthrough September 2005";
Note the line breaks
forced by the ~n
escape sequences
30
The Future of DATA _NULL_ Reporting
The Report Writing Interface (RWI)
• New to SAS programming are data step “objects” – there are currently two:
– The HASH object
• Contains key-value data lists that can be quickly loaded and searched
– The ODSOUT object
• Can create output with tables, rows, columns, cells, text (and more)
• The ODSOUT object can be used to create highly customized tables and reports with data step code
59
Getting Started with RWIInitializing the Object
• Let’s create a simple table with the RWI
– First, initialize the ODSOUT object with the
DECLARE statement
• Only needs to be done once
– We can use “methods” of that object to create
tables, rows, cells, text, etc.60
if _n_ eq 1 then if _n_ eq 1 then if _n_ eq 1 then if _n_ eq 1 then do;do;do;do;declare odsout o();declare odsout o();declare odsout o();declare odsout o();
end;end;end;end;
Only DECLARE once
• DECLARE is the statement
• ODSOUT is the type of
object
• “o” is the name of the object
31
One Way to StartThe TABLE_START Method
• The TABLE_START method begins a table
• There is a TABLE_END method that ends a table
• The syntax for all method calls is the same
– name of the object (dot) method name
– Most methods have parameters that can be used to
change the default behavior of the object
• Place the parameters in the parentheses
• The parentheses are required, even if not parameters are used
61
o.table_start();o.table_start();o.table_start();o.table_start();
This is a complete data step
statement, ending with a semi-
colon
Adding Rows and Cells
• For a table, what’s printed are the contents of cells, which are inside rows
• There are defaults for the appearance of the table
– Fonts, borders, colors, alignment, etc
– Based on the ODS style that’s being used
62
o.row_start();o.row_start();o.row_start();o.row_start();o.format_cell(text: "text in a cell");o.format_cell(text: "text in a cell");o.format_cell(text: "text in a cell");o.format_cell(text: "text in a cell");
o.row_end();o.row_end();o.row_end();o.row_end();
ROW_START begins a row
ROW_END ends a row
FORMAT_CELL
places text in a cell
(column) of the row.
The TEXT parameter
contains the text to
be printed.
32
Adding Rows and Cells
• This example would create a single cell table, with all the default attributes
63
o.row_start();o.row_start();o.row_start();o.row_start();o.format_cell(text: "text in a cell");o.format_cell(text: "text in a cell");o.format_cell(text: "text in a cell");o.format_cell(text: "text in a cell");
o.row_end();o.row_end();o.row_end();o.row_end();
Assume that the
object has been
declared and that
there is a table start
and end
If we were using the
ODS style “DEFAULT”,
the page would contain
this formatted text
Many Rows and Columns
• You can have as many rows and columns (cells) as you need
64
o.table_start();o.table_start();o.table_start();o.table_start();o.row_start();o.row_start();o.row_start();o.row_start();o.format_cell(text: "Header A");o.format_cell(text: "Header A");o.format_cell(text: "Header A");o.format_cell(text: "Header A");o.format_cell(text: "Header B");o.format_cell(text: "Header B");o.format_cell(text: "Header B");o.format_cell(text: "Header B");
o.row_end();o.row_end();o.row_end();o.row_end();o.row_start();o.row_start();o.row_start();o.row_start();o.format_cell(text: "data a1");o.format_cell(text: "data a1");o.format_cell(text: "data a1");o.format_cell(text: "data a1");o.format_cell(text: "data b1");o.format_cell(text: "data b1");o.format_cell(text: "data b1");o.format_cell(text: "data b1");
o.row_end();o.row_end();o.row_end();o.row_end();
o.table_end();o.table_end();o.table_end();o.table_end();
This will create a table with
two rows, each with two cells
Each row in the table must
have the same number of
cells, but there are
parameters to span columns
33
Changing the Appearanceof the Output
• Most methods allow for overriding the default appearance attributes
65
o.table_start(overrides: 'rules=none frame=void');o.table_start(overrides: 'rules=none frame=void');o.table_start(overrides: 'rules=none frame=void');o.table_start(overrides: 'rules=none frame=void');
o.format_cell(text: "Header A", o.format_cell(text: "Header A", o.format_cell(text: "Header A", o.format_cell(text: "Header A", overrides: 'background=yellowoverrides: 'background=yellowoverrides: 'background=yellowoverrides: 'background=yellow
font_weight=bold');font_weight=bold');font_weight=bold');font_weight=bold');
These are some of the types of overrides
that we can use:
• Turn off the borders on the table
• Change the color and weight of the text
• Other attributes were changed to create
this version of the table
Not Just Simple Tables
• There are other methods that are not associated with a table, these include:
– FORMAT_TEXT() adds text, even without a table
cell
– LINE() draws a horizontal line across the page
– PAGE() inserts a page break
– TITLE() and FOOTNOTE() add titles and footnotes
• Tables can even be placed inside another table’s cell
– Some pretty fancy reports can be created66
34
67
RWI can be Used toCreate Complex Reports
• This report page contains a number of separate text and table elements
– The page header was
created with a
FORMAT_TEXT
method
– The data portion of the
page contains seven
distinct tables
68
Conclusion
• ODS makes reporting fun!
• There are almost limitless possibilities for report layout and formatting that were never available with SAS before
• Experiment with ODS options and statements– Especially LAYOUT and ESCAPECHAR
• There are lots of references cited in the paper – Lots more details that are well worth reading
35
69
Let Me Know the New Things
You Discover
Pete LundLooking Glass Analytics215 Legion Way SWOlympia, WA 98501
(360) [email protected]