BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Bryan5
Calcite | Level 5

I am having issues adjusting the frame=hsdies and rules=groups options for my PDF output when using proc template. When I output to RTF I have no issues changing the thickness of the borders using the borderwidth option and when I INCREASE the borderwidth it increases, but when i try to make it thinner, it stays too thick. Unfortunately this table will be part of a CSR that was done externally from my company and our standard macros cannot support a table of its type so I need to solve this isse of simply getting the border to be less thick. 

 

Here is my code: 

 

1) The proc template I am using: (I underlined, bolded, and italicized the option that when i increase the value it gets bigger in the PDF but when I decrease it stays too thick...)

 

       %let bottommargin= 0.8in;

       %let topmargin= 1in;

       %let rightmargin= 1in;

       %let leftmargin= 1in;

       %let frame=hsides;

       %let rules=groups;

 

proc Template;

   define style Landscape_8pt;

   parent=styles.printer;

   replace fonts /

      'docFont'            =("Courier",8pt)

      'FixedFont'          =("Courier",8pt)

      'BatchFixedFont'     =("Courier",8pt)

      'FixedStrongFont'    =("Courier",8pt)

      'FixedHeadingFont'   =("Courier",8pt)

      'FixedEmphasisFont'  =("Courier",8pt)

      'EmphasisFont'       =("Courier",8pt)

      'HeadingEmphasisFont'=("Courier",8pt)

      'StrongFont'         =("Courier",8pt)

      'HeadingFont'        =("Courier",8pt)

      'TitleFont'          =("Courier",8pt)

      'TitleFont2'         =("Courier",8pt)

      'TitleFont3'         =("Courier",8pt) ;

 

style table /

      protectspecialchars=off

      frame=&frame

      width=9in

      rules=&rules

      font=fonts('docFont')

      borderwidth=0.05pt
      cellpadding = 1pt

      cellspacing = 1pt;

 

 

 

style parskip from parskip /

      font=("Courier", 2pt);

 

replace HeadersAndFooters from Cell /

      font = fonts('TitleFont')

      foreground=colors('datafg')

      background=colors('databg')

      protectspecialchars= off;

 

replace SystemFooter from TitlesAndFooters /

      font=fonts('TitleFont3')

      protectspecialchars= off

      just=c;

 

replace body from Document /

      bottommargin=&bottommargin

      topmargin   =&topmargin

      rightmargin =&rightmargin

      leftmargin  =&leftmargin

      protectspecialchars= off

;

end;

run;

quit;

2) The proc reports (i have taken out and identifying information)

 

options orientation=landscape linesize=142 nodate nonumber;

ods escapechar='^';

ods pdf file="&outloc./test.pdf" style=Landscape_8pt; 

 

%let LineSize=142;

 

 

 


  TItle4 j=center "Table 14.3.1.22.1";

  TItle5 j=center "Symptoms and Findings of Differentiation Syndrome from eCRF IDH-DS";

  Title6 j=center "(Safety Population)";

   

 



 




 

PROC REPORT DATA=final_out nowd missing headline headskip spacing=1 split='~' ;                                                                                                                        

 

 

  compute after parcat1n;

    line'';

  endcomp;

 

   COLUMN ( pagen parcat1n paramn _col_1 _col_2 _col_3 _col_4);                                          

 

   DEFINE PAGEN / WIDTH=8 ORDER order noprint " ";                                                                                                                                                     

   DEFINE PARAMN / WIDTH=8       order noprint " ";                                                                                                                                                    

   DEFINE PARCAT1N / WIDTH=8 ORDER order noprint " ";                                                                                                                                                   

   DEFINE _COL_1 / WIDTH=134       id width=80 left flow style=[asis=on]" ";

 


 

   DEFINE _COL_2 / WIDTH=20       width=17 center "Study~ (N=&n2)";                                                                                                                                  

   DEFINE _COL_3 / WIDTH=20       width=17 center "Placebo ~ (N=&n3)";                                                                                                                                     

   DEFINE _COL_4 / WIDTH=20   order    width=17 center "Total ~ (N=&n4)";  

 

    BREAK AFTER pagen / page skip; 

     BREAK AFTER parcat1n /skip;     

run;                                                                                                                                                                    

 

