BookmarkSubscribeRSS Feed
Rain_28
Fluorite | Level 6

Hi,

Thanks in advance for stopping by and helping.

I am getting an error while writing to a text file using PUT statement. If I remove the inner j loop, the program works fine. Here is the piece of problematic code:

put "%nrstr(%xx());"//
"options validavarname= v7;"//;

%do i=1 %to &n;
put "data &&fm&i.;"/
    "set xx;"/
    %do j = 1 %to &&cnt&i;
	if type = 2 then
	do;
	  if x ne y then 
	  do;
		put +2 x " = " y ";"//
	  end;
	end;
    %end;
"run;"//;
%end;

 Here is the error:

Rain_28_0-1770254685398.png

Please suggest the solution. Thanks again!

4 REPLIES 4
ballardw
Super User

A tool that is good to learn for use in debugging macro related code, your %Do loops are macro code, is to turn on one or more options of Mprint, Symbolgen or Mlogic.  Add something like

options MPRINT;

before the code in question when executed. Use Options nomprint; to turn off.

 

You should see that the resolved code in the LOG using the Mprint that you get a separate instruction code line of "run;" because your current' code does not have that quoted string as part of the argument for the PUT instruction. The current "If type= 2" and related code ends the PUT. So you need another PUT before the "run;".

 

Hint: It is usually a good idea to include the entire code for a data step or procedure that is having issues and better to include a small data set in the form of working data step code that could be used to test the code. Since your code doesn't define where the values of Type, X or Y variables come from I have to assume there is another data set involved and more code using that data set prior to what you have shown.

Tom
Super User Tom
Super User

Your code does not appear to make much sense as written. And there are not any comments explaining what it is trying to do.

 

We could try to add some more code so that we can see what SAS code it is trying to generate.

%macro xx(); This is what XX emits. %mend xx;
%macro test;

put "%nrstr(%xx());"//
"options validavarname= v7;"//;

%do i=1 %to &n;
put "data &&fm&i.;"/
    "set xx;"/
    %do j = 1 %to &&cnt&i;
  if type = 2 then
  do;
    if x ne y then 
    do;
    put +2 x " = " y ";"//
    end;
  end;
    %end;
"run;"//;
%end;

%mend test;

But to test it we will have to make a lot of assumptions about the macro variables it is referencing.

%let n=2;
%let fm=fm;
%let fm1=out1;
%let fm2=out2;
%let cnt=cnt;
%let cnt1=2 ;
%let cnt2=3;

Now we can try calling the macro in the middle of a data step and see what the data step compiler makes of the SAS statements the macro code generates.

options mprint;
data _null_;
%test;
run;

You can see that the macro generates that quoted string outside of any of the other SAS statements it generates.

 MPRINT(TEST):   put "%xx();"// "options validavarname= v7;"//;
 MPRINT(TEST):   put "data out1;"/ "set xx;"/ if type = 2 then do;
 MPRINT(TEST):   if x ne y then do;
 MPRINT(TEST):   put +2 x " = " y ";"// end;
 MPRINT(TEST):   end;
 MPRINT(TEST):   if type = 2 then do;
 MPRINT(TEST):   if x ne y then do;
 MPRINT(TEST):   put +2 x " = " y ";"// end;
 MPRINT(TEST):   end;
 NOTE: Line generated by the invoked macro "TEST".
 106         "run;"//;
             ______
             180
 MPRINT(TEST):   "run;"//;
 MPRINT(TEST):   put "data out2;"/ "set xx;"/ if type = 2 then do;
 MPRINT(TEST):   if x ne y then do;
 MPRINT(TEST):   put +2 x " = " y ";"// end;
 MPRINT(TEST):   end;
 MPRINT(TEST):   if type = 2 then do;
 MPRINT(TEST):   if x ne y then do;
 MPRINT(TEST):   put +2 x " = " y ";"// end;
 MPRINT(TEST):   end;
 MPRINT(TEST):   if type = 2 then do;
 MPRINT(TEST):   if x ne y then do;
 MPRINT(TEST):   put +2 x " = " y ";"// end;
 MPRINT(TEST):   end;
 NOTE: Line generated by the invoked macro "TEST".
 106         "run;"//;
             ______
             180
 MPRINT(TEST):   "run;"//;
 ERROR 180-322: Statement is not valid or it is used out of proper order.
 
 107        run;
 
 NOTE: The SAS System stopped processing this step because of errors.
 NOTE: DATA statement used (Total process time):
       real time           0.00 seconds
       cpu time            0.00 seconds

But it is also generating other silly SAS statements, like:

MPRINT(TEST):   put "data out2;"/ "set xx;"/ if type = 2 then do;
MPRINT(TEST):   put +2 x " = " y ";"// end;

Does your input dataset actually have variables named IF, TYPE , THEN, DO and END? 

 

And that inner %DO loop over the macro variable J makes no sense becuase it is just generating the same code multiple times.  Only way it makes sense is if those macro variables it is referencing can only have values of 0 or 1.  In which case why not just use an %IF %THEN %DO block instead of %DO loop.

 

And how did you get those series of &&FM&I and &&CNT&I variables?  Did you generate them from a dataset? Why not just use the data step that reads in that dataset to drive the loop instead of converting the dataset variables into macro variables and then passing the macro variables back a data step as quoted strings to then write out?

 

 

 

Rain_28
Fluorite | Level 6

I do use mprint, symbolgen, etc options before macro but am not getting this Put statement. It's the first time I am trying to write to a file using PUT. So have a big time confusion where it is ending. I am pretty sure, there must be some issue ending this put statement in the J loop.

This code is part of bigger code and I don't know how much I can copy here. The 2 loops may not be making sense here but they are doing what they are supposed to do. I can try to explain here what they are for:

variable i has count for no. of datasets, for ex: 2 (A & B)

variable j has count of no. of variables in those datasets - For example A has 10 variables & B has 100. I am trying to assign these data variables to another variables and put out in a text file. So that I don't have to manually assign each variables.

 

I had tried as much I could... like adding the PUT statement before run ---> getting error:

Rain_28_0-1770264821868.png

 

If I add extra semi-colon before // , that is also not helping.

put +2 x " = " y ";" ; //

 

andreas_lds
Jade | Level 19

The code posted does not make any sense at all. Please post the complete data step / macro.

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
  • 4 replies
  • 137 views
  • 2 likes
  • 4 in conversation