DATA Step, Macro, Functions and more

macro parameter

Accepted Solution Solved
Reply
Contributor
Posts: 41
Accepted Solution

macro parameter

I tried to call macro using parameter which is variables, so I cannot write it directly in macro call.  I want pass the value of the variable memname...

 

 


154  options mprint;
155  %macro readdata(mname);
156  filename datafile "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\&mname..xml" ;
157  filename mapfile
157! "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;
158
159  libname datafile xmlv2 xmlmap=mapfile automap=replace;
160
161  proc copy in=datafile out=work;
162  run;
163  %mend;
164
165  data _null_;
166  memname = compress (memname, ".xml");
167  call symput('mname',memname);
168  do i = 1 to &mcount;
169   %readdata(&&mname)
WARNING: Apparent symbolic reference MNAME not resolved.
ERROR: The text expression &MNAME contains a recursive reference to the macro variable MNAME.
       The macro variable will be assigned the null value.
MPRINT(READDATA):   filename datafile
"e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\.xml" ;
MPRINT(READDATA):   filename mapfile
"e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;
MPRINT(READDATA):   libname datafile xmlv2 xmlmap=mapfile automap=replace;
ERROR: With the AUTOMAP= option, the specified XML document must exist.
ERROR: Error in the LIBNAME statement.

NOTE: Line generated by the invoked macro "READDATA".
1      filename datafile "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\&mname..xml"
1  !  ; filename mapfile
1  ! "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;  libname
1  ! datafile xmlv2 xmlmap=mapfile automap=replace;  proc
                                                    -
                                                    117
ERROR 117-185: There was 1 unclosed DO block.

NOTE: Numeric values have been converted to character values at the places given by:
      (Line)Smiley SadColumn).
      166:21   167:21
NOTE: Character values have been converted to numeric values at the places given by:
      (Line)Smiley SadColumn).
      166:11
NOTE: The SAS System stopped processing this step because of errors.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.00 seconds


MPRINT(READDATA):   proc copy in=datafile out=work;
MPRINT(READDATA):   run;
ERROR: Libref DATAFILE is not assigned.
NOTE: Statements not processed because of errors noted above.
NOTE: PROCEDURE COPY used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

NOTE: The SAS System stopped processing this step because of errors.
170  end;
171  run;


Accepted Solutions
Solution
‎01-22-2018 01:59 PM
Super User
Posts: 6,626

Re: macro parameter

That missing part of the program turns out to be important.  Try replacing this DATA step:

 

data _null_;
set contents;
call symput('mname',memname);
do i = 1 to &mcount;
 %readdata(&&mname)
end;
run;

 

Instead, use:

 

data _null_;
set contents;

call execute('%nrstr(%readdata(' || memname || '))' ) ;
run;

 

It's untested (obviously?), but I think I got the quotes in the proper place.

View solution in original post


All Replies
Respected Advisor
Posts: 2,802

Re: macro parameter

The error message is very clear about what the problem is:

 

ERROR 117-185: There was 1 unclosed DO block.

--
Paige Miller
Contributor
Posts: 41

Re: macro parameter

Posted in reply to PaigeMiller

thank you for your quick reply.

I cannot find unclosed do loop anywhere.

 

17   options mprint;
18   %macro readdata(mname);
19   filename datafile "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\&mname..xml" ;
20   filename mapfile
20 ! "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;
21
22   libname datafile xmlv2 xmlmap=mapfile automap=replace;
23
24   proc copy in=datafile out=work;
25   run;
26   %mend;

27   data _null_;
28   set contents;
29   memname = compress (memname, ".xml");
30   call symput('mname',memname);
31   do i = 1 to &mcount;
32    %readdata(&&mname)
WARNING: Apparent symbolic reference MNAME not resolved.
ERROR: The text expression &MNAME contains a recursive reference to the macro variable MNAME.
       The macro variable will be assigned the null value.
MPRINT(READDATA):   filename datafile
"e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\.xml" ;
MPRINT(READDATA):   filename mapfile
"e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;
MPRINT(READDATA):   libname datafile xmlv2 xmlmap=mapfile automap=replace;
ERROR: With the AUTOMAP= option, the specified XML document must exist.
ERROR: Error in the LIBNAME statement.

NOTE: Line generated by the invoked macro "READDATA".
1      filename datafile "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\&mname..xml"
1  !  ; filename mapfile
1  ! "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;  libname
1  ! datafile xmlv2 xmlmap=mapfile automap=replace;  proc
                                                    -
                                                    117
ERROR 117-185: There was 1 unclosed DO block.

NOTE: The SAS System stopped processing this step because of errors.
NOTE: DATA statement used (Total process time):
      real time           0.12 seconds
      cpu time            0.06 seconds


NOTE: Writing HTML Body file: sashtml.htm
MPRINT(READDATA):   proc copy in=datafile out=work;
MPRINT(READDATA):   run;
ERROR: Libref DATAFILE is not assigned.
NOTE: Statements not processed because of errors noted above.
NOTE: PROCEDURE COPY used (Total process time):
      real time           0.30 seconds
      cpu time            0.18 seconds

NOTE: The SAS System stopped processing this step because of errors.
33   end;
34   run;

