I am working on generate a PDF file with several listings with TOC. It is several PROC REPORT in one ODS PDF destination. After referenced some papers and searched in the community about managing TOC by ODS Document and proc document. I can get what I needed if the individual listing can be displayed in one page. And the issues come when the individual listing has multiple pages.
The PROC REPORT generated one bookmark with same name specified at CONTENTS="" for each page when BREAK statement used for page break. However, these bookmarks for each page just has one node (such as \Report#1\Report#1\Report#1), which cannot be delete. And I have to let the page break if the row number large than>18. which means, if one listing has 25 rows, then I want there are 2 pages, the first page has 17 rows and has one bookmark, the second page has 8 rows and has no bookmark.
http://support.sas.com/kb/31/278.html, the way in the support web cannot help me, above issues come if I have to use two breaks.
Is there a way to suppress the unexpected bookmarks in above situation?
Thanks a lot for any help !
Thanks for your suggestion, SAS Tech support provide an way to meet my need. The key is CONTENTS=' ' in BREAK statement, then the bookmark will only show in the first page after set label and copy the path in PROC DOCUMENT.
Hi:
I'm not sure what you mean by unexpected bookmarks. You referred to some kind of problem with the code to suppress the extra TABLE1 node, but you didn't post any code, any data or any picture of what the issue is.
When you describe "each page" as having a bookmark, I'm not sure I understand what you mean, ODS PDF only makes bookmarks based on the options you specify in CONTENTS=.
PROC REPORT is dealing with "objects", not physical pages, so if you have a group of 25 rows and that is one "object" which gets one "bookmark" then if that object displays on multiple physical pages, you would not get a bookmark for each physical page. For example, in the screenshot below, I have used BY group processing to create a bookmark for every Region in my subset of SASHELP.SHOES. Pacific uses more than 1 page for the report rows. But the link for Second Node, is only designed to take me to the TOP of that group, just as the second node for Canada takes me to the TOP of that group. There is nothing in the way bookmarks function to take me to each page within a group.
But you haven't posted anything that really explains what you're getting, and how your getting it or what's wrong with it. Here's some code to test that produced the above screen shot. Note that I did NOT get rid of Third Node, just to illustrate that there are 3 bookmarks possible with PROC REPORT -- note that the BY group processing caused a bookmark too, but the BY group bookmarks are nested underneath the First Node bookmark:
data test;
set sashelp.shoes;
where region in ('Canada', 'Pacific');
count=1;
run;
proc sort data=test;
by region product;
run;
ods pdf file="c:\temp\testtoc.pdf";
ods proclabel="First Node";
proc report nowd data=test contents="Second Node";
by region;
column count region product sales;
define count / group noprint;
break before count / contents="Third Node" page;
run;
ods _all_ close;
If, in my example, you would want a bookmark for page 1 of Pacific and a different bookmark to page 2 of Pacific, that is not something that PROC REPORT or ODS PDF would give you by default.
cynthia
Hi:
In thinking more about it, I wonder whether you want something like this, where you get a certain number of obs (like 35) per page and you really want a separate bookmark for every internal page in a group??
which was produced with this code:
data test;
set newshoes; by region;
retain pgcntr grpobs;
count=1;
if first.region then do; PageNumber=0; grpobs=0; end;
grpobs + 1;
PageNumber = int(divide(grpobs,35))+1;
run;
proc sort data=test;
by region PageNumber;
run;
title;
ods pdf file="c:\temp\toc_pages.pdf";
ods proclabel="Region report";
proc report nowd data=test contents="";
by Region PageNumber;
column count region product sales;
define count / group noprint;
break before count / contents="" page;
run;
ods _all_ close;
cynthia
Hi Cynthia,
Thanks a lot for your reply. I will give you more details and see if there is way to do it.
Let me explain my needs in your second example? I don't want the bookmark for PageNumber=2, but I do need the content of PageNumber=2 show in the physical page = 2 and 4 in the PDF.
When I use BY in the PROC REPORT I will get an NODE for PageNumber=2, but if I remove the NODE, the contents of PageNumber=2 will go. When I use second BREAK (after break before count), there is no NODE for PageNumber=2.
My testing code is:
Hi Cynthia,
Really thanks for your input. I agree your way to code PROC DOCUMENT, but this is a simple example, so I just try the simplest code.
I have a long listing with more than 100 records, and only want to show 20 records in every physical page, which I think can be done by BY or BREAK in PROC REPORT. And I want only one bookmark shown in the first physical page. Am I explaining my need clear?
Your paper is quite detailed, but it hasn't offer an idea how to remove the bookmarks in every physical page after first page but not remove page break.
If using BY in PROC REPORT for page break, copy the level-3 path (path of Type=Table) after first physical page is useless, due to the bookmark is still there.
If using BREAK in PROC REPORT for page break, copy the level-3 path (only one can see in the path, but bookmarks show in every physical page) to new structure cannot change anything, the bookmarks still show in each physical page.
I test in this way:
proc document name=reorder;
list / levels=all;
run;
quit;
proc document;
doc name=work.neworder(write);
make report;
dir \;
dir report;
dir;
copy \work.reorder\Report#1\Report#1 to ^;
copy \work.reorder\Report#1\Report#1\Report#1 to \work.reorder\Report#1\Report#1;
ods pdf file="testpdf.pdf";
replay;
run;
ods pdf close;
run;
quit;
ods _all_ close;
Thanks a lot.
Hi:
I think that anything you do to force a separate object for every physical page you want (such as only 20 obs per page for each group) is going to cause a separate node for the page -- whether you use BY groups or internal Breaks with PROC REPORT. The challenge is that I don't believe you can have the output without the node/bookmark. So this might be a question you have to ask of Tech Support -- whether ODS DOCUMENT nodes can be constructed in such as way that you can copy the output but suppress the node in the Bookmarks. They can look at all of your data and all of your code and advise you whether what you want can be done with ODS PDF and ODS DOCUMENT.
cynthia
Thanks for your suggestion, SAS Tech support provide an way to meet my need. The key is CONTENTS=' ' in BREAK statement, then the bookmark will only show in the first page after set label and copy the path in PROC DOCUMENT.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.