BookmarkSubscribeRSS Feed
JasonNC
Quartz | Level 8
Hi SAS People,

I have the following report layout.

Report:xxx Company Name Date : MMDDYYYY
code:xxx xxxxxxx page : 1


NAME: XXXXXXXXXXXX
ID:XXXXX

KIDSNAME SEX AGE
xxxxxx x xx More variables continue
xxxxxx x xx

NAME: XXXXXXXXXXXX
ID: XXXXX

KIDSNAME SEX AGE
xxxxxxxx x xx More variables continue
xxxxxxx x xx

I am trying to create the above report in PDF and each page should has page numbers like in the above layout.
The Report and code should be left side of the page and the company name should be in the center and date and page fileds should be right side of the page.
And in the last page the footnote should say " END".
We use proc report for most of the reports.
But for this report I am really lost and couldnt get any ides.

So, I would really appreciate any help.

Jason.

Message was edited by: JasonNC Message was edited by: JasonNC
11 REPLIES 11
Cynthia_sas
SAS Super FREQ
Hi:
What does your data look like???? This report probably -could- be done with PROC REPORT or it could be done with the pre-production DATA step interface to ODS (still experimental) or it might be able to be done with PUT _ODS_ statements.

It also depends on what destination you are interested in. You say you want PDF -- you could create this file using "classic" PUT statements with DATA _NULL_ and then distill the LISTING report manually to PDF using Adobe Acrobat or some 3rd party tool

For an idea of a possible approach with PROC REPORT, review the code and output below. Note that the report dataset was created directly with an INFILE statement -- you would have to take your data and manipulate it to be in a similar structure. It is the TYPE variable that determines what rows are shown in BOLD when the value of TYPE=HDR. The PGNUM, GRPNUM and LN_NUM variables are important because they ensure that all the "header" lines and "data" lines appear in the correct order. I only made 3 columns in the fake data and you could have more columns -- they would just need to be manipulated in the same way. I used an explicit PGNUM variable so that any "family" would not split across pages. That meant I had to create the report at least 1 time and visually inspect the report to see where the manual "break" needed to be.

Turning off the interior table lines with the STYLE override removes the interior lines; the NOHEADER option turns off all the TABLE headers, so it looks as though the fake headers in your data are the only headers there are; and the TITLE statements with J=L, J=C and J=R take care of the titles the way you want. ODS PDF TEXT= is used for the text string at the end of the report.

cynthia
[pre]
Data ReportFile;
length pgnum grpnum ln_num idval 8 type $8 col1 col2 col3 $35;
infile datalines dsd dlm=',' missover;
input pgnum grpnum ln_num type $ IDval col1 $ col2 $ col3 $;
return;
datalines;
1,1, 10, hdr, 12345,IDSNAME, SEX, AGE
1,1, 11, data, 12345,"John Doe", M, 45
1,1, 12, data, 12345,"Jane Doe", F, 44
1,1, 13, brk, 12345, ".", ".", "."
1,1, 14, data, 12345,"NAME:", "Doe Family","."
1,1, 15, data, 12345,"ID:", 12345,"."
1,1, 16, brk, 12345, ".", ".", "."
1,1, 17, hdr, 12345,KIDSNAME, SEX, AGE
1,1, 18, data, 12345,John, M, 14
1,1, 19, data, 12345,Mary, F, 12
1,1, 20, data, 12345,Billie, M, 10
1,2, 10, hdr, 22345,IDSNAME, SEX, AGE
1,2, 11, data, 22345,"Fred Flintstone", M, 45
1,2, 12, data, 22345,"Wilma Flintstone", F, 44
1,2, 13, brk, 22345, ".", ".", "."
1,2, 14, data, 22345,"NAME:", "Flintstone Family","."
1,2, 15, data, 22345,"ID:", 22345,"."
1,2, 16, brk, 22345, ".", ".", "."
1,2, 17, hdr, 22345,KIDSNAME, SEX, AGE
1,2, 18, data, 22345,Pebbles, F, 4
1,3, 10, hdr, 32345,IDSNAME, SEX, AGE
1,3, 11, data, 32345,"John Walton", M, 45
1,3, 12, data, 32345,"Olivia Walton", F, 44
1,3, 13, brk, 32345, ".", ".", "."
1,3, 14, data, 32345,"NAME:", "Walton Family","."
1,3, 15, data, 32345,"ID:", 32345,"."
1,3, 16, brk, 32345, ".", ".", "."
1,3, 17, hdr, 32345,KIDSNAME, SEX, AGE
1,3, 18, data, 32345,John , M, 14
1,3, 19, data, 32345,"Mary Ellen", F, 12
1,3, 20, data, 32345,Jason, M, 10
1,3, 21, data, 32345,Erin, F, 8
1,3, 22, data, 32345,Ben, M, 6
2,4, 10, hdr, 22345,IDSNAME, SEX, AGE
2,4, 11, data, 42345,"Ricky Ricardo", M, 45
2,4, 12, data, 42345,"Lucy Ricardo", F ,44
2,4, 13, brk, 42345, ".", ".", "."
2,4, 14, data, 42345,"NAME:", "Ricardo Family","."
2,4, 15, data, 42345,"ID:", 42345,"."
2,4, 16, brk , 42345, ".", ".", "."
2,4, 17, hdr , 42345,KIDSNAME, SEX, AGE
2,4, 18, data, 42345, Lucy, F , 6
2,4, 19, data, 42345,Ricky , M , 4
;
run;