PROC REPORT DATA=final_out nowd missing headline headskip spacing=1 split='~';                                                                                                                         

 

  compute before _page_;

 

    line '^S={just=left} Pre-Selected to WWW';

  endcomp;

 

  compute after parcat1n;

    line'';

  endcomp;

 

   COLUMN ( pagen parcat1n paramn _col_1 _col_5 _col_6 _col_7);                                         

 

   DEFINE PAGEN / WIDTH=8 ORDER order noprint " ";                                                                                                                                                      

   DEFINE PARAMN / WIDTH=8       order noprint " ";                                                                                                                                                     

   DEFINE PARCAT1N / WIDTH=8 ORDER order noprint " ";                                                                                                                                                  

   DEFINE _COL_1 / WIDTH=134       id width=80 left flow style=[asis=on]" ";

 

   DEFINE _COL_5 / WIDTH=20       width=17 center "Study ~ (N=&n5)";                                                                                                                                   

   DEFINE _COL_6 / WIDTH=20       width=17 center "Placebo ~ (N=&n6)";                                                                                                                            

   DEFINE _COL_7 / WIDTH=20       width=17 center "Total ~ (N=&n7)";  

 

    BREAK AFTER pagen / page skip; 

     BREAK AFTER parcat1n /skip;     

 

run;

 

PROC REPORT DATA=final_out nowd missing headline headskip spacing=1 split='~';                                                                                                                         

 

 

  compute before _page_;

    line '^S={just=left} Pre-Selected to XXX';

  endcomp;

 

compute after parcat1n;

    line'';

  endcomp;

 

   COLUMN ( pagen parcat1n paramn _col_1 _col_8 _col_9 _col_10);   

 

   DEFINE PAGEN / WIDTH=8 ORDER order noprint " ";                                                                                                                                                     

   DEFINE PARAMN / WIDTH=8       order noprint " ";                                                                                                                                                     

   DEFINE PARCAT1N / WIDTH=8 ORDER order noprint " ";                                                                                                                                                   

   DEFINE _COL_1 / WIDTH=134       id width=80 left flow style=[asis=on]" ";

 

 

   DEFINE _COL_8 / WIDTH=20       width=17 center "Study ~ (N=&n8)";                                                                                                                                   

   DEFINE _COL_9 / WIDTH=20       width=17 center "Placebo ~ (N=&n9)";      

   DEFINE _COL_10 / WIDTH=20       width=17 center "Total ~ (N=&n10)";        

 

 

    BREAK AFTER pagen / page skip; 

     BREAK AFTER parcat1n /skip;      

run;

 

PROC REPORT DATA=final_out nowd missing headline headskip spacing=1 split='~';                                                                                                                         

 

  compute before _page_;

    line '^S={just=left} Pre-Selected to YYYY';

  endcomp;

 

 

  compute after parcat1n;

    line'';

  endcomp;

 

   COLUMN ( pagen parcat1n paramn _col_1 _col_11 _col_12 _col_13);   

 

   DEFINE PAGEN / WIDTH=8 ORDER order noprint " ";                                                                                                                                                      

   DEFINE PARAMN / WIDTH=8       order noprint " ";                                                                                                                                                    

   DEFINE PARCAT1N / WIDTH=8 ORDER order noprint " ";                                                                                                                                                   

   DEFINE _COL_1 / WIDTH=134       id width=80 left flow style=[asis=on]" ";

 

 

   DEFINE _COL_11 / WIDTH=20       width=17 center "Study ~ (N=&n11)";                                                                                                                                   

   DEFINE _COL_12 / WIDTH=20       width=17 center "Placebo ~ (N=&n12)";                                                                                                                        

   DEFINE _COL_13 / WIDTH=20       width=17 center "Total ~ (N=&n13)";      

 

 

    BREAK AFTER pagen / page skip; 

     BREAK AFTER parcat1n /skip;      

run;

 

PROC REPORT DATA=final_out nowd missing headline headskip spacing=1 split='~';                                                                                                                          

 

  compute before _page_;

    line '^S={just=left} Pre-Selected to ZZZZ';

  endcomp;

 

  compute after parcat1n;

    line'';

  endcomp;

 

   COLUMN ( pagen parcat1n paramn _col_1 _col_14 _col_15 _col_16);   

 

   DEFINE PAGEN / WIDTH=8 ORDER order noprint " ";                                                                                                                                                      

   DEFINE PARAMN / WIDTH=8       order noprint " ";                                                                                                                                                    

   DEFINE PARCAT1N / WIDTH=8 ORDER order noprint " ";                                                                                                                                                  

   DEFINE _COL_1 / WIDTH=134       id width=80 left flow style=[asis=on]" ";

 

   DEFINE _COL_14 / WIDTH=20       width=17 center "Study ~ (N=&n14)";                                                                                                                                  

   DEFINE _COL_15 / WIDTH=20       width=17 center "Placebo ~ (N=&n15)";                                                                                                                        

   DEFINE _COL_16 / WIDTH=20       width=17 center "Total ~ (N=&n16)";    

 

 

    BREAK AFTER pagen / page skip; 

     BREAK AFTER parcat1n /skip;      

