BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
RichardP
Quartz | Level 8

Hello,
I am using ODS document to compose a report. I am using PROC PRINT and PROC ODSTEXT. When replaying the output into an RTF document I cannot seem to control the pagebreaks. There is always a page break after each object. If I specify STARTPAGE=NO then they are removed but I lose all control over the pagebreaks. I have tried OBSPAGE in PROC DOCUMENT to delete the pagebreaks and when inpecting the catalog it would appear that pagebreaks are not present. How do I use pagebreaks in combination with PROC DOCUMENT? I have included very simple code to illustrate the issue. Any help very much appreciated!

 


libname docout "c:\home\";

ods document name=docout.test(write) ;

ods proclabel " ";
title;
proc odstext contents="" ;
p "{\pard\s1\b\ul sashelp.class listing \par}" / style=[fontsize=14pt fontweight=bold fontfamily=Arial]; /* adds a HEADER1 to word document */
run;

ods proclabel " ";
proc print data=sashelp.class;
run;

ods document close;


ods rtf file="C:\Home\test.rtf"
contents=no toc_data startpage=no;

ODS RTF TEXT="{\pard\b\fs28\l\ulth {Table of Contents} \par}";
run;
ODS RTF TEXT="{\field{\*\fldinst {\\TOC \\f \\h} } }";
RUN;


proc document name=docout.test;
replay \ODSText#1\TextBlock#1;
replay \Print#1\Print#1 / ;

/* PAGE BREAK HERE PLEASE */
replay \ODSText#1\TextBlock#1;
replay \Print#1\Print#1 / ;
run;

ods rtf close;

1 ACCEPTED SOLUTION

Accepted Solutions
RichardP
Quartz | Level 8

Hi, 

 

the solution is to use OBSPAGE <object> with no further parameters. This adds a PAGEBREAK to the beginning of object. However the post from @Cynthia_sas paved the way for a better understanding of how PROD DOCUMENT works, worth a read, see above. 

 

proc document name=docout.test;

OBSPAGE  \ODSText#1\TextBlock#1; /* add a pagebreak */
replay \ODSText#1\TextBlock#1;
replay \Print#1\Print#1 /;   

/* PAGE BREAK HERE PLEASE */
replay \ODSText#1\TextBlock#1;
replay \Print#1\Print#1 / ;
run;

 

View solution in original post

6 REPLIES 6
RichardP
Quartz | Level 8

@Cynthia_sas Would you perhaps have an answer to this? 

 

 

Cynthia_sas
SAS Super FREQ

Hi:
Well, I've never mixed RTF control strings with output that I'm sending to ODS RTF via ODS DOCUMENT, so I can't speak to that. My habit is to NOT use any titles and I turn procedures titles off when I write the original output to the DOCUMENT store. If I'm doing BY group processing, I'll keep the BYLINES in the document until I figure out whether I want them or not. Also, I do not do anything to remove the normal page breaks between tables at this point (like with startpage).

Then I rearrange my output in a new document store the way I want and replay it to my destination, without doing anything about titles, footnotes or page breaks. Next, I see how the document output looks, after being rearranged and replayed. I make a backup copy of the rearranged document in the document store so I have something to fall back to if I completely mess things up.

Now that I see where ODS wants to put the page breaks in the rearranged document, I start removing the page breaks from the top of the new document, just a few page breaks at a time to see how things fit. This is sort of fiddly, but I prefer to make gradual changes and see how they work out instead of writing one huge program at a time. Once I figure out what object needs to get a page break, I will insert it with the correct OB command and stick in the OB titles while I'm at it. Then I keep on deleting, inserting and fiddling with the page breaks until everything's the way I want. Since most of the OB commands are PROC DOCUMENT commands, I usually end up with one PROC DOCUMENT that does the rearranging and then a second PROC DOCUMENT that does the page breaking and titles. When I finally have everything the way I want, I will combine the 2 PROC DOCUMENTS into 1 PROC DOCUMENT step and replay the new document.

If I don't want to keep the backup of the original document or the rearranged backup, then I will delete them. But honestly, I'm too paranoid to ever get rid of the original DOCUMENT that I created, so I rarely ever delete that, just in case.

It almost looks to me like you're trying to replay the same output twice, but with your own TOC. You can use startpage=now, but it has to be at a break between PROC steps, so it can't be inside PROC DOCUMENT. But have you considered something like this:

ods rtf startpage=now;

Cynthia_sas_0-1599873615218.png


I did not succeed at making the TOC get generated, but I think that's because you have to do that protectspecialchars=off to have the control strings pass through to RTF without being "protected".

Hope this points you in a direction. For help with the TOC, I'd recommend working with Tech Support. I never try to build my own TOC -- I just use the one that RTF generates for me.

Cynthia

RichardP
Quartz | Level 8

Wow Cynthia thanks for this very insightful answer! I am still trying to understand how proc document is working and this post cleared up a few things for me. I like this way of working. 

 

With regards to the custom TOC, yes this is also not my preferred way however my document has two cover pages and then the TOC appears. With the standard RTF TOC it would appear to be placed at the beginning of the document. Is there a way to customize the location? With the custom TOC using PROC ODSTEXT I can position it where needed.

 

ballardw
Super User

Not sure how feasible this might be in practice but I would be tempted to create some output that contains only a page break character, likely with a Data _null_ step and File print ods .

Then replay that "document" as needed.

RichardP
Quartz | Level 8
Hi thanks for this, This was fall back solution 😉
RichardP
Quartz | Level 8

Hi, 

 

the solution is to use OBSPAGE <object> with no further parameters. This adds a PAGEBREAK to the beginning of object. However the post from @Cynthia_sas paved the way for a better understanding of how PROD DOCUMENT works, worth a read, see above. 

 

proc document name=docout.test;

OBSPAGE  \ODSText#1\TextBlock#1; /* add a pagebreak */
replay \ODSText#1\TextBlock#1;
replay \Print#1\Print#1 /;   

/* PAGE BREAK HERE PLEASE */
replay \ODSText#1\TextBlock#1;
replay \Print#1\Print#1 / ;
run;

 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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