Get the value of a macro variable into a BOX

Accepted Solution Solved
Reply
Contributor
Posts: 26
Accepted Solution

Get the value of a macro variable into a BOX

Hi All,

 

 

I have a lengthy comment getting into a macro variable from an external text file. Now, I am just writing the value of macro variable into a rtf file using PUT statement .

 

The requirement is, I need to  align the data properly and also it should fit in a box. Thanks in advance.

 

 


Accepted Solutions
Solution
‎01-06-2018 02:18 PM
SAS Super FREQ
Posts: 9,036

Re: Get the value of a macro variable into a BOX

[ Edited ]

Hi:
Most of what you describe can be produced by using a Macro program definition. Where I have my %let statements, you would have some kind of looping construct that would cause the program to create 1 RTF file for each of your subjects. That part is fairly straightforward.

Your requirement for suppressing null strings is easily done with IF statements, my program did not get that complicated, but instead of doing a simple CATX, as I show, you could include another test for the value of any line's macro variable to be missing or not. Something like this, if you were going to do your test inside a DATA step:
else if linenum = 5 then do;
    if "&stdt1" = " " then linestr = " ";
    else if "&stdt1" gt " " then linestr = catx(' ',linestr,"&stdt1")
end;

or, you might choose to make the test part of the macro code and use the presence or absence of the macro variable to determine the code that was written. That is more of a design approach.

For your question about having the comments in an Excel file, my suggestion would be that there are a couple of ways to deal with this. You could either read the subject file and the comment file separately and merge them together ahead of time (before your loop) so that you have the appropriate comment in the same data file with the subjects -- 100 subjects and 5 variables or 6 variables -- even lengthy strings is not going to be too big to process. Or, you could read the Excel file one time for each subject and extract only the comment you need for that subject inside the loop to produce the RTF file. My tendency would be to use the first approach. I'm a fan of getting all my data organized the way I want before I start a reporting step.

I envision 1 PROC REPORT step if you get all the data organized into 1 dataset. However, if the data is in 2 datasets and you need 2 different reports, then I would envision something like this:


** looping structure for each subject;

ods rtf file="&&subj&i..rtf" startpage=no;

** first proc report for main subject information;
** can use a WHERE statement to restrict the PROC REPORT to one subject;

** second proc report for information from Excel file, which you will;
** need to get into a SAS dataset before this step;
** can also use a WHERE statement to restrict the PROC REPORT to the comment ;
** for one subject;

ods rtf close;

** end looping structure;

It really comes down to what you feel comfortable with and what can be maintained over time. For example, you could want 2 types of report -- it's not clear to me what you might want to see produced. Here is an example:

not_clear.png

cynthia

View solution in original post


All Replies
Super User
Super User
Posts: 8,634

Re: Get the value of a macro variable into a BOX

Examples?

 

There are two parts here, first importing the data from the text file into a SAS dataset.  I assume that is fine from your side?

 

Next is outputting to the RTF file, is there a reason you cannot use proc report - as that has border controls, alignment and such like built in, would make life a lot easier?

 

Or is it for a title, if so you can apply styles also to that.  Without some information its really hard to guess.

Contributor
Posts: 26

Re: Get the value of a macro variable into a BOX

[ Edited ]

Thanks for reply.

 

I am writing some data (specific columns for each subject which are fetched from a dataset into macro variables) already through PUT statement into a external RTF file. 

 

At last I have to append Comments (This value I will fetch it from a different file into a macro variable). I am trying to write the value from a macro variable using PUT statement after all columns printed through put statements as mentioned above.

for comments value, I need to display with proper alignment with in a box, just to look good. Now since comments value is a lengthy statement and its not getting displayed properly in the RTF file.

 

as you mentioned, we may try to display the macro variable with in TITLE/FOOTNTE statement with styles applied to it. please suggest how can we do this.  Just assume a macro variable with lengthy single statement in it as a value and we have to write to a RTF file and the value should be with in box.

 