RUN;  

ods pdf close;

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Cynthia_sas
Diamond | Level 26
Hi: As I explained in my posting, there are values which ODS PDF will just not use. You can try other units of measure for width values, pt, px, in, cm -- but I always recommend that you actually print your output to be sure that the line is as thick as you think it is. Screen resolution and the printed page do look different. I have seen PDF files where the lines look "crooked" or like they have a break in the line, but when I print it looks fine (even under a magnifying glass) and if I fiddle with the monitor resolution and/or the PDF zoom level, eventually the lines get straight.

Recommend you work with Tech Support if this is urgent.
Cynthia

View solution in original post

9 REPLIES 9
Bryan5
Calcite | Level 5
Might also be important to mention I can change the color, but can't change the line to dashed or dotted... and again borderwidth=15pt makes it super thick, but borderwidth=.05pt is smaller, but still thicker than what I need it as.
ballardw
Super User

Without data it is extremely hard to test Proc Report output.

 

Instructions here: https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat... will show how to turn an existing SAS data set into data step code that can be pasted into a forum code box using the </> icon or attached as text to show exactly what you have and that we can test code against.

Bryan5
Calcite | Level 5
My apologies

Here is some data. Since its not important what the data is it is just
this:

*data* final_out;

input pagen paramn parcat1n

_col_1$ _col_2$ _col_3$ _col_4$ _col_5$ _col_6$

_col_7$ _col_8$ _col_9$ _col_10$ _col_11$ _col_12$

_col_13$ _col_14$ _col_15$ _col_16$;

datalines;

1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

;

*run*;

I tested and the problem persists with the above dataset rather than the
one I'm actually using.

Thanks
Bryan
Cynthia_sas
Diamond | Level 26

Hi:
Unfortunately, I'm in class this week and not able to run code. However, the first thing I would do is clean up your PROC REPORT and your Template code. Unless you are still running in SAS 9.1, you should not be using the REPLACE statement in your template code. That statement was deprecated starting in SAS 9.2 and I think the only reason they didn't get rid of it was that they didn't want to yank it away from users, but my experience with REPLACE after 9.2 was that it was far better to stick with STYLE or CLASS instead of REPLACE.

System Options like LINESIZE and PAGESIZE are LISTING only options and are ignored by ODS PDF. You should try to set your ODS PDF margins using the regular system option margins (instead of in the template) because as long as you set the options BEFORE ODS PDF starts, they should be respected by PDF. PROC REPORT options like HEADLINE, HEADSKIP, FLOW, WIDTH= are also LISTING only options and will not be respected or even used by ODS PDF. In addition, you have WIDTH= repeated multiple times in one define statement -- which will not work at all, even in LISTING. I've highlighted a few places where these statements should be revised for use with ODS PDF.

Cynthia_sas_0-1598491525057.png


If I have a chance when class is over, I will try to run your code. What I know about PDF and borders and line widths is that if you specify a value that is incompatible with the PDF construction of a document or table, then PDF will basically ignore your setting. For example, an attempt to set margins too small or fonts too small will simply result in your settings being ignored. If you need immediate help with this, you should consider opening a track with Tech Support.

Cynthia

ghosh
Barite | Level 11

Try this quick fix to the proc report line

PROC REPORT DATA=final_out nowd missing headline headskip spacing=1 split='~' style(column)=[borderwidth=0.05pt];                                                                                                                        
Bryan5
Calcite | Level 5
I put this in, but the lines stay the same. Again in the proc template if I
increase the borderwidth like to 15pt or 25pt it gets super thick... can
PDF just not handle less than 1pt? Also its very thick for 1pt...
Cynthia_sas
Diamond | Level 26
Hi: As I explained in my posting, there are values which ODS PDF will just not use. You can try other units of measure for width values, pt, px, in, cm -- but I always recommend that you actually print your output to be sure that the line is as thick as you think it is. Screen resolution and the printed page do look different. I have seen PDF files where the lines look "crooked" or like they have a break in the line, but when I print it looks fine (even under a magnifying glass) and if I fiddle with the monitor resolution and/or the PDF zoom level, eventually the lines get straight.

