The SAS Output Delivery System and reporting techniques

ODS Data Step Object

Reply
Frequent Contributor
Posts: 102

ODS Data Step Object

I wonder how many people use the ODS data step object. I know it's experimental, but lots of people use experimental features.

An enhancement I'd like: the ability to directly address table cells, instead of having to figure out where everything is going to go, and then writing it sequentially.

One way to specify it: add ROWS and COLUMNS parameters to TABLE_START, then ROW and COLUMN to FORMAT_CELL and CELL_START.

Hmm, what if I want to get to a nested table from the outer table, or to the outer table from a nested table? I guess htat would be hard.

I guess I could set up a big mess of arrays, write my data there, and then at the end go through the arrays and make the ODS calls, but I'd prefer something a bit more built in.

The specific application I'm thinking about is the ability to build a spreadsheet, filling out cells one at a time.
SAS Employee
Posts: 174

Re: ODS Data Step Object

Jack,

The data step object integrates the DATA step with ODS' document model,
which includes a table model. ODS' table model is based on the HTML table
model, which is a table-row-cell model. ODS' table model implementation
doesn't support the kind of random access you're describing.

Tables and spreadsheets are fundamentally different things.

Thanks for experimenting with the data step object.

-- David Kelley, SAS
N/A
Posts: 0

Re: ODS Data Step Object

I appreciate the elegance of the HTML-like cell-addressable approach to building table reports provided by the ODS Data Step Object. As I can do in HTML, I am trying to stack 2 cells in column 2 to complete a ROW_SPAN. Here is a picture of my intent.

row1:col1 row1:col2 row1:col3
row2:col2

In the following code, I want util2 to stack under util1.

obj.ROW_START();
obj.FORMAT_CELL(TEXT: utilgrp,ROW_SPAN : 2);
obj.FORMAT_CELL(TEXT: util1);
obj.FORMAT_CELL(TEXT: cpmpm,ROW_SPAN : 2);
obj.ROW_END();

obj.ROW_START();
obj.FORMAT_CELL(TEXT: util2);
obj.ROW_END();

Here is what I get.

row1:col1 row1:col2 row1:col3
row2:col1 null null
SAS Employee
Posts: 16

Re: ODS Data Step Object

ods pdf file="test.pdf";
data _null_;
dcl odsout obj();

obj.table_start();
obj.row_start();
obj.format_cell( text: "utilgrp",
row_span: 2 );
obj.format_cell( text: "util1" );
obj.format_cell( text: "cmppm",
row_span: 2 );
obj.row_end();

obj.row_start();
obj.format_cell( text: "util2" );
obj.row_end();
obj.table_end();

obj.delete();
run;

ods pdf close;

The above pgm produced something similar to the following diagram at v9.2 and v9.1.3sp4.

Forgive the formating it does not want to retain my spacing.

----------------------------
| utilgrp | util1 | cmppm |
| | util2 | |
----------------------------

Is this what you want?
What release are you using?
SAS Employee
Posts: 174

Re: ODS Data Step Object

Although it doesn't appear to be documented in the Help, the forum software supports preformatted text. All you have to do is enclose the text in bracketed pre and /pre tags. Here's what I think Dan wished to express:
[pre]
----------------------------
| utilgrp | util1 | cmppm |
| | util2 | |
----------------------------
[/pre]
-- David Kelley, SAS
N/A
Posts: 0

Re: ODS Data Step Object

Dan,

Yes, this is what I want. We are running SAS 9.1.3 Service Pack 3. Do I need SP4 to make this work?

Regards,

Dwight
SAS Employee
Posts: 174

Re: ODS Data Step Object

I expect that SP3 works the same as SP4.

-- David Kelley, SAS
N/A
Posts: 0

Re: ODS Data Step Object

Sorry if I jump in like this, but how do I access documentation on the ODS data step object? I searched for it at the SAS 9.1 Online documentation at http://support.sas.com/onlinedoc/913, but couldn't find anything.
Furthermore, under the path Base SAS -> SAS Language Concepts -> Data Step Concepts -> Using DATA Step Component Objects, the only objects listed as available in a data step are the Hash object and the Hash Iterator object.
Thanks


Message was edited by: DanielMastropietro at Mar 22, 2006 4:40 PM
Message was edited by: DanielMastropietro at Mar 22, 2006 6:44 PM
SAS Employee
Posts: 174

Re: ODS Data Step Object

Daniel,

Here is some documentation:

http://support.sas.com/rnd/base/topics/datastep/dsobject/

-- David Kelley, SAS
SAS Employee
Posts: 16

Re: ODS Data Step Object

Dwight,

It appears to work at Service Pack 3 for me as well.
Can you confirm with the test pgm that I provided?

thanks,
Dan
N/A
Posts: 0

Re: ODS Data Step Object

Dan,

Your example works as you expected on our SP3. I will retry this approach on my code and let you know.
N/A
Posts: 0

Re: ODS Data Step Object

I think I discovered my problem with ROWSPAN: I was using a character argument instead of numeric. Whoops! Thanks for your assistance.
N/A
Posts: 0

Re: ODS Data Step Object

This code joins the 2 FORMAT_TEXT strings above the table.
How can I get the strings on separate lines?

IF FIRST.type THEN DO;
obj.FORMAT_TEXT(TEXT: CATX(' ','Normative Comparison Summary for',type));
END;

IF FIRST.frstincr THEN DO;
obj.FORMAT_TEXT(TEXT: time);
END;

obj.TABLE_START();
obj.ROW_START(TYPE: 'HEADER');
obj.FORMAT_CELL(TEXT: ' ');
obj.FORMAT_CELL(TEXT: 'Avg. LOS');
obj.FORMAT_CELL(TEXT: 'Admits/1,000');
obj.FORMAT_CELL(TEXT: 'Scripts/Member');
obj.ROW_END();

obj.ROW_START();
obj.FORMAT_CELL(TEXT: 'Account');
obj.FORMAT_CELL(TEXT: PUT(avglos ,7.2));
obj.FORMAT_CELL(TEXT: PUT(admthou,7.2));
obj.FORMAT_CELL(TEXT: PUT(rx_util,7.2));
obj.ROW_END();
obj.TABLE_END();
N/A
Posts: 0

Re: ODS Data Step Object

How can I replicate the behavior of the following 2-part TITLE statement using the TITLE() method?

title j=c 'Main Title' j=r "DATE: %SYSFUNC(TODAY(),MMDDYY10.)";
proc print data=sashelp.class;
run;
SAS Employee
Posts: 16

Re: ODS Data Step Object

ods listing close;

/* Try pdf & rtf as well */
%let dest =html;
options nodate nonumber;
ods &dest file="test.&dest";

title j=c 'Main Title' j=r "DATE: %SYSFUNC(TODAY(),MMDDYY10.)";
proc print data=sashelp.class;
run;

title;
data _null_;
set sashelp.class end=eof;
if _n_ = 1 then do;
dcl odsout obj();
obj.title(text: "Main Title",
overrides: "width=5.5in just=right",
text: "Date %SYSFUNC(TODAY(), MMDDYY10.)",
overrides: "width=4.5in just=right");

obj.table_start();
obj.row_start(type: "header");
obj.format_cell(text: "Name");
obj.format_cell(text: "Sex" );
obj.row_end();
end;

obj.row_start();
obj.format_cell(text: name);
obj.format_cell(text: sex);
obj.row_end();

put eof=;

if eof = 1 then do;
obj.table_end();
obj.delete();
end;
run;

ods &dest close;
Ask a Question
Discussion stats
  • 18 replies
  • 260 views
  • 0 likes
  • 4 in conversation