Hi Community,
I need your help in achieving this case using PROC REPORT and output to ODS PDF .
I have 2 PROC Reports lets call PR1 and PR2
PR1 - contains Header and has detailed data
PR2 - No Header and has summarized data of PR1(Single row)
Problem is that: When PR1 page fills page1 completely, PR2 prints on a new page with NO HEADERS, where as the requirement is that even if moves to next page, PR1 Headers should be intact, so that users can understand that summarized values are meant for those columns.
How can i achieve this, so that i can have PR1 header to be printed(in next page) whenever PR2 moves to the next page.
Sample Report:
Product sales (PR1)
a 23
b 24
c 23
...
...
...................PR2
Total 70
when PR2 is moved down to next page i need Headers of PR1, Which tell users that it is the total of PR1 report.
ods listing close;
options orientation=portrait topmargin=.05in bottommargin=.05in leftmargin=.4in rightmargin=.01in nonumber nodate;
ods pdf file="W:\Project\test\Task\output\PR_REPORT.pdf" notoc style=report;
/*Sample data*/
data dummy;
keep regionname productline productname price1 price2 date;
set sashelp.pricedata;
run;
/*Inserting Dummy records for Region1, so that PR2 prints on 2nd Page*/
proc sql;
insert into dummy values ("1jan1998"d,52.4, 52.3, "Region1", "Line1", "Product1");
insert into dummy values ("2jan1998"d,53.4, 52.3, "Region1", "Line1", "Product1");
insert into dummy values ("3jan1998"d,54.4, 52.3, "Region1", "Line1", "Product1");
insert into dummy values ("4jan1998"d,55.4, 52.3, "Region1", "Line1", "Product1");
insert into dummy values ("5jan1998"d,56.4, 52.3, "Region1", "Line1", "Product1");
..
..
..
..
;quit;
/*Sorting */
proc sort data=dummy;
by regionname productline productname;
run;
/*Filtering only for 1 Region*/
data dummy;
set dummy;
where regionname="Region1";
run;
/*PR1*/
ods escapechar='~';
proc report data=work.dummy
style(column)=[color=black fontsize=6pt borderspacing=0 borderwidth=0 fontfamily=courier textalign=left ASIS=ON]
style(header)=[color=black fontsize=6pt background=white fontfamily=courier textalign=left borderbottomwidth=1px borderbottomstyle=solid borderbottomcolor=black borderleftwidth=0 borderrightwidth=0]
style(report)=[ASIS=ON bordercolor=white borderwidth=0 fontfamily=courier textalign=left fontsize=6pt rules=none frame=void cellspacing=0 cellpadding=4]
nowindows headskip;
column hierarchy productLine productname date price1 price2;
define hierarchy / group ;
define productLine / group noprint ;
define productname/group noprint ;
define price1 / analysis ;
define price2 / analysis ;
define date/display;
define line / display ;
define pge / order ;
where year(date)=1998;
run;
/*Creating Aggregate table for PR2*/
proc sql;
create table agg_dummy as
select regionname,productline, productname, sum(price1) as sum_price1, sum(price2) as sum_price2
from work.dummy
group by regionname,productline, productname
;quit;
/*PR2*/
ods pdf startpage=no;
proc report data=work.agg_dummy
style(column)=[color=black fontsize=6pt borderspacing=0 borderwidth=0 fontfamily=courier textalign=left ASIS=ON]
style(header)=[color=black fontsize=6pt background=white fontfamily=courier textalign=left borderbottomwidth=1px borderbottomstyle=solid borderbottomcolor=black borderleftwidth=0 borderrightwidth=0]
style(report)=[ASIS=ON bordercolor=white borderwidth=0 fontfamily=courier textalign=left fontsize=6pt rules=none frame=void cellspacing=0 cellpadding=4]
nowd nowindows headskip noheader;
column regionname productline productname sum_price1 sum_price2 ;
define regionname / group ;
define productLine / group ;
define productname/group ;
define sum_price1 / analysis ;
define sum_price2 / analysis ;
run;
ods pdf close;
ods _all_ close;
Let me know if you need more information.
Thank you 🙂
Hi:
I'm sorry, when I look at SASHELP.PRICEDATA, I do not see the variable PGE that you have in your data. Here's what I see in PROC CONTENTS:
and yet your COLUMN statement has a variable named PGE? What version of SASHELP.PRICEDATA are you using? I am running SAS 9.4 M5 and do not have a variable called PGE. And, in fact, if I run your code, as written, I get this error:
ERROR: Variable pge is not on file SASHELP.PRICEDATA.
Then your second step uses a file called: WORK.AGG_DATA which you do NOT provide. However, in the PROC REPORT statement you are explictly turning off headers with the NOHEADER option. Have you tried removing that option to see if the output is closer to what you want?? Your second report has REGIONNAME on the report, so it would never line up with the columns from the previous report, anyway.
Also you have some options in your code like HEADSKIP which will be ignored by ODS PDF and you do not show your ODS PDF statements. So, no one can run your code and observe what you are observing. Also, I could not open your attachment because it was being scanned for viruses and would not open.
Cynthia
Hi Cynthia,
I have updated the question with all the working code i have.
PGE Variable - i missed out while cleaning up the code before posting, it is not available in the dataset.
I have added WORK.AGG_DATA PROC SQL code
For some reason it is still scanning for virus, please refer below for the report layout
PR1 regionname productline productname price1 price2
… … … … …
… … … … … PAGE1
… … … … …
PR2 SUM … …
PR1 regionname productline productname price1 price2
… … … … …
… … … … … PAGE-1 bottom
… … … … …
regionname productline productname price1 price2 -----> This header I would like to have when PR2 comes down to a new page
PR2 SUM … …. PAGE-2
Let me know if you need any more information.
Thank you.
Hi:
I'm sorry, I don't see a HIERARCHY variable in SASHELP.PRICEDATA. Still can't run your code. Still don't know how you're doing what you're doing or how you're creating the HIERARCHY variable.
This might be the kind of question that you're better off asking of Tech Support. They can look at ALL your code and your actual data and help you come to a resolution.
Cynthia
Hi:
Let's start from code and data that works, that anyone can run and that only depends on variables in the data. When I run this code, I make 2 months of data for 3 regions in SASHELP.SHOES:
data newshoes;
set sashelp.shoes;
where region in ('Canada', 'Asia', 'Pacific');
** make some fake data for 2 months;
do date='01jan2019'd to '28feb2019'd by 1;
sales= sales + 1;
inventory = inventory + 1;
output;
end;
run;
Now I run these 2 PROC REPORTS to ODS PDF. I have simplified the PROC REPORTS to take all the defaults as far as style and output and the ONLY thing I have done to ODS PDF is turn STARTPAGE=NO so that I can see the summary from the 2nd PROC REPORT immediately underneath the output from the first PROC REPORT. Here's my PROC REPORT code -- I have now provided data with 3 grouping variables (REGION, PRODUCT and DATE) and 2 numeric variables SALES and INVENTORY. Anyone can run my program to make the data and run my PROC REPORT code:
ods pdf file='c:\temp\two_reports.pdf' startpage=no;
proc report data=newshoes nowd;
column region product date sales inventory ;
define region / group ;
define product/ group ;
define date / group order=internal f=monyy.;
define sales / analysis sum;
define inventory / analysis sum;
run;
proc report data=newshoes nowd;
column region product sales inventory ;
define region / group ;
define product/ group ;
define sales / analysis sum;
define inventory / analysis sum;
run;
ods pdf close;
Here's the output I get:
As you can see, by default, when my first report output spills over to page 2, the headers are repeated. Then, the output from the second PROC REPORT also shows headers. The first PROC REPORT shows the summary for each month within Region and Product and the second PROC REPORT shows the summary just by REGION and PRODUCT without regard to Date.
Since you post code with variables that are not in SASHELP.PRICEDATA and since I can't run code without data, I'm taking a different approach. I don't see that you need your own "PGE" variable to control page breaking. I can get headers on the second PROC REPORT using the defaults (and without the NOHEADER option). So perhaps you can explain using my code and output as the basis, what it is about the report that my code creates that you would want to change. I did not bother to add a BREAK statement in my first PROC REPORT because I wanted to keep the output to 2 pages for both reports.
Cynthia
Hi Cynthia,
Thank you 🙂 for all the effort you put in to understand and help me in solving this problem.
I have used your code and enhanced it as per the requirement.
Two challenges which i am working on:
1. Repetitive Headers of PR1
2. PR1 header needs to be printed on next page when PR2(no header) moves to a new page.
Here is the code which i have developed, you can run this code as is and generate the PDF report
data newshoes;
set sashelp.shoes;
**removing single quotes from products;
product = compress(product, "'");
where region in ('Canada', 'Asia', 'Pacific');
** make some fake data for 2 months;
do date='01jan2019'd to '28mar2019'd by 1;
sales= sales + 1;
inventory = inventory + 1;
output;
end;
run;
**Getting distinct of Region and Product;
proc sql;
create table dist_Region_prod as
select distinct region, product from newshoes;
;quit;
**Assigning Row number;
data dist_Region_prod;
set dist_Region_prod;
sno = _n_;
run;
**creating macro variable nrows with count value;
proc sql noprint;
select count(*) as cnt into :nrows from dist_region_prod;
;quit;
ods pdf file='W:\TestProject\task\output\two_reports.pdf' startpage=no ;
%macro filter_report();
%macro d;%mend d;
%do i=1 %to &nrows;
/*Running loop for distinct region and product and assigning to a macro variable*/
proc sql noprint;
select distinct strip(region) into :region from dist_Region_prod where strip(put(sno,8.))="&i";
select distinct strip(product) into :product from dist_Region_prod where strip(put(sno,8.))="&i";
;quit;
/*filtering data for distinct region and product using macro variable created above*/
data newshoes_filtered;
set newshoes;
where region = strip("®ion.") and product = strip("&product.") ;
run;
/*PR1:*/
proc report data=newshoes_filtered nowd
style(column)=[color=black fontsize=6pt borderspacing=0 borderwidth=0 fontfamily=courier textalign=left ASIS=ON]
style(header)=[color=black fontsize=6pt background=white fontfamily=courier textalign=left borderbottomwidth=1px borderbottomstyle=solid borderbottomcolor=black borderleftwidth=0 borderrightwidth=0]
style(report)=[ASIS=ON bordercolor=white borderwidth=0 fontfamily=courier textalign=left fontsize=6pt rules=none frame=void cellspacing=0 cellpadding=4]
;
column region product date sales inventory ;
define region / group ;
define product/ group ;
define date / group order=internal f=monyy.;
define sales / analysis ;
define inventory / analysis ;
define gap / ' ' style={cellheight=.70in};
run;
/*PR2:*/
/*noheader option is used as we get headers from PR1*/
proc report data=newshoes_filtered nowd noheader
style(column)=[color=black fontsize=8pt borderspacing=0 borderwidth=0 fontfamily=courier textalign=left ASIS=ON]
style(header)=[color=black fontsize=8pt background=white fontfamily=courier textalign=left borderbottomwidth=1px borderbottomstyle=solid borderbottomcolor=black borderleftwidth=0 borderrightwidth=0]
style(report)=[ASIS=ON bordercolor=white borderwidth=0 fontfamily=courier textalign=left fontsize=7pt rules=none frame=void cellspacing=0 cellpadding=4]
;
column region product gap sales inventory ;
define region / group ;
define product/ group ;
define sales / analysis sum ;
define inventory / analysis sum;
run;
%end;
%mend filter_report;
%filter_report;
ods pdf close;
Report Output would be similar to the above image also I have highlighted the challenges.
Please ignore the formatting and indentation of PR2.
Let me know if you need anymore information.
Thank you 🙂
Hi Cynthia,
Thank you for the detailed explanation.
Can we have PROC REPORT 2 header to print only when it is starting at the TOP of a NEW PAGE?
If it is not at the TOP of the page, it should not print PAGE HEADER.
Thank you.
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.