ods listing;
proc print data=ReportFile;
title 'What is structure of dataset for PROC REPORT';
run;

options nodate nonumber;
title; footnote;
ods listing close;
ods pdf file='c:\temp\reportspecial.pdf';
ods escapechar='^';

%let repdate = %sysfunc(today(),mmddyy10.);
title j=l "Report: xxx" j=c "Company Name" j=r "Date: &repdate";
title2 j=l "code: xxx" j=c "xxxxxxx" j=r "^{thispage}";

proc report data=reportfile nowd noheader
style(report)={rules=none frame=void cellspacing=0};
column pgnum grpnum ln_num IDval type col1 col2 col3 ;
define pgnum / order noprint;
define grpnum / order noprint;
define ln_num / order noprint missing;
define IDval / order noprint;
define type / display noprint;
define col1 / display;
define col2 / display;
define col3 / display;
break after pgnum / page;
compute after grpnum;
line ' ';
endcomp;
compute col1;
if col1 in ('NAME:', 'ID:') then do;
call define(_COL_,'style','style={font_weight=bold}');
end;
endcomp;
compute col3;
if type = 'hdr' then do;
call define(_ROW_,'style','style={font_weight=bold}');
end;
else if type = 'brk' then do;
call define(_ROW_,'style','style={foreground=white background=white}');
end;
endcomp;
run;

ods pdf text='^S={just=c font_weight=bold font_size=18pt}^_^5nEnd of Report';

ods pdf close;

[/pre]
JasonNC
Quartz | Level 8
Hi,

Here is the input dataset.
Name ID Kidsname Sex Age
abc 100 x F 10
abc 100 y M 15
xyz 101 x F 11
xyz 102 y M 15
goes on;

And i need headers also . In the report
first row Name filed and second row Id filed then
the other 3 fileds header like Kidsname Sex and Age and under these the values.

Then some space and then next Name filed and in the next line
again ID field
and the other 3 fields Kidsname, sex and age
follows
Cynthia_sas
SAS Super FREQ
Hi:
A variation of my program would still work. I see you changed the original posted version of the report. The key thing would be the data transformation from the structure of your original dataset to the structure needed for PROC REPORT code similar to mine. Your alternative is to investigate DATA _NULL_ with PUT statements. The thing is that there's different DATA _NULL_ syntax for LISTING output versus the DATA _NULL_ syntax for ODS output, such as PDF, RTF or HTML.

We have some recorded e-lectures on the topic of DATA _NULL_ and the LISTING destination and DATA _NULL_ and ODS. You can find the electure bundle here.
https://support.sas.com/edu/schedules.html?id=986&ctry=US

There are also good examples of a "free-format" DATA _NULL_ report here (for the LISTING window):
http://support.sas.com/kb/25/429.html
http://support.sas.com/kb/24/608.html

cynthia
JasonNC
Quartz | Level 8
Hi Cynthia,

As you mentioned that a variation of your program works for my sample data, I am trying to transform the data and couldn't get.

Could you help me out in transforming my sample data so that i can use proc report to get the output.

Thanks & Regards
Jason
Cynthia_sas
SAS Super FREQ
Hi:
You say (above) that this is a representation of your input file:

Name ID Kidsname Sex Age
abc 100 x F 10
abc 100 y M 15
xyz 101 x F 11
xyz 102 y M 15


Are there any changes you want to make??? For example, why for person abc, is the ID (100) the same on both records??? But for person xyz, the ID is different (101 and 102) on both records. Is there a person ID -and- a kids ID?????

