BookmarkSubscribeRSS Feed
gamotte
Rhodochrosite | Level 12

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

9 REPLIES 9
gamotte
Rhodochrosite | Level 12

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.

Peter_C
Rhodochrosite | Level 12

Try recfm= N

gamotte
Rhodochrosite | Level 12

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

data_null__
Jade | Level 19

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
Astounding
PROC Star

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_ / @;

gamotte
Rhodochrosite | Level 12

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

gamotte
Rhodochrosite | Level 12

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

gamotte
Rhodochrosite | Level 12

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

gamotte
Rhodochrosite | Level 12

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.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 9 replies
  • 2344 views
  • 1 like
  • 4 in conversation