BookmarkSubscribeRSS Feed
JackHamilton
Lapis Lazuli | Level 10
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.
18 REPLIES 18
David_SAS
SAS Employee
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
deleted_user
Not applicable
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
DanO_sas_com
SAS Employee
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?
David_SAS
SAS Employee
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
deleted_user
Not applicable
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
David_SAS
SAS Employee
I expect that SP3 works the same as SP4.

-- David Kelley, SAS
deleted_user
Not applicable
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
David_SAS
SAS Employee
Daniel,

Here is some documentation:

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

-- David Kelley, SAS
DanO_sas_com
SAS Employee
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
deleted_user
Not applicable
Dan,

Your example works as you expected on our SP3. I will retry this approach on my code and let you know.
deleted_user
Not applicable
I think I discovered my problem with ROWSPAN: I was using a character argument instead of numeric. Whoops! Thanks for your assistance.
deleted_user
Not applicable
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();
deleted_user
Not applicable
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;
DanO_sas_com
SAS Employee
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;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 18 replies
  • 1874 views
  • 0 likes
  • 4 in conversation