DATA Step, Macro, Functions and more

Line truncation in a macro

Reply
Regular Contributor
Posts: 194

Line truncation in a macro

Hi,

I have a HTML file that contains a call to some macro display_tab_rows that generates the

rows of a javascript table :

-------

<html>

<head>

<script type="text/javascript" >

var tab=[

       %display_tab_rows;

];

function doSomething() { ...}

</script>

</head>

<body>

...

</body>

</html>

----

Now this macro is defined as follows

/* 1 - first macro to generate the rows */

%macro create_tab_rows(value);

    proc sql;

        SELECT count(*), cats('["',x,'", "', y,'", "' z,'"])

        INTO :nrows, :lst_rows SEPARATED BY '@'

        FROM a_sas_dataset

        WHERE t=&value.;

    quit;

%mend;

/* 2 - second macro for their display */

%macro display_tab_rows;

%local i;

%do i=1 %to &nrows.;
  %let row=%scan(%quote(&lst_rows.),&i.,'@');
  %if &i.<&nrows. %then %do;
&row.,
  %end;
  %else %do;
&row.
  %end;
%end;

%mend;

Finally, the real HTML file is created by the program

data _null_;
file _webout;
infile ref_to_my_html_file;
input;
_infile_ = resolve(_infile_);
put _infile_;
run;

My problem is that the rows are all written on the same line of the output file and the result is truncated after the 256th character.

I would like to write each row on a new line but AFAIK there is no escape character for this in macro language.

I tried "option LRECL=32767;" to remove the output length limitation but it only works locally.

Any idea to either avoid the truncation or insert newlines in macro language ?

Thanks

Regular Contributor
Posts: 194

Re: Line truncation in a macro

A simpler version :

File input.txt (1 line)

8<-----------------------------------

%my_macro

8<-----------------------------------

File prog.sas

8<-----------------------------------

filename in "c:/temp/input.txt";

filename out "c:/temp/output.txt";

%macro my_macro;

hello

everybody

!

How

are

You

?

%mend;

data _null_;

    file out;

    infile in;

    input;

    _infile_ = resolve(_infile_);

    put _infile_;

run;

8<-----------------------------------

output.txt contains : hello everybody ! How are You ?

instead of

hello

everybody

!

How

are

You

?

Is there a way to take carriage returns into account ?

I managed to avoid the length limitation by putting the LRECL option on the infile statement.

Thanks.

Valued Guide
Posts: 2,175

Re: Line truncation in a macro

Try recfm= N

Regular Contributor
Posts: 194

Re: Line truncation in a macro

Using the option recfm=N generates the following error :

ERROR: The '_INFILE_' INPUT/PUT statement option is inconsistent with binary mode I/O.  The

       execution of the DATA STEP is being terminated.

http://support.sas.com/kb/3/404.html proposes using the _INFILE_ option as a workaround but when I

try it (locally), SAS seems to enter an infinite loop. Tried on the simpe "hello" example above, I have to

break the execution to regain control

72

73   data _null_;

74

75       file out;

76       infile in recfm=N _infile_=txtfile;

77       input;

78       *txtfile = resolve(txtfile);

79       put txtfile;

80

81   run;

NOTE: The file OUT is:

      File Name=c:\temp\output.txt,

      RECFM=V,LRECL=256

NOTE: UNBUFFERED is the default with RECFM=N.

NOTE: The infile IN is:

      File Name=c:\temp\input.txt,

      RECFM=N,LRECL=256

NOTE: The data step has been abnormally terminated.

NOTE: 50107773 records were written to the file OUT.

      The minimum record length was 1.

      The maximum record length was 1.

NOTE: DATA statement used (Total process time):

      real time           17.03 seconds

      cpu time            14.26 seconds

Respected Advisor
Posts: 3,777

Re: Line truncation in a macro

Maybe you should look at PROC STREAM.

%macro display_tab_rows;
hello
everybody
!
How
are
You
?
  
%mend;
filename out temp;
proc stream outfile=out;
begin
<html>
<head>
<script type=
"text/javascript" >
var tab=[%
display_tab_rows]
function doSomething() {
...}
</script>
</head>
<body>
...
</body>
</html>
;;;;
   run;
data _null_;
  
infile out;
   input;
  
put _infile_;
  
run;

16         %macro display_tab_rows;
17         hello
18         everybody
19         !
20         How
21         are
22         You
23         ?
24            %mend;
25         filename out temp;
26         proc stream outfile=out;
NOTE: PROC STREAM is an experimental procedure in 9.3.
27         begin
28         <html>
29         <head>
30         <script type="text/javascript" >
31         var tab=[%display_tab_rows]
32         function doSomething() { ...}
33         </script>
34         </head>
NOTE: PROCEDURE STREAM used (Total process time):
      real time          
0.00 seconds
      cpu time           
0.00 seconds
     
35         <body>
36         ...
37         </body>
38         </html>
39         ;;;;

40            run;
41         data _null_;
42            infile out;
43            input;
44            put _infile_;
45            run;

NOTE: The infile OUT is:
      (system-specific pathname),
      (system-specific file attributes)

<html><head><script type=
"text/javascript" >var tab=[hello everybody ! How are You ?]function doSomething() { ...}</script></head><b
ody>
...</body></html>
NOTE:
1 record was read from the infile (system-specific pathname).
      The minimum record length was
153.
      The maximum record length was
153.
NOTE: DATA statement used (Total process time):
      real time          
0.00 seconds
      cpu time           
0.00 seconds
Super User
Posts: 5,081

Re: Line truncation in a macro

Since the words are written out by one statement, you could try modifying that statement.  Instead of:

put _infile_;

Try:

put _infile_ / ;

If by some magic that leaves extra blank lines, try:

put _infile_ / @;

Regular Contributor
Posts: 194

Re: Line truncation in a macro

This does not seem to work. Thanks anyway for your answer.

Regular Contributor
Posts: 194

Re: Line truncation in a macro

Thanks for your suggestions. I will try them next monday since I don't have SAS at home.

I can't use proc stream as I only have access to the 9.1.3 version of SAS

Regular Contributor
Posts: 194

Re: Line truncation in a macro

I could achieve what I wanted to do by using several consecutive data steps :

- one for the header that reads and resolves an external HTML file

- one for the javascrit block that uses put statements

- one for the rest of the document that reads and resolves an external HTML file

Thanks all for your help

Regular Contributor
Posts: 194

Re: Line truncation in a macro

In case it it of interest for someone, I have thought of a more useful solution

that doesn't need to use several data steps : using a predefined sequence of characters

and the tranwrd function to replace all occurrence of this sequence by carriage

returns (hexadecimal '0A') before dumping the resolved file contents to the ouptut file

%macro my_macro;

hello@@@

everybody@@@

!@@@

How@@@

are@@@

You@@@

?

%mend;

data _null_;

    file out linesize=&ls.;

    infile in lrecl=&lr.;

    input;

    _infile_ = tranwrd(resolve(_infile_),"@@@",'0A'x);

    put _infile_;

run;

options linesize on the file statement and lrecl on the infile statement avoid

unwanted line breaks.

This technique allows to create a web application by using html files containing

a few sas macro commands for dynamic content instead of generating html

pages with a lot of put statements in a data step.

Ask a Question
Discussion stats
  • 9 replies
  • 721 views
  • 1 like
  • 4 in conversation