BookmarkSubscribeRSS Feed
jerry898969
Pyrite | Level 9

Hi Cynthia,

Thank you so much for your reply.

On the alt_report is there a way to have the long question merge into the second column so the text is on top of the codes?

Thanks again for all the help. 

Ksharp
Super User

OK. Here is . You can link the qtype to the right place within the same pdf .and the same principle for Questions. I think you can do it on your own.

data have;
input Year Question $ 6-27 AnsCode AnsText $ 30-35 QType $;
question=dequote(question);anstext=dequote(anstext);qtype=dequote(qtype);
datalines;
2010 "Is this the test 1?" 1 "Yes" "Intro"
2010 "Is this the test 1?" 2 "No"   "Intro"
2010 "Is this the test 1?" 3 "N/A"  "Intro"
2010 "Is this the test 2?" 1 "Yes" "Sec1"
2010 "Is this the test 2?" 2 "No"   "Sec1"
2010 "Is this the test 2?" 3 "N/A"  "Sec1"
2014 "Is this the test 3?" 1 "Yes"  "Intro"
2014 "Is this the test 3?" 2 "No"    "Intro"
2014 "Is this the test 3?" 3 "N/A"   "Intro"
;
run;


data report;
 set have;
 by  Year QType     Question;
 length y t q x z$ 40;
 if first.Question then do;
  y=year;output; y=' ';
  t=qtype;output;t=' ';
  q=question;output;
  q='CODES:';output; q=' ';
  end;
x=anscode;z=anstext;output;
keep y t q x z;
run;

data Intro;
 x='asdfsadfasfda';
run;
data Sec1;
 x='asdfasdfad';
run;





ods listing close;
ods pdf file='x.pdf' style=sasweb;
title1 'Summary';
proc report data=report nowd noheader;
compute t;
rtag = "#"||trim(t);
if not missing(t) then call define(_col_,'url',rtag);
endcomp;
run;


ods pdf anchor="Intro" startpage=now;
ods proclabel="Intro";
title1 'Intro Summary';
proc report data=Intro nowd;run;


ods pdf anchor="Sec1" startpage=now;
ods proclabel="Sec1";
title1 'Sec1 Summary';
proc report data=Intro nowd;run;




ods pdf close;
ods listing;


Good Luck

Xia Keshan

Message was edited by: xia keshan

jerry898969
Pyrite | Level 9

Thank you Ksharp for all your help.  I'm slowly piecing everything together with everyone help.

I will post all my code when I have it generating correctly.

Thank you

Cynthia_sas
Diamond | Level 26

No, the question is in the COL1 variable, so it will be confined to the COL1 cell and cannot span on the top of the COL2 cell. If that's what you want, then the first example, that created "other_report.html" is the better example to follow because what is written with the LINE statement does span the whole table. The program I posted was a modification of DATA _NULL_'s example.

cynthia

jerry898969
Pyrite | Level 9

Hi Cynthia,

thank you for your reply.  Here is my code so far using the first approach:

ods listing ;

title ;

footnote ;

options orientation=portrait topmargin=.5in bottommargin=.5in rightmargin=.5in leftmargin=.5in ;

options nodate nonumber nocenter ;

ods listing close ;

ods pdf file='H:\shared\jwarra\SAS_ODS_PDF\other_report.pdf' style=Temp ;

ods pdf uniform ;

proc report data=x nowd 

     style(lines)=[TEXTALIGN=left]

     style(header)={background=white}

     style(report)={rules=none frame=void cellspacing=0 cellpadding=2px} ;

     column  year cname vname ;

   define year / order order=internal noprint ;   

   define cname / order order=internal noprint ;

   define vname / order order=internal noprint ;  

   compute before year / style={font_weight=bold font_face=Courier} ;

      line year 4. ;

   endcomp ;     

   compute before cname / style={font_weight=bold font_face=Courier marginleft=.50in} ;

      qlg = length(cname) ;

      line cname $varying. qlg ;

   endcomp ;

   compute before vname / style={font_face=Courier marginleft=.90in} ;

      qlg = length(vname) ;

      urlstring="#"||strip(vname) ;

         call define('vname',"URL",urlstring) ;        

      line vname $varying. qlg ;

   endcomp ;  

run;

ods pdf close ;

title; footnote ;

I have the layout working like I needed it.

2010

  Intro

    V1234 - Variable 1

    V5678 - Variable 2

  Sec1

    V0009 - Variable 3

2014

  Into

    V4562 - Variable 4

My issue now is that when I try and do a compute with vname and add a url it doesn't generate a url on the pdf file.

Should I remove the line option and make vname display instead of noprint?  Is there a way I can make the text the link not

the cell?

Thank you everyone for your help. 

Cynthia_sas
Diamond | Level 26


Hi:

  First, I am not certain that you can make a URL string that starts with a # for PDF. You'd have to check with Tech Support about that. Usually, when you are making anchors, you need to also use the ANCHOR= option in the ODS PDF statement, too.

  Second, you have NOPRINT for VNAME, so there's nothing to change with the CALL DEFINE. You will have to put the entire URL or link in your LINE statement. The URL style in PROC REPORT will only apply to the data cell for VNAME, which is not visible on your report. So whatever the syntactically correct URL is for what you want to do in PDF, would be what you write in the COMPUTE block for VNAME. But I don't understand what's going to happen when they click on a VNAME -- where will the link go to??? If the URL for VNAME is VNAME, that seems self-referential to me. I would expect that the URL for VNAME would go to some other document that was more information about THAT particular VNAME.

  I am not in a position to test code for the rest of the week. So if you have an immediate need for a resolution, I'd recommend that you work with Tech Support.

cynthia

jerry898969
Pyrite | Level 9

Thanks for the reply Cynthia,

Sorry I didn't explain I will have freq data later in my pdf and I want to link the listed variable to it's freq data at a different point in my pdf.  I'm trying to create a table of contents with some description of my variables.  I will keep working and testing out a way to get the text to be a link.

Thank you again.

jwillis
Quartz | Level 8

Jerry,

I had some success with adding links and anchors to a pdf document.   I did have help from Cynthia (via her books and writings) and Tech Support along the way.

First:

/***
There have been some bugs when using one file to open another file and go to the correct page with
the anchor.  The version of SAS will play a role in this.

Thanks,
Jane Eslinger
SAS Technical Support

If an ODS PDF ANCHOR= statement is used to create an anchor from which a URL links to a specific page
in a PDF file, the links will exist, but might not work. The URL links are converted to all lower case
letters, so despite attempts to use UPCASE or mixed case values when a URL= or LINK= argument is used,
the links are in lower case. To circumvent the problem, use all lower case letters for the ANCHOR= value(s).

See also: "Usage Note 24174: How do links work under PDF in ODS?"

    /*** URL sends the user away.  ANCHOR brings them back ***/
    /*** The placement of the anchor tag does make a difference!!! ***/

***/

Second:

I could not figure out how to link/anchor to specific words in the PDF report (I can with RTF) so I placed an anchor at the top/bottom of each PDF page.

ods pdf anchor=%sysfunc(lowcase("rpt%trim(%left(&line.))%trim(%left(&brand.))%sysfunc(translate(%trim(%left(&sku.)),'xxx','.00'))%trim(%left(&lotnum.))"));

*footnote8 Justify=CENTER HEIGHT=9PT "[PAGE 00000 OF 99999]";

Thirdly:

I built a url from the proc report cell value to the page anchor tag.

DEFINE CT_GRAPH_LINK        / DISPLAY center style(column)={

                                                cellwidth=100

          url=%sysfunc(lowcase("#ct%trim(%left(&line.))%trim(%left(&brand.))%sysfunc(translate(%trim(%left(&sku.)),'xxx','.00'))%trim(%left(&lotnum.))"))

                                                COLOR=BLACK

                                                LINKCOLOR=BLACK

                                                RULES=NONE

                                                ASIS=OFF

                                                };

Finally:

I added links to take me back to the anchor page I started from.  I handcoded all the values and tested that they worked before I coded them as macro variable values.


         /*** add blank lines between the graph and the link ***/
ODS PDF TEXT="    ";
ODS PDF TEXT="    ";
ODS PDF TEXT="    ";

        /*** LINKCOLOR DETERMINES THE COLOR OF THE BORDER SURROUNDING THE TEXT ***/
        /*** TEXTDECORATION=LINE_THROUGH HAD NO EFFECT                         ***/

/*** imbedding spaces causes the pdf text to fail ***/
/**NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS release.  Inserting white space between a quoted string and the succeeding identifier is recommended. **/

ODS PDF TEXT=
%IF &PARAM.= PW %THEN %DO;
"^{style[JUST = C URL = %str('%lowcase(#rpt&line.&brand.%sysfunc(translate(%trim(%left(&sku.)),'xxx','.00'))&lotnum.)')COLOR=PURPLE LINKCOLOR=WHITE]&CLICK}";
%END;
%IF &PARAM.= BC %THEN %DO;
"^{style[JUST = C URL = %str('%lowcase(#rpt&line.&brand.%sysfunc(translate(%trim(%left(&sku.)),'xxx','.00'))&lotnum.)')COLOR=RED LINKCOLOR=WHITE]&CLICK}";
%END;
%IF &PARAM.=CT %THEN %DO;
"^{style[JUST = C URL = %str('%lowcase(#rpt&line.&brand.%sysfunc(translate(%trim(%left(&sku.)),'xxx','.00'))&lotnum.)')COLOR=BLACK LINKCOLOR=WHITE]&CLICK}";
%END;
%IF &PARAM.=DM %THEN %DO;
"^{style[JUST = C URL = %str('%lowcase(#rpt&line.&brand.%sysfunc(translate(%trim(%left(&sku.)),'xxx','.00'))&lotnum.)')COLOR=GREEN LINKCOLOR=WHITE]&CLICK}";
%END;

title "";
footnote;

jerry898969
Pyrite | Level 9

Hi jwillis,

Thank you so much for you suggestions.  I'm working on it now and will let you know what my results are.  With the help of everyone on this discussion I have a good portion generating and looking like the way I need it. 

Thank you.

jerry898969
Pyrite | Level 9

Hello,

I've hit a small issue in terms of the layout.  I'm very close to getting the correct layout but when I add a new variable to my proc report it displays those values above the question instead of below the question.  My dataset is not a good as I think it should be.  I have to join another table that joins on the key and will expand my dataset by how many results match.  I took my original data and joined to my new table this is the results

MyData

Year Question AnsCode AnsText QType Letter

2010 "Is this the test 1?" 1 "Yes" "Intro"  A     

2010 "Is this the test 1?" 2 "No"   "Intro"  A    

2010 "Is this the test 1?" 3 "N/A"  "Intro" A    

2010 "Is this the test 1?" 1 "Yes" "Intro"  B    

2010 "Is this the test 1?" 2 "No"   "Intro"  B   

2010 "Is this the test 1?" 3 "N/A"  "Intro" B   

2010 "Is this the test 1?" 1 "Yes" "Intro"  C   

2010 "Is this the test 1?" 2 "No"   "Intro"  C  

2010 "Is this the test 1?" 3 "N/A"  "Intro" C  

I need this data to display like this:

Is this the test1?

   NC Notes

     A

     B

     C

What i'm getting now is

A

B

C

Is this test1?

Here is my code:

ods listing ; title; footnote ;

options orientation=portrait topmargin=.1in bottommargin=.1in rightmargin=.1in leftmargin=.1in;

options nodate nonumber nocenter ;

ods listing close ;

ods escapechar='\' ;

ods pdf file='c:\temp\other_report.pdf' style=JWTest ;

ods pdf uniform ;

proc report data=yz nowd 

    style(lines)=[TEXTALIGN=left]

    style(header)={background=white}

    style(report)={rules=none frame=void cellspacing=0 cellpadding=2px} ;

    column vlabel vindex question vname letter ;   

    define vname / group noprint ;

    define vlabel / group ' ' ;

    define vindex / group ' ' ;

    define question / group noprint ' ' ;               

    define letter / group ' ' noprint ;

     compute vlabel ;

        call define(_col_,'style', 'style=[font_weight=bold cellwidth=7in marginleft=.50in just=l font_face=Courier ]') ;

    endcomp ;      

    compute vindex ;               

        urlstring='#'||strip(vname) ;

        call define(_col_,'URL',urlstring) ;

        call define(_col_,'style', 'style=[just=l font_face=Courier color=blue cellwidth=.80in]') ;        

        call define(_row_,'style', 'style=[linkcolor=white]') ;                          

    endcomp ;   

    compute after question / style={cellwidth=7in marginleft=.50in just=l font_face=Courier}  ;       

        qlg = length(question);

          line question $varying. qlg;

    endcomp ;

    compute after letter ;

        qlg = length(letter);

          line letter $varying. qlg;

    endcomp ;

run ;

ods pdf close ;

title; footnote ;

Thank you again for everyones help.

jerry898969
Pyrite | Level 9

Hi Cynthia,

Is what I'm trying to do possible in ODS PDF? 

Can I post the pdf i'm trying to mimic to my post to show you what i'm trying to accomplish?  I've just been going in circles and I end up fixing one issue but causing a few more.  Is there a better way in SAS to create a PDF?

Thank you again for all your help.

Jerry

Cynthia_sas
Diamond | Level 26

Hi: I'm teaching this week and next, so I have limited time to write code. But if you post your PDF then other forum members can also see what you're trying to do. The issue that I see with what you've described is that you have to show us the FINAL and complete data. So you can't get a solution for what you've posted and then come back and say, "Well, my data is REALLY like this". That is frustrating for everyone.

   Personally, I think that you may have to either restructure your data or revisit your "cosmetics". In the example I posted (that you didn't like), I showed you a way to get things in the "right" order, but then the column 1 didn't span cosmetically the way you wanted. Trying to do what you're doing in the LINE statement might not work the way you want if the structure of your data changes again, because you can ONLY write a LINE statement at certain "break" points that are defined based on ORDER or GROUP variables.

  You may not be able to post a PDF here, but you should be able to post enough of a screen shot to illustrate your point. Having data without having to make up something fake would be useful, too.

cynthia

jerry898969
Pyrite | Level 9

Hi Cynthia,

Thank you so much for your reply.  I apologize for my vagueness with the data but I'm not allowed to show can real data because of privacy concerns.  I did screen shot one of the pdf's i'm trying to duplicate and attached the images below show the text and the different links.  I do appreciate your suggestions and they have helped me get close.  The issue I have is that I don't have any authority to change the layout of this PDF.   That part is what is causing me the most frustration.  I know if I could do it however would work best that I would have it completed by now.  If this PDF can not be duplicated use ODS PDF then I will be forced to go to my lead and find an alternative solution.  Thank you again for all your help.

page1.jpg

page2.jpg

page3.jpg

Cynthia_sas
Diamond | Level 26

HI: Thanks for posting the screen shot of what you're trying. In looking over your posted PDF, I am not sure that you can produce this with PROC REPORT. You may have to use the Report Writing Interface, as described here http://support.sas.com/resources/papers/proceedings13/040-2013.pdf and here http://support.sas.com/resources/papers/proceedings11/247-2011.pdf (starting on page 13) and http://support.sas.com/resources/papers/proceedings13/015-2013.pdf. Again, to use the Report Writing Interface may mean that you need to restructure your data. But since you haven't posted any data to show us the form that it is in, it is hard to speculate on whether you will need to restructure or not.

  I am still teaching this week and next, so unless someone comes up with a PROC REPORT solution that works, you might need to open a track with Tech Support for some help with this. Tech Support will need to have a copy of your test data, because, (did I mention this?), the structure of your input data will have an impact on the program logic.

cynthia

jerry898969
Pyrite | Level 9

Thank you so much for the suggestion Cynthia I will be taking a look at it.  Here is an example of my test data

ID    YEAR    CATAGORY    VNAMELABEL                QUESTION        LTR LTR_TEXT             CODE CODE_TEXT

1    1968      IndData       VAR1  "DUMMY VARIABLE"  "BIRTH MONTH?"     a   "definition for a"  1    January

1    1968      IndData       VAR1  "DUMMY VARIABLE"  "BIRTH MONTH?"     b    "definition for b"  1    January

1    1968      IndData       VAR1  "DUMMY VARIABLE"  "BIRTH MONTH?"     a    "definition for a"  2    February

1    1968      IndData       VAR1  "DUMMY VARIABLE"  "BIRTH MONTH?"     b    "definition for b"  2    February

1    1968      IndData       VAR1  "DUMMY VARIABLE"  "BIRTH MONTH?"     a    "definition for a"  3    March

1    1968      IndData       VAR1  "DUMMY VARIABLE"  "BIRTH MONTH?"     b    "definition for b"  3    March

1    1968      IndData       VAR1  "DUMMY VARIABLE"  "BIRTH MONTH?"     a    "definition for a"  4    April

1    1968      IndData       VAR1  "DUMMY VARIABLE"  "BIRTH MONTH?"     b    "definition for b"  4    April

1    1968      IndData       VAR1  "DUMMY VARIABLE"  "BIRTH MONTH?"     a    "definition for a"  5    May

1    1968      IndData       VAR1  "DUMMY VARIABLE"  "BIRTH MONTH?"     b    "definition for b"  5    May

Thank you

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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
  • 33 replies
  • 3666 views
  • 6 likes
  • 9 in conversation