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

Hi there,

I'm trying to duplicate Pete Lund's approach to embed a histogram in a pdf PROC REPORT (247-2011: You Did That Report in SAS®!? - The Power of the ODS PDF Destination) but instead of the histogram, I'm getting 'g'. It looks fine on the HTML version, but not on the pdf  version. Can anyone help me? I've included an Excel sample if that helps. This is also the first of 4 proc reports on a legal size paper and I'm using absolute layout (but haven't gotten to that part yet!). 

 

Thanks!

 

Here's my code:

data uc1;
INPUT DIVISION $  No       pct_n_total  Yes    pct_y_total       ;
LENGTH DIVISION  $ 1 No 8 pct_n_total 8 Yes 8 pct_y_total  8;
FORMAT
DIVISION         $CHAR1.
No               COMMA12.2
pct_n_total      COMMA12.2
Yes              COMMA12.2
pct_y_total      COMMA12.2;
datalines;
a 79354 0.4685 90034 0.5315
b 94541 0.6260 56479 0.3740
c 10635 0.1183 79255 0.8817
d 40340 0.4720 45118 0.5280
;
run;
ods pdf file = /home/me/file.pdf   style=smaller  STARTPAGE=NEVER;
footnote j=c "Page ^{thispage} of ^{lastpage}"; 
 
proc report data= uc1 nowd missing split= '~' 
style(report) = [cellspacing = 2 cellpadding =2 rules=groups frame=hsides]
style(header) = [fontsize=6pt vjust = top]
style(column)=[fontsize=6pt]; 
Title "uc1";
DIVISION
       No
   pct_n_total
   Yes
   pct_y_total
   bar;
define unit / 'DIVISION' ;
define No / 'No' format = comma15.0;
define pct_n_total / '% No' format = percent10.2;
define Yes / '% Yes' format = comma15.0;
define pct_y_total / '% Yes' format = percent10.2
style(column) = [borderrightcolor=black borderrightwidth=.5pt];
define bar / 'PROGRESS'  style(column) = [cellwidth=75mm font_size=4pt
font_face=Webdings vjust=middle 
just=left cellpadding=0];
 
compute bar / char length=20;
barsize = round(pct_y_total.sum*50);
if barsize gt 0 then bar = repeat('67'x,barsize);
endcomp;
run; 
 
ods layout end;
ods pdf close;
example.png
 
Thank you!
 
 
1 ACCEPTED SOLUTION

Accepted Solutions
Kathryn_SAS
SAS Employee

Your code works for me after I add COLUMN and change Unit to Division on the DEFINE statement.

Revised code:

ods listing close;
ods pdf file = 'file.pdf'    STARTPAGE=NEVER;
footnote j=c "Page ^{thispage} of ^{lastpage}"; 
 
proc report data= uc1 nowd missing split= '~' 
style(report) = [cellspacing = 2 cellpadding =2 rules=groups frame=hsides]
style(header) = [fontsize=6pt vjust = top]
style(column)=[fontsize=6pt]; 
Title "uc1";
column DIVISION
       No
   pct_n_total
   Yes
   pct_y_total
   bar;
define division / 'DIVISION' ;
define No / 'No' format = comma15.0;
define pct_n_total / '% No' format = percent10.2;
define Yes / '% Yes' format = comma15.0;
define pct_y_total / '% Yes' format = percent10.2
style(column) = [borderrightcolor=black borderrightwidth=.5pt];
define bar / 'PROGRESS'  style(column) = [cellwidth=75mm font_size=4pt
font_face=Webdings vjust=middle 
just=left cellpadding=0];
 
compute bar / char length=20;
barsize = round(pct_y_total.sum*50);
if barsize gt 0 then bar = repeat('67'x,barsize);
endcomp;
run; 

ods listing;
ods pdf close;

If you continue to have problems, please send your log.

View solution in original post

5 REPLIES 5
Kathryn_SAS
SAS Employee

Your code works for me after I add COLUMN and change Unit to Division on the DEFINE statement.

Revised code:

ods listing close;
ods pdf file = 'file.pdf'    STARTPAGE=NEVER;
footnote j=c "Page ^{thispage} of ^{lastpage}"; 
 
proc report data= uc1 nowd missing split= '~' 
style(report) = [cellspacing = 2 cellpadding =2 rules=groups frame=hsides]
style(header) = [fontsize=6pt vjust = top]
style(column)=[fontsize=6pt]; 
Title "uc1";
column DIVISION
       No
   pct_n_total
   Yes
   pct_y_total
   bar;
define division / 'DIVISION' ;
define No / 'No' format = comma15.0;
define pct_n_total / '% No' format = percent10.2;
define Yes / '% Yes' format = comma15.0;
define pct_y_total / '% Yes' format = percent10.2
style(column) = [borderrightcolor=black borderrightwidth=.5pt];
define bar / 'PROGRESS'  style(column) = [cellwidth=75mm font_size=4pt
font_face=Webdings vjust=middle 
just=left cellpadding=0];
 