Super User
Posts: 23,237

Re: macro parameter

Post your code as well. Reading it with the line numbers is problematic.

 

 

Super User
Posts: 6,626

Re: macro parameter

[ Edited ]

At a minimum, you have two issues to fix.

 

Where does &MCOUNT come from? 

 

The DATA step that uses CALL SYMPUT to create &MNAME ... it has to execute CALL SYMPUT in order to create &MNAME.  But the DATA step has not yet executed by the time &MNAME is needed.  This actually requires some in-depth knowledge about the timing of actions in the DATA step vs. macro language.

 

The other issue is that COMPRESS does not work the way you hope.  It does not look for the word ".xml" and remove it.  It looks for all instances of "." and all instances of "x" and all instances of "m" and all instances of "l" and removes any and all of them.  You need a better way to remove ".xml" from the end of your file names, assuming that is your intention.

Contributor
Posts: 41

Re: macro parameter

Posted in reply to Astounding

thank you for your reply.

the first step of the program is like this and the memname and memcount has been created in this step.

1    filename inzip ZIP "e:\Users\mhollifi\Desktop\Jotikasthira\USA_FO_Active_2016-04.zip";
2    data contents;
3     length memname $200;
4     fid=dopen("inzip");
5     PUT 'fid: ' fid=;
6     if fid=0 then
7      stop;
8     memcount=dnum(fid);
9     PUT 'Memcount: ' memcount=;
10    do i=1 to memcount;
11     memname=dread(fid,i);
12     output;
13    end;
14    rc=dclose(fid);
15    call symput('mcount',memcount);
16   run;

NOTE: Numeric values have been converted to character values at the places given by:
      (Line)Smiley SadColumn).
      15:23
fid: fid=1
Memcount: memcount=4172

Contributor
Posts: 41

Re: macro parameter

my code is

 

filename inzip ZIP "e:\Users\mhollifi\Desktop\Jotikasthira\USA_FO_Active_2016-04.zip";
data contents;
 length memname $200;
 fid=dopen("inzip");
 PUT 'fid: ' fid=;
 if fid=0 then
  stop;
 memcount=dnum(fid);
 PUT 'Memcount: ' memcount=;
 do i=1 to memcount;
  memname=dread(fid,i);
  output;
 end;
 rc=dclose(fid);
 call symput('mcount',memcount);
run;
options mprint;
%macro readdata(mname);
filename datafile "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\&mname" ;
filename mapfile  "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;

libname datafile xmlv2 xmlmap=mapfile automap=replace;

proc copy in=datafile out=work;
run;
%mend;

data _null_;
set contents;
call symput('mname',memname);
do i = 1 to &mcount;
 %readdata(&&mname)
end;
run;

Contributor
Posts: 41

Re: macro parameter

thank you all for your help.

When I put run after call symput statement, it reads only the last observation.  I want go through variables after variables.

So the solution with symput doesn't work...How to use variable name as macro parameter?

 

126  options mprint;
127  %macro readdata(mname);
128  filename datafile "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\&mname" ;
129  filename mapfile
129! "e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;
130
131  libname datafile xmlv2 xmlmap=mapfile automap=replace;
132
133  proc copy in=datafile out=work;
134  run;
135  %mend;
136
137  data _null_;
138  set contents;
139  call symput('mname',memname); run;

NOTE: There were 4172 observations read from the data set WORK.CONTENTS.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds


ERROR: The %DO statement is not valid in open code.
140  %do i = 1 %to &mcount;
141   %readdata(&&mname)
MPRINT(READDATA):   filename datafile
"e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\999845-2016-04-30.xml" ;
MPRINT(READDATA):   filename mapfile
"e:\Users\mhollifi\Desktop\Chotibhak\USA_FO_Active_2016-04\5-2016-04-30.map" ;
MPRINT(READDATA):   libname datafile xmlv2 xmlmap=mapfile automap=replace;
ERROR: With the AUTOMAP= option, the specified XML document must exist.
ERROR: Error in the LIBNAME statement.
MPRINT(READDATA):   proc copy in=datafile out=work;
MPRINT(READDATA):   run;
ERROR: Libref DATAFILE is not assigned.
NOTE: Statements not processed because of errors noted above.
NOTE: PROCEDURE COPY used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds

NOTE: The SAS System stopped processing this step because of errors.
ERROR: The %END statement is not valid in open code.
142  %end;
143  run;

 

Solution
‎01-22-2018 01:59 PM
Super User
Posts: 6,626

Re: macro parameter

That missing part of the program turns out to be important.  Try replacing this DATA step:

 

data _null_;
set contents;
call symput('mname',memname);
do i = 1 to &mcount;
 %readdata(&&mname)
end;
run;

 

Instead, use:

 

data _null_;
set contents;

call execute('%nrstr(%readdata(' || memname || '))' ) ;
run;

 

It's untested (obviously?), but I think I got the quotes in the proper place.

Contributor
Posts: 41

Re: macro parameter

Posted in reply to Astounding
thank you. it worked.
☑ This topic is solved.

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

Discussion stats
  • 9 replies
  • 115 views
  • 0 likes
  • 4 in conversation