Please consider &comm. has the value, you can see Put "&comm."; in the code below.

 

 

 

%MACRO AEDATA();

%DO i=1 %to &total.;

 

data _NULL_;

file "XXXXXXXXX\testf&i..rtf" print  ;

 

Title;

put ' ';

put ' ';

PUT 'SUBECT ID :' "&&sub&i.";

%IF %sysfunc(length("&&aetrm&i.")) > 2 %then %do;

put 'AE Term is :' "&&aetrm&i.";

%end;

%IF %sysfunc(length(&&llt&i.)) > 0 %then %do;

put 'AE Llt is :' "&&llt&i.";

%end;

put 'Start date is :' "&&stdt&i.";

put '*************************';

put '*************************';

put '*************************';

put '*************************';

put "&comm.";

 

run;

%END;

%MEND;

 

%aedata;

 

 

 

 

Super Contributor
Posts: 424

Re: Get the value of a macro variable into a BOX

Without seeing any data it is difficult to suggest something, except: don't use macro language if you don't have to. RTF-files can be created by ods rtf, there is hardly any need to do this manually with data steps.

Super User
Super User
Posts: 8,634

Re: Get the value of a macro variable into a BOX

As @andreas_lds has said, its far simpler to use the tools built to generate outputs.

 

It looks to me like your creating some sort of patient profile as a text file.  You can achieve the same thing, just get all your data into a dataset and then use proc report - you can add borders, change fonts etc. and with ods rtf create an rtf file from it.  Just putting plain text out to a file, you would need to have a good level of RTF tagset knowledge to apply all the relevant tags.

Super User
Posts: 21,530

Re: Get the value of a macro variable into a BOX

Look at PROC ODSTEXT.

SAS Super FREQ
Posts: 9,036

Re: Get the value of a macro variable into a BOX

Or, in addition to Reeza's suggestion, you could use PROC REPORT to generate something like this:

text_in_box.png

Which was created using ODS RTF with PROC REPORT instead of using PUT statements.

 

Here's the sample code -- instead of putting the program in a loop, I just hardcoded values for the macro variables.

%let  sub1 = Lewis Carroll ;
%let  aetrm1 = Term 1 ;
%let  llt1 = Something Else ;
%let  stdt1 = January 4, 2018 ;
%let  comm1= %str(Twas brillig and the slithy toves did gyre and gimble in the wabe. All mimsy were the borogroves and the momeraths outgrabe.);

data comment;
  length linestr $1000;
  infile datalines dlm=',' dsd;
  input linenum linestr $;
  if linenum = 1 then linestr = catx(' ',linestr,"&sub1");
  else if linenum = 3 then linestr = catx(' ',linestr,"&aetrm1");
  else if linenum = 4 then linestr = catx(' ',linestr,"&llt1");
  else if linenum = 5 then linestr = catx(' ',linestr,"&stdt1");
  else if linenum = 7 then linestr = catx(' ',linestr,"&comm1");
return;
datalines;
1,'^{style[fontweight=bold]SUBECT ID:}'  
2,'^{newline 2}'
3,"^{style[fontweight=bold]AE Term is:} "
4,"^{style[fontweight=bold]AE Llt is:}"
5,"^{style[fontweight=bold]Start date is:}"
6,"*************************"
7,"^{style[fontweight=bold]Comment:}"
;
run;

ods escapechar='^';
options nodate number;
title;

ods rtf file="c:\temp\testf1.rtf" style=rtf;

  proc report data=comment noheader
      style(report)={rules=none frame=box cellspacing=0 width=5in};
  column linenum linestr;
  define linenum / order noprint;
  define linestr / display;
  run;

ods rtf close;
 

Cynthia

Contributor
Posts: 26

Re: Get the value of a macro variable into a BOX

Posted in reply to Cynthia_sas

HI Cynthia,

 