compute bar / char length=20;
barsize = round(pct_y_total.sum*50);
if barsize gt 0 then bar = repeat('67'x,barsize);
endcomp;
run; 

ods listing;
ods pdf close;

If you continue to have problems, please send your log.

SASGeek
Quartz | Level 8

Thank you. Actually, the real problem was that my SAS EG only accepts LATIN1 encoding so once I changed to fontfamily = 'Courier New' and then use unicode 2588, it worked great. Thanks!

Tom
Super User Tom
Super User

So you will need to make the calculated BAR variable three times as long (150 byte length) because U+2588 is stored as the three byte sequence 'E29688'x in UTF-8 encoding.

 

Also you should subtract 1 from the integer passed to the REPEAT() function.  It helps to think of that second argument to the REPEAT() function as the number of EXTRA copies of the string to add.

Spoiler
data uc1;
  LENGTH DIVISION $1 ;
  INPUT DIVISION No pct_n_total Yes pct_y_total;
  FORMAT No Yes comma12. pct_n_total pct_y_total percent10.2;
datalines;
a 79354 0.4685 90034 0.5315
b 94541 0.6260 56479 0.3740
c 10635 0.1183 79255 0.8817
d 40340 0.4720 45118 0.5280
;

proc print;
run;

footnote j=c "Page ^{thispage} of ^{lastpage}"; 
Title "uc1";
 
proc report data= uc1 nowd missing split= '~' 
  style(report) = [cellspacing = 2 cellpadding =2 rules=groups frame=hsides]
  style(header) = [fontsize=6pt vjust = top]
  style(column)=[fontsize=6pt]
; 
column
  DIVISION
  No
  pct_n_total
  Yes
  pct_y_total
  bar
;
define division / 'DIVISION' ;
define No / 'No' format = comma15.0;
define pct_n_total / '% No' format = percent10.2;
define Yes / '% Yes' format = comma15.0;
define pct_y_total / '% Yes' format = percent10.2
  style(column) = [borderrightcolor=black borderrightwidth=.5pt]
;
define bar / 'PROGRESS'
  style(column) =
   [cellwidth=75mm font_size=4pt
    font_face='Courier New' vjust=middle 
    just=left cellpadding=0
   ]
;
compute bar / char length=150;
  barsize = round(pct_y_total.sum*50);
  if barsize gt 0 then bar = repeat('E29688'x,barsize-1);
endcomp;
run; 

Code

PDFPDFHTMLHTML

 

 

 

 

 

 

SASGeek
Quartz | Level 8

Thank you so much. That worked better!

Ksharp
Super User
data a;
input a $ actual goal   ;
v=actual/goal;
format v percent7.1;
cards;
a 850 1200
b 150 1500
c 450 1600 
d 650 1000
;
proc sql;
create table _a as
select *,max(v) as max from a;

create table want as
select * from _a
union all
select 'TOTALS',sum(actual),sum(goal),sum(actual)/sum(goal),. from _a
;
quit;


%let path=c:\temp\;  *the path name stored image;
%macro get_bar(value=,imagename=);
data _null_;
set _a;
if _n_=1 then call symputx('max',max);
run;
ods _all_ close;
ods listing gpath="&path." image_dpi=300;
ods graphics /noborder reset=index width=100px height=15px imagename="&imagename" outputfmt=png;
proc sgplot data=_a noborder noautolegend ;
where a="&value.";
hbarparm category=a response=v/ filltype=GRADIENT displaybaseline=off
 barwidth=1 outlineattrs=(color=green) fillattrs=(color=white) fillendcolor=green;
scatter x=max y=a/datalabel=v labelstrip  datalabelpos=left datalabelattrs=(size=25) markerattrs=(size=0);
xaxis min=0 max=&max. offsetmin=0 offsetmax=0 display=none;
yaxis offsetmin=0 offsetmax=0 display=none;
run;
%mend;
data _null_;
set a;
call execute(catt('%nrstr(%get_bar)(value=',a,',imagename=',a,')'));
run;

ods pdf file='c:\temp\want.pdf' style=htmlblue dpi=300;
proc report data=want nowd style(header)=header ;
column ('Region' a  actual goal v dummy);
define a/display;
define dummy/computed '%Covered' ;
define v/display noprint;
compute dummy/character length=10 ;
 dummy=' ';
 if a ne 'TOTALS' then call define(_col_,'style',"style={preimage='c:\temp\"||strip(a)||".png'}");
else do;dummy=vvalue(v);call define(_row_,'style','style=header');call define(_col_,'style','style=header{just=r}');end;
endcomp;
run;
ods pdf close;

/*****Excel 中加入图片:
https://blogs.sas.com/content/sgf/2017/02/20/tips-for-using-the-ods-excel-destination/
***/

屏幕截图 2026-04-14 143212.png

Catch up on SAS Innovate 2026

Nearly 200 sessions are now available on demand with the SAS Innovate Digital Pass.

Explore 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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 574 views
  • 1 like
  • 4 in conversation