cynthia
JasonNC
Quartz | Level 8
Hi Cynthia,
That was a mistake.

Here is the Corrected input dataset layout.

Name ID Kidsname Sex Age
abc 100 x F 10
abc 100 y M 15
xyz 101 x F 11
xyz 101 y M 15.



and The Report
should look like the following.
all the titles i can get them.
I have hard time to get the main report data layout. and I need to display like
the following

Name: abc
Id : 100

Kidsname Sex Age
x F 10
y M 15

Name: xyz
ID: 101

Kidsname Sex Age
x F 11
y M 15


thanks
Jason
Cynthia_sas
SAS Super FREQ
Hi, Jason:
Does every family have exactly 2 kids??? Could there be a family without any kids? 1 kid?? 20 kids?? What would those records look like?? Is there an upper limit on the number of kids a family could have??? Are there any rules about splitting a family across a page??? Should a family always stay together???

To me, this looks like a fairly standard DATA step program using FIRST. and LAST. processing (depending on the complexity of the "family") observations. Your program would need to create multiple observations per "family". So if you were going to use my program sample, you would need one observation for the "NAME" line, a second observation for the "ID" line and a third observation for the "break" line -- I think that this would all happen on the FIRST.ID or FIRST.NAME observation. Then you'd need a fourth observation for the "KIDSNAME" header line, etc, etc. But without more information about the data (how many kids -- at least 1, always 2, up to 20) -- there's no point in writing a program until those facts about the data are known.

cynthia
JasonNC
Quartz | Level 8
Hi Cynthia,

Well the kids can be any number and no limit.
if a family can't fit on a page then it can go to a next page.

Jason
Cynthia_sas
SAS Super FREQ
Does ANY number mean 0 kids??? What would the record look like if there were 0 kids????
[pre]
abc 100 xenia F 10
abc 100 yorick M 15
xyz 101 anne F 11
xyz 101 bill M 15
def 102 ??? ? ?? <---no kids??
ghi 103 mary F 12 <---1 kid
[/pre]

Would there even BE any records with 0 kids???

cynthia
JasonNC
Quartz | Level 8
Hi Cynthia,

THere won't be a case with zero kids.
Each name will have non zero number kids.


Jason
Cynthia_sas
SAS Super FREQ
Hi:
That's good. Have you done much DATA step programming or used FIRST. or LAST. processing???? Do you know how the OUTPUT statement works?

For example, if you run the program below, you would get a dataset with 1 output observation for every input observation:
[pre]
data one_in_one_out;
set sashelp.class;
age_in_5 = age + 5;
ht_in_5 = height * 1.10;
output;
run;

proc print data=one_in_one_out;
title 'One Obs in, One Obs out -- show all 19 obs';
run;
[/pre]

But in order to transform the data so you can use it with PROC REPORT (which means making your own pgnum, ln_num, col1, col2, etc variables -- as shown in my program), then you would have to output more than one observation for some of the observations in your input file.

So consider how this program will work:
[pre]
data one_in_more_out(keep=name obsno type col1 col2);
set sashelp.class;
length type $10 col1 col2 $25;

obsno = _n_;

type='hdr';
col1='Name:';
col2 = Name;
output;

type='hdr';
col1 = 'Gender';
col2 = 'Height';
output;

type='data';
col1 = sex;
col2 = put(height,4.1);
output;

type='brk';
col1 = ' ';
col2 = ' ';
output;
run;

proc print data=one_in_more_out;
where name in ('Alfred', 'Alice', 'Barbara');
title 'One Obs in, One Obs out -- show only for 3 names';
run;

[/pre]

When the above program runs, it will read through SASHELP.CLASS and output more than 1 observation for every student. The following PROC PRINT output shows what is in the output dataset for 3 of the names:
[pre]
One Obs in, One Obs out -- show only for 3 names

Obs Name type col1 col2 obsno

1 Alfred hdr Name: Alfred 1
2 Alfred hdr Gender Height 1
3 Alfred data M 69.0 1
4 Alfred brk 1
5 Alice hdr Name: Alice 2
6 Alice hdr Gender Height 2
7 Alice data F 56.5 2
8 Alice brk 2
9 Barbara hdr Name: Barbara 3
10 Barbara hdr Gender Height 3
11 Barbara data F 65.3 3
12 Barbara brk 3
[/pre]

So if you compare the output above to what I originally posted as a possible program, you should start to get some idea of how you can produce the report you want with PROC REPORT.

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
  • 11 replies
  • 1181 views
  • 0 likes
  • 2 in conversation