Recommend you work with Tech Support if this is urgent.
Cynthia
Bryan5
Calcite | Level 5
Thanks for your input Cynthia, I think I will marked this as solved and
speak with management about the line thickness being controlled by
something on their side. Thanks everyone for all the help!
Cynthia_sas
Diamond | Level 26

Hi:

  Now that class is over I had a chance to work with your code a bit. I changed your template to use Journal style because I wanted to illustrate the border issue without any distraction from changing the borders. Consider this:

Cynthia_sas_0-1598715475762.png

 

  Journal style removes the interior table lines and puts a line around the headers and at the bottom of the table. In the multi-page view, the bottom line looks darker than the other lines. However, Adobe Reader has a Loupe tool that you can use to zoom in on a part of the page and if you look at the 2 lines under the tool, you can see that they are the same size, even though they may not look the same when viewed on a screen.

 

  I tweaked your template a bit to remove all the default attributes, to change REPLACE to CLASS and to use Courier New instead of just Courier as the font name. Here's an example of Page 1 zoomed to 125%:

Cynthia_sas_1-1598715952375.png

As you can see, when zoomed to 125% the lines are all the same width. When printed they look the same width. Sorry, can't post a printed image here.

 

  I adjusted your _COL_1 variable to have more text and you can see that it do NOT have FLOW in the DEFINE for that column, but the text flows anyway to the column width. I see the width to 9 inches for the whole report and then allowed PROC REPORT to fit the columns in that width. Your WIDTH= option was a LISTING only option and was ignored by ODS PDF and specified incorrectly (some of your statements had 2 WIDTH= for LISTING. I also cleaned up the BREAK statements and put all the COMPUTE blocks and BREAK statements together because conceptually, PROC REPORT has a pre-processing phase that it goes through and it "collects" all the COMPUTE blocks and BREAK statements and executes them as it needs to. Putting the COMPUTE block first was just distracting to me. I also cleaned up your STYLE overrides to refer to STYLE(HEADER) and STYLE(COLUMN) in the DEFINE Statement, as PROC REPORT expects.

 

  I also added a second row with a different PAGEN value in the fake data, to test the BREAK processing on PAGEN. I only did 3 PROC REPORT steps instead of your original number of steps. Here's the code I tested:


ods path work.tmp(update) sasuser.templat(update) sashelp.tmplmst(read);
  
proc Template;
   define style styles.new8;
   parent=styles.journal;
   class fonts /
    'docFont'   =("Courier New, Courier",8pt)
    'FixedFont' =("Courier New, Courier",8pt)
    'BatchFixedFont' =("Courier New, Courier",8pt)
    'FixedStrongFont' =("Courier New, Courier",8pt)
    'FixedHeadingFont'   =("Courier New, Courier",8pt)
    'FixedEmphasisFont'  =("Courier New, Courier",8pt)
    'EmphasisFont' =("Courier New, Courier",8pt)
    'HeadingEmphasisFont'=("Courier New, Courier",8pt)
    'StrongFont' =("Courier New, Courier",8pt)
    'HeadingFont' =("Courier New, Courier",8pt)
    'TitleFont' =("Courier New, Courier",8pt)
    'TitleFont2' =("Courier New, Courier",8pt)
    'TitleFont3' =("Courier New, Courier",8pt) ;
class table /
 protectspecialchars=off
 font=fonts('docFont')
 cellpadding = 1pt;

class parskip /
 font=("Courier New, Courier",2pt);

class HeadersAndFooters /
 font = ("Courier New, Courier",8pt)
 protectspecialchars= off;

class SystemTitle /
 font=("Courier New, Courier",8pt)
 protectspecialchars= off;

class SystemFooter  /
 font=("Courier New, Courier",8pt)
 protectspecialchars= off;

class body /
 protectspecialchars= off;
end;
run;
  
 ** create some macro variables;
 %let bottommargin= 1in;
 %let topmargin= 1in;
 %let rightmargin= 1in;
 %let leftmargin= 1in;

 %let l1 = %str(Twas brillig and the slity toves did gyre and gimble in the wabe.);
 %let l2 = %str(All mimsy were the borogroves, and the Momeraths outgrabe.);
 %let l3 = %str(Beware the Jabberwock my son, the jaws that bite, the claws that snatch.);
 %let l4 = %str(Beware the Jubjub bird and shun the frumious Bandersnatch.);

** set System options. ODS PDF should respect margin options/orientation here;
options orientation=landscape 
        bottommargin=&bottommargin topmargin=&topmargin 
        rightmargin =&rightmargin leftmargin=&leftmargin  nodate nonumber;

ods escapechar='^';

** read in test data, make _COL_1 bigger to hold multiple lines of text;
** in order to show FLOW behavior in PDF without using FLOW LISTING option;
** added another fake data row to test break for PAGEN variable;
data final_out;
length _col_1 $500;
input pagen paramn parcat1n
_col_1$ _col_2$ _col_3$ _col_4$ _col_5$ _col_6$
_col_7$ _col_8$ _col_9$ _col_10$ _col_11$ _col_12$
_col_13$ _col_14$ _col_15$ _col_16$;
_col_1 = catx('~',pagen,"&l1. &l2. &l3. &l4");
datalines;
1 1 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
2 1 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
;
run;

** no values for &n macro variables n2-n16, so just used text instead of macro var;
** not sure what TITLE1-TITLE3 are supposed to be so just used placeholders;
** used new style template based on JOURNAL, not on PRINTER style. ;
ods pdf file="c:\temp\testcourier.pdf" style=styles.new8; 
  title1 'Title1';
  title2 'Title2';
  title3 'Title3';
  TItle4  "Table 14.3.1.22.1";
  TItle5  "Symptoms and Findings of Differentiation Syndrome from eCRF IDH-DS";
  Title6  "(Safety Population)";

PROC REPORT DATA=final_out nowd missing split='~' 
            style(report)={width=9in};   
   COLUMN ( pagen parcat1n paramn _col_1 _col_2 _col_3 _col_4); 
   DEFINE PAGEN /   ORDER order noprint " "; 
   DEFINE PARAMN /  order noprint " "; 
   DEFINE PARCAT1N /  ORDER order noprint " ";   
   DEFINE _COL_1 /  id   "Col1" 
          style(header)={just=l} style(column)=[just=l];
   DEFINE _COL_2 /  "Study~ (N=-n2)" style(column)=[just=c  ]; 
   DEFINE _COL_3 /   "Placebo ~ (N=-n3)" style(column)=[just=c ]; 
   DEFINE _COL_4 /   "Total ~ (N=-n4)" style(column)=[just=c  ];  
  compute after parcat1n;
      line ' ';
  endcomp;
  BREAK AFTER pagen / page  ; 
run;  

PROC REPORT DATA=final_out nowd missing split='~' 
            style(report)={width=9in};   
   COLUMN ( pagen parcat1n paramn _col_1 _col_5 _col_6 _col_7); 
   DEFINE PAGEN /  ORDER order noprint " "; 
   DEFINE PARAMN /  order noprint " "; 
   DEFINE PARCAT1N /  ORDER order noprint " ";  
   DEFINE _COL_1 /  id   "Col1" 
          style(header)={just=l} style(column)=[just=l];
   DEFINE _COL_5 /   "Study ~ (N=-n5)" style(column)=[just=c]; 
   DEFINE _COL_6 /  "Placebo ~ (N=-n6)" style(column)=[just=c] ; 
   DEFINE _COL_7 /   "Total ~ (N=-n7)" style(column)=[just=c];  
   compute before _page_ / style={just=l};
      line 'Pre-Selected to WWW';
   endcomp;
   compute after parcat1n;
      line ' ';
   endcomp;
 BREAK AFTER pagen / page  ; 
run;

PROC REPORT DATA=final_out nowd missing split='~' 
            style(report)={width=9in};   
   COLUMN ( pagen parcat1n paramn _col_1 _col_8 _col_9 _col_10);   
   DEFINE PAGEN / ORDER order noprint " "; 
   DEFINE PARAMN / order noprint " "; 
   DEFINE PARCAT1N /ORDER order noprint " ";   
   DEFINE _COL_1 /  id   "Col1" 
          style(header)={just=l} style(column)=[just=l];
   DEFINE _COL_8 /  "Study ~ (N=-n8)" style(column)=[just=c]; 
   DEFINE _COL_9 / "Placebo ~ (N=-n9)" style(column)=[just=c]; 
   DEFINE _COL_10 / "Total ~ (N=-n10)" style(column)=[just=c]; 
   compute before _page_ / style={just=l};
      line 'Pre-Selected to XXX';
   endcomp;
   compute after parcat1n;
      line ' ';
   endcomp;
   BREAK AFTER pagen / page  ; 
run;

ods pdf close;
title; footnote;

Hope this helps,

Cynthia

 

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

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
  • 9 replies
  • 3009 views
  • 0 likes
  • 4 in conversation