BookmarkSubscribeRSS Feed
CC_SAS
Obsidian | Level 7

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 🙂

9 REPLIES 9
Cynthia_sas
SAS Super FREQ

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

 

CC_SAS
Obsidian | Level 7

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.

Cynthia_sas
SAS Super FREQ

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

Cynthia_sas
SAS Super FREQ

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:

shoes_two_reports.png

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

CC_SAS
Obsidian | Level 7

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("&region.") 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;

VSA-2.jpg

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 🙂

 

Cynthia_sas
SAS Super FREQ
Hi:
There's a problem with your assumption that PROC REPORT2 will use the headers for PROC REPORT1. That is NOT possible. PROC REPORT2 will NEVER use the headers from PROC REPORT1. I believe that you will need to work with Tech Support on this challenge or to find a workaround. Even if you make your own page variable, the headers for PROC REPORT 1 only belong to PROC REPORT 1. When PROC REPORT 1 is finished, there are NO headers to print. PROC REPORT 2 has to supply headers. If you use NOHEADER for PROC REPORT 2, then you will NOT have any headers at all.

Cynthia
CC_SAS
Obsidian | Level 7

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.

Cynthia_sas
SAS Super FREQ
Hi:
Headers are not conditional. If headers are turned on, then they are used. If you turn off the headers using NOHEADER, then they are off.

I don't think you can do what you envision.

Cynthia
CC_SAS
Obsidian | Level 7
ok, Thank you Cynthia for the help 🙂 Have a good day 🙂

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
  • 9 replies
  • 5254 views
  • 1 like
  • 2 in conversation