Thanks a lot for your inputs.

 

I will give what exactly my requirement is,

 

1. I have a data set with 100 subjects and 5 variables.

2. For each subject I have to display a separate RTF file with the actual data as per data set in the format that you gave in the

    previous reply. Also For ex: if there is any field, lets assume 'Start date' is one of the fields and for a specific subject start date is  

    Null, we should not get that row at all in the rtf file.

3. At last, I have another Excel input where we get reviewer comments in it in a single cell and it could be very lengthy. I have to

   append those comments to the respective RTF file subject wise with a neat text alignment and borders to it (Comments should be With in a BOX at the end of the RTF file for each subject with proper format).

 

 

please help me on this requirement.

 

Thanks,

Hari

Solution
‎01-06-2018 02:18 PM
SAS Super FREQ
Posts: 9,036

Re: Get the value of a macro variable into a BOX

[ Edited ]

Hi:
Most of what you describe can be produced by using a Macro program definition. Where I have my %let statements, you would have some kind of looping construct that would cause the program to create 1 RTF file for each of your subjects. That part is fairly straightforward.

Your requirement for suppressing null strings is easily done with IF statements, my program did not get that complicated, but instead of doing a simple CATX, as I show, you could include another test for the value of any line's macro variable to be missing or not. Something like this, if you were going to do your test inside a DATA step:
else if linenum = 5 then do;
    if "&stdt1" = " " then linestr = " ";
    else if "&stdt1" gt " " then linestr = catx(' ',linestr,"&stdt1")
end;

or, you might choose to make the test part of the macro code and use the presence or absence of the macro variable to determine the code that was written. That is more of a design approach.

For your question about having the comments in an Excel file, my suggestion would be that there are a couple of ways to deal with this. You could either read the subject file and the comment file separately and merge them together ahead of time (before your loop) so that you have the appropriate comment in the same data file with the subjects -- 100 subjects and 5 variables or 6 variables -- even lengthy strings is not going to be too big to process. Or, you could read the Excel file one time for each subject and extract only the comment you need for that subject inside the loop to produce the RTF file. My tendency would be to use the first approach. I'm a fan of getting all my data organized the way I want before I start a reporting step.

I envision 1 PROC REPORT step if you get all the data organized into 1 dataset. However, if the data is in 2 datasets and you need 2 different reports, then I would envision something like this:


** looping structure for each subject;

ods rtf file="&&subj&i..rtf" startpage=no;

** first proc report for main subject information;
** can use a WHERE statement to restrict the PROC REPORT to one subject;

** second proc report for information from Excel file, which you will;
** need to get into a SAS dataset before this step;
** can also use a WHERE statement to restrict the PROC REPORT to the comment ;
** for one subject;

ods rtf close;

** end looping structure;

It really comes down to what you feel comfortable with and what can be maintained over time. For example, you could want 2 types of report -- it's not clear to me what you might want to see produced. Here is an example:

not_clear.png

cynthia

Contributor
Posts: 26

Re: Get the value of a macro variable into a BOX

Posted in reply to Cynthia_sas
Thanks a Lot Cynthia. :-)
SAS Super FREQ
Posts: 9,036

Re: Get the value of a macro variable into a BOX

You're welcome! BTW, I'm not entirely sure you need to have extensive macro variables for each subject. I created some fake data for the 2 screen shots and did use a macro program for the looping, but did NOT use macro variables to write the values in the box -- I just used regular DATA set variables in a concatenate. I found I did not really need macro variables.

And, as others have explained in regard to your other posting about "appending" to an RTF file. It is very, very hard to create an RTF file and then append any addition output to it. It is far easier to have 1 ODS RTF "sandwich" which captures the output from the first procedure or step and then captures the output from the next procedure or step and puts both outputs into 1 ODS RTF file.

cynthia

cynthia
☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 10 replies
  • 191 views
  • 2 likes
  • 5 in conversation