BookmarkSubscribeRSS Feed
deleted_user
Not applicable
Hello All,

I have few (around 5) tables to put in ODS RTF. Each table corresponds to each proc report in my code.

1) I tried to put them without any extra code other than individual proc reports. The result was that I got a single table in each page with enough space to fit one or two more.
2) Then, I tried to put some pagebreaks manually between two or three tables (after my earlier post "Pagebreaks in ODS RTF"). This works fine most of the times. But, if I have little more information in one of my tables, the table goes to the next page and make things still worse.

Do we have any avenue in SAS 8 to fit exact number of tables, it can, into a single page rather than forcing pagebreaks. Can anyone help me with this?

Thanx in advance
N. Hemanth Padmakar.
8 REPLIES 8
Cynthia_sas
SAS Super FREQ
Hi,
When you use startpage=no option with ODS RTF, you are telling SAS to suppress any page feed characters or instructions that it normally puts at the beginning of every procedure.

When you use startpage=now to force a page break between procedures, SAS will insert a page feed character or instruction.

The KEEPN option for RTF puts an instruction into your RTF document that you want tables to stay together on one page (rather than split them across pages). So if you try this:
[pre]
ods rtf file='somefile.rtf' startpage=no keepn;

** proc report 1;
** proc report 2;
** proc report 3;
ods rtf close;
[/pre]

Then let's say that proc report 3 output did not have enough room to fit the whole table on the same page as proc report 2 -- you should then see that proc report 3's output starts on a page to itself.

cynthia
deleted_user
Not applicable
Hello,

Thanx for you reply Cynthia,

Keepn looks for a single table to split across pages or not. But my intention is to put multiple tables across pages. So, my main aim is to fit as many tables as i can into a single page. For instance, if I've put two tables into a page and still, I've enough spce to put the third one, I need to put the third one into the same page. (A kind of automation).

So, Is there any macro variable or function or any method to get how many lines does a proc report occupy in the output page? Once, we get this, My idea is to find if the next report has sufficient room in this page.

Can I get some info regarding this.

Thanx,
Hemanth.
Cynthia_sas
SAS Super FREQ
Have you tried startpage=no -- the whole purpose of the startpage option is to put as many tables on a page as possible. Right now, in SAS 9.1.3, there is NO vertical measurement technique available for ODS RTF.

For example, in a DATA step program to the LISTING destination, you can count the number of lines per printed page, by generally, counting PUT statements or using a technique called LINESLEFT. However, the LISTING destination is a monospace font destination and techniques that work for LISTING do not work for ODS RTF, ODS PDF or ODS HTML.

Every word processor that opens an RTF file will control the page breaks (or vertical measurement) based on the proportional font of the document and how many lines -AT THAT FONT SIZE- will fit on a page. In addition, the word processor program (probably MIcrosoft Word) has to reserve space around tables for the table grid lines. A table rendered in proportional font Times Roman at 20 pt will take up more room on the page than a table rendered in proportional font 10pt on a page.

To further complicate things -- it would be possible for you to have 2 tables on a page in 2 different font sizes! The number of lines "available" would change in the between the two tables.

SAS does not RENDER the RTF file. SAS only creates the control strings that MUST be rendered by the Word Processor (Word) or RTF rendering program. In addition, the RTF document can be altered or changed by Word .dot templates or Word macros after the file has been created by SAS -- so 2 people with 2 different settings in Word, might see an RTF file created by SAS a different way (perhaps one person automatically applies a Word formatting macro to their opened documents and the other person doesn't).

In SAS 9.2, there will be a new "flavor" of RTF (different from the current RTF) that will give you more control over page-breaking. That flavor of RTF is called "measured" RTF. I still do not think you will have LINE-by-LINE control (such as counting each line) -- but you should have more control over some RTF capabilities, as described here: http://www2.sas.com/proceedings/sugi31/067-31.pdf

In addition, there is a lot of excitement over Microsoft's announcement that they were going to support something called Open Document Format -- a standard for documents that was not created by Microsoft (RTF was a Microsoft created specification). You can read the announcement of the ODF adoption by the ISO here: http://www.computerworld.com/softwaretopics/software/apps/story/0,10801,111130,00.html

And there's mention of possible ODS creation of Open Document Format output in this paper: http://support.sas.com/rnd/base/topics/odsmarkup/Paper_227-2007_ODS_Office.pdf

However, that technology is in the future and won't help you now. Your best bet is to experiment with startpage=no for now or to contact Tech Support for more help.

cynthia

ps...in the ODS RTF documentation for KEEPN, there is this tip:
Although KEEPN minimizes page breaks in tables, it might use substantially more paper than NOKEEPN because it issues a page break before starting to print any table that does not fit on the remainder of the page.
This statement implies to me that ODS RTF is internally doing SOME kind of "counting" behind the scenes in order to approximate what will fit on a "page" -- however, you cannot get to that internal code.
Duong
Obsidian | Level 7
Hi Hemanth

Pagination is not easy in ODS RTF.
but Jiang and Boisvert (PharmaSug 2006) have a beautiful solution for it.



Duong
deleted_user
Not applicable
Hello,

Thanks for you replies,

Cynthia, Startpage=No is a nice option, but shouldn't I have to compromise with the titles, because this option (looks like) suppresses all the titles. Otherwise it's fine.

Duong, I've read the paper before. It's really good, but I think, they were explaining the scenario, when you have a single report which flows to the next page. But, my issue was with multiple reports. I think I need to do some modifications to his code and work on that. Not sure, if it applies to me or not.

However thanx a lot.

Regards,
Hemanth.
Cynthia_sas
SAS Super FREQ
But, you can use ODS RTF TEXT= to place text between the procedures. That allows you to simulate the SAS Title.

You only have an issue because by default the SAS title goes into an RTF control string that defines the document header text. So when you have startpage=no, there is no header "between" tables. So you have to look to alternate techniques, like TEXT= to insert title-like text between tables.

In fact, the only time I ever use ODS RTF TEXT= is when I use STARTPAGE=NO.

[pre]
title; footnote;
options nodate nonumber;

ods path sasuser.templat(update)
sashelp.tmplmst(read);

** this template code will cause the UserText style element to be formatted;
** in a larger font and centered.;
** by default, it is left justified and in a small font.;
proc template;
define style styles.utext;
parent=styles.rtf;
style UserText from UserText /
just=c
font_size=12pt
font_face='Times New Roman'
font_weight=bold
font_style=italic
protectspecialchars=off;
end;
run;

ods rtf file='c:\temp\sp_text.rtf' startpage=no style=styles.utext;
** need escapechar for page x of y page numbering;
ods escapechar='^';

title j=c 'The Report Title in the Header' j=r '^{pageof}';

ods rtf text='First One';
proc print data=sashelp.class;
where age gt 14;
run;

ods rtf text='End of print \line';
** the \line is an RTF control string for some extra space;
** after this text line;

ods rtf text='Second Proc';

proc means data=sashelp.shoes min median max;
var sales;
run;

ods rtf text='Means on Actual';

proc means data=sashelp.prdsale min median max;
var actual;
class prodtype;
run;

ods rtf text='Short Students';
proc print data=sashelp.class;
where Height lt 70;
run;

ods rtf text='No More Short Students \line';
ods rtf text='Twas brillig and the slithy toves';
ods rtf text='Did gyre and gimble in the wabe';
ods rtf text='All mimsy were the borogroves';
ods rtf text='And the mome raths outgrabe.';
ods rtf close;
[/pre]

Between startpage=no and TEXT=, I think you'll come very close to what you want.

You may have a few final tweaks, after you look at the output, but those should be minor.

Good luck!
cynthia
deleted_user
Not applicable
Hello Cynthia,
Thanks for your reply,
I'm currently working on this. I hope this will help me, but I'm sure that I need to compromise with things like, text(ods rtf text=) coming in one page (at the end) and the corresponding table coming in the next page. Isn't it? Or, do we have any solution for that?

But still, my task seems to be almost achieved. Thanx a lot.

Regards,
Hemanth.
Cynthia_sas
SAS Super FREQ
Hemanth:
Well, I don't consider it a compromise issue, so much as a "this is how it works" issue. Many times when I am typing in Word, there is room for one more line at the bottom of the page, but not for 3 more lines. I have to decide whether to manually insert a page break in Word or do a "Keep With Next" -- based on what I'm -seeing- in the document.

However, this is where
ODS RTF STARTPAGE=NOW;
can help you. Place it BEFORE the ODS RTF TEXT where you want the page break control to be inserted. For this particular set of data, if you go back and forth between the document with one set of STARTPAGE settings and a different set of STARTPAGE settings, you should be able to come very close to what you need. After that, manual tweaks in Word may still be needed, but they should be minimal. Just keep in mind that 2 different folks with 2 different default font sizes and 2 different margin settings could open your RTF document into Word and then their 2 versions of the same document might have different page breaks.

I consider the use of STARTPAGE and ODS TEXT= to be an iterative process...create the file the first time, look at where the page breaks happen, compared to the size of your tables. I always start at the beginning of the document to place my STARTPAGE=NOW instruction because page break insertions at the front of the document will have an effect on how the rest of the document looks.

A few things to watch out for:
1) always close your word processor/RTF file before you run a job a second time with the same name for FILE= -- otherwise, you get "file in use" messages because Word will be holding the document open for editing.
2) Sometimes, when you just visually scan the page, it seems as though there ought to be room for what you want. Generally, to verify whether I am right, I save my RTF file as a Word doc and then go back into the Word doc, remove the page break (have to turn on "Show/Hide" paragraph button) and see whether -- given my margins, fonts and the gridlines on the table -- there is really room for the text and table. Most times, I discover that I am wrong and Word does not think it has enough room on the page.
3) There is an RTF control string for doing page breaks -- two of them in fact --
[pre]
ods rtf text='\pagebb';
ods rtf text='Want this on new page';
or
ods rtf text='\page';
ods rtf text='Want this on new page';
[/pre]

The "pagebb" says to put a page break before the next paragraph. The "page" says to insert a required page break. I have used them with only partial success. I find STARTPAGE=NOW to be more reliable than these particular control strings.

Good luck!
cynthia

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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
  • 8 replies
  • 12690 views
  • 0 likes
  • 3